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

Reply via email to