> I'm going to guess that you will object to the race condition that exists
> between the time the flag is tested and the URB is submitted. Yes,
> there's a race. But it is unavoidable, unless you want to surround every
> call to the usb core with a spinlock_irq or the equivalent. And in any
That's exactly what's needed. But why irq? Disconnect() runs from task
context.
> case it doesn't matter, since we only want to guarantee that no URB will
> be submitted after disconnect() _returns_. We don't need to (and in fact
> cannot) guarantee that no URB will be submitted after disconnect() _is
> called_.
Right. But why should this matter? If there's a race there's a race.
Unless you can guarantee that disconnect() setting a flag for disconnection
and an urb being submitted or a synchronous helper running don't race
it's a bug.
> Perhaps the real question is: Do we need to guarantee that no URBs will
> remain outstanding after disconnect() returns? This seems to be what you
if (!(dev = urb->dev) || !dev->bus || dev->devnum <= 0)
return -ENODEV;
if (!(op = dev->bus->op) || !op->submit_urb)
return -ENODEV;
from usb_submit_urb(). This is deadly. Unlinking after disconnect() is
deadly as well.
But for an indeterminate amount of time after usb_submit_urb is called,
it's dangerous. Shortly, it's safe only if they are dead.
> are getting at. Unfortunately, I haven't seen written down anywhere
> exactly what conditions the driver needs to satisfy. It would be nice if
> this sort of thing could be added to the documentation somewhere.
Yes.
> > > Here's a suggestion that would help all existing usb drivers. Add an
> > > additional parameter to usb_control_msg (and the other synchronous
> > > message subroutines as well) that takes a struct urb **. The
> > > subroutines can use it to store a pointer to the dynamically allocated
> > > URB, so that the driver would have the ability to cancel the URB
> > > whenever it wanted.
> >
> > No, not whenever, only after the synchronous call has set the pointer.
> > Which you cannot know.
>
> I'm afraid you're right about that. Maybe the synchronous call routines
> should be eliminated entirely.
Now, a week before freeze?
> > I think that it won't work. The correct sequence is:
> > ...
> > down()
> > if (device_not_disconnected)
> > synchronous_call()
> > up()
> > ...
> >
> > and in disconnect():
> >
> > down()
> > mark_as_disconnected()
> > up()
> >
> > As you can see, the check for disconnection cannot be in the synchronous
> > helper.
>
> I'm not clear on how this helps. Yes, if you do it this way then you
> never have to cancel a synchronous message. But instead you force
> disconnect() to hang around waiting until the synchronous message
> completes. Is that really any better? And if it is, why not have
Disconnect() may block. As long as there's an upper limit, it's safe.
> disconnect() do the mark_as_disconnected() before doing the down()?
Why not. I see no real difference.
> > The solution you suggest only works if you can ensure that the
> > synchronous call has given you a handle to unlink the urb before
> > disconnect() runs. To do so requires the synchronous helper to be called
> > with a lock against disconnect() already held.
>
> Well no, I only need to insure that the synchronous call has given me a
> handle before disconnect() _returns_. But I agree that it's a problem.
You cannot do that as well. Furthermore you must not call a synchronous
call after disconnect() has returned. The device pointer you pass is
dangerous.
> My feeling is that we need either to rethink the synchronous calls or get
> rid of them altogether. There's another aspect of usb-storage that runs
It's a week till feature freeze.
> into difficulties with regard to synchronous calls. The problem is that
> most of the things that usb-storage does come about because of calls from
> the scsi layer, and most of these calls are protected by a timeout and
> abort handler. But not all of them are, and also there are a few things
> usb-storage does on its own behalf (initialization, mostly) that also do
> not have the protection of an abort handler.
>
> As a result, we have to be able to abort some calls on demand but not
> others, and we have to use timeouts for some calls but not others. It's a
> real mess, and we haven't gotten it straightened out yet. My vote goes
> for making things as uniform as possible, but Matt Dharm doesn't agree.
> He has said that the driver should use different code paths for the
> different situations. Maybe this discussion about the problems with
> synchronous calls will make us rethink the whole question.
I am afraid I don't know the storage driver well enough to comment on that.
Regards
Oliver
-------------------------------------------------------
This sf.net email is sponsored by: Influence the future
of Java(TM) technology. Join the Java Community
Process(SM) (JCP(SM)) program now.
http://ads.sourceforge.net/cgi-bin/redirect.pl?sunm0002en
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel