On Friday 25 May 2007, Tony Lindgren wrote: > + Mostly this patch just seems to move a block of code into a standalone function, removing some nesting ... which is OK as a cleanup, but makes it hard to see the substantive changes in this routine.
So it'd be best to see a minimal patch just fixing any bugs... Those substantive changes unfortunately include inserting bugs ... which would have been easier to see if they were not interspersed with cleanups! > + /* If B-device wants to do HNP, it will do it after we suspend */ > + if (bus->b_hnp_enable) { > + dev_err(&udev->dev, "trying HNP, suspending bus\n"); > + err = __usb_port_suspend(udev, udev->bus->otg_port); No, it shouldn't suspend at this point. If the device is in the targeted peripherals list, the host must continue to try using the device ... using the normal code paths. Here, you've changed it to immediately try HNP, even when the host wants to handle the targeted device (that is, when A_BUS_REQ is true). > + if (err < 0) { > + dev_err(&udev->dev, "suspend for HNP failed\n"); > + return -ENODEV; > + } > + > + /* TB_ASE0_BRST, minimum 3.125 ms */ > + mdelay(4); The assumption was that lower level code would manage T(A/SE0 --> B/RST) as part of triggering HNP in the root hub ... the root hub can always tell if it's triggering HNP, so that timeout applies. Since that timeout tends to have hardware support, I'd rather not see it here. > + > + /* Failed resume means B-device took over the bus with HNP */ There's another suspend/resume sequence to consider. That's one triggered by autosuspend ... or in terms of the OTG spec, when A_BUS_REQ goes false. The original code sequence -- only trigger HNP for unsupported devices -- handled normal use cases correctly: hook up an OTG capable peripheral to the OTG host, it gets used as usual until everything goes idle, then it suspends ("autoidle"), and attempts HNP. If HNP succeeds, work gets done the other direction (host and peripheral roles switched), until *that* is idlle, at which point b_host suspends; disconnect. This modified code sequence skips that primary usage: the peripheral can't be used as a peripheral, since it immediately jumps into host mode. > + err = usb_port_resume(udev); > + if (err < 0) { > + dev_err(&udev->dev, "HNP success\n"); Not an error. Except in the sense that it shouldn't have been tried here at all ... not a _runtime_ error. > + return -ENODEV; > + } > + } > + > + /* HNP failed. Reject B-devices not in our whitelist */ > + if (!is_targeted(udev)) ... and here you fail for the wrong reason. The original logic was OTG-conformant: - Enable HNP "early" (later would be OK too); - For non-whitelisted devices: * trigger HNP if possible * never proceed any further - For whitelisted devices (*) * proceed normally * implicitly, autosuspend triggers HNP This patch removes the primary (*) branch. - Dave > + return -ENODEV; > + > + return 0; ------------------------------------------------------------------------- This SF.net email is sponsored by DB2 Express Download DB2 Express C - the FREE version of DB2 express and take control of your XML. No limits. Just data. Click to get it now. http://sourceforge.net/powerbar/db2/ _______________________________________________ linux-usb-devel@lists.sourceforge.net To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel