ChangeSet 1.1843.4.19, 2004/08/24 13:38:39-07:00, [EMAIL PROTECTED]

[PATCH] USB: ub patch to use add_timer

It just occured to me that urb->timeout is not functional.


 drivers/block/ub.c |   80 ++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 70 insertions(+), 10 deletions(-)


diff -Nru a/drivers/block/ub.c b/drivers/block/ub.c
--- a/drivers/block/ub.c        2004-08-26 16:42:02 -07:00
+++ b/drivers/block/ub.c        2004-08-26 16:42:02 -07:00
@@ -107,6 +107,8 @@
  * A second ought to be enough for a 32K transfer (UB_MAX_SECTORS)
  * even if a webcam hogs the bus (famous last words).
  * Some CDs need a second to spin up though.
+ * ZIP drive rejects commands when it's not spinning,
+ * so it does not need long timeouts either.
  */
 #define UB_URB_TIMEOUT (HZ*2)
 #define UB_CTRL_TIMEOUT        (HZ/2) /* 500ms ought to be enough to clear a stall */
@@ -287,6 +289,7 @@
 
        struct ub_completion work_done;
        struct urb work_urb;
+       struct timer_list work_timer;
        int last_pipe;                  /* What might need clearing */
        struct bulk_cb_wrap work_bcb;
        struct bulk_cs_wrap work_bcs;
@@ -776,16 +779,20 @@
        sc->last_pipe = sc->send_bulk_pipe;
        usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->send_bulk_pipe,
            bcb, US_BULK_CB_WRAP_LEN, ub_urb_complete, sc);
-       sc->work_urb.timeout = UB_URB_TIMEOUT;
+       sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
 
        /* Fill what we shouldn't be filling, because usb-storage did so. */
        sc->work_urb.actual_length = 0;
        sc->work_urb.error_count = 0;
        sc->work_urb.status = 0;
 
+       sc->work_timer.expires = jiffies + UB_URB_TIMEOUT;
+       add_timer(&sc->work_timer);
+
        if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
                /* XXX Clear stalls */
                printk("ub: cmd #%d start failed (%d)\n", cmd->tag, rc); /* P3 */
+               del_timer(&sc->work_timer);
                ub_complete(&sc->work_done);
                return rc;
        }
@@ -796,6 +803,19 @@
 }
 
 /*
+ * Timeout handler.
+ */
+static void ub_urb_timeout(unsigned long arg)
+{
+       struct ub_dev *sc = (struct ub_dev *) arg;
+       unsigned long flags;
+
+       spin_lock_irqsave(&sc->lock, flags);
+       usb_unlink_urb(&sc->work_urb);
+       spin_unlock_irqrestore(&sc->lock, flags);
+}
+
+/*
  * Completion routine for the work URB.
  *
  * This can be called directly from usb_submit_urb (while we have
@@ -943,14 +963,18 @@
                sc->last_pipe = pipe;
                usb_fill_bulk_urb(&sc->work_urb, sc->dev, pipe,
                    cmd->data, cmd->len, ub_urb_complete, sc);
-               sc->work_urb.timeout = UB_URB_TIMEOUT;
+               sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
                sc->work_urb.actual_length = 0;
                sc->work_urb.error_count = 0;
                sc->work_urb.status = 0;
 
+               sc->work_timer.expires = jiffies + UB_URB_TIMEOUT;
+               add_timer(&sc->work_timer);
+
                if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
                        /* XXX Clear stalls */
                        printk("ub: data #%d submit failed (%d)\n", cmd->tag, rc); /* 
P3 */
+                       del_timer(&sc->work_timer);
                        ub_complete(&sc->work_done);
                        ub_state_done(sc, cmd, rc);
                        return;
@@ -1034,16 +1058,20 @@
                        usb_fill_bulk_urb(&sc->work_urb, sc->dev,
                            sc->recv_bulk_pipe, &sc->work_bcs,
                            US_BULK_CS_WRAP_LEN, ub_urb_complete, sc);
-                       sc->work_urb.timeout = UB_URB_TIMEOUT;
+                       sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
                        sc->work_urb.actual_length = 0;
                        sc->work_urb.error_count = 0;
                        sc->work_urb.status = 0;
 
