Lenovo T61, USB fails to power on after resume
Hans Petter Selasky
hps at selasky.org
Tue Jun 3 20:21:06 UTC 2014
On 06/03/14 22:11, Sean Bruno wrote:
> On Tue, 2014-06-03 at 21:59 +0200, Hans Petter Selasky wrote:
>> On 06/03/14 20:28, Sean Bruno wrote:
>>> On Tue, 2014-06-03 at 18:58 +0200, Hans Petter Selasky wrote:
>>>> On 06/03/14 18:36, Sean Bruno wrote:
>>>>> On Tue, 2014-06-03 at 17:54 +0200, Hans Petter Selasky wrote:
>>>>>> On 06/03/14 16:56, Sean Bruno wrote:
>>>>>>> Noted that on resume, the USB ports on my T61 don't seem to be active.
>>>>>>>
>>>>>>> How should I go about debugging this?
>>>>>>>
>>>>>>> sean
>>>>>>
>>>>>> Hi,
>>>>>>
>>>>>> The USB stack performs the same EHCI/OHCI/UHCI/XHCI reset which is does
>>>>>> during power on, when it resumes. Ensure the ports are powered. +5V.
>>>>>> Might be a BIOS/PCI/ACPI issue.
>>>>>>
>>>>>> --HPS
>>>>>>
>>>>>
>>>>>
>>>>> Is there something in the output of usbconfig that I can poke at to see
>>>>> if the hardware *thinks* it is powered on?
>>>>>
>>>>> sean
>>>>>
>>>>>
>>>>
>>>> Yes, there is the port status.
>>>>
>>>> struct usb_port_status {
>>>> uWord wPortStatus;
>>>> #define UPS_CURRENT_CONNECT_STATUS 0x0001
>>>> #define UPS_PORT_ENABLED 0x0002
>>>> #define UPS_SUSPEND 0x0004
>>>> #define UPS_OVERCURRENT_INDICATOR 0x0008
>>>> #define UPS_RESET 0x0010
>>>> #define UPS_PORT_L1 0x0020 /* USB 2.0 only */
>>>> /* The link-state bits are valid for Super-Speed USB HUBs */
>>>> #define UPS_PORT_LINK_STATE_GET(x) (((x) >> 5) & 0xF)
>>>> #define UPS_PORT_LINK_STATE_SET(x) (((x) & 0xF) << 5)
>>>> #define UPS_PORT_LS_U0 0x00
>>>> #define UPS_PORT_LS_U1 0x01
>>>> #define UPS_PORT_LS_U2 0x02
>>>> #define UPS_PORT_LS_U3 0x03
>>>> #define UPS_PORT_LS_SS_DIS 0x04
>>>> #define UPS_PORT_LS_RX_DET 0x05
>>>> #define UPS_PORT_LS_SS_INA 0x06
>>>> #define UPS_PORT_LS_POLL 0x07
>>>> #define UPS_PORT_LS_RECOVER 0x08
>>>> #define UPS_PORT_LS_HOT_RST 0x09
>>>> #define UPS_PORT_LS_COMP_MODE 0x0A
>>>> #define UPS_PORT_LS_LOOPBACK 0x0B
>>>> #define UPS_PORT_LS_RESUME 0x0F
>>>> #define UPS_PORT_POWER 0x0100
>>>> #define UPS_PORT_POWER_SS 0x0200 /* super-speed only */
>>>> #define UPS_LOW_SPEED 0x0200
>>>> #define UPS_HIGH_SPEED 0x0400
>>>> #define UPS_OTHER_SPEED 0x0600 /* currently FreeBSD
>>>> specific */
>>>> #define UPS_PORT_TEST 0x0800
>>>> #define UPS_PORT_INDICATOR 0x1000
>>>> #define UPS_PORT_MODE_DEVICE 0x8000 /* currently FreeBSD
>>>> specific */
>>>> uWord wPortChange;
>>>> #define UPS_C_CONNECT_STATUS 0x0001
>>>> #define UPS_C_PORT_ENABLED 0x0002
>>>> #define UPS_C_SUSPEND 0x0004
>>>> #define UPS_C_OVERCURRENT_INDICATOR 0x0008
>>>> #define UPS_C_PORT_RESET 0x0010
>>>> #define UPS_C_PORT_L1 0x0020 /* USB 2.0 only */
>>>> #define UPS_C_BH_PORT_RESET 0x0020 /* USB 3.0 only */
>>>> #define UPS_C_PORT_LINK_STATE 0x0040
>>>> #define UPS_C_PORT_CONFIG_ERROR 0x0080
>>>> } __packed;
>>>>
>>>> It is probed regularly by the UHUB driver and the port status is printed
>>>> in dmesg.
>>>>
>>>> Turn on like this:
>>>>
>>>> sysctl hw.usb.uhub.debug=16
>>>>
>>>> By resetting the root HUB, you can write new power on bits:
>>>>
>>>> usbconfig -d X.1 set_config 255
>>>> usbconfig -d X.1 set_config 0
>>>>
>>>> --HPS
>>>
>>> Well, that's problematic. The USB tree looks like this normally:
>>>
>>> ugen0.1: <UHCI root HUB Intel> at usbus0, cfg=0 md=HOST spd=FULL
>>> (12Mbps) pwr=SAVE (0mA)
>>> ugen1.1: <UHCI root HUB Intel> at usbus1, cfg=0 md=HOST spd=FULL
>>> (12Mbps) pwr=SAVE (0mA)
>>> ugen2.1: <EHCI root HUB Intel> at usbus2, cfg=0 md=HOST spd=HIGH
>>> (480Mbps) pwr=SAVE (0mA)
>>> ugen3.1: <UHCI root HUB Intel> at usbus3, cfg=0 md=HOST spd=FULL
>>> (12Mbps) pwr=SAVE (0mA)
>>> ugen4.1: <UHCI root HUB Intel> at usbus4, cfg=0 md=HOST spd=FULL
>>> (12Mbps) pwr=SAVE (0mA)
>>> ugen5.1: <UHCI root HUB Intel> at usbus5, cfg=0 md=HOST spd=FULL
>>> (12Mbps) pwr=SAVE (0mA)
>>> ugen6.1: <EHCI root HUB Intel> at usbus6, cfg=0 md=HOST spd=HIGH
>>> (480Mbps) pwr=SAVE (0mA)
>>> ugen0.2: <Biometric Coprocessor STMicroelectronics> at usbus0, cfg=0
>>> md=HOST spd=FULL (12Mbps) pwr=ON (100mA)
>>>
>>>
>>> But, on resume ... sometimes ... ugen0.1 is just flatout gone (along
>>> with the ugen0.2 device, obviously). This only seems to happen with
>>> various USB device plugged in (tried about 4 different make/model usb
>>> sticks and ext drives).
>>>
>>> So, resetting doesn't work as the device is literally gone. Thoughts?
>>>
>>> sean
>>>
>>
>> Setting hw.usb.debug=15 should give you some hints. Are you sure the PCI
>> device is still there after resume?
>>
>> --HPS
>>
>
> I did a pre/post resume pciconf -lv and I see no difference between the
> two.
>
> On initial resume, ugen0.1 appears to be there in usbconfig output, but
> trying to set_config on it, causes it to dissapear and causes usbconfig
> to hang:
>
> root at bruno:/home/sbruno # usbconfig -d 0.1 set_config 255
> load: 0.36 cmd: usbconfig 1540 [UGONE] 4.19r 0.00u 0.00s 0% 2064k
> load: 0.36 cmd: usbconfig 1540 [UGONE] 5.00r 0.00u 0.00s 0% 2064k
> load: 0.36 cmd: usbconfig 1540 [UGONE] 5.16r 0.00u 0.00s 0% 2064k
> load: 0.36 cmd: usbconfig 1540 [UGONE] 5.35r 0.00u 0.00s 0% 2064k
> load: 0.36 cmd: usbconfig 1540 [UGONE] 5.51r 0.00u 0.00s 0% 2064k
>
>
Hi,
What kind of USB devices are attached? Are any of these USB devices
preventing detach? Could you check the USB threads using kgdb?
--HPS
More information about the freebsd-usb
mailing list