Hi,
Tor Krill wrote:
> +static uint16_t portreset;
> +static struct QH qh_list __attribute__ ((aligned (32)));
> +
> +static struct {
> +     uint8_t hub[8];
> +     uint8_t device[18];
> +     uint8_t config[9];
> +     uint8_t interface[9];
> +     uint8_t endpoint[7];
> +} descr = {
> +     {                       /* HUB */
> +             sizeof (descr.hub),     /* bDescLength */
> +                 0x29,       /* bDescriptorType: hub descriptor */
> +                 2,          /* bNrPorts -- runtime modified */
> +                 0, 0,       /* wHubCharacteristics -- runtime modified */
> +                 0xff,       /* bPwrOn2PwrGood */
> +                 0,          /* bHubCntrCurrent */
> +                 0           /* DeviceRemovable XXX at most 7 ports! XXX */
> +     }
> +     , {                     /* DEVICE */
> +             sizeof (descr.device),  /* bLength */
> +                 1,          /* bDescriptorType: UDESC_DEVICE */
> +                 0x00, 0x02, /* bcdUSB: v2.0 */
> +                 9,          /* bDeviceClass: UDCLASS_HUB */
> +                 0,          /* bDeviceSubClass: UDSUBCLASS_HUB */
> +                 1,          /* bDeviceProtocol: UDPROTO_HSHUBSTT */
> +                 64,         /* bMaxPacketSize: 64 bytes */
> +                 0x00, 0x00, /* idVendor */
> +                 0x00, 0x00, /* idProduct */
> +                 0x00, 0x01, /* bcdDevice */
> +                 1,          /* iManufacturer */
> +                 2,          /* iProduct */
> +                 0,          /* iSerialNumber */
> +                 1           /* bNumConfigurations: 1 */
> +     }
> +     , {                     /* CONFIG */
> +             sizeof (descr.config),  /* bLength */
> +                 2,          /* bDescriptorType: UDESC_CONFIG */
> +                 sizeof (descr.config) + sizeof (descr.interface) +
> +                 sizeof (descr.endpoint), 0,
> +                 /* wTotalLength */
> +                 1,          /* bNumInterface */
> +                 1,          /* bConfigurationValue */
> +                 0,          /* iConfiguration */
> +                 0x40,       /* bmAttributes: UC_SELF_POWERED */
> +                 0           /* bMaxPower */
> +     }
> +     , {                     /* INTERFACE */
> +             sizeof (descr.interface),       /* bLength */
> +                 4,          /* bDescriptorType: UDESC_INTERFACE */
> +                 0,          /* bInterfaceNumber */
> +                 0,          /* bAlternateSetting */
> +                 1,          /* bNumEndpoints */
> +                 9,          /* bInterfaceClass: UICLASS_HUB */
> +                 0,          /* bInterfaceSubClass: UISUBCLASS_HUB */
> +                 0,          /* bInterfaceProtocol: UIPROTO_HSHUBSTT */
> +                 0           /* iInterface */
> +     }
> +     , {                     /* ENDPOINT */
> +             sizeof (descr.endpoint),        /* bLength */
> +                 5,          /* bDescriptorType: UDESC_ENDPOINT */
> +                 0x81,       /* bEndpointAddress: UE_DIR_IN | 
> EHCI_INTR_ENDPT */
> +                 3,          /* bmAttributes: UE_INTERRUPT */
> +                 8, 0,       /* wMaxPacketSize */
> +                 255         /* bInterval */
> +     }
> +};
> +
>   
I prefer using:

struct usb_device_descriptor device = {
        sizeof(struct usb_device_descriptor),   /* bLength */
        1,              /* bDescriptorType: UDESC_DEVICE */
        0x0002,         /* bcdUSB: v2.0 */
        9,              /* bDeviceClass: UDCLASS_HUB */
        0,              /* bDeviceSubClass: UDSUBCLASS_HUB */
        1,              /* bDeviceProtocol: UDPROTO_HSHUBSTT */
        64,             /* bMaxPacketSize: 64 bytes */
        0x0000,         /* idVendor */
        0x0000,         /* idProduct */
        0x0001,         /* bcdDevice */
        1,              /* iManufacturer */
        2,              /* iProduct */
        0,              /* iSerialNumber */
        1               /* bNumConfigurations: 1 */
};