+                       sc->work_timer.expires = jiffies + UB_URB_TIMEOUT;
+                       add_timer(&sc->work_timer);
+
                        rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC);
                        if (rc != 0) {
                                /* XXX Clear stalls */
                                printk("%s: CSW #%d submit failed (%d)\n",
                                   sc->name, cmd->tag, rc); /* P3 */
+                               del_timer(&sc->work_timer);
                                ub_complete(&sc->work_done);
                                ub_state_done(sc, cmd, rc);
                                return;
@@ -1153,14 +1181,18 @@
        sc->last_pipe = sc->recv_bulk_pipe;
        usb_fill_bulk_urb(&sc->work_urb, sc->dev, sc->recv_bulk_pipe,
            &sc->work_bcs, US_BULK_CS_WRAP_LEN, ub_urb_complete, sc);
-       sc->work_urb.timeout = UB_URB_TIMEOUT;
+       sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
        sc->work_urb.actual_length = 0;
        sc->work_urb.error_count = 0;
        sc->work_urb.status = 0;
 
+       sc->work_timer.expires = jiffies + UB_URB_TIMEOUT;
+       add_timer(&sc->work_timer);
+
        if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
                /* XXX Clear stalls */
                printk("ub: CSW #%d submit failed (%d)\n", cmd->tag, rc); /* P3 */
+               del_timer(&sc->work_timer);
                ub_complete(&sc->work_done);
                ub_state_done(sc, cmd, rc);
                return;
@@ -1233,14 +1265,17 @@
        UB_INIT_COMPLETION(sc->work_done);
 
        usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe,
-           (unsigned char*) cr, NULL, 0,
-           ub_urb_complete, sc);
-       sc->work_urb.timeout = UB_CTRL_TIMEOUT;
+           (unsigned char*) cr, NULL, 0, ub_urb_complete, sc);
+       sc->work_urb.transfer_flags = URB_ASYNC_UNLINK;
        sc->work_urb.actual_length = 0;
        sc->work_urb.error_count = 0;
        sc->work_urb.status = 0;
 
+       sc->work_timer.expires = jiffies + UB_CTRL_TIMEOUT;
+       add_timer(&sc->work_timer);
+
        if ((rc = usb_submit_urb(&sc->work_urb, GFP_ATOMIC)) != 0) {
+               del_timer(&sc->work_timer);
                ub_complete(&sc->work_done);
                return rc;
        }
@@ -1653,6 +1688,12 @@
        complete(cop);
 }
 
+static void ub_probe_timeout(unsigned long arg)
+{
+       struct completion *cop = (struct completion *) arg;
+       complete(cop);
+}
+
 /*
  * Clear initial stalls.
  */
@@ -1661,6 +1702,7 @@
        int endp;
        struct usb_ctrlrequest *cr;
        struct completion compl;
+       struct timer_list timer;
        int rc;
 
        init_completion(&compl);
@@ -1677,21 +1719,35 @@
        cr->wLength = cpu_to_le16(0);
 
        usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe,
-           (unsigned char*) cr, NULL, 0,
-           ub_probe_urb_complete, &compl);
-       sc->work_urb.timeout = UB_CTRL_TIMEOUT;
+           (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl);
+       sc->work_urb.transfer_flags = 0;
        sc->work_urb.actual_length = 0;
        sc->work_urb.error_count = 0;
        sc->work_urb.status = 0;
 
+       init_timer(&timer);
+       timer.function = ub_probe_timeout;
+       timer.data = (unsigned long) &compl;
+       timer.expires = jiffies + UB_CTRL_TIMEOUT;
+       add_timer(&timer);
+
        if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) {
                printk(KERN_WARNING
                     "%s: Unable to submit a probe clear (%d)\n", sc->name, rc);
+               del_timer_sync(&timer);
                return rc;
        }
 
        wait_for_completion(&compl);
 
+       del_timer_sync(&timer);
+       /*
+        * Most of the time, URB was done and dev set to NULL, and so
+        * the unlink bounces out with ENODEV. We do not call usb_kill_urb
+        * because we still think about a backport to 2.4.
+        */
+       usb_unlink_urb(&sc->work_urb);
+
        /* reset the endpoint toggle */
        usb_settoggle(sc->dev, endp, usb_pipeout(sc->last_pipe), 0);
 
@@ -1766,6 +1822,10 @@
        usb_init_urb(&sc->work_urb);
        tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc);
        atomic_set(&sc->poison, 0);
+
+       init_timer(&sc->work_timer);
+       sc->work_timer.data = (unsigned long) sc;
+       sc->work_timer.function = ub_urb_timeout;
 
        ub_init_completion(&sc->work_done);
        sc->work_done.done = 1;         /* A little yuk, but oh well... */



-------------------------------------------------------
SF.Net email is sponsored by Shop4tech.com-Lowest price on Blank Media
100pk Sonic DVD-R 4x for only $29 -100pk Sonic DVD+R for only $33
Save 50% off Retail on Ink & Toner - Free Shipping and Free Gift.
http://www.shop4tech.com/z/Inkjet_Cartridges/9_108_r285
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to