cleaned up

This commit is contained in:
Markus Fröschle
2013-12-15 07:04:54 +00:00
parent 060dcbfed3
commit 0cf42dbbf9
4 changed files with 255 additions and 59 deletions

View File

@@ -34,10 +34,11 @@
#undef DEBUG
#undef SHOW_INFO
char ehci_inited;
static char ehci_inited;
static int rootdev;
static uint16_t portreset, companion;
static uint16_t portreset;
static uint16_t companion;
struct descriptor {
struct usb_hub_descriptor hub;
@@ -49,26 +50,26 @@ struct descriptor {
static struct descriptor rom_descriptor = {
{
0x8, /* bDescLength */
0x29, /* bDescriptorType: hub descriptor */
0x8, /* bDescLength */
0x29, /* bDescriptorType: hub descriptor */
2, /* bNrPorts -- runtime modified */
0, /* wHubCharacteristics */
0xff, /* bPwrOn2PwrGood */
0xff, /* bPwrOn2PwrGood */
0, /* bHubCntrCurrent */
{}, /* Device removable */
{} /* at most 7 ports! XXX */
},
{
0x12, /* bLength */
0x12, /* bLength */
1, /* bDescriptorType: UDESC_DEVICE */
0x0002, /* bcdUSB: v2.0 */
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 */
0x0000, /* idVendor */
0x0000, /* idProduct */
0x0001, /* bcdDevice */
1, /* iManufacturer */
2, /* iProduct */
0, /* iSerialNumber */
@@ -81,11 +82,11 @@ static struct descriptor rom_descriptor = {
1, /* bNumInterface */
1, /* bConfigurationValue */
0, /* iConfiguration */
0x40, /* bmAttributes: UC_SELF_POWER */
0x40, /* bmAttributes: UC_SELF_POWER */
0 /* bMaxPower */
},
{
0x9, /* bLength */
0x9, /* bLength */
4, /* bDescriptorType: UDESC_INTERFACE */
0, /* bInterfaceNumber */
0, /* bAlternateSetting */
@@ -96,11 +97,11 @@ static struct descriptor rom_descriptor = {
0 /* iInterface */
},
{
0x7, /* bLength */
0x7, /* bLength */
5, /* bDescriptorType: UDESC_ENDPOINT */
0x81, /* bEndpointAddress: UE_DIR_IN | EHCI_INTR_ENDPT */
0x81, /* bEndpointAddress: UE_DIR_IN | EHCI_INTR_ENDPT */
3, /* bmAttributes: UE_INTERRUPT */
8, 0, /* wMaxPacketSize */
8, 0, /* wMaxPacketSize */
255 /* bInterval */
},
};
@@ -143,7 +144,8 @@ struct pci_device_id ehci_usb_pci_table[] =
}
};
static struct ehci {
static struct ehci
{
/* ------- common part -------- */
long handle; /* PCI BIOS */
const struct pci_device_id *ent;
@@ -195,6 +197,7 @@ static void cache_qh(struct QH *qh, int flush)
struct qTD *qtd;
struct qTD *next;
static struct qTD *first_qtd;
/* Walk the QH list and flush/invalidate all entries */
while(1)
{
@@ -205,6 +208,7 @@ static void cache_qh(struct QH *qh, int flush)
qh = (struct QH *)(swpl(qh->qh_link) + gehci.dma_offset);
}
qh = qh_addr(qh);
/* Save first qTD pointer, needed for invalidating pass on this QH */
if (flush)
{
@@ -215,6 +219,7 @@ static void cache_qh(struct QH *qh, int flush)
}
else
qtd = first_qtd;
/* Walk the qTD list and flush/invalidate all entries */
while(1)
{
@@ -255,7 +260,7 @@ static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
wait(1);
usec--;
}
while(usec > 0);
while (usec > 0);
return -1;
}
@@ -269,22 +274,24 @@ static int ehci_reset(void)
uint32_t tmp;
uint32_t *reg_ptr;
int ret = 0;
if ((gehci.ent->vendor == PCI_VENDOR_ID_NEC)
&& (gehci.ent->device == PCI_DEVICE_ID_NEC_USB_2))
if ((gehci.ent->vendor == PCI_VENDOR_ID_NEC) && (gehci.ent->device == PCI_DEVICE_ID_NEC_USB_2))
{
debug("ehci_reset set 48MHz clock\r\n");
pci_write_config_longword(gehci.handle, 0xE4, 0x20); // oscillator
}
cmd = ehci_readl(&gehci.hcor->or_usbcmd);
debug("cmd: 0x%08x\r\n", cmd);
debug("%s cmd: 0x%08x\r\n", __FUNCTION__, cmd);
cmd |= CMD_RESET;
ehci_writel(&gehci.hcor->or_usbcmd, cmd);
ret = handshake((uint32_t *)&gehci.hcor->or_usbcmd, CMD_RESET, 0, 250 * 1000);
ret = handshake((uint32_t *) &gehci.hcor->or_usbcmd, CMD_RESET, 0, 250);
if (ret < 0)
{
err("EHCI fail to reset");
goto out;
}
if (ehci_is_TDI())
{
reg_ptr = (uint32_t *)((u8 *)gehci.hcor + USBMODE);
@@ -307,6 +314,7 @@ static void *ehci_alloc(size_t sz, size_t align)
p = gehci.qh;
ntds = 0;
break;
case sizeof(struct qTD):
if (ntds == 3)
{
@@ -316,6 +324,7 @@ static void *ehci_alloc(size_t sz, size_t align)
p = gehci.td[ntds];
ntds++;
break;
default:
debug("unknown allocation size\r\n");
return NULL;
@@ -326,11 +335,15 @@ static void *ehci_alloc(size_t sz, size_t align)
static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
{
uint32_t addr, delta, next;
uint32_t addr;
uint32_t delta;
uint32_t next;
int idx;
addr = (uint32_t)buf;
idx = 0;
while(idx < 5)
while (idx < 5)
{
td->qt_buffer[idx] = swpl(addr - gehci.dma_offset);
next = (addr + 4096) & ~4095;
@@ -341,6 +354,7 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
addr = next;
idx++;
}
if (idx == 5)
{
debug("out of buffer pointers (%u bytes left)\r\n", sz);
@@ -360,27 +374,46 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
uint32_t c, toggle;
uint32_t cmd;
int ret = 0;
debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\r\n", dev, pipe, buffer, length, req);
debug("%s: dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\r\n", __FUNCTION__, dev, pipe, buffer, length, req);
if (req != NULL)
debug("ehci_submit_async req=%u (%#x), type=%u (%#x), value=%u (%#x), index=%u\r\n",
req->request, req->request, req->requesttype, req->requesttype, swpw(req->value), swpw(req->value), swpw(req->index));
req->request, req->request,
req->requesttype, req->requesttype,
swpw(req->value), swpw(req->value), swpw(req->index));
qh = ehci_alloc(sizeof(struct QH), 32);
if (qh == NULL)
{
debug("unable to allocate QH\r\n");
return -1;
}
qh->qh_link = swpl(((uint32_t)gehci.qh_list - gehci.dma_offset) | QH_LINK_TYPE_QH);
qh->qh_link = swpl(((uint32_t) gehci.qh_list - gehci.dma_offset) | QH_LINK_TYPE_QH);
c = (usb_pipespeed(pipe) != USB_SPEED_HIGH && usb_pipeendpoint(pipe) == 0) ? 1 : 0;
endpt = (8 << 28) | (c << 27) | (usb_maxpacket(dev, pipe) << 16) | (0 << 15) | (1 << 14) | (usb_pipespeed(pipe) << 12) | (usb_pipeendpoint(pipe) << 8) | (0 << 7) | (usb_pipedevice(pipe) << 0);
endpt = (8 << 28) |
(c << 27) |
(usb_maxpacket(dev, pipe) << 16) |
(0 << 15) |
(1 << 14) |
(usb_pipespeed(pipe) << 12) |
(usb_pipeendpoint(pipe) << 8) |
(0 << 7) |
(usb_pipedevice(pipe) << 0);
qh->qh_endpt1 = swpl(endpt);
endpt = (1 << 30) | (dev->portnr << 23) | (dev->parent->devnum << 16) | (0 << 8) | (0 << 0);
endpt = (1 << 30) |
(dev->portnr << 23) |
(dev->parent->devnum << 16) |
(0 << 8) |
(0 << 0);
qh->qh_endpt2 = swpl(endpt);
qh->qh_overlay.qt_next = swpl(QT_NEXT_TERMINATE);
qh->qh_overlay.qt_altnext = swpl(QT_NEXT_TERMINATE);
td = NULL;
tdp = &qh->qh_overlay.qt_next;
toggle = usb_gettoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe));
if (req != NULL)
{
td = ehci_alloc(sizeof(struct qTD), 32);
@@ -403,6 +436,7 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
tdp = &td->qt_next;
toggle = 1;
}
if (length > 0 || req == NULL)
{
td = ehci_alloc(sizeof(struct qTD), 32);
@@ -424,6 +458,7 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
*tdp = swpl((uint32_t)td - gehci.dma_offset);
tdp = &td->qt_next;
}
if (req != NULL)
{
td = ehci_alloc(sizeof(struct qTD), 32);
@@ -439,6 +474,7 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
*tdp = swpl((uint32_t)td - gehci.dma_offset);
tdp = &td->qt_next;
}
gehci.qh_list->qh_link = swpl(((uint32_t)qh - gehci.dma_offset) | QH_LINK_TYPE_QH);
/* Flush dcache */
ehci_flush_dcache(gehci.qh_list);
@@ -448,6 +484,7 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
cmd = ehci_readl(&gehci.hcor->or_usbcmd);
cmd |= CMD_ASE;
ehci_writel(&gehci.hcor->or_usbcmd, cmd);
ret = handshake((uint32_t *)&gehci.hcor->or_usbsts, STD_ASS, STD_ASS, 100 * 1000);
if (ret < 0)
{
@@ -479,6 +516,7 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
goto fail;
}
gehci.qh_list->qh_link = swpl(((uint32_t)gehci.qh_list - gehci.dma_offset) | QH_LINK_TYPE_QH);
token = swpl(qh->qh_overlay.qt_token);
if (!(token & 0x80))
{
@@ -490,17 +528,21 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
usb_settoggle(dev, usb_pipeendpoint(pipe), usb_pipeout(pipe), toggle);
dev->status = 0;
break;
case 0x40:
dev->status = USB_ST_STALLED;
break;
case 0xa0:
case 0x20:
dev->status = USB_ST_BUF_ERR;
break;
case 0x50:
case 0x10:
dev->status = USB_ST_BABBLE_DET;
break;
default:
dev->status = USB_ST_CRC_ERR;
break;
@@ -511,11 +553,12 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
{
dev->act_len = 0;
debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\r\n",
dev->devnum, ehci_readl(&gehci.hcor->or_usbsts), ehci_readl(&gehci.hcor->or_portsc[0]), ehci_readl(&gehci.hcor->or_portsc[1]));
dev->devnum, ehci_readl(&gehci.hcor->or_usbsts),
ehci_readl(&gehci.hcor->or_portsc[0]), ehci_readl(&gehci.hcor->or_portsc[1]));
}
return (dev->status != USB_ST_NOT_PROC) ? 0 : -1;
fail:
td = (void *)swpl(qh->qh_overlay.qt_next);
td = (void *) swpl(qh->qh_overlay.qt_next);
if (td != (void *)QT_NEXT_TERMINATE)
td = (struct qTD *)(gehci.dma_offset + (uint32_t)td);
while(td != (void *)QT_NEXT_TERMINATE)
@@ -530,9 +573,13 @@ fail:
if (ehci_readl(&gehci.hcor->or_usbsts) & STS_HSE) /* Host System Error */
{
unsigned short status = pci_read_config_word(gehci.handle, PCISR);
err("EHCI Host System Error, controller usb-%s disabled\r\n(SR:0x%04X%s%s%s%s%s%s)", gehci.slot_name, status & 0xFFFF,
status & 0x8000 ? ", Parity error" : "", status & 0x4000 ? ", Signaled system error" : "", status & 0x2000 ? ", Received master abort" : "",
status & 0x1000 ? ", Received target abort" : "", status & 0x800 ? ", Signaled target abort" : "", status & 0x100 ? ", Data parity error" : "");
err("EHCI Host System Error, controller usb-%s disabled\r\n(SR:0x%04X%s%s%s%s%s%s)",
gehci.slot_name, status & 0xFFFF, status & 0x8000 ? ", Parity error" : "",
status & 0x4000 ? ", Signaled system error" : "",
status & 0x2000 ? ", Received master abort" : "",
status & 0x1000 ? ", Received target abort" : "",
status & 0x800 ? ", Signaled target abort" : "",
status & 0x100 ? ", Data parity error" : "");
}
return -1;
}
@@ -574,11 +621,13 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
srcptr = &gehci.descriptor->device;
srclen = 0x12;
break;
case USB_DT_CONFIG:
debug("USB_DT_CONFIG config\r\n");
srcptr = &gehci.descriptor->config;
srclen = 0x19;
break;
case USB_DT_STRING:
debug("USB_DT_STRING config\r\n");
switch(swpw(req->value) & 0xff)
@@ -587,14 +636,17 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
srcptr = "\4\3\1\0";
srclen = 4;
break;
case 1: /* Vendor */
srcptr = "\2\3";
srclen = 2;
break;
case 2: /* Product */
srcptr = "\34\3E\0H\0C\0I\0 \0R\0o\0o\0t\0 \0H\0u\0b\0";
srclen = 28;
break;
default:
debug("unknown value DT_STRING %x\r\n",
swpw(req->value));
@@ -606,6 +658,7 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
goto unknown;
}
break;
case USB_REQ_GET_DESCRIPTOR | ((USB_DIR_IN | USB_RT_HUB) << 8):
switch(swpw(req->value) >> 8)
{
@@ -614,28 +667,34 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
srcptr = &gehci.descriptor->hub;
srclen = 0x8;
break;
default:
debug("unknown value %x\r\n", swpw(req->value));
goto unknown;
}
break;
case USB_REQ_SET_ADDRESS | (USB_RECIP_DEVICE << 8):
debug("USB_REQ_SET_ADDRESS\r\n");
rootdev = swpw(req->value);
break;
case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
debug("USB_REQ_SET_CONFIGURATION\r\n");
/* 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 USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8):
memset(tmpbuf, 0, 4);
reg = ehci_readl(status_reg);
if ((reg & EHCI_PS_PR) && (portreset & (1 << swpw(req->index))))
{
int ret;
@@ -646,11 +705,12 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
if (!ret)
{
tmpbuf[0] |= USB_PORT_STAT_RESET;
reg = ehci_readl(status_reg);
reg = ehci_readl(status_reg);
}
else
err("port(%d) reset error", swpw(req->index) - 1);
}
if (reg & EHCI_PS_CS)
tmpbuf[0] |= USB_PORT_STAT_CONNECTION;
if (reg & EHCI_PS_PE)
@@ -665,14 +725,22 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
{
switch((reg >> 26) & 3)
{
case 0: break;
case 1: tmpbuf[1] |= USB_PORT_STAT_LOW_SPEED >> 8; break;
case 0:
break;
case 1:
tmpbuf[1] |= USB_PORT_STAT_LOW_SPEED >> 8;
break;
case 2:
default: tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8; break;
default:
tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
break;
}
}
else
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)
@@ -681,9 +749,11 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
tmpbuf[2] |= USB_PORT_STAT_C_OVERCURRENT;
if (portreset & (1 << swpw(req->index)))
tmpbuf[2] |= USB_PORT_STAT_C_RESET;
srcptr = tmpbuf;
srclen = 4;
break;
case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
reg = ehci_readl(status_reg);
reg &= ~EHCI_PS_CLEAR;
@@ -693,6 +763,7 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
reg |= EHCI_PS_PE;
ehci_writel(status_reg, reg);
break;
case USB_PORT_FEAT_POWER:
if (HCS_PPC(ehci_readl(&gehci.hccr->cr_hcsparams)))
{
@@ -700,6 +771,7 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
ehci_writel(status_reg, reg);
}
break;
case USB_PORT_FEAT_RESET:
if ((reg & (EHCI_PS_PE | EHCI_PS_CS)) == EHCI_PS_CS && !ehci_is_TDI() && EHCI_PS_IS_LOWSPEED(reg))
{
@@ -723,13 +795,15 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
portreset |= (1 << swpw(req->index));
}
break;
default:
debug("unknown feature %x\r\n", swpw(req->value));
goto unknown;
}
/* unblock posted writes */
(void)ehci_readl(&gehci.hcor->or_usbcmd);
(void) ehci_readl(&gehci.hcor->or_usbcmd);
break;
case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
reg = ehci_readl(status_reg);
switch(swpw(req->value))
@@ -737,29 +811,35 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
case USB_PORT_FEAT_ENABLE:
reg &= ~EHCI_PS_PE;
break;
case USB_PORT_FEAT_C_ENABLE:
reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_PE;
break;
case USB_PORT_FEAT_POWER:
if (HCS_PPC(ehci_readl(&gehci.hccr->cr_hcsparams)))
reg = reg & ~(EHCI_PS_CLEAR | EHCI_PS_PP);
case USB_PORT_FEAT_C_CONNECTION:
reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_CSC;
break;
case USB_PORT_FEAT_OVER_CURRENT:
reg = (reg & ~EHCI_PS_CLEAR) | EHCI_PS_OCC;
break;
case USB_PORT_FEAT_C_RESET:
portreset &= ~(1 << swpw(req->index));
break;
default:
debug("unknown feature %x\r\n", swpw(req->value));
goto unknown;
}
ehci_writel(status_reg, reg);
/* unblock posted write */
(void)ehci_readl(&gehci.hcor->or_usbcmd);
(void) ehci_readl(&gehci.hcor->or_usbcmd);
break;
default:
debug("Unknown request\r\n");
goto unknown;
@@ -775,7 +855,7 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
return 0;
unknown:
debug("requesttype=%x, request=%x, value=%x, index=%x, length=%x\r\n",
req->requesttype, req->request, swpw(req->value), swpw(req->index), swpw(req->length));
req->requesttype, req->request, swpw(req->value), swpw(req->index), swpw(req->length));
dev->act_len = 0;
dev->status = USB_ST_STALLED;
return -1;
@@ -797,6 +877,7 @@ static int hc_interrupt(struct ehci *ehci)
i--;
continue;
}
if (companion & (1 << i))
{
/* Low speed device, give up ownership. */
@@ -806,7 +887,8 @@ static int hc_interrupt(struct ehci *ehci)
i--;
}
}
ehci_writel(&ehci->hcor->or_usbsts, status);
ehci_writel(&ehci->hcor->or_usbsts, status);
return(1); /* interrupt was from this card */
}
@@ -823,11 +905,13 @@ static int handle_usb_interrupt(struct ehci *ehci)
static void hc_free_buffers(struct ehci *ehci)
{
int i;
if (ehci->descriptor != NULL)
{
usb_free(ehci->descriptor);
ehci->descriptor = NULL;
}
for (i = 0; i < 3; i++)
{
if (ehci->td_unaligned[i] != NULL)
@@ -836,11 +920,13 @@ static void hc_free_buffers(struct ehci *ehci)
ehci->td_unaligned[i] = NULL;
}
}
if (ehci->qh_unaligned != NULL)
{
usb_free(ehci->qh_unaligned);
ehci->qh_unaligned = NULL;
}
if (ehci->qh_list_unaligned != NULL)
{
usb_free(ehci->qh_list_unaligned);
@@ -855,6 +941,7 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
uint32_t cmd;
uint32_t usb_base_addr = 0xFFFFFFFF;
struct pci_rd *pci_rsc_desc;
pci_rsc_desc = pci_get_resource(handle); /* USB EHCI */
if (handle && (ent != NULL))
{
@@ -864,6 +951,7 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
}
else if (!gehci.handle) /* for restart USB cmd */
return(-1);
gehci.qh_list_unaligned = (struct QH *)usb_malloc(sizeof(struct QH) + 32);
if (gehci.qh_list_unaligned == NULL)
{
@@ -871,9 +959,11 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
hc_free_buffers(&gehci);
return(-1);
}
gehci.qh_list = (struct QH *)(((uint32_t)gehci.qh_list_unaligned + 31) & ~31);
memset(gehci.qh_list, 0, sizeof(struct QH));
gehci.qh_unaligned = (struct QH *)usb_malloc(sizeof(struct QH) + 32);
if (gehci.qh_unaligned == NULL)
{
debug("QHs malloc failed");
@@ -882,6 +972,7 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
}
gehci.qh = (struct QH *)(((uint32_t)gehci.qh_unaligned + 31) & ~31);
memset(gehci.qh, 0, sizeof(struct QH));
for (i = 0; i < 3; i++)
{
gehci.td_unaligned[i] = (struct qTD *)usb_malloc(sizeof(struct qTD) + 32);
@@ -894,6 +985,7 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
gehci.td[i] = (struct qTD *)(((uint32_t)gehci.td_unaligned[i] + 31) & ~31);
memset(gehci.td[i], 0, sizeof(struct qTD));
}
gehci.descriptor = (struct descriptor *)usb_malloc(sizeof(struct descriptor));
if (gehci.descriptor == NULL)
{
@@ -902,6 +994,7 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
return(-1);
}
memcpy(gehci.descriptor, &rom_descriptor, sizeof(struct descriptor));
if ((long) pci_rsc_desc >= 0)
{
unsigned short flags;
@@ -925,18 +1018,20 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
flags = pci_rsc_desc->flags;
pci_rsc_desc = (struct pci_rd *)((uint32_t)pci_rsc_desc->next + (uint32_t)pci_rsc_desc);
}
while(!(flags & FLG_LAST));
while (!(flags & FLG_LAST));
}
else
{
hc_free_buffers(&gehci);
return(-1); /* get_resource error */
}
if (usb_base_addr == 0xFFFFFFFF)
{
hc_free_buffers(&gehci);
return(-1);
}
if (handle && (ent != NULL))
{
switch(ent->vendor)
@@ -955,6 +1050,7 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
hc_free_buffers(&gehci);
return(-1);
}
/* Set head of reclaim list */
gehci.qh_list->qh_link = swpl(((uint32_t)gehci.qh_list - gehci.dma_offset) | QH_LINK_TYPE_QH);
gehci.qh_list->qh_endpt1 = swpl((1 << 15) | (USB_SPEED_HIGH << 12));
@@ -967,6 +1063,7 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
reg = ehci_readl(&gehci.hccr->cr_hcsparams);
gehci.descriptor->hub.bNbrPorts = HCS_N_PORTS(reg);
info("Register %x NbrPorts %d", reg, gehci.descriptor->hub.bNbrPorts);
/* Port Indicators */
if (HCS_INDICATOR(reg))
gehci.descriptor->hub.wHubCharacteristics |= 0x80;
@@ -1002,19 +1099,24 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
int ehci_usb_lowlevel_stop(void *priv)
{
uint32_t cmd;
if (priv);
if (!ehci_inited)
return(0);
/* turn off interrupts */
/* turn off interrupts */
ehci_writel(&gehci.hcor->or_usbintr, 0);
pci_unhook_interrupt(gehci.handle);
/* stop the controller */
cmd = ehci_readl(&gehci.hcor->or_usbcmd);
cmd &= ~CMD_RUN;
ehci_writel(&gehci.hcor->or_usbcmd, cmd);
/* turn off all ports => todo */
/* use the companions */
ehci_writel(&gehci.hcor->or_configflag, 0);
/* unblock posted write */
cmd = ehci_readl(&gehci.hcor->or_usbcmd);
ehci_reset();
@@ -1040,6 +1142,7 @@ int ehci_submit_control_msg(struct usb_device *dev, uint32_t pipe, void *buffer,
debug("non-control pipe (type=%lu)", usb_pipetype(pipe));
return -1;
}
if (usb_pipedevice(pipe) == rootdev)
{
if (rootdev == 0)