Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=ca79b7b4158cbf32625793a1fc1d59ac46d44197
Commit:     ca79b7b4158cbf32625793a1fc1d59ac46d44197
Parent:     3f141e2aed586c41c2666d49c70c1c1bbb6d6abd
Author:     Oliver Neukum <[EMAIL PROTECTED]>
AuthorDate: Mon Feb 12 08:41:35 2007 +0100
Committer:  Greg Kroah-Hartman <[EMAIL PROTECTED]>
CommitDate: Fri Feb 16 15:32:21 2007 -0800

    USB: cdc-acm: fix incorrect throtteling, make set_control optional
    
    this is Joris' fixes reshuffelled and features renamed as David requested.
    
    - acm_set_control is not mandatory, honour that
    - throtteling is reset upon open
    - throtteling is read consistently when processing input data
    
    Signed-off-by: Joris van Rantwijk <[EMAIL PROTECTED]>
    Signed-off-by: Oliver Neukum <[EMAIL PROTECTED]>
    Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]>
---
 drivers/usb/class/cdc-acm.c |   29 ++++++++++++++++++-----------
 include/linux/usb/cdc.h     |    7 +++++++
 2 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 9819962..023cf5d 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -326,10 +326,16 @@ static void acm_rx_tasklet(unsigned long _acm)
        struct tty_struct *tty = acm->tty;
        struct acm_ru *rcv;
        unsigned long flags;
-       int i = 0;
+       unsigned char throttled;
        dbg("Entering acm_rx_tasklet");
 
-       if (!ACM_READY(acm) || acm->throttle)
+       if (!ACM_READY(acm))
+               return;
+
+       spin_lock(&acm->throttle_lock);
+       throttled = acm->throttle;
+       spin_unlock(&acm->throttle_lock);
+       if (throttled)
                return;
 
 next_buffer:
@@ -346,22 +352,20 @@ next_buffer:
        dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size);
 
        tty_buffer_request_room(tty, buf->size);
-       if (!acm->throttle)
+       spin_lock(&acm->throttle_lock);
+       throttled = acm->throttle;
+       spin_unlock(&acm->throttle_lock);
+       if (!throttled)
                tty_insert_flip_string(tty, buf->base, buf->size);
        tty_flip_buffer_push(tty);
 
-       spin_lock(&acm->throttle_lock);
-       if (acm->throttle) {
-               dbg("Throtteling noticed");
-               memmove(buf->base, buf->base + i, buf->size - i);
-               buf->size -= i;
-               spin_unlock(&acm->throttle_lock);
+       if (throttled) {
+               dbg("Throttling noticed");
                spin_lock_irqsave(&acm->read_lock, flags);
                list_add(&buf->list, &acm->filled_read_bufs);
                spin_unlock_irqrestore(&acm->read_lock, flags);
                return;
        }
-       spin_unlock(&acm->throttle_lock);
 
        spin_lock_irqsave(&acm->read_lock, flags);
        list_add(&buf->list, &acm->spare_read_bufs);
@@ -467,7 +471,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file 
*filp)
                goto bail_out;
        }
 
-       if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | 
ACM_CTRL_RTS))
+       if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | 
ACM_CTRL_RTS) &&
+           (acm->ctrl_caps & USB_CDC_CAP_LINE))
                goto full_bailout;
 
        INIT_LIST_HEAD(&acm->spare_read_urbs);
@@ -480,6 +485,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file 
*filp)
                list_add(&(acm->rb[i].list), &acm->spare_read_bufs);
        }
 
+       acm->throttle = 0;
+
        tasklet_schedule(&acm->urb_task);
 
 done:
diff --git a/include/linux/usb/cdc.h b/include/linux/usb/cdc.h
index ba617c3..956edf3 100644
--- a/include/linux/usb/cdc.h
+++ b/include/linux/usb/cdc.h
@@ -73,6 +73,13 @@ struct usb_cdc_acm_descriptor {
        __u8    bmCapabilities;
 } __attribute__ ((packed));
 
+/* capabilities from 5.2.3.3 */
+
+#define USB_CDC_COMM_FEATURE   0x01
+#define USB_CDC_CAP_LINE       0x02
+#define USB_CDC_CAP_BRK        0x04
+#define USB_CDC_CAP_NOTIFY     0x08
+
 /* "Union Functional Descriptor" from CDC spec 5.2.3.8 */
 struct usb_cdc_union_desc {
        __u8    bLength;
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to