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