Hi,

this is a tested patch which introduces a gfp field to usb_submit_urb
and usb_alloc_urb. The changes to hcd.c are incomplete. They just
allow it to compile. I've tested on UP and OHCI.

        Regards
                Oliver

--- drivers/usb/hub.c.alt       Fri Feb  1 16:41:16 2002
+++ drivers/usb/hub.c   Sun Feb  3 14:21:57 2002
@@ -303,7 +303,7 @@
        if (maxp > sizeof(hub->buffer))
                maxp = sizeof(hub->buffer);
 
-       hub->urb = usb_alloc_urb(0);
+       hub->urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!hub->urb) {
                err("couldn't allocate interrupt urb");
                kfree(hub->descriptor);
@@ -312,7 +312,7 @@
 
        FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq,
                hub, endpoint->bInterval);
-       ret = usb_submit_urb(hub->urb);
+       ret = usb_submit_urb(hub->urb, GFP_KERNEL);
        if (ret) {
                err("usb_submit_urb failed (%d)", ret);
                kfree(hub->descriptor);
@@ -498,7 +498,7 @@
                return -1;
 
        hub->urb->dev = dev;                                                    
-       if (usb_submit_urb(hub->urb))
+       if (usb_submit_urb(hub->urb, GFP_KERNEL))
                return -1;
 
        usb_hub_power_on(hub);
@@ -878,6 +878,9 @@
 
 static int usb_hub_thread(void *__hub)
 {
+       int pending = 0;
+       long flags;
+       wait_queue_t wait;
        lock_kernel();
 
        /*
@@ -889,12 +892,20 @@
 
        /* Setup a nice name */
        strcpy(current->comm, "khubd");
-
+       init_waitqueue_entry(&wait, current);
        /* Send me a signal to get me die (for debugging) */
+       add_wait_queue(&khubd_wait, &wait);
        do {
                usb_hub_events();
-               interruptible_sleep_on(&khubd_wait);
+               set_current_state(TASK_INTERRUPTIBLE);
+               spin_lock_irqsave(&hub_event_lock, flags);
+               pending = !list_empty(&hub_event_list);
+               spin_unlock_irqrestore(&hub_event_lock, flags);
+               if (!pending)
+                       schedule();
        } while (!signal_pending(current));
+       remove_wait_queue(&khubd_wait, &wait);
+       set_current_state(TASK_RUNNING);
 
        dbg("usb_hub_thread exiting");
 
@@ -1095,4 +1106,5 @@
 
        return 0;
 }
+
 
--- drivers/usb/hcd.c.pre       Sun Feb  3 11:02:14 2002
+++ drivers/usb/hcd.c   Sun Feb  3 11:04:08 2002
@@ -1316,7 +1316,7 @@
        else if (urb->next) {
                int     status;
 
-               status = usb_submit_urb (urb->next);
+               status = usb_submit_urb (urb->next, GFP_ATOMIC);
                if (status) {
                        dbg ("urb %p chain fail, %d", urb->next, status);
                        urb->next->status = -ENOTCONN;
--- drivers/usb/usb.c.pre       Sun Feb  3 10:18:38 2002
+++ drivers/usb/usb.c   Sun Feb  3 10:51:28 2002
@@ -1087,13 +1087,13 @@
  *
  * The driver must call usb_free_urb() when it is finished with the urb.
  */
-struct urb *usb_alloc_urb(int iso_packets)
+struct urb *usb_alloc_urb(int iso_packets, int gfp)
 {
        struct urb *urb;
 
        urb = (struct urb *)kmalloc(sizeof(struct urb) + 
                iso_packets * sizeof(struct usb_iso_packet_descriptor),
-               in_interrupt() ? GFP_ATOMIC : GFP_KERNEL);
+               gfp);
        if (!urb) {
                err("alloc_urb: kmalloc failed");
                return NULL;
@@ -1199,10 +1199,10 @@
  * the periodic request, and bandwidth reservation is being done for
  * this controller, submitting such a periodic request will fail. 
  */
-int usb_submit_urb(struct urb *urb)
+int usb_submit_urb(struct urb *urb, int gfp)
 {
        if (urb && urb->dev && urb->dev->bus && urb->dev->bus->op)
-               return urb->dev->bus->op->submit_urb(urb);
+               return urb->dev->bus->op->submit_urb(urb, gfp);
        else
                return -ENODEV;
 }
@@ -1272,7 +1272,7 @@
        add_wait_queue(&awd.wqh, &wait);
 
        urb->context = &awd;
-       status = usb_submit_urb(urb);
+       status = usb_submit_urb(urb, GFP_KERNEL);
        if (status) {
                // something went wrong
                usb_free_urb(urb);
@@ -1321,7 +1321,7 @@
        int retv;
        int length;
 
-       urb = usb_alloc_urb(0);
+       urb = usb_alloc_urb(0, GFP_KERNEL);
        if (!urb)
                return -ENOMEM;
   
@@ -1409,7 +1409,7 @@
        if (len < 0)
                return -EINVAL;
 
-       urb=usb_alloc_urb(0);
+       urb=usb_alloc_urb(0, GFP_KERNEL);
        if (!urb)
                return -ENOMEM;
 
--- include/linux/usb.h.pre     Sun Feb  3 10:26:08 2002
+++ include/linux/usb.h Sun Feb  3 11:07:04 2002
@@ -853,11 +853,11 @@
 #define 
FILL_INT_URB(URB,DEV,PIPE,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT,INTERVAL) \
     
usb_fill_int_urb(URB,DEV,PIPE,TRANSFER_BUFFER,BUFFER_LENGTH,COMPLETE,CONTEXT,INTERVAL)
 
-extern struct urb *usb_alloc_urb(int iso_packets);
+extern struct urb *usb_alloc_urb(int iso_packets, int gfp);
 extern void usb_free_urb(struct urb *urb);
 #define usb_put_urb usb_free_urb
 extern struct urb *usb_get_urb(struct urb *urb);
-extern int usb_submit_urb(struct urb *urb);
+extern int usb_submit_urb(struct urb *urb,int gfp);
 extern int usb_unlink_urb(struct urb *urb);
 
 /*-------------------------------------------------------------------*
@@ -906,7 +906,7 @@
        int (*allocate)(struct usb_device *);
        int (*deallocate)(struct usb_device *);
        int (*get_frame_number) (struct usb_device *usb_dev);
-       int (*submit_urb) (struct urb *urb);
+       int (*submit_urb) (struct urb *urb, int gfp);
        int (*unlink_urb) (struct urb *urb);
 };
 

_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to