Alan Stern wrote:
I think we really should lock the device during configuration changes. ...


Here's another argument you may find more convincing. I went back and
looked at the stuff you wrote before about using a separate lock for the
"logical" children. Let's take that one step further and consider using 3
locks: a logical-children lock (LL) that prevents configuration and
binding changes, a physical-children lock (PL) that prevents adding or removing child devices, and (for want of a better name) a state lock (SL) that prevents suspend/resume/reset/disconnect.

And I've been talking as if semantics for that SL state lock should match the semantics USB defines for those operations: applying to the entire subtree starting at a given port. Maybe that's not true, but it's certainly been part of my assumptions.


Of course the PL only affects hubs.  Notice, however, that any change in
configuration or bindings will necessarily cause a change in the physical
children, since the hub driver will disconnect all the children when it
unbinds.  Hence it makes no sense ever to lock PL and not LL.  What about

But are the scopes the same? If PL were port-specific, and LL were sharable, then it should be possible to grab the shared LL and then the port-specific PL ... and have another task to the same thing for a different port. To talk about such a port-specific lock, I'll introduce the notation PL(n) referring to a lock for just that port. Likewise SL(n), applying to the entire tree below it.


the other way around? Locking LL but not PL means you want to keep the
interfaces and bindings the same but you don't care if children are added
or removed. I suppose you _might_ want to do this on occasion... but
there would be no great loss in always locking PL whenever you lock LL. Thus there's no need to distinguish PL and LL at all; they can be combined
into a single child-lock (CL).

In a sense, it's successful probe() of a hub which creates PL; until that's done, it's just a device that has no driver, but does have an LL.


Now notice that pretty much any time you hold SL you also will want to hold CL. That includes times such as during suspend, resume, reset, and config change, because these state changes will affect all the

That's not quite how I'd parse the problem. Any time you hold SL(n), you'd implicitly hold PL(n) as well as LL for the hub. This suggests that SL(n) and PL(n) might be the same, but not LL; so CL would work a bit differently, maybe like CL(n).

Again, one perspective might be that LL is the upstream link
on any device including a hub, while PL(n) and SL(n) would be
for downstream links -- only on hubs.


interfaces. There are a few times when you might want to hold CL but not SL, such as during tree traversal. But these will be sufficiently infrequent that I think there's no harm in combining CL and SL into a single big lock -- and that's what serialize is!

See above ... I think of dev->serialize as more like PL(n)+SL(n), at least after debouncing and hub->children[n]->serialize exists. Though I'm not sure where that leaves LL; it's not quite the same as dev->parent->serialize since it's exclusive, not sharable.


I haven't gone through all the details of this. It's not clear that all
those states are needed, for example, although they do form a logical set. My main reason for adding them was to let usb_reset_device() work in as
many contexts as possible. One thing I am certain of is that the
interface field needed to deal with the usb-storage/SCSI-EH problem. If
that problem goes away then the field can probably go too.


It turns out that's not correct; the field is still needed so that
reset-during-probe can be detected.  When a reset is done as part of the
probe sequence there's no need to lock the device, so we have to be able
to tell when that is happening.

I'm not sure why reset-during-probe should be a special case though. The only reason it's that way _today_ is because the current version of LL, used during probe to prevent config change, is dev->serialize; while reset processing uses instead it as SL(n).

Maybe dev->serialize should be LL, and maybe sharable; and hubs should
have an array of semaphores SL(n).  Probe would readlock LL, reset
would down(SL[n]), and nobody would collide.

- Dave






-------------------------------------------------------
This SF.Net email is sponsored by Sleepycat Software
Learn developer strategies Cisco, Motorola, Ericsson & Lucent use to deliver higher performing products faster, at low TCO.
http://www.sleepycat.com/telcomwpreg.php?From=osdnemail3
_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to