> > That's not "wrong" ... it's 100% consistent with suspending any other > > hub interface! When it finishes suspending, the down-stream links are > > all suspended; not the upstream one. (True for both faces of the > > downstream link... though the usb_interface is always suspended first.) > > Consider what will happen when we remove _all_ the recursion from the USB > suspend/resume routines. Suspending an external hub's interface won't > have any effect on the downstream ports; they will be affected only when > you call usb_suspend_device for the children.
True, but that must always have happened before the interface can suspend in any case... unless of course USB_SUSPEND is off, in which case root hubs will kick in bus-wide suspend in their hub_suspend() methods. (Which may start by forcing port-by-port suspend anyway...) > What happens when an external hub's interface is suspended but the > downstream ports are still active? Answer: There's no status URB queued, > so usbcore won't be aware of port status changes, but the hub will > continue to relay packets. That's part of why we mark things suspended in software: so we'll reject them consistently, whether or not its upstream (usb) port really IS in a suspend state. Which is I don't like your experiment of dropping that test... > Root hubs should be capable of the same sort of behavior. They should do the same thing, in fact, through the public API (URBs, configurations, etc). There might be bugs though. > ... > At this point, you'll probably want to say that my analysis is wrong, that > virtual root hubs are effectively split into two halves. The USB hub spec describes upstream and downstream signaling separately; figure 11-1 or (for resume signaling) 11-3 shows this. Clearly for root hubs the upstream port is different; no commands can come in through USB, and resume/wakeup signaling can't go out through it either. They both must follow different (non-USB) rules. Virtual root hubs are effectively split into three faces: upstream (pci or other bus ... only external hubs can have USB here), downstream (each usb port), and a stub usb_device (which for external devices would be a proxy for that device's upstream port). upstream: /sys/devices/pci0000:00/0000:00:02.1 downstream: /sys/devices/pci0000:00/0000:00:02.1/usb3/3-0:1.0 stub: /sys/devices/pci0000:00/0000:00:02.1/usb3 Linux won't manage downstream ports except through the hub interface. > The upstream > half is the HC device, and what we've been calling the root hub is really > only the downstream usb_device half. To fully suspend the root hub, it's > necessary to suspend both halves. Or: "to suspend the upstream port, first suspend the downstream ports." Just like any hub, except that it's wired differently. Its upstream link is /sys/class/usb_host/usbN/device not /sys/.../usbN/device/usbN (the stub usb_device) because there is no such USB link. > Nor should it be necessary to make two distinct > suspend calls to suspend a root hub, seeing as how one call suffices for > external hubs. All the USB parts of the root hub are suspended by operations in the USB parts of the driver model. Are you saying you want to equate the upstream link and the stub usb_device ... the non-USB parts with a USB part? If so, why? > Or put it another way. You can fully suspend an external hub by calling > usb_suspend_device(hdev); that single call should suffice even when hdev > is a root hub. The USB calls should certainly affect the USB links that way. I think where we differ is the treatment of non-USB links. You seem to suggest a third model (than what we have now, or than that patch I posted) ... > ... > True. But resuming a hub and calling usb_resume_device for its children > _should_ cause those downstream links to become active, even if the hub's > interface remains suspended. By "resuming a hub" do you mean "resuming its upstream link"? That shouldn't imply resuming the downstream links (though currently it does). We manage downstream links through the hub usb_interface ... it's not meaningful to talk about resuming children before the interface. Even if the driver model does let you do that; this is actually a place where dev->power.pm_parent ought (someday) to solve several problems. > It's clearer to say that with USB_SUSPEND set, usb_suspend_device will > work on any device. Otherwise it will work only on root hubs. Except usb_suspend_device() is all but completely internal to usbcore. Maybe just say it enables (a) selective suspend, and (b) remote wakeup. - Dave ------------------------------------------------------- SF.Net email is sponsored by: Tame your development challenges with Apache's Geronimo App Server. Download it for free - -and be entered to win a 42" plasma tv or your very own Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel