working on USB device scan

This commit is contained in:
Markus Fröschle
2014-10-03 09:58:45 +00:00
parent f5556e023e
commit 19be22b106
8 changed files with 331 additions and 299 deletions

View File

@@ -23,9 +23,6 @@
#define USB_EHCI_H #define USB_EHCI_H
#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 5 #define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 5
#if !defined(CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS)
#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 2
#endif
/* (shifted) direction/type/recipient from the USB 2.0 spec, table 9.2 */ /* (shifted) direction/type/recipient from the USB 2.0 spec, table 9.2 */
#define DeviceRequest \ #define DeviceRequest \
@@ -46,7 +43,8 @@
/* /*
* Register Space. * Register Space.
*/ */
struct ehci_hccr { struct ehci_hccr
{
uint32_t cr_capbase; uint32_t cr_capbase;
#define HC_LENGTH(p) (((p) >> 0) & 0x00ff) #define HC_LENGTH(p) (((p) >> 0) & 0x00ff)
#define HC_VERSION(p) (((p) >> 16) & 0xffff) #define HC_VERSION(p) (((p) >> 16) & 0xffff)
@@ -58,7 +56,8 @@ struct ehci_hccr {
uint8_t cr_hcsp_portrt[8]; uint8_t cr_hcsp_portrt[8];
} __attribute__ ((packed)); } __attribute__ ((packed));
struct ehci_hcor { struct ehci_hcor
{
uint32_t or_usbcmd; uint32_t or_usbcmd;
#define CMD_PARK (1 << 11) /* enable "park" */ #define CMD_PARK (1 << 11) /* enable "park" */
#define CMD_PARK_CNT(c) (((c) >> 8) & 3) /* how many transfers to park */ #define CMD_PARK_CNT(c) (((c) >> 8) & 3) /* how many transfers to park */

View File

@@ -39,7 +39,7 @@ extern long *tab_funcs_pci;
#define __u8 uint8_t #define __u8 uint8_t
#define __u16 uint16_t #define __u16 uint16_t
#define __u32 uint32_t #define __u32 uint32_t
#define u8 uint8_t //#define u8 uint8_t
#define u16 uint16_t #define u16 uint16_t
#define u32 uint32_t #define u32 uint32_t
#define uint8_t uint8_t #define uint8_t uint8_t

View File

@@ -29,13 +29,24 @@
#include "usb.h" #include "usb.h"
#include "ehci.h" #include "ehci.h"
#define DBG_EHCI
#ifdef DBG_EHCI
#define dbg(format, arg...) xprintf("DEBUG %s(): " format, __FUNCTION__, ## arg)
#else
#define dbg(format, arg...) do {} while (0)
#endif /* DBG_EHCI */
#define err(format, arg...) xprintf("ERROR %s(): " format, __FUNCTION__, ## arg)
#define info(format, arg...) xprintf("INFO %s(): " format, __FUNCTION__, ## arg)
static char ehci_inited; static char ehci_inited;
static int rootdev; static int rootdev;
static uint16_t portreset; static uint16_t portreset;
static uint16_t companion; static uint16_t companion;
struct descriptor { struct descriptor
{
struct usb_hub_descriptor hub; struct usb_hub_descriptor hub;
struct usb_device_descriptor device; struct usb_device_descriptor device;
struct usb_linux_config_descriptor config; struct usb_linux_config_descriptor config;
@@ -43,7 +54,8 @@ struct descriptor {
struct usb_endpoint_descriptor endpoint; struct usb_endpoint_descriptor endpoint;
} __attribute__ ((packed)); } __attribute__ ((packed));
static struct descriptor rom_descriptor = { static struct descriptor rom_descriptor =
{
{ {
0x8, /* bDescLength */ 0x8, /* bDescLength */
0x29, /* bDescriptorType: hub descriptor */ 0x29, /* bDescriptorType: hub descriptor */
@@ -101,12 +113,6 @@ static struct descriptor rom_descriptor = {
}, },
}; };
#if defined(CONFIG_EHCI_IS_TDI)
#define ehci_is_TDI() (1)
#else
#define ehci_is_TDI() (0)
#endif
struct pci_device_id ehci_usb_pci_table[] = struct pci_device_id ehci_usb_pci_table[] =
{ {
{ {
@@ -161,23 +167,12 @@ static struct ehci
const char *slot_name; const char *slot_name;
} gehci; } gehci;
#define DEBUG
#ifdef DEBUG
#define dbg(format, arg...) xprintf("DEBUG: " format, __FUNCTION__, ## arg)
#else
#define dbg(format, arg...) do {} while (0)
#endif /* DEBUG */
#define err xprintf
#ifdef SHOW_INFO
#define info(format, arg...) xprintf("INFO: " format, __FUNCTION__, ## arg)
#else
#define info(format, arg...) do {} while (0)
#endif
static void cache_qtd(struct qTD *qtd, int flush) static void cache_qtd(struct qTD *qtd, int flush)
{ {
flush_and_invalidate_caches(); /*
* not needed
*/
//flush_and_invalidate_caches();
} }
static inline struct QH *qh_addr(struct QH *qh) static inline struct QH *qh_addr(struct QH *qh)
@@ -246,14 +241,18 @@ static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
{ {
result = ehci_readl(ptr); result = ehci_readl(ptr);
if (result == ~ (uint32_t) 0) if (result == ~ (uint32_t) 0)
{
return -1; return -1;
}
result &= mask; result &= mask;
if (result == done) if (result == done)
{
return 0; return 0;
}
wait(1); wait(1);
usec--; usec--;
} } while (usec > 0);
while (usec > 0);
return -1; return -1;
} }
@@ -264,35 +263,27 @@ static void ehci_free(void *p, size_t sz)
static int ehci_reset(void) static int ehci_reset(void)
{ {
uint32_t cmd; uint32_t cmd;
uint32_t tmp;
uint32_t *reg_ptr;
int ret = 0; 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))
{ {
dbg("ehci_reset set 48MHz clock\r\n"); dbg("ehci_reset set 48MHz clock\r\n");
pci_write_config_longword(gehci.handle, 0xE4, 0x20); // oscillator pci_write_config_longword(gehci.handle, 0xE4, 0x20); // oscillator
wait(5);
} }
cmd = ehci_readl(&gehci.hcor->or_usbcmd); cmd = ehci_readl(&gehci.hcor->or_usbcmd);
dbg("%s cmd: 0x%08x\r\n", __FUNCTION__, cmd); dbg("%s cmd: 0x%08x\r\n", __FUNCTION__, cmd);
cmd |= CMD_RESET; cmd |= CMD_RESET;
ehci_writel(&gehci.hcor->or_usbcmd, cmd); ehci_writel(&gehci.hcor->or_usbcmd, cmd);
ret = handshake((uint32_t *) &gehci.hcor->or_usbcmd, CMD_RESET, 0, 250); ret = handshake((uint32_t *) &gehci.hcor->or_usbcmd, CMD_RESET, 0, 250);
if (ret < 0) if (ret < 0)
{ {
err("EHCI fail to reset"); err("*** EHCI fail to reset! ***\r\n");
goto out; goto out;
} }
if (ehci_is_TDI())
{
reg_ptr = (uint32_t *)((u8 *)gehci.hcor + USBMODE);
tmp = ehci_readl(reg_ptr);
tmp |= USBMODE_CM_HC;
tmp |= USBMODE_BE;
ehci_writel(reg_ptr, tmp);
}
out: out:
return ret; return ret;
} }
@@ -363,18 +354,23 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
volatile struct qTD *vtd; volatile struct qTD *vtd;
uint32_t ts; uint32_t ts;
uint32_t *tdp; uint32_t *tdp;
uint32_t endpt, token, usbsts; uint32_t endpt;
uint32_t c, toggle; uint32_t token;
uint32_t usbsts;
uint32_t c;
uint32_t toggle;
uint32_t cmd; uint32_t cmd;
int ret = 0; int ret = 0;
dbg("%s: dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\r\n", __FUNCTION__, dev, pipe, buffer, length, req); dbg("%s: dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\r\n", __FUNCTION__, dev, pipe, buffer, length, req);
#ifdef DBG_EHCI
if (req != NULL) if (req != NULL)
dbg("ehci_submit_async req=%u (%#x), type=%u (%#x), value=%u (%#x), index=%u\r\n", dbg("ehci_submit_async req=%u (%#x), type=%u (%#x), value=%u (%#x), index=%u\r\n",
req->request, req->request, req->request, req->request,
req->requesttype, req->requesttype, req->requesttype, req->requesttype,
swpw(req->value), swpw(req->value), swpw(req->index)); swpw(req->value), swpw(req->value), swpw(req->index));
#endif /* DBG_EHCI */
qh = ehci_alloc(sizeof(struct QH), 32); qh = ehci_alloc(sizeof(struct QH), 32);
if (qh == NULL) if (qh == NULL)
@@ -469,10 +465,12 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
} }
gehci.qh_list->qh_link = swpl(((uint32_t)qh - gehci.dma_offset) | QH_LINK_TYPE_QH); gehci.qh_list->qh_link = swpl(((uint32_t)qh - gehci.dma_offset) | QH_LINK_TYPE_QH);
/* Flush dcache */ /* Flush dcache */
ehci_flush_dcache(gehci.qh_list); ehci_flush_dcache(gehci.qh_list);
usbsts = ehci_readl(&gehci.hcor->or_usbsts); usbsts = ehci_readl(&gehci.hcor->or_usbsts);
ehci_writel(&gehci.hcor->or_usbsts, (usbsts & 0x3f)); ehci_writel(&gehci.hcor->or_usbsts, (usbsts & 0x3f));
/* Enable async. schedule. */ /* Enable async. schedule. */
cmd = ehci_readl(&gehci.hcor->or_usbcmd); cmd = ehci_readl(&gehci.hcor->or_usbcmd);
cmd |= CMD_ASE; cmd |= CMD_ASE;
@@ -484,6 +482,7 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
err("EHCI fail timeout STD_ASS set (usbsts=%#x)", ehci_readl(&gehci.hcor->or_usbsts)); err("EHCI fail timeout STD_ASS set (usbsts=%#x)", ehci_readl(&gehci.hcor->or_usbsts));
goto fail; goto fail;
} }
/* Wait for TDs to be processed. */ /* Wait for TDs to be processed. */
ts = 0; ts = 0;
vtd = td; vtd = td;
@@ -493,11 +492,13 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
ehci_invalidate_dcache(gehci.qh_list); ehci_invalidate_dcache(gehci.qh_list);
token = swpl(vtd->qt_token); token = swpl(vtd->qt_token);
if (!(token & 0x80)) if (!(token & 0x80))
{
break; break;
}
wait(1 * 1000); wait(1 * 1000);
ts++; ts++;
} } while (ts < 1000);
while(ts < 1000);
/* Disable async schedule. */ /* Disable async schedule. */
cmd = ehci_readl(&gehci.hcor->or_usbcmd); cmd = ehci_readl(&gehci.hcor->or_usbcmd);
cmd &= ~CMD_ASE; cmd &= ~CMD_ASE;
@@ -594,16 +595,19 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
int len, srclen; int len, srclen;
uint32_t reg; uint32_t reg;
uint32_t *status_reg; uint32_t *status_reg;
if (swpw(req->index) > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) if (swpw(req->index) > CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS)
{ {
err("the requested port(%d) is not configured\r\n", swpw(req->index) - 1); err("the requested port(%d) is not configured\r\n", swpw(req->index) - 1);
return -1; return -1;
} }
status_reg = (uint32_t *) &gehci.hcor->or_portsc[swpw(req->index) - 1]; status_reg = (uint32_t *) &gehci.hcor->or_portsc[swpw(req->index) - 1];
srclen = 0; srclen = 0;
dbg("ehci_submit_root req=%u (%#x), type=%u (%#x), value=%u, index=%u\r\n", dbg("ehci_submit_root req=%u (%#x), type=%u (%#x), value=%u, index=%u\r\n",
req->request, req->request, req->requesttype, req->requesttype, swpw(req->value), swpw(req->index)); req->request, req->request, req->requesttype, req->requesttype, swpw(req->value), swpw(req->index));
typeReq = req->request | req->requesttype << 8; typeReq = req->request | req->requesttype << 8;
switch(typeReq) switch(typeReq)
{ {
case DeviceRequest | USB_REQ_GET_DESCRIPTOR: case DeviceRequest | USB_REQ_GET_DESCRIPTOR:
@@ -714,24 +718,7 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT; tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT;
if (reg & EHCI_PS_PP) if (reg & EHCI_PS_PP)
tmpbuf[1] |= USB_PORT_STAT_POWER >> 8; tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
if (ehci_is_TDI())
{
switch((reg >> 26) & 3)
{
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;
}
}
else
tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8; tmpbuf[1] |= USB_PORT_STAT_HIGH_SPEED >> 8;
if (reg & EHCI_PS_CSC) if (reg & EHCI_PS_CSC)
@@ -766,7 +753,7 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
break; break;
case USB_PORT_FEAT_RESET: case USB_PORT_FEAT_RESET:
if ((reg & (EHCI_PS_PE | EHCI_PS_CS)) == EHCI_PS_CS && !ehci_is_TDI() && EHCI_PS_IS_LOWSPEED(reg)) if ((reg & (EHCI_PS_PE | EHCI_PS_CS)) == EHCI_PS_CS && EHCI_PS_IS_LOWSPEED(reg))
{ {
/* Low speed device, give up ownership. */ /* Low speed device, give up ownership. */
dbg("port %d low speed --> companion\r\n", swpw(req->index)); dbg("port %d low speed --> companion\r\n", swpw(req->index));
@@ -858,10 +845,14 @@ unknown:
static int hc_interrupt(struct ehci *ehci) static int hc_interrupt(struct ehci *ehci)
{ {
uint32_t status = ehci_readl(&ehci->hcor->or_usbsts); uint32_t status = ehci_readl(&ehci->hcor->or_usbsts);
dbg("\r\n");
if (status & STS_PCD) /* port change detect */ if (status & STS_PCD) /* port change detect */
{ {
uint32_t reg = ehci_readl(&ehci->hccr->cr_hcsparams); uint32_t reg = ehci_readl(&ehci->hccr->cr_hcsparams);
uint32_t i = HCS_N_PORTS(reg); uint32_t i = HCS_N_PORTS(reg);
while(i) while(i)
{ {
uint32_t pstatus = ehci_readl(&ehci->hcor->or_portsc[i-1]); uint32_t pstatus = ehci_readl(&ehci->hcor->or_portsc[i-1]);
@@ -882,7 +873,7 @@ static int hc_interrupt(struct ehci *ehci)
} }
ehci_writel(&ehci->hcor->or_usbsts, status); ehci_writel(&ehci->hcor->or_usbsts, status);
return(1); /* interrupt was from this card */ return 1; /* interrupt was from this card */
} }
void ehci_usb_enable_interrupt(int enable) void ehci_usb_enable_interrupt(int enable)
@@ -892,7 +883,7 @@ void ehci_usb_enable_interrupt(int enable)
static int handle_usb_interrupt(struct ehci *ehci) static int handle_usb_interrupt(struct ehci *ehci)
{ {
return(hc_interrupt(ehci)); return hc_interrupt(ehci);
} }
static void hc_free_buffers(struct ehci *ehci) static void hc_free_buffers(struct ehci *ehci)
@@ -943,14 +934,17 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
gehci.ent = ent; gehci.ent = ent;
} }
else if (!gehci.handle) /* for restart USB cmd */ else if (!gehci.handle) /* for restart USB cmd */
return(-1); {
dbg("!gehci.handle\r\n");
return -1;
}
gehci.qh_list_unaligned = (struct QH *) driver_mem_alloc(sizeof(struct QH) + 32); gehci.qh_list_unaligned = (struct QH *) driver_mem_alloc(sizeof(struct QH) + 32);
if (gehci.qh_list_unaligned == NULL) if (gehci.qh_list_unaligned == NULL)
{ {
dbg("QHs malloc failed"); dbg("QHs malloc failed\r\n");
hc_free_buffers(&gehci); hc_free_buffers(&gehci);
return(-1); return -1;
} }
gehci.qh_list = (struct QH *)(((uint32_t)gehci.qh_list_unaligned + 31) & ~31); gehci.qh_list = (struct QH *)(((uint32_t)gehci.qh_list_unaligned + 31) & ~31);
@@ -959,9 +953,10 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
if (gehci.qh_unaligned == NULL) if (gehci.qh_unaligned == NULL)
{ {
dbg("QHs malloc failed"); dbg("QHs malloc failed\r\n");
hc_free_buffers(&gehci); hc_free_buffers(&gehci);
return(-1);
return -1;
} }
gehci.qh = (struct QH *)(((uint32_t) gehci.qh_unaligned + 31) & ~31); gehci.qh = (struct QH *)(((uint32_t) gehci.qh_unaligned + 31) & ~31);
memset(gehci.qh, 0, sizeof(struct QH)); memset(gehci.qh, 0, sizeof(struct QH));
@@ -971,9 +966,10 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
gehci.td_unaligned[i] = (struct qTD *) driver_mem_alloc(sizeof(struct qTD) + 32); gehci.td_unaligned[i] = (struct qTD *) driver_mem_alloc(sizeof(struct qTD) + 32);
if (gehci.td_unaligned[i] == NULL) if (gehci.td_unaligned[i] == NULL)
{ {
dbg("TDs malloc failed"); dbg("TDs malloc failed\r\n");
hc_free_buffers(&gehci); hc_free_buffers(&gehci);
return(-1);
return -1;
} }
gehci.td[i] = (struct qTD *)(((uint32_t) gehci.td_unaligned[i] + 31) & ~31); gehci.td[i] = (struct qTD *)(((uint32_t) gehci.td_unaligned[i] + 31) & ~31);
memset(gehci.td[i], 0, sizeof(struct qTD)); memset(gehci.td[i], 0, sizeof(struct qTD));
@@ -982,9 +978,10 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
gehci.descriptor = (struct descriptor *) driver_mem_alloc(sizeof(struct descriptor)); gehci.descriptor = (struct descriptor *) driver_mem_alloc(sizeof(struct descriptor));
if (gehci.descriptor == NULL) if (gehci.descriptor == NULL)
{ {
dbg("decriptor malloc failed"); dbg("decriptor malloc failed\r\n");
hc_free_buffers(&gehci); hc_free_buffers(&gehci);
return(-1);
return -1;
} }
memcpy(gehci.descriptor, &rom_descriptor, sizeof(struct descriptor)); memcpy(gehci.descriptor, &rom_descriptor, sizeof(struct descriptor));
@@ -1016,7 +1013,9 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
else else
{ {
hc_free_buffers(&gehci); hc_free_buffers(&gehci);
return(-1); /* get_resource error */ dbg("pci_get_resource() error\r\n");
return -1;
} }
if (usb_base_addr == 0xFFFFFFFF) if (usb_base_addr == 0xFFFFFFFF)
@@ -1041,7 +1040,10 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
if (ehci_reset() != 0) if (ehci_reset() != 0)
{ {
hc_free_buffers(&gehci); hc_free_buffers(&gehci);
return(-1);
dbg("ehci_reset() failed\r\n");
return -1;
} }
/* Set head of reclaim list */ /* Set head of reclaim list */
@@ -1051,20 +1053,28 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
gehci.qh_list->qh_overlay.qt_next = swpl(QT_NEXT_TERMINATE); gehci.qh_list->qh_overlay.qt_next = swpl(QT_NEXT_TERMINATE);
gehci.qh_list->qh_overlay.qt_altnext = swpl(QT_NEXT_TERMINATE); gehci.qh_list->qh_overlay.qt_altnext = swpl(QT_NEXT_TERMINATE);
gehci.qh_list->qh_overlay.qt_token = swpl(0x40); gehci.qh_list->qh_overlay.qt_token = swpl(0x40);
/* Set async. queue head pointer. */ /* Set async. queue head pointer. */
ehci_writel(&gehci.hcor->or_asynclistaddr, (uint32_t) gehci.qh_list - gehci.dma_offset); ehci_writel(&gehci.hcor->or_asynclistaddr, (uint32_t) gehci.qh_list - gehci.dma_offset);
reg = ehci_readl(&gehci.hccr->cr_hcsparams); reg = ehci_readl(&gehci.hccr->cr_hcsparams);
gehci.descriptor->hub.bNbrPorts = HCS_N_PORTS(reg); gehci.descriptor->hub.bNbrPorts = HCS_N_PORTS(reg);
info("Register %x NbrPorts %d", reg, gehci.descriptor->hub.bNbrPorts); info("Register %x NbrPorts %d\r\n", reg, gehci.descriptor->hub.bNbrPorts);
/* Port Indicators */ /* Port Indicators */
if (HCS_INDICATOR(reg)) if (HCS_INDICATOR(reg))
{
gehci.descriptor->hub.wHubCharacteristics |= 0x80; gehci.descriptor->hub.wHubCharacteristics |= 0x80;
}
/* Port Power Control */ /* Port Power Control */
if (HCS_PPC(reg)) if (HCS_PPC(reg))
{
gehci.descriptor->hub.wHubCharacteristics |= 0x01; gehci.descriptor->hub.wHubCharacteristics |= 0x01;
}
/* Start the host controller. */ /* Start the host controller. */
cmd = ehci_readl(&gehci.hcor->or_usbcmd); cmd = ehci_readl(&gehci.hcor->or_usbcmd);
/* /*
* Philips, Intel, and maybe others need CMD_RUN before the * Philips, Intel, and maybe others need CMD_RUN before the
* root hub will detect new devices (why?); NEC doesn't * root hub will detect new devices (why?); NEC doesn't
@@ -1072,21 +1082,29 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
cmd &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); cmd &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
cmd |= CMD_RUN; cmd |= CMD_RUN;
ehci_writel(&gehci.hcor->or_usbcmd, cmd); ehci_writel(&gehci.hcor->or_usbcmd, cmd);
/* take control over the ports */ /* take control over the ports */
ehci_writel(&gehci.hcor->or_configflag, FLAG_CF); ehci_writel(&gehci.hcor->or_configflag, FLAG_CF);
/* unblock posted write */ /* unblock posted write */
cmd = ehci_readl(&gehci.hcor->or_usbcmd); cmd = ehci_readl(&gehci.hcor->or_usbcmd);
wait(5 * 1000); wait(5 * 1000);
reg = HC_VERSION(ehci_readl(&gehci.hccr->cr_capbase)); reg = HC_VERSION(ehci_readl(&gehci.hccr->cr_capbase));
info("USB EHCI %x.%02x", reg >> 8, reg & 0xff); info("USB EHCI host controller version %x.%02x\r\n", reg >> 8, reg & 0xff);
/* turn on interrupts */ /* turn on interrupts */
pci_hook_interrupt(handle, handle_usb_interrupt, &gehci); pci_hook_interrupt(handle, handle_usb_interrupt, &gehci);
ehci_writel(&gehci.hcor->or_usbintr, INTR_PCDE); ehci_writel(&gehci.hcor->or_usbintr, INTR_PCDE);
rootdev = 0; rootdev = 0;
if (priv != NULL) if (priv != NULL)
{
*priv = (void *) &gehci; *priv = (void *) &gehci;
}
ehci_inited = 1; ehci_inited = 1;
return(0);
return 0;
} }
int ehci_usb_lowlevel_stop(void *priv) int ehci_usb_lowlevel_stop(void *priv)

View File

@@ -53,7 +53,7 @@
#undef OHCI_VERBOSE_DEBUG /* not always helpful */ #undef OHCI_VERBOSE_DEBUG /* not always helpful */
#undef OHCI_FILL_TRACE #undef OHCI_FILL_TRACE
#define DEBUG_OHCI //#define DEBUG_OHCI
#ifdef DEBUG_OHCI #ifdef DEBUG_OHCI
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else #else

View File

@@ -33,7 +33,7 @@
#include "interrupts.h" #include "interrupts.h"
#include "wait.h" #include "wait.h"
//#define DEBUG_PCI #define DEBUG_PCI
#ifdef DEBUG_PCI #ifdef DEBUG_PCI
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else #else
@@ -184,7 +184,7 @@ static int32_t pci_get_interrupt_cause(int32_t *handles)
return handle; return handle;
} }
} }
dbg("%s: no interrupt cause found\r\n"); dbg("no interrupt cause found\r\n");
return -1; return -1;
} }
@@ -224,7 +224,7 @@ void irq5_handler(void)
newvalue = pci_call_interrupt_chain(handle, value); newvalue = pci_call_interrupt_chain(handle, value);
if (newvalue == value) if (newvalue == value)
{ {
dbg("%s: interrupt not handled!\r\n"); dbg("interrupt not handled!\r\n");
} }
} }
} }
@@ -247,7 +247,7 @@ void irq7_handler(void)
newvalue = pci_call_interrupt_chain(handle, value); newvalue = pci_call_interrupt_chain(handle, value);
if (newvalue == value) if (newvalue == value)
{ {
dbg("%s: interrupt not handled!\r\n"); dbg("interrupt not handled!\r\n");
} }
} }
} }
@@ -878,7 +878,7 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
*/ */
struct pci_rd *rd = &descriptors[barnum]; struct pci_rd *rd = &descriptors[barnum];
dbg("%s: address = %08x\r\n", address); dbg("address = %08x\r\n", address);
if (IS_PCI_MEM_BAR(address)) if (IS_PCI_MEM_BAR(address))
{ {
/* adjust base address to card's alignment requirements */ /* adjust base address to card's alignment requirements */
@@ -967,10 +967,10 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
/* write it to PCIERBAR and enable ROM */ /* write it to PCIERBAR and enable ROM */
pci_write_config_longword(handle, PCIERBAR, swpl(address | 1)); pci_write_config_longword(handle, PCIERBAR, swpl(address | 1));
dbg("%s: set PCIERBAR on device 0x%02x to 0x%08x\r\n", handle, address | 1); dbg("set PCIERBAR on device 0x%02x to 0x%08x\r\n", handle, address | 1);
/* read value back just to be sure */ /* read value back just to be sure */
dbg("%s: PCIERBAR = %p\r\n", swpl(pci_read_config_longword(handle, PCIERBAR))); dbg("PCIERBAR = %p\r\n", swpl(pci_read_config_longword(handle, PCIERBAR)));
rd->next = sizeof(struct pci_rd); rd->next = sizeof(struct pci_rd);
@@ -1224,8 +1224,10 @@ void init_pci(void)
/* initialize/clear resource descriptor table */ /* initialize/clear resource descriptor table */
memset(&resource_descriptors, 0, NUM_CARDS * NUM_RESOURCES * sizeof(struct pci_rd)); memset(&resource_descriptors, 0, NUM_CARDS * NUM_RESOURCES * sizeof(struct pci_rd));
/* initialize/clear handles array */ /* initialize/clear handles array */
memset(handles, 0, NUM_CARDS * sizeof(int32_t)); memset(handles, 0, NUM_CARDS * sizeof(int32_t));
/* initialize/clear interrupts array */ /* initialize/clear interrupts array */
memset(interrupts, 0, MAX_INTERRUPTS * sizeof(struct pci_interrupt)); memset(interrupts, 0, MAX_INTERRUPTS * sizeof(struct pci_interrupt));
@@ -1233,7 +1235,7 @@ void init_pci(void)
* give devices a chance to come up befor attempting to configure them, * give devices a chance to come up befor attempting to configure them,
* necessary to properly detect the FireBee USB chip * necessary to properly detect the FireBee USB chip
*/ */
wait(400000); wait(600000);
/* /*
* do normal initialization * do normal initialization

View File

@@ -54,7 +54,7 @@
#include "usb.h" #include "usb.h"
#include "video.h" #include "video.h"
//#define DEBUG_SYSINIT #define DEBUG_SYSINIT
#ifdef DEBUG_SYSINIT #ifdef DEBUG_SYSINIT
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else #else
@@ -702,7 +702,7 @@ void init_usb(void)
do do
{ {
handle = pci_find_device(0x0000, 0xffff, index++); handle = pci_find_classcode(PCI_CLASS_SERIAL_USB, index++);
if (handle > 0) if (handle > 0)
{ {
uint32_t id = 0; uint32_t id = 0;

View File

@@ -203,6 +203,8 @@ int usb_init(int32_t handle, const struct pci_device_id *ent)
bus_index++; bus_index++;
usb_started = 1; usb_started = 1;
xprintf("done.\r\n");
return 0; return 0;
} }
else else

View File

@@ -12,7 +12,7 @@
#include "usb.h" #include "usb.h"
#include "usb_hub.h" #include "usb_hub.h"
//#define DEBUG_HUB #define DEBUG_HUB
#ifdef DEBUG_HUB #ifdef DEBUG_HUB
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else #else
@@ -296,6 +296,7 @@ static void usb_hub_events(struct usb_device *dev)
if (usb_get_port_status(dev, i + 1, &portsts) < 0) if (usb_get_port_status(dev, i + 1, &portsts) < 0)
{ {
dbg("get_port_status failed\r\n"); dbg("get_port_status failed\r\n");
continue; continue;
} }
portstatus = swpw(portsts.wPortStatus); portstatus = swpw(portsts.wPortStatus);
@@ -424,7 +425,8 @@ int usb_hub_configure(struct usb_device *dev)
driver_mem_free(buffer); driver_mem_free(buffer);
return -1; return -1;
} }
dbg("bLength:%02X bDescriptorType:%02X bNbrPorts:%02X\r\n", buffer[0], buffer[1], buffer[2]);
dbg("bLength:0x%02X bDescriptorType:0x%02X bNbrPorts:0x%02X\r\n", buffer[0], buffer[1], buffer[2]);
descriptor = (struct usb_hub_descriptor *)buffer; descriptor = (struct usb_hub_descriptor *)buffer;
/* silence compiler warning if USB_BUFSIZ is > 256 [= sizeof(char)] */ /* silence compiler warning if USB_BUFSIZ is > 256 [= sizeof(char)] */
@@ -507,7 +509,9 @@ int usb_hub_configure(struct usb_device *dev)
for (i = 0; i < dev->maxchild; i++) for (i = 0; i < dev->maxchild; i++)
{ {
dbg("USB %d port %d is%s removable\r\n", dev->usbnum, i + 1, hub->desc.DeviceRemovable[(i + 1) / 8] & (1 << ((i + 1) % 8)) ? " not" : ""); dbg("USB %d port %d is%s removable\r\n",
dev->usbnum, i + 1,
hub->desc.DeviceRemovable[(i + 1) / 8] & (1 << ((i + 1) % 8)) ? " not" : "");
} }
if (sizeof(struct usb_hub_status) > USB_BUFSIZ) if (sizeof(struct usb_hub_status) > USB_BUFSIZ)
@@ -526,7 +530,7 @@ int usb_hub_configure(struct usb_device *dev)
return -1; return -1;
} }
#ifdef USB_DEBUG #ifdef DEBUG_HUB
{ {
struct usb_hub_status *hubsts; struct usb_hub_status *hubsts;
@@ -559,6 +563,7 @@ int usb_hub_configure(struct usb_device *dev)
} }
if (queue_poll_hub == NULL) if (queue_poll_hub == NULL)
#endif #endif
usb_hub_events(dev); usb_hub_events(dev);
driver_mem_free(buffer); driver_mem_free(buffer);
@@ -586,12 +591,15 @@ int usb_hub_probe(struct usb_device *dev, int ifnum)
*/ */
if ((iface->bInterfaceSubClass != 0) && (iface->bInterfaceSubClass != 1)) if ((iface->bInterfaceSubClass != 0) && (iface->bInterfaceSubClass != 1))
{ {
dbg("iface->bInterfaceSubClass != {0, 1} (%d instead)\r\n", iface->bInterfaceSubClass);
return 0; return 0;
} }
/* Multiple endpoints? What kind of mutant ninja-hub is this? */ /* Multiple endpoints? What kind of mutant ninja-hub is this? */
if (iface->bNumEndpoints != 1) if (iface->bNumEndpoints != 1)
{ {
dbg("iface->bNumEndpoints != 1 (%d instead)\r\n", iface->bNumEndpoints);
return 0; return 0;
} }
@@ -600,6 +608,8 @@ int usb_hub_probe(struct usb_device *dev, int ifnum)
/* Output endpoint? Curiousier and curiousier.. */ /* Output endpoint? Curiousier and curiousier.. */
if (!(ep->bEndpointAddress & USB_DIR_IN)) if (!(ep->bEndpointAddress & USB_DIR_IN))
{ {
dbg("!(ep->bEndpointAddress != USB_DIR_IN (0x%x instead)\r\n", ep->bEndpointAddress);
return 0; return 0;
} }
@@ -611,6 +621,7 @@ int usb_hub_probe(struct usb_device *dev, int ifnum)
/* We found a hub */ /* We found a hub */
dbg("USB %d hub found\r\n", dev->usbnum); dbg("USB %d hub found\r\n", dev->usbnum);
ret = usb_hub_configure(dev); ret = usb_hub_configure(dev);
return ret; return ret;