On Monday 03 November 2003 01:50, Ted Phelps wrote:
> At the end of September, I wrote:
> > For some time now I've been getting a kernel panic when I kill the
> > Speed Touch user-space daemon, modem_run, and I finally found the
> > time to investigate. The information below is from the
> > linux-2.6.0-test6 kernel but the problem has been going on for a
> > while.
>
> I've done some digging and come up with a patch against
> linux-2.6.0-test9 that Works For Me which I'm offering up criticism.
> Of interest is the comment at the beginning hcd_unlink_urb
> (hcd.c:1155):
>
> /*
> * called in any context; note ASYNC_UNLINK restrictions
> *
> * caller guarantees urb won't be recycled till both unlink()
> * and the urb's completion function return
> */
> static int hcd_unlink_urb (struct urb *urb)
>
>
> I note that the destroy_async function (devio.c:274) does not wait
> until the URB's completion function has returned. A comment
> (devio.c:284) suggests that a call to usb_unlink_urb will immediately
> move a URB from the list of outstanding async operations to the list
> of completed ones (which it then purges). Unfortunately, this is not
> the case if URB_ASYNC_UNLINK is set, as described in usb_unlink_urb's
> comment (urb.c:378):
>
> /**
> * usb_unlink_urb - abort/cancel a transfer request for an endpoint
> * @urb: pointer to urb describing a previously submitted request
> *
> [snip]
> *
> * When the URB_ASYNC_UNLINK transfer flag for the URB is set, this
> * request is asynchronous. Success is indicated by returning
> -EINPROGRESS, * at which time the urb will normally not have been unlinked.
> * The completion function will see urb->status -ECONNRESET. Failure
> * is indicated by any other return value.
> */
Hi Ted, I'm confused. These urbs do not have the URB_ASYNC_UNLINK flag set!
The async in destroy_async etc refers to the fact that user space submits an urb
and gets the result later rather than submits the urb and blocks until it is done,
i.e. these functions implement something which is asynchronous for user space.
It has nothing to do with synchronous vs asynchronous unlinking! Indeed these
urbs are supposed to be unlinked synchronously.
Could you please check if
usb_unlink_urb(as->urb);
returns a non-zero error code?
Thanks,
Duncan.
> The patch below resolves this inconsistency by having destroy_async
> count the number of async operations as it unlinks them and then make
> sure that it reaps completed ones before it returns. I don't know if
> this is legitimate (can the operations be reaped elsewhere?) but it
> resolves the issue I was seeing.
>
> --- usb.diff ---
>
> --- ./linux-2.6.0-test9/drivers/usb/core/devio.c 2003-11-03
> 00:20:02.000000000 +0000 +++
> ./linux-2.6.0-test9/drivers/usb/core/devio.c 2003-11-03 00:29:20.000000000
> +0000 @@ -275,7 +275,9 @@
> {
> struct async *as;
> unsigned long flags;
> + unsigned int count;
>
> + count = 0;
> spin_lock_irqsave(&ps->lock, flags);
> while (!list_empty(list)) {
> as = list_entry(list->next, struct async, asynclist);
> @@ -284,10 +286,20 @@
> /* usb_unlink_urb calls the completion handler with status
> == -ENOENT */ usb_unlink_urb(as->urb);
> spin_lock_irqsave(&ps->lock, flags);
> + count++;
> }
> spin_unlock_irqrestore(&ps->lock, flags);
> - while ((as = async_getcompleted(ps)))
> - free_async(as);
> +
> + /* Make sure we wait for all of the async entries to complete */
> + while (count) {
> + while ((as = async_getcompleted(ps))) {
> + free_async(as);
> + count--;
> + }
> +
> + if (count)
> + schedule();
> + }
> }
>
> static void destroy_async_on_interface (struct dev_state *ps, unsigned int
> intf)
>
> --- end usb.diff ---
>
> Thanks,
> -Ted
-------------------------------------------------------
This SF.net email is sponsored by: SF.net Giveback Program.
Does SourceForge.net help you be more productive? Does it
help you create better code? SHARE THE LOVE, and help us help
YOU! Click Here: http://sourceforge.net/donate/
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-users