Re: Slightly off-topic, USB code in Linux working, but fails in U-Boot

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Feb 9, 2014, at 9:38 PM, Peter Chen <Peter.Chen@xxxxxxxxxxxxx> wrote:
>> 
>> 
>> Unfortunately, similar reports on the U-Boot mailing list have been met
>> with no useful information. I'm asking here because 1) the setup works on
>> Linux, and 2) there are a lot of knowledgable USB folks here.
>> 
>> That being said, my issue has to do with a Freescale PowerPC SoC based
>> system: P4080 with dual ehci-fsl USB controllers. One of them is internal
>> only, and has a DisplayLink device attached. The second is connected to
>> an internal USB2514 hub, self-powered. The 2514 is then connected to 3
>> external ports. The issues are to do with the second hcd and certain
>> devices connected to the USB2514 hub.
>> 
>> Here is lsusb -t from Linux (as I said, things work in Linux):
>> 
>> /:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=fsl-ehci/1p, 480M
>>    |__ Port 1: Dev 2, If 0, Class=Vendor Specific Class, Driver=udlfb,
>> 480M
>> /:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=fsl-ehci/1p, 480M
>>    |__ Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M
>>        |__ Port 1: Dev 3, If 0, Class=Hub, Driver=hub/3p, 12M
>>            |__ Port 1: Dev 4, If 0, Class=Human Interface Device,
>> Driver=usbhid, 1.5M
>>            |__ Port 1: Dev 4, If 1, Class=Human Interface Device,
>> Driver=usbhid, 1.5M
>>            |__ Port 3: Dev 5, If 0, Class=Human Interface Device,
>> Driver=usbhid, 1.5M
>> 
>> So the problem in U-Boot has to do with device 3 on bus 1, which is a
>> Dell USB keyboard with internal hub (it has two ports on the keyboard for
>> attaching a mouse, etc).
>> 
>> Now, on U-Boot, if I connect a standard device such as a USB stick or USB
>> mouse, to the 2514 (device 2, bus 1), it is detected and works without
>> issue.
>> 
>> However, this external Dell Keyboard Hub (and a few other similar
>> keyboard devices) cause an error when U-Boot tries to probe it. The error
>> occurs when retrieving the descriptor. U-Boot has both methods (8byte and
>> 64byte) for retrieving descriptor, and both fail the same way. The status
>> returned from the hcd is 0x4a (Stalled, XactErr, SplitXState). I've even
>> tried setting the device address first (which succeeds) and then
>> retrieving the descriptor, but that descriptor request fails the same way.
>> 
>> Note that all other devices in this tree are detected fine, including the
>> 2514 Hub, and simple devices attached to it.
>> 
>> Here is the code in question from U-Boot usb.c:
>> 
>>        desc = (struct usb_device_descriptor *)tmpbuf;
>>        dev->descriptor.bMaxPacketSize0 = 64;       /* Start off at 64
>> bytes  */
>>        /* Default to 64 byte max packet size */
>>        dev->maxpacketsize = PACKET_SIZE_64;
>>        dev->epmaxpacketin[0] = 64;
>>        dev->epmaxpacketout[0] = 64;
>> 
>>        err = usb_control_msg(dev, usb_rcvaddr0pipe(),
>>                        USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
>>                        USB_DT_DEVICE << 8, 0, desc, 64,
>>                        USB_CNTL_TIMEOUT);
>> 
>>        if (err < 0) {
>>                printf("usb_new_device: usb_get_descriptor() failed\n");
>>                return 1;
>>        }
>> 
>> This control message fails. Here's the full lsusb output from Linux:
>> 
> 
> - If you have a usb bus analyzer, please check if the GET_DESCRPTOR sends out successfully.
> (Most probably, I don't think it sends out)

Just ordered a Beagle USB-12. I'll see what happens when I get that. The rest of the devices get scanned correctly. My assumption at this point is that the U-Boot creates the qTD's slightly improperly, which most devices ignore, but some devices just choke on and reject.

> - You may need to check if the value for qh and qtd are the same with Linux (for GET_DESCRITPOR)
> The hardware will use qh and qtd to sends data. You can dump memory for that. 
> At linux, the code to print current qh and qtd: at drivers/usb/host/ehci-q.c (fn: qh_link_async)
> NOTE: You can only print current qh/qtd before the async schedule has begun.
> 
>                {
>                int i;
>                struct ehci_qtd *qtd;
>                u32 *qh_addr_virt = qh->hw;
>                printk("addr of qh 0x%x\n", qh_addr_virt);
>                for (i=0; i<12;i++)
>                        printk("0x%x\n", *(u32 *)(qh_addr_virt + i));
>                qtd = list_entry (qh->qtd_list.next,
>                                struct ehci_qtd, qtd_list);
>                printk("addr of qtd 0x%x\n", qtd);
>                for (i=0; i<8;i++)
>                        printk("0x%x\n", *((u32 *)qtd + i));
> 
>                }

Thanks. I'll see if anything shows up with this code.

--
Servergy  : http://www.servergy.com/
SwissDisk : http://www.swissdisk.com/
Ubuntu    : http://www.ubuntu.com/
My Blog   : http://ben-collins.blogspot.com/

Attachment: signature.asc
Description: Message signed with OpenPGP using GPGMail


[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux