On Thu, 15 Sep 2005, David Brownell wrote: > > But I was talking about a > > different problem. Even when CONFIG_USB_SUSPEND is set, your patch will > > prevent usbcore from suspending root hubs during FREEZE events. > > Actually it _does_ suspend them ... in the same way it does without > that CONFIG option. That is, as part of suspending the controller > itself. Though (as you pointed out later) because those #ifdefs, the > HCDs don't expect that path when USB_SUSPEND is enabled; we don't > want that to stick around either. > > At any rate, that'd only break an EXPERIMENTAL feature, one that's > clearly labeled as "... may not work as expected ...".
True. See below. > > The patch should have said something more like this: > > > > + udev = to_usb_device(dev); > > + if (message.event == PM_EVENT_FREEZE && udev->parent) { > > + dev->power.power_state = message; > > + return 0; > > + } > > + return usb_suspend_device (udev); > > The operative change being testing udev->parent. I think I prefer > the solution of having the hub suspend code call the root hub suspend > code, to make layering a bit more clear. Do you mean having the HCD suspend code call the root hub suspend code? Either way could work. I prefer to do it this way, though. (1) It would mean we don't lie to the PM core for a brief while, saying that the root hub is in FREEZE when it isn't. (2) The logic is located in this one spot, instead of being copied (error-prone!) among a bunch of different HCDs. Or perhaps you were referring to the change I suggested to the non-USB_SUSPEND version of usb_suspend_device? That won't help with this problem, since without the change above that code wouldn't get called. > > > This seems related to two OHCI regressions I noticed, by the way. > > > > > > In one case, resume-via-reset seems broken without CONFIG_USB_SUSPEND; > > > the root hub timer doesn't restart correctly. (It tries to resubmit > > > the URB while the hub is suspended, fails, then dies.) In the other, > > > wakeup is broken since khubd never notices USB_PORT_STAT_C_SUSPEND; > > > as if the root hub timer stopped (new behavior?) and didn't restart. > > > > It looks like the first problem is a logical error in the USB resume code: > > Device states are set back to USB_STATE_CONFIGURED _after_ the devices are > > resumed. Naturally, URBs can complete as soon as the physical resume is > > done, and completion handlers may try to resubmit -- but they will fail > > until the state is set back. Clearly the state needs to be changed > > _before_ the resume is done. > > Sounds right, but I'll look at that again. There were (are!!) some > funky interactions with root hubs; they've been getting less funky > over time, and are soon (I hope!) to become even less funky. Well, it was close but not quite right. I looked at the ohci_hub_suspend and ohci_hub_resume routines; the problem seems to be that they set hcd->state in the wrong place. For instance, the resume routine doesn't set it back to HC_STATE_RUNNING until just before returning, but port-change interrupts (which will trigger the completion and resubmission of the status URB) can start up many milliseconds earlier. In fact, it seems a little odd that the root-hub routines should affect hcd->state. In the UHCI driver, only the HC routines change it. But of course, that's a matter of personal programming style. > > I don't understand the second problem. Why would you expect wakeup to > > work when CONFIG_USB_SUSPEND isn't set? Why should it have to work at > > all in that case? > > The second case assumed USB_SUSPEND, otherwise there'd be no wakeup! > Sorry for the confusion. :) Maybe fixing the first problem will cure the second problem too. > > Maybe a better fix for this problem would be to make the non-USB_SUSPEND > > version of usb_suspend_device more than just an empty placeholder. > > It's not empty ... it has a "return 0"! And a comment!! By George, you're right about the "return 0"! But I don't see any comments in the routine, although there is a comment on the "#else" line. > Which is part of why your small patch above bothers me: it's NOP unless > the USB_SUSPEND stuff is present. So the two paths would still act > different, and HCDs would still need special casing. > > > > If the > > device is a root hub, do perform the hcd->hub_suspend call. And likewise > > for usb_resume_device, of course. Then all that special indirect upstream > > stuff could be removed from the HCDs. > > We do want to get rid of that special casing in the HCDs, yes. The sooner > the better; it was expedient at the time (when hub_suspend was young, just > last year!, and few HCDs supported it) but now it's just confusing. If we make the second change (non-USB_SUSPEND version of usb_suspend_device) then the first change (usb_generic_suspend) will no longer be a NOP. Making _both_ changes will not only allow removal of the special casing from the HCDs, it also means that the oddball parallel-execution paths are localized to one spot, clearly marked by #ifdef. Furthermore it puts the decision about how to handle a FREEZE where it logically belongs, at the interface between usbcore and the PM core. Above that point we have all the pm_state weirdness, while below it there's nothing but USB suspend or resume. Alan Stern ------------------------------------------------------- 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