ChangeSet 1.1722.83.9, 2004/06/02 13:49:28-07:00, [EMAIL PROTECTED]

[PATCH] USB: fix racy access to urb->status in cdc acm driver

Hi,

fix access to urb->status by introduction of an explicit flag
for finished data transfer.
  - fix racy access to urb->status

Signed-off-by: Oliver Neukum <[EMAIL PROTECTED]>
Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>


 drivers/usb/class/cdc-acm.c |   16 ++++++++++------
 drivers/usb/class/cdc-acm.h |    1 +
 2 files changed, 11 insertions(+), 6 deletions(-)


diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
--- a/drivers/usb/class/cdc-acm.c       Fri Jun 18 11:05:57 2004
+++ b/drivers/usb/class/cdc-acm.c       Fri Jun 18 11:05:57 2004
@@ -223,12 +223,14 @@
        struct acm *acm = (struct acm *)urb->context;
 
        if (!ACM_READY(acm))
-               return;
+               goto out;
 
        if (urb->status)
                dbg("nonzero write bulk status received: %d", urb->status);
 
        schedule_work(&acm->work);
+out:
+       acm->ready_for_write = 1;
 }
 
 static void acm_softint(void *private)
@@ -328,7 +330,7 @@
 
        if (!ACM_READY(acm))
                return -EINVAL;
-       if (acm->writeurb->status == -EINPROGRESS)
+       if (!acm->ready_for_write)
                return 0;
        if (!count)
                return 0;
@@ -344,10 +346,11 @@
        acm->writeurb->transfer_buffer_length = count;
        acm->writeurb->dev = acm->dev;
 
-       /* GFP_KERNEL probably works if from_user */
-       stat = usb_submit_urb(acm->writeurb, GFP_ATOMIC);
+       acm->ready_for_write = 0;
+       stat = usb_submit_urb(acm->writeurb, GFP_NOIO);
        if (stat < 0) {
                dbg("usb_submit_urb(write bulk) failed");
+               acm->ready_for_write = 1;
                return stat;
        }
 
@@ -359,7 +362,7 @@
        struct acm *acm = tty->driver_data;
        if (!ACM_READY(acm))
                return -EINVAL;
-       return acm->writeurb->status == -EINPROGRESS ? 0 : acm->writesize;
+       return !acm->ready_for_write ? 0 : acm->writesize;
 }
 
 static int acm_tty_chars_in_buffer(struct tty_struct *tty)
@@ -367,7 +370,7 @@
        struct acm *acm = tty->driver_data;
        if (!ACM_READY(acm))
                return -EINVAL;
-       return acm->writeurb->status == -EINPROGRESS ? 
acm->writeurb->transfer_buffer_length : 0;
+       return !acm->ready_for_write ? acm->writeurb->transfer_buffer_length : 0;
 }
 
 static void acm_tty_throttle(struct tty_struct *tty)
@@ -610,6 +613,7 @@
        acm->bh.func = acm_rx_tasklet;
        acm->bh.data = (unsigned long) acm;
        INIT_WORK(&acm->work, acm_softint, acm);
+       acm->ready_for_write = 1;
 
 
        if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
diff -Nru a/drivers/usb/class/cdc-acm.h b/drivers/usb/class/cdc-acm.h
--- a/drivers/usb/class/cdc-acm.h       Fri Jun 18 11:05:57 2004
+++ b/drivers/usb/class/cdc-acm.h       Fri Jun 18 11:05:57 2004
@@ -96,6 +96,7 @@
        unsigned int minor;                             /* acm minor number */
        unsigned char throttle;                         /* throttled by tty layer */
        unsigned char clocal;                           /* termios CLOCAL */
+       unsigned char ready_for_write;                  /* write urb can be used */
 };
 
 /* "Union Functional Descriptor" from CDC spec 5.2.3.X */



-------------------------------------------------------
This SF.Net email is sponsored by The 2004 JavaOne(SM) Conference
Learn from the experts at JavaOne(SM), Sun's Worldwide Java Developer
Conference, June 28 - July 1 at the Moscone Center in San Francisco, CA
REGISTER AND SAVE! http://java.sun.com/javaone/sf Priority Code NWMGYKND
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to