Hi,
Here's a patch against 2.4.11-pre6 that updates the usb core code to the
same version that is in the -ac tree.
thanks,
greg k-h
(temporary USB maintainer)
diff --minimal -Nru a/drivers/usb/usb.c b/drivers/usb/usb.c
--- a/drivers/usb/usb.c Tue Oct 9 14:16:55 2001
+++ b/drivers/usb/usb.c Tue Oct 9 14:16:55 2001
@@ -1042,15 +1042,11 @@
*-------------------------------------------------------------------*/
static void usb_api_blocking_completion(urb_t *urb)
{
- api_wrapper_data *awd = (api_wrapper_data *)urb->context;
+ struct usb_api_data *awd = (struct usb_api_data *)urb->context;
- if (waitqueue_active(awd->wakeup))
- wake_up(awd->wakeup);
-#if 0
- else
- dbg("(blocking_completion): waitqueue empty!");
- // even occurs if urb was unlinked by timeout...
-#endif
+ awd->done = 1;
+ wmb();
+ wake_up(&awd->wqh);
}
/*-------------------------------------------------------------------*
@@ -1061,38 +1057,46 @@
static int usb_start_wait_urb(urb_t *urb, int timeout, int* actual_length)
{
DECLARE_WAITQUEUE(wait, current);
- DECLARE_WAIT_QUEUE_HEAD(wqh);
- api_wrapper_data awd;
+ struct usb_api_data awd;
int status;
-
- awd.wakeup = &wqh;
- init_waitqueue_head(&wqh);
- current->state = TASK_INTERRUPTIBLE;
- add_wait_queue(&wqh, &wait);
+
+ init_waitqueue_head(&awd.wqh);
+ awd.done = 0;
+
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ add_wait_queue(&awd.wqh, &wait);
+
urb->context = &awd;
status = usb_submit_urb(urb);
if (status) {
// something went wrong
usb_free_urb(urb);
- current->state = TASK_RUNNING;
- remove_wait_queue(&wqh, &wait);
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&awd.wqh, &wait);
return status;
}
- if (urb->status == -EINPROGRESS) {
- while (timeout && urb->status == -EINPROGRESS)
- status = timeout = schedule_timeout(timeout);
- } else
- status = 1;
+ while (timeout && !awd.done)
+ {
+ timeout = schedule_timeout(timeout);
+ set_current_state(TASK_UNINTERRUPTIBLE);
+ rmb();
+ }
- current->state = TASK_RUNNING;
- remove_wait_queue(&wqh, &wait);
+ set_current_state(TASK_RUNNING);
+ remove_wait_queue(&awd.wqh, &wait);
- if (!status) {
- // timeout
- printk("usb_control/bulk_msg: timeout\n");
- usb_unlink_urb(urb); // remove urb safely
- status = -ETIMEDOUT;
+ if (!timeout && !awd.done) {
+ if (urb->status != -EINPROGRESS) { /* No callback?!! */
+ printk(KERN_ERR "usb: raced timeout, "
+ "pipe 0x%x status %d time left %d\n",
+ urb->pipe, urb->status, timeout);
+ status = urb->status;
+ } else {
+ printk("usb_control/bulk_msg: timeout\n");
+ usb_unlink_urb(urb); // remove urb safely
+ status = -ETIMEDOUT;
+ }
} else
status = urb->status;
@@ -1116,15 +1120,14 @@
if (!urb)
return -ENOMEM;
- FILL_CONTROL_URB(urb, usb_dev, pipe, (unsigned char*)cmd, data, len, /*
build urb */
- (usb_complete_t)usb_api_blocking_completion,0);
+ FILL_CONTROL_URB(urb, usb_dev, pipe, (unsigned char*)cmd, data, len,
+ usb_api_blocking_completion, 0);
retv = usb_start_wait_urb(urb, timeout, &length);
if (retv < 0)
return retv;
else
return length;
-
}
/**
@@ -1205,8 +1208,8 @@
if (!urb)
return -ENOMEM;
- FILL_BULK_URB(urb,usb_dev,pipe,(unsigned char*)data,len, /* build urb */
- (usb_complete_t)usb_api_blocking_completion,0);
+ FILL_BULK_URB(urb, usb_dev, pipe, data, len,
+ usb_api_blocking_completion, 0);
return usb_start_wait_urb(urb,timeout,actual_length);
}
@@ -1767,8 +1770,11 @@
* These are the actual routines to send
* and receive control messages.
*/
-
+#ifdef CONFIG_USB_LONG_TIMEOUT
+#define GET_TIMEOUT 4
+#else
#define GET_TIMEOUT 3
+#endif
#define SET_TIMEOUT 3
int usb_set_address(struct usb_device *dev)
@@ -2410,3 +2416,4 @@
EXPORT_SYMBOL(usb_bulk_msg);
EXPORT_SYMBOL(usb_devfs_handle);
+MODULE_LICENSE("GPL");
diff --minimal -Nru a/drivers/usb/uss720.c b/drivers/usb/uss720.c
--- a/drivers/usb/uss720.c Tue Oct 9 14:16:55 2001
+++ b/drivers/usb/uss720.c Tue Oct 9 14:16:55 2001
@@ -75,9 +75,10 @@
if (!usbdev)
return -1;
ret = usb_control_msg(usbdev, usb_rcvctrlpipe(usbdev,0), 3, 0xc0, ((unsigned
int)reg) << 8, 0, priv->reg, 7, HZ);
- if (ret) {
- printk(KERN_DEBUG "uss720: get_1284_register(%d) failed, status
0x%x\n",
+ if (ret != 7) {
+ printk(KERN_DEBUG "uss720: get_1284_register(%d) failed, status 0x%x
+expected 7\n",
(unsigned int)reg, ret);
+ ret = -1;
} else {
#if 0
printk(KERN_DEBUG "uss720: get_1284_register(%d) return %02x %02x %02x
%02x %02x %02x %02x\n",
@@ -88,6 +89,7 @@
/* if nAck interrupts are enabled and we have an interrupt, call the
interrupt procedure */
if (priv->reg[2] & priv->reg[1] & 0x10)
parport_generic_irq(0, pp, NULL);
+ ret = 0;
}
if (val)
*val = priv->reg[(reg >= 9) ? 0 : regindex[reg]];
@@ -636,6 +638,7 @@
{ USB_DEVICE(0x047e, 0x1001) },
{ USB_DEVICE(0x0557, 0x2001) },
{ USB_DEVICE(0x0729, 0x1284) },
+ { USB_DEVICE(0x1293, 0x0002) },
{ } /* Terminating entry */
};
@@ -653,6 +656,7 @@
MODULE_AUTHOR( DRIVER_AUTHOR );
MODULE_DESCRIPTION( DRIVER_DESC );
+MODULE_LICENSE("GPL");
static int __init uss720_init(void)
{
diff --minimal -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h Tue Oct 9 14:16:55 2001
+++ b/include/linux/usb.h Tue Oct 9 14:16:55 2001
@@ -539,13 +539,12 @@
* SYNCHRONOUS CALL SUPPORT *
*-------------------------------------------------------------------*/
-typedef struct
+struct usb_api_data
{
- wait_queue_head_t *wakeup;
-
- void* stuff;
- /* more to follow */
-} api_wrapper_data;
+ wait_queue_head_t wqh;
+ int done;
+ /* void* stuff; */ /* Possible extension later. */
+};
/* -------------------------------------------------------------------------- */
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel