I looked at the patch to orinoco_usb.c by Tomasz, which did NOT work for
me properly on FC4's newly released 2.6.14 kernel. After playing
around with it I realized usb_kill_urb can wait holding a spinlock, and
that usb_unlink_urb is now (in 2.6.14) always asynchronous.
So a better patch diff is attached. This works in both 2.6.13 and
2.6.14, for me, with the W200 card. (note that I still compile in the
firmware in my version because I'm lazy about fixing the udev ruleset
that comes with FC4).
It still, however, generates a warning in orinoco.c from the
WirelessExtensions update for the /proc/net/wireless interface that will
go away after 2.6.14.
Someone should merge this fix into the CVS eventually.
--- orinoco_usb.c 2005-11-15 14:56:30.000000000 -0500
+++ orinoco_usb.c.new 2005-11-15 14:19:58.000000000 -0500
@@ -79,10 +79,6 @@
# define fw_dev_param (&interface->dev)
#endif
-#ifndef URB_ASYNC_UNLINK
-#define URB_ASYNC_UNLINK 0
-#endif
-
struct ez_usb_fw {
u16 size;
u8 *code;
@@ -99,7 +95,7 @@
* (typically /usr/lib/hotplug/firmware) and make sure that you have
* hotplug installed and enabled in the kernel.
*/
-/* #define EZUSB_FW_INCLUDED 1 */
+#define EZUSB_FW_INCLUDED 1
#ifdef EZUSB_FW_INCLUDED
/* Header with the firmware */
@@ -365,7 +361,6 @@
{
struct request_context *ctx = (void *) _ctx;
- ctx->outurb->transfer_flags |= URB_ASYNC_UNLINK;
if (usb_unlink_urb(ctx->outurb) == -EINPROGRESS) {
ctx->state = EZUSB_CTX_REQ_TIMEOUT;
} else {
@@ -721,8 +716,7 @@
state);
/* Throw this CTX away and try submitting another */
del_timer(&ctx->timer);
- ctx->outurb->transfer_flags |= URB_ASYNC_UNLINK;
- usb_unlink_urb(ctx->outurb);
+ usb_kill_urb(ctx->outurb);
ezusb_req_queue_run(dev);
break;
} /* switch */
@@ -833,7 +827,7 @@
retval = -ENOENT;
goto exit;
}
- retval = usb_unlink_urb(dev->read_urb);
+ usb_kill_urb(dev->read_urb);
exit:
return retval;
}
@@ -1413,13 +1407,9 @@
ctx = list_entry(item, struct request_context, list);
atomic_inc(&ctx->refcount);
- ctx->outurb->transfer_flags |= URB_ASYNC_UNLINK;
- if (usb_unlink_urb(ctx->outurb) == -EINPROGRESS) {
- spin_unlock_irqrestore(&dev->req_lock, flags);
- wait_for_completion(&ctx->done);
- } else {
- spin_unlock_irqrestore(&dev->req_lock, flags);
- }
+ retval = usb_unlink_urb(ctx->outurb);
+ spin_unlock_irqrestore(&dev->req_lock, flags);
+ if (retval == -EINPROGRESS) wait_for_completion(&ctx->done);
del_timer_sync(&ctx->timer);
/* FIXME: there is an slight chance for the irq handler to
* be running */
|