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