[mc1322x] [PATCH 4/4] handle cases with the linux driver is out of sync with the serial

Mariano Alvira mar at devl.org
Mon Mar 29 19:52:30 EDT 2010


clean up state instead of bugging out

check that we aren't going to overflow the allocated receive data.
---
 drivers/ieee802154/serial.c |   38 +++++++++++++++++++++++---------------
 1 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/drivers/ieee802154/serial.c b/drivers/ieee802154/serial.c
index 0c6c012..033ef2a 100644
--- a/drivers/ieee802154/serial.c
+++ b/drivers/ieee802154/serial.c
@@ -133,6 +133,18 @@ struct zb_device {
  *****************************************************************************/
 static int _open_dev(struct zb_device *zbdev);
 
+static void
+cleanup(struct zb_device *zbdev)
+{
+	zbdev->state = STATE_WAIT_START1;
+	zbdev->id = 0;
+	zbdev->param1 = 0;
+	zbdev->param2 = 0;
+	zbdev->index = 0;
+	zbdev->pending_id = 0;
+	zbdev->pending_size = 0;
+}
+
 static int
 _send_pending_data(struct zb_device *zbdev)
 {
@@ -181,7 +193,8 @@ send_cmd(struct zb_device *zbdev, u8 id)
 	if (zbdev->pending_size) {
 		printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
 			__func__, zbdev->pending_id);
-		BUG();
+		cleanup(zbdev);
+		return -EAGAIN;
 	}
 
 	/* Prepare a message */
@@ -222,7 +235,8 @@ send_cmd2(struct zb_device *zbdev, u8 id, u8 extra)
 	if (zbdev->pending_size) {
 		printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
 			__func__, zbdev->pending_id);
-		BUG();
+		cleanup(zbdev);
+		return -EAGAIN;
 	}
 
 	/* Prepare a message */
@@ -262,7 +276,8 @@ send_block(struct zb_device *zbdev, u8 len, u8 *data)
 	if (zbdev->pending_size) {
 		printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
 			__func__, zbdev->pending_id);
-		BUG();
+		cleanup(zbdev);
+		return -EAGAIN;
 	}
 
 	/* Prepare a message */
@@ -286,16 +301,6 @@ send_block(struct zb_device *zbdev, u8 len, u8 *data)
 	return _send_pending_data(zbdev);
 }
 
-static void
-cleanup(struct zb_device *zbdev)
-{
-	zbdev->state = STATE_WAIT_START1;
-	zbdev->id = 0;
-	zbdev->param1 = 0;
-	zbdev->param2 = 0;
-	zbdev->index = 0;
-}
-
 static int
 is_command(unsigned char c)
 {
@@ -446,7 +451,8 @@ process_char(struct zb_device *zbdev, unsigned char c)
 		break;
 
 	case STATE_WAIT_DATA:
-		if (zbdev->index < sizeof(zbdev->data)) {
+		if ((zbdev->index < sizeof(zbdev->data)) &&
+		    (zbdev->param2 <= sizeof(zbdev->data))) {
 			zbdev->data[zbdev->index] = c;
 			zbdev->index++;
 			/*
@@ -454,6 +460,7 @@ process_char(struct zb_device *zbdev, unsigned char c)
 			 * param2 is length for DATA_RECV_BLOCK
 			 */
 			if (zbdev->index == zbdev->param2) {
+				zbdev->state = STATE_WAIT_START1;
 				process_command(zbdev);
 				cleanup(zbdev);
 			}
@@ -489,7 +496,8 @@ static int _open_dev(struct zb_device *zbdev)
 	if (zbdev->pending_size) {
 		printk(KERN_ERR "%s(): cmd is already pending, id = %u\n",
 			__func__, zbdev->pending_id);
-		BUG();
+		cleanup(zbdev);
+		return -EAGAIN;
 	}
 
 	/* Prepare a message */
-- 
1.7.0.3




More information about the mc1322x mailing list