struct usb_interface_descriptor interface = {
        sizeof(struct usb_interface_descriptor),        /* bLength */
        4,              /* bDescriptorType: UDESC_INTERFACE */
        0,              /* bInterfaceNumber */
        0,              /* bAlternateSetting */
        1,              /* bNumEndpoints */
        9,              /* bInterfaceClass: UICLASS_HUB */
        0,              /* bInterfaceSubClass: UISUBCLASS_HUB */
        0,              /* bInterfaceProtocol: UIPROTO_HSHUBSTT */
        0               /* iInterface */
};

struct usb_endpoint_descriptor endpoint = {
        sizeof(struct usb_endpoint_descriptor),         /* bLength */
        5,              /* bDescriptorType: UDESC_ENDPOINT */
        0x81,           /* bEndpointAddress: UE_DIR_IN | EHCI_INTR_ENDPT */
        3,              /* bmAttributes: UE_INTERRUPT */
        8, 0,           /* wMaxPacketSize */
        255             /* bInterval */

};

struct usb_hub_descriptor hub = {
        sizeof(struct usb_hub_descriptor),      /* bDescLength */
        0x29,                           /* bDescriptorType: hub 
descriptor */
        2,                              /* bNrPorts -- runtime modified */
        0, 0,                           /* wHubCharacteristics */
        0xff,                           /* bPwrOn2PwrGood */
        {},                             /* bHubCntrCurrent */
        {}                              /* at most 7 ports! XXX */
};

Why don't use somenthing like this? (see up)

