[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