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