> +static int
> +ehci_submit_root (struct usb_device *dev, unsigned long pipe, void *buffer,
> +               int length, struct devrequest *req)
> +{
> +     uint8_t tmpbuf[4];
> +     void *srcptr;
> +     int len, srclen;
> +     uint32_t reg;
> +
> +     srclen = 0;
> +     srcptr = NULL;
> +
> +     debug ("req=%u (%#x), type=%u (%#x), value=%u, index=%u",
> +            req->request, req->request,
> +            req->requesttype, req->requesttype,
> +            le16_to_cpu (req->value), le16_to_cpu (req->index));
> +
> +#define C(a,b)       (((b) << 8) | (a))
> +
> +     switch (C (req->request, req->requesttype)) {
> +     case C (USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RECIP_DEVICE):
> +             switch (le16_to_cpu (req->value) >> 8) {
> +             case USB_DT_DEVICE:
> +                     srcptr = descr.device;
> +                     srclen = sizeof (descr.device);
> +                     break;
> +             case USB_DT_CONFIG:
> +                     srcptr = descr.config;
> +                     srclen = sizeof (descr.config) +
> +                         sizeof (descr.interface) + sizeof (descr.endpoint);
> +                     break;
> +             case USB_DT_STRING:
> +                     switch (le16_to_cpu (req->value) & 0xff) {
> +                     case 0: /* Language */
> +                             srcptr = "\4\3\1\0";
> +                             srclen = 4;
> +                             break;
> +                     case 1: /* Vendor */
> +                             srcptr = "\16\3u\0-\0b\0o\0o\0t\0";
> +                             srclen = 14;
> +                             break;
> +                     case 2: /* Product */
> +                             srcptr = "\52\3E\0H\0C\0I\0 \0H\0o\0s\0t\0 
> \0C\0o\0n\0t\0r\0o\0l\0l\0e\0r\0";
> +                             srclen = 42;
> +                             break;
> +                     default:
> +                             goto unknown;
> +                     }
> +                     break;
> +             default:
> +                     debug ("unknown value %x", le16_to_cpu (req->value));
> +                     goto unknown;
> +             }
> +             break;
> +     case C (USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB):
> +             switch (le16_to_cpu (req->value) >> 8) {
> +             case USB_DT_HUB:
> +                     srcptr = descr.hub;
> +                     srclen = sizeof (descr.hub);
> +                     break;
> +             default:
> +                     debug ("unknown value %x", le16_to_cpu (req->value));
> +                     goto unknown;
> +             }
> +             break;
> +     case C (USB_REQ_SET_ADDRESS, USB_RECIP_DEVICE):
> +             rootdev = le16_to_cpu (req->value);
> +             break;
> +     case C (USB_REQ_SET_CONFIGURATION, USB_RECIP_DEVICE):
> +             /* Nothing to do */
> +             break;
> +     case C (USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB):
> +             tmpbuf[0] = 1;  /* USB_STATUS_SELFPOWERED */
> +             tmpbuf[1] = 0;
> +             srcptr = tmpbuf;
> +             srclen = 2;
> +             break;
> +     case C (USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT):
> +             memset (tmpbuf, 0, 4);
> +             reg = le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 
> 1]);
> +             if (reg & EHCI_PS_CS)
> +                     tmpbuf[0] |= USB_PORT_STAT_CONNECTION;
> +             if (reg & EHCI_PS_PE)
> +                     tmpbuf[0] |= USB_PORT_STAT_ENABLE;
> +             if (reg & EHCI_PS_SUSP)
> +                     tmpbuf[0] |= USB_PORT_STAT_SUSPEND;
> +             if (reg & EHCI_PS_OCA)
> +                     tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT;
> +             if (reg & EHCI_PS_PR)
> +                     tmpbuf[0] |= USB_PORT_STAT_RESET;
> +             if (reg & EHCI_PS_PP)
> +                     tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
> +             tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
> +
> +             if (reg & EHCI_PS_CSC)
> +                     tmpbuf[2] |= USB_PORT_STAT_C_CONNECTION;
> +             if (reg & EHCI_PS_PEC)
> +                     tmpbuf[2] |= USB_PORT_STAT_C_ENABLE;
> +             if (reg & EHCI_PS_OCC)
> +                     tmpbuf[2] |= USB_PORT_STAT_C_OVERCURRENT;
> +             if (portreset & (1 << le16_to_cpu (req->index)))
> +                     tmpbuf[2] |= USB_PORT_STAT_C_RESET;
> +             srcptr = tmpbuf;
> +             srclen = 4;
> +             break;
> +     case C (USB_REQ_SET_FEATURE, USB_DIR_OUT | USB_RT_PORT):
> +             reg = le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 
> 1]);
> +             reg &= ~EHCI_PS_CLEAR;
> +             switch (le16_to_cpu (req->value)) {
> +             case USB_PORT_FEAT_POWER:
> +                     reg |= EHCI_PS_PP;
> +                     break;
> +             case USB_PORT_FEAT_RESET:
> +                     if (EHCI_PS_IS_LOWSPEED (reg)) {
> +                             /* Low speed device, give up ownership. */
> +                             reg |= EHCI_PS_PO;
> +                             break;
> +                     }
> +                     /* Start reset sequence. */
> +                     reg &= ~EHCI_PS_PE;
> +                     reg |= EHCI_PS_PR;
> +                     hcor->or_portsc[le16_to_cpu (req->index) - 1] =
> +                         cpu_to_le32 (reg);
> +                     /* Wait for reset to complete. */
> +                     udelay (500000);
> +                     /* Terminate reset sequence. */
> +                     reg &= ~EHCI_PS_PR;
> +                     /* TODO: is it only fsl chip that requires this
> +                      * manual setting of port enable?
> +                      */
> +                     reg |= EHCI_PS_PE;
> +                     hcor->or_portsc[le16_to_cpu (req->index) - 1] =
> +                         cpu_to_le32 (reg);
> +                     /* Wait for HC to complete reset. */
> +                     udelay (2000);
> +                     reg =
> +                         le32_to_cpu (hcor->or_portsc[le16_to_cpu 
> (req->index) - 1]);
> +                     reg &= ~EHCI_PS_CLEAR;
> +                     if ((reg & EHCI_PS_PE) == 0) {
> +                             /* Not a high speed device, give up ownership. 
> */
> +                             reg |= EHCI_PS_PO;
> +                             break;
> +                     }
> +                     portreset |= 1 << le16_to_cpu (req->index);
> +                     break;
> +             default:
> +                     debug ("unknown feature %x", le16_to_cpu (req->value));
> +                     goto unknown;
> +             }
> +             hcor->or_portsc[le16_to_cpu (req->index) - 1] = cpu_to_le32 
> (reg);
> +             break;
> +     case C (USB_REQ_CLEAR_FEATURE, USB_DIR_OUT | USB_RT_PORT):
> +             reg = le32_to_cpu (hcor->or_portsc[le16_to_cpu (req->index) - 
> 1]);
> +             reg &= ~EHCI_PS_CLEAR;
> +             switch (le16_to_cpu (req->value)) {
> +             case USB_PORT_FEAT_ENABLE:
> +                     reg &= ~EHCI_PS_PE;
> +                     break;
> +             case USB_PORT_FEAT_C_CONNECTION:
> +                     reg |= EHCI_PS_CSC;
> +                     break;
> +             case USB_PORT_FEAT_C_RESET:
> +                     portreset &= ~(1 << le16_to_cpu (req->index));
> +                     break;
> +             default:
> +                     debug ("unknown feature %x", le16_to_cpu (req->value));
> +                     goto unknown;
> +             }
> +             hcor->or_portsc[le16_to_cpu (req->index) - 1] = cpu_to_le32 
> (reg);
> +             break;
> +     default:
> +             debug ("Unknown request %x",
> +                    C (req->request, req->requesttype));
> +             goto unknown;
> +     }
> +
> +#undef C
> +
> +     len = min3 (srclen, le16_to_cpu (req->length), length);
> +     if (srcptr != NULL && len > 0)
> +             memcpy (buffer, srcptr, len);
> +     dev->act_len = len;
> +     dev->status = 0;
> +     return (0);
> +
> +      unknown:
> +     debug ("requesttype=%x, request=%x, value=%x, index=%x, length=%x",
> +            req->requesttype, req->request, le16_to_cpu (req->value),
> +            le16_to_cpu (req->index), le16_to_cpu (req->length));
> +
> +     dev->act_len = 0;
> +     dev->status = USB_ST_STALLED;
> +     return (-1);
> +}
> +
>   
This code can be change according with this one.

