Hi Oliver, I decided to see how other drivers deal with this usb_unlink_urb issue. The first thing I looked was devio.c. And guess what, it looks like it assumes that the completion handler has completed by the time usb_unlink_urb finishes:
static void destroy_async (struct dev_state *ps, struct list_head *list) { struct async *as; unsigned long flags; spin_lock_irqsave(&ps->lock, flags); while (!list_empty(list)) { as = list_entry(list->next, struct async, asynclist); list_del_init(&as->asynclist); spin_unlock_irqrestore(&ps->lock, flags); /* usb_unlink_urb calls the completion handler with status == -ENOENT */ usb_unlink_urb(as->urb); spin_lock_irqsave(&ps->lock, flags); } spin_unlock_irqrestore(&ps->lock, flags); while ((as = async_getcompleted(ps))) <=== assumes completion handler finished before this call free_async(as); Hmm, I wonder what the chances are that the next driver I look at suffers from the same kind of problem. All the best, Duncan. On Friday 10 January 2003 14:55, Oliver Neukum wrote: > Am Freitag, 10. Januar 2003 13:21 schrieb Duncan Sands: > > > I am afraid I do not agree. Your reasoning is correct only on UP. > > > If the code in question runs on another CPU, you are in trouble. > > > > It all depends on the semantics of usb_unlink_urb. Consider the > > patch below. Is this any better? Maybe not: if usb_unlink_urb > > returns before the completion handler (running on another CPU) > > reaches the tasklet_schedule statement, then what is to stop > > the tasklet being scheduled by the completion handler after the > > tasklet_kill? Nothing. So it all depends on whether or > > not usb_unlink_urb guarantees that the completion handler has > > finished running before it (usb_unlink_urb) returns. > > if (urb->status != -EINPROGRESS) { > retval = -EBUSY; > goto done; > } > from hcd.c > > So, usb_unlink_urb() will explicitely return if the completion handler > is running. To be safe you need something like: > > (in disconnect() ) > spin_lock_irq(...); > descriptor->disconnected = 1; > tasklet_kill(...); > spin_unlock_irq(...); > > (in the completion handler) > spin_lock(...); > if (!descriptor->disconnected) > tasklet_schedule(...); > spin_unlock(...); > > HTH > Oliver ------------------------------------------------------- This SF.NET email is sponsored by: SourceForge Enterprise Edition + IBM + LinuxWorld = Something 2 See! http://www.vasoftware.com _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel