
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