static int ehci_submit_root(struct usb_device *dev, unsigned long pipe,
                            void *buffer, int length, struct devrequest 
*req)
{
        uint8_t tmpbuf[4];
        u16 typeReq;
        void *srcptr;
        int len, srclen;
        uint32_t reg;

        srclen = 0;
        srcptr = NULL;

        DBG("req=%u (%#x), type=%u (%#x), value=%u, index=%u",
            req->request, req->request,
            req->requesttype, req->requesttype,
            swap_16(req->value), swap_16(req->index));

        typeReq = req->request << 8 | req->requesttype;

        switch (typeReq) {

        case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
                switch(swap_16(req->value) >> 8) {
                case USB_DT_DEVICE:
                        srcptr = &device;
                        srclen = sizeof(struct usb_device_descriptor);
                        break;
                case USB_DT_CONFIG:
                        srcptr = &config;
                        srclen = sizeof(config) +
                                sizeof(struct usb_interface_descriptor) +
                                sizeof(struct usb_hub_descriptor);
                        break;
                case USB_DT_STRING:
                        switch (swap_16(req->value) & 0xff) {
                        case 0:         /* Language */
                                srcptr = "\4\3\1\0";
                                srclen = 4;
                                break;
                        case 1:         /* Vendor */
                                srcptr = "\20\3P\0h\0i\0l\0i\0p\0s\0";
                                srclen = 16;
                                break;
                        case 2:         /* Product */
                                srcptr = "\12\3E\0H\0C\0I\0";
                                srclen = 10;
                                break;
                        default:
                                goto unknown;
                        }
                        break;
                default:
                        DBG("unknown value %x", swap_16(req->value));
                        goto unknown;
                }
                break;
        case USB_REQ_GET_DESCRIPTOR | (( USB_DIR_IN | USB_RT_HUB) << 8):
                switch (swap_16(req->value) >> 8) {
                case USB_DT_HUB:
                        srcptr = &hub;
                        srclen = sizeof(hub);
                        break;
                default:
                        DBG("unknown value %x", swap_16(req->value));
                        goto unknown;
                }
                break;
        case USB_REQ_SET_ADDRESS | (USB_RECIP_DEVICE << 8):
                rootdev = swap_16(req->value);
                break;
        case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
                /* Nothing to do */
                break;
        case USB_REQ_GET_STATUS | ((USB_DIR_IN | USB_RT_HUB) << 8):
                tmpbuf[0] = 1; /* USB_STATUS_SELFPOWERED */
                tmpbuf[1] = 0;
                srcptr = tmpbuf;
                srclen = 2;
                break;
        case DeviceRequest | USB_REQ_GET_STATUS:
                memset(tmpbuf, 0, 4);
                reg = swap_32(hcor->or_portsc[swap_16(req->index) - 1]);
                if (reg & EHCI_PS_CS)
                        tmpbuf[0] |= USB_PORT_STAT_CONNECTION;
                if (reg & EHCI_PS_PE)
                        tmpbuf[0] |= USB_PORT_STAT_ENABLE;
                if (reg & EHCI_PS_SUSP)
                        tmpbuf[0] |= USB_PORT_STAT_SUSPEND;
                if (reg & EHCI_PS_OCA)
                        tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT;
                if (reg & EHCI_PS_PR)
                        tmpbuf[0] |= USB_PORT_STAT_RESET;
                if (reg & EHCI_PS_PP)
...

All the struct are defined in u-boot and you can reuse that one, I think.

Regards Michael




-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
U-Boot-Users mailing list
U-Boot-Users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/u-boot-users

Reply via email to