diff options
-rw-r--r-- | drivers/usb/serial/mos7840.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 603fb70dde80..73dda1cc8028 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -183,6 +183,10 @@ | |||
183 | #define LED_ON_MS 500 | 183 | #define LED_ON_MS 500 |
184 | #define LED_OFF_MS 500 | 184 | #define LED_OFF_MS 500 |
185 | 185 | ||
186 | enum mos7840_flag { | ||
187 | MOS7840_FLAG_CTRL_BUSY, | ||
188 | }; | ||
189 | |||
186 | static int device_type; | 190 | static int device_type; |
187 | 191 | ||
188 | static const struct usb_device_id id_table[] = { | 192 | static const struct usb_device_id id_table[] = { |
@@ -241,6 +245,8 @@ struct moschip_port { | |||
241 | bool led_flag; | 245 | bool led_flag; |
242 | struct timer_list led_timer1; /* Timer for LED on */ | 246 | struct timer_list led_timer1; /* Timer for LED on */ |
243 | struct timer_list led_timer2; /* Timer for LED off */ | 247 | struct timer_list led_timer2; /* Timer for LED off */ |
248 | |||
249 | unsigned long flags; | ||
244 | }; | 250 | }; |
245 | 251 | ||
246 | /* | 252 | /* |
@@ -460,10 +466,10 @@ static void mos7840_control_callback(struct urb *urb) | |||
460 | case -ESHUTDOWN: | 466 | case -ESHUTDOWN: |
461 | /* this urb is terminated, clean up */ | 467 | /* this urb is terminated, clean up */ |
462 | dev_dbg(dev, "%s - urb shutting down with status: %d\n", __func__, status); | 468 | dev_dbg(dev, "%s - urb shutting down with status: %d\n", __func__, status); |
463 | return; | 469 | goto out; |
464 | default: | 470 | default: |
465 | dev_dbg(dev, "%s - nonzero urb status received: %d\n", __func__, status); | 471 | dev_dbg(dev, "%s - nonzero urb status received: %d\n", __func__, status); |
466 | return; | 472 | goto out; |
467 | } | 473 | } |
468 | 474 | ||
469 | dev_dbg(dev, "%s urb buffer size is %d\n", __func__, urb->actual_length); | 475 | dev_dbg(dev, "%s urb buffer size is %d\n", __func__, urb->actual_length); |
@@ -476,6 +482,8 @@ static void mos7840_control_callback(struct urb *urb) | |||
476 | mos7840_handle_new_msr(mos7840_port, regval); | 482 | mos7840_handle_new_msr(mos7840_port, regval); |
477 | else if (mos7840_port->MsrLsr == 1) | 483 | else if (mos7840_port->MsrLsr == 1) |
478 | mos7840_handle_new_lsr(mos7840_port, regval); | 484 | mos7840_handle_new_lsr(mos7840_port, regval); |
485 | out: | ||
486 | clear_bit_unlock(MOS7840_FLAG_CTRL_BUSY, &mos7840_port->flags); | ||
479 | } | 487 | } |
480 | 488 | ||
481 | static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, | 489 | static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, |
@@ -486,6 +494,9 @@ static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, | |||
486 | unsigned char *buffer = mcs->ctrl_buf; | 494 | unsigned char *buffer = mcs->ctrl_buf; |
487 | int ret; | 495 | int ret; |
488 | 496 | ||
497 | if (test_and_set_bit_lock(MOS7840_FLAG_CTRL_BUSY, &mcs->flags)) | ||
498 | return -EBUSY; | ||
499 | |||
489 | dr->bRequestType = MCS_RD_RTYPE; | 500 | dr->bRequestType = MCS_RD_RTYPE; |
490 | dr->bRequest = MCS_RDREQ; | 501 | dr->bRequest = MCS_RDREQ; |
491 | dr->wValue = cpu_to_le16(Wval); /* 0 */ | 502 | dr->wValue = cpu_to_le16(Wval); /* 0 */ |
@@ -497,6 +508,9 @@ static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, | |||
497 | mos7840_control_callback, mcs); | 508 | mos7840_control_callback, mcs); |
498 | mcs->control_urb->transfer_buffer_length = 2; | 509 | mcs->control_urb->transfer_buffer_length = 2; |
499 | ret = usb_submit_urb(mcs->control_urb, GFP_ATOMIC); | 510 | ret = usb_submit_urb(mcs->control_urb, GFP_ATOMIC); |
511 | if (ret) | ||
512 | clear_bit_unlock(MOS7840_FLAG_CTRL_BUSY, &mcs->flags); | ||
513 | |||
500 | return ret; | 514 | return ret; |
501 | } | 515 | } |
502 | 516 | ||