tried to fix PCI - sometimes all three USB controllers are detected, sometimes not, sometimes there is even a PCI bus hang

This commit is contained in:
Markus Fröschle
2014-10-03 07:29:42 +00:00
parent b3ef74342e
commit b1c2026746
9 changed files with 5581 additions and 5548 deletions

View File

@@ -32,19 +32,19 @@ NATIVECC=gcc
INCLUDE=-Iinclude
CFLAGS=-mcpu=5474 \
-Wall \
-g3 \
-g \
-fomit-frame-pointer \
-ffreestanding \
-fleading-underscore \
-Wa,--register-prefix-optional
CFLAGS_OPTIMIZED = -mcpu=5474 \
-Wall \
-g3 \
-O2 \
-fomit-frame-pointer \
-ffreestanding \
-fleading-underscore \
-Wa,--register-prefix-optional
LDFLAGS=-g
TRGTDIRS= ./firebee ./m5484lite ./m54455
OBJDIRS=$(patsubst %, %/objs,$(TRGTDIRS))
@@ -271,7 +271,7 @@ endif
$(1)_MAPFILE_RAM=$(1)/$$(basename $$(RAM_EXEC)).map
$(1)/$$(RAM_EXEC): $(1)/$(LIBBAS) $(LDCSRC)
$(CPP) $(INCLUDE) -DCOMPILE_RAM -DOBJDIR=$(1)/objs -P -DFORMAT_ELF=$(FORMAT_ELF) -D$$(MACHINE) $(LDCSRC) -o $(1)/$$(LDRFILE)
$(LD) -g --oformat $$(FORMAT) -Map $$($(1)_MAPFILE_RAM) --cref -T $(1)/$$(LDRFILE) -o $$@
$(LD) $(LDFLAGS) --oformat $$(FORMAT) -Map $$($(1)_MAPFILE_RAM) --cref -T $(1)/$$(LDRFILE) -o $$@
ifeq ($(COMPILE_ELF),Y)
$(OBJCOPY) -O srec $$@ $$(basename $$@).s19
else

View File

@@ -29,11 +29,6 @@
#include "usb.h"
#include "ehci.h"
//extern xQueueHandle queue_poll_hub;
//#undef DEBUG
//#undef SHOW_INFO
static char ehci_inited;
static int rootdev;
@@ -166,17 +161,15 @@ static struct ehci
const char *slot_name;
} gehci;
//#define DEBUG
//#define SHOW_INFO
#define DEBUG
#ifdef DEBUG
#define debug(format, arg...) xprintf("DEBUG: " format "\r\n", ## arg)
#define dbg(format, arg...) xprintf("DEBUG: " format, __FUNCTION__, ## arg)
#else
#define debug(format, arg...) do {} while (0)
#define dbg(format, arg...) do {} while (0)
#endif /* DEBUG */
#define err xprintf
#ifdef SHOW_INFO
#define info(format, arg...) xprintf("INFO: " format "\r\n", ## arg)
#define info(format, arg...) xprintf("INFO: " format, __FUNCTION__, ## arg)
#else
#define info(format, arg...) do {} while (0)
#endif
@@ -277,11 +270,11 @@ static int ehci_reset(void)
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");
dbg("ehci_reset set 48MHz clock\r\n");
pci_write_config_longword(gehci.handle, 0xE4, 0x20); // oscillator
}
cmd = ehci_readl(&gehci.hcor->or_usbcmd);
debug("%s cmd: 0x%08x\r\n", __FUNCTION__, cmd);
dbg("%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);
@@ -318,7 +311,7 @@ static void *ehci_alloc(size_t sz, size_t align)
case sizeof(struct qTD):
if (ntds == 3)
{
debug("out of TDs\r\n");
dbg("out of TDs\r\n");
return NULL;
}
p = gehci.td[ntds];
@@ -326,7 +319,7 @@ static void *ehci_alloc(size_t sz, size_t align)
break;
default:
debug("unknown allocation size\r\n");
dbg("unknown allocation size\r\n");
return NULL;
}
memset(p, sz, 0);
@@ -357,7 +350,7 @@ static int ehci_td_buffer(struct qTD *td, void *buf, size_t sz)
if (idx == 5)
{
debug("out of buffer pointers (%u bytes left)\r\n", sz);
dbg("out of buffer pointers (%u bytes left)\r\n", sz);
return -1;
}
return 0;
@@ -375,10 +368,10 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
uint32_t cmd;
int ret = 0;
debug("%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);
if (req != NULL)
debug("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->requesttype, req->requesttype,
swpw(req->value), swpw(req->value), swpw(req->index));
@@ -386,7 +379,7 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
qh = ehci_alloc(sizeof(struct QH), 32);
if (qh == NULL)
{
debug("unable to allocate QH\r\n");
dbg("unable to allocate QH\r\n");
return -1;
}
qh->qh_link = swpl(((uint32_t) gehci.qh_list - gehci.dma_offset) | QH_LINK_TYPE_QH);
@@ -419,7 +412,7 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
td = ehci_alloc(sizeof(struct qTD), 32);
if (td == NULL)
{
debug("unable to allocate SETUP td\r\n");
dbg("unable to allocate SETUP td\r\n");
goto fail;
}
td->qt_next = swpl(QT_NEXT_TERMINATE);
@@ -428,7 +421,7 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
td->qt_token = swpl(token);
if (ehci_td_buffer(td, req, sizeof(*req)) != 0)
{
debug("unable construct SETUP td\r\n");
dbg("unable construct SETUP td\r\n");
ehci_free(td, sizeof(*td));
goto fail;
}
@@ -442,7 +435,7 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
td = ehci_alloc(sizeof(struct qTD), 32);
if (td == NULL)
{
debug("unable to allocate DATA td\r\n");
dbg("unable to allocate DATA td\r\n");
goto fail;
}
td->qt_next = swpl(QT_NEXT_TERMINATE);
@@ -451,7 +444,7 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
td->qt_token = swpl(token);
if (ehci_td_buffer(td, buffer, length) != 0)
{
debug("unable construct DATA td\r\n");
dbg("unable construct DATA td\r\n");
ehci_free(td, sizeof(*td));
goto fail;
}
@@ -464,7 +457,7 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
td = ehci_alloc(sizeof(struct qTD), 32);
if (td == NULL)
{
debug("unable to allocate ACK td\r\n");
dbg("unable to allocate ACK td\r\n");
goto fail;
}
td->qt_next = swpl(QT_NEXT_TERMINATE);
@@ -520,7 +513,7 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
token = swpl(qh->qh_overlay.qt_token);
if (!(token & 0x80))
{
debug("TOKEN=%#x\r\n", token);
dbg("TOKEN=%#x\r\n", token);
switch(token & 0xfc)
{
case 0:
@@ -552,7 +545,7 @@ static int ehci_submit_async(struct usb_device *dev, uint32_t pipe, void *buffer
else
{
dev->act_len = 0;
debug("dev=%u, usbsts=%#x, p[1]=%#x, p[2]=%#x\r\n",
dbg("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]));
}
@@ -608,7 +601,7 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
}
status_reg = (uint32_t *)&gehci.hcor->or_portsc[swpw(req->index) - 1];
srclen = 0;
debug("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));
typeReq = req->request | req->requesttype << 8;
switch(typeReq)
@@ -617,19 +610,19 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
switch(swpw(req->value) >> 8)
{
case USB_DT_DEVICE:
debug("USB_DT_DEVICE request\r\n");
dbg("USB_DT_DEVICE request\r\n");
srcptr = &gehci.descriptor->device;
srclen = 0x12;
break;
case USB_DT_CONFIG:
debug("USB_DT_CONFIG config\r\n");
dbg("USB_DT_CONFIG config\r\n");
srcptr = &gehci.descriptor->config;
srclen = 0x19;
break;
case USB_DT_STRING:
debug("USB_DT_STRING config\r\n");
dbg("USB_DT_STRING config\r\n");
switch(swpw(req->value) & 0xff)
{
case 0: /* Language */
@@ -648,13 +641,13 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
break;
default:
debug("unknown value DT_STRING %x\r\n",
dbg("unknown value DT_STRING %x\r\n",
swpw(req->value));
goto unknown;
}
break;
default:
debug("unknown value %x\r\n", swpw(req->value));
dbg("unknown value %x\r\n", swpw(req->value));
goto unknown;
}
break;
@@ -663,24 +656,24 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
switch(swpw(req->value) >> 8)
{
case USB_DT_HUB:
debug("USB_DT_HUB config\r\n");
dbg("USB_DT_HUB config\r\n");
srcptr = &gehci.descriptor->hub;
srclen = 0x8;
break;
default:
debug("unknown value %x\r\n", swpw(req->value));
dbg("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");
dbg("USB_REQ_SET_ADDRESS\r\n");
rootdev = swpw(req->value);
break;
case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:
debug("USB_REQ_SET_CONFIGURATION\r\n");
dbg("USB_REQ_SET_CONFIGURATION\r\n");
/* Nothing to do */
break;
@@ -776,7 +769,7 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
if ((reg & (EHCI_PS_PE | EHCI_PS_CS)) == EHCI_PS_CS && !ehci_is_TDI() && EHCI_PS_IS_LOWSPEED(reg))
{
/* Low speed device, give up ownership. */
debug("port %d low speed --> companion\r\n", swpw(req->index));
dbg("port %d low speed --> companion\r\n", swpw(req->index));
reg |= EHCI_PS_PO;
ehci_writel(status_reg, reg);
companion |= (1 << swpw(req->index));
@@ -797,7 +790,7 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
break;
default:
debug("unknown feature %x\r\n", swpw(req->value));
dbg("unknown feature %x\r\n", swpw(req->value));
goto unknown;
}
/* unblock posted writes */
@@ -832,7 +825,7 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
break;
default:
debug("unknown feature %x\r\n", swpw(req->value));
dbg("unknown feature %x\r\n", swpw(req->value));
goto unknown;
}
ehci_writel(status_reg, reg);
@@ -841,7 +834,7 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
break;
default:
debug("Unknown request\r\n");
dbg("Unknown request\r\n");
goto unknown;
}
wait(1 * 1000);
@@ -849,12 +842,12 @@ static int ehci_submit_root(struct usb_device *dev, uint32_t pipe, void *buffer,
if (srcptr != NULL && len > 0)
memcpy(buffer, srcptr, len);
else
debug("Len is 0\r\n");
dbg("Len is 0\r\n");
dev->act_len = len;
dev->status = 0;
return 0;
unknown:
debug("requesttype=%x, request=%x, value=%x, index=%x, length=%x\r\n",
dbg("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));
dev->act_len = 0;
dev->status = USB_ST_STALLED;
@@ -955,7 +948,7 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
gehci.qh_list_unaligned = (struct QH *)driver_mem_alloc(sizeof(struct QH) + 32);
if (gehci.qh_list_unaligned == NULL)
{
debug("QHs malloc failed");
dbg("QHs malloc failed");
hc_free_buffers(&gehci);
return(-1);
}
@@ -966,7 +959,7 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
if (gehci.qh_unaligned == NULL)
{
debug("QHs malloc failed");
dbg("QHs malloc failed");
hc_free_buffers(&gehci);
return(-1);
}
@@ -978,7 +971,7 @@ 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);
if (gehci.td_unaligned[i] == NULL)
{
debug("TDs malloc failed");
dbg("TDs malloc failed");
hc_free_buffers(&gehci);
return(-1);
}
@@ -989,7 +982,7 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
gehci.descriptor = (struct descriptor *)driver_mem_alloc(sizeof(struct descriptor));
if (gehci.descriptor == NULL)
{
debug("decriptor malloc failed");
dbg("decriptor malloc failed");
hc_free_buffers(&gehci);
return(-1);
}
@@ -1000,7 +993,7 @@ int ehci_usb_lowlevel_init(long handle, const struct pci_device_id *ent, void **
unsigned short flags;
do
{
debug("PCI USB descriptors (at %p): flags 0x%04x start 0x%08lx \r\n offset 0x%08lx dmaoffset 0x%08lx length 0x%08lx\r\n", pci_rsc_desc,
dbg("PCI USB descriptors (at %p): flags 0x%04x start 0x%08lx \r\n offset 0x%08lx dmaoffset 0x%08lx length 0x%08lx\r\n", pci_rsc_desc,
pci_rsc_desc->flags, pci_rsc_desc->start, pci_rsc_desc->offset, pci_rsc_desc->dmaoffset, pci_rsc_desc->length);
if (!(pci_rsc_desc->flags & FLG_IO))
{
@@ -1129,7 +1122,7 @@ int ehci_submit_bulk_msg(struct usb_device *dev, uint32_t pipe, void *buffer, in
{
if (usb_pipetype(pipe) != PIPE_BULK)
{
debug("non-bulk pipe (type=%lu)", usb_pipetype(pipe));
dbg("non-bulk pipe (type=%lu)", usb_pipetype(pipe));
return -1;
}
return ehci_submit_async(dev, pipe, buffer, length, NULL);
@@ -1139,7 +1132,7 @@ int ehci_submit_control_msg(struct usb_device *dev, uint32_t pipe, void *buffer,
{
if (usb_pipetype(pipe) != PIPE_CONTROL)
{
debug("non-control pipe (type=%lu)", usb_pipetype(pipe));
dbg("non-control pipe (type=%lu)", usb_pipetype(pipe));
return -1;
}
@@ -1154,7 +1147,7 @@ int ehci_submit_control_msg(struct usb_device *dev, uint32_t pipe, void *buffer,
int ehci_submit_int_msg(struct usb_device *dev, uint32_t pipe, void *buffer, int length, int interval)
{
debug("submit_int_msg dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d", dev, pipe, buffer, length, interval);
dbg("submit_int_msg dev=%p, pipe=%lu, buffer=%p, length=%d, interval=%d", dev, pipe, buffer, length, interval);
return -1;
}

View File

@@ -53,7 +53,7 @@
#undef OHCI_VERBOSE_DEBUG /* not always helpful */
#undef OHCI_FILL_TRACE
//#define DEBUG_OHCI
#define DEBUG_OHCI
#ifdef DEBUG_OHCI
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else
@@ -1316,8 +1316,8 @@ static unsigned char root_hub_str_index1[] =
#define OK(x) len = (x); break
#ifdef DEBUG_OHCI
#define WR_RH_STAT(x) { info("WR:status %#8x", (x)); writel((x), &ohci->regs->roothub.status); }
#define WR_RH_PORTSTAT(x) { info("WR:portstatus[%d] %#8x", wIndex - 1, (x)); writel((x), &ohci->regs->roothub.portstatus[wIndex - 1]); }
#define WR_RH_STAT(x) { err("WR:status %#8x", (x)); writel((x), &ohci->regs->roothub.status); }
#define WR_RH_PORTSTAT(x) { err("WR:portstatus[%d] %#8x", wIndex - 1, (x)); writel((x), &ohci->regs->roothub.portstatus[wIndex - 1]); }
#else
#define WR_RH_STAT(x) { writel((x), &ohci->regs->roothub.status); }
#define WR_RH_PORTSTAT(x) { writel((x), &ohci->regs->roothub.portstatus[wIndex - 1]); }
@@ -1374,13 +1374,14 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip
#else
if (ohci->irq)
{
wait(1 * 1000);
wait(10);
}
#endif
if (usb_pipeint(pipe))
{
err("Root-Hub submit IRQ: NOT implemented");
err("Root-Hub submit IRQ: NOT implemented\r\n");
return 0;
}
@@ -1405,19 +1406,19 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip
OK(2);
case RH_GET_STATUS | RH_INTERFACE:
*(uint16_t *)data_buf = swpw(0);
*(uint16_t *) data_buf = swpw(0);
OK(2);
case RH_GET_STATUS | RH_ENDPOINT:
*(uint16_t *)data_buf = swpw(0);
*(uint16_t *) data_buf = swpw(0);
OK(2);
case RH_GET_STATUS | RH_CLASS:
*(uint32_t *)data_buf = swpl(RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
*(uint32_t *) data_buf = swpl(RD_RH_STAT & ~(RH_HS_CRWE | RH_HS_DRWE));
OK(4);
case RH_GET_STATUS | RH_OTHER | RH_CLASS:
*(uint32_t *)data_buf = swpl(RD_RH_PORTSTAT);
*(uint32_t *) data_buf = swpl(RD_RH_PORTSTAT);
OK(4);
case RH_CLEAR_FEATURE | RH_ENDPOINT:
@@ -1461,7 +1462,7 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip
OK(0);
case (RH_PORT_POWER):
WR_RH_PORTSTAT(RH_PS_PPS);
wait(100 * 1000);
wait(100);
OK(0);
case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/
if (RD_RH_PORTSTAT & RH_PS_CCS)
@@ -1561,7 +1562,7 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip
#else
if (ohci->irq)
{
wait(1 * 1000);
wait(10);
}
#endif
@@ -1581,7 +1582,7 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip
if (ohci->irq)
{
wait(1 * 1000);
wait(10);
}
#endif
@@ -1628,7 +1629,7 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe
#else
if (ohci->irq)
{
wait(1 * 1000);
wait(10);
}
#endif
@@ -1645,7 +1646,7 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe
}
#if 0
wait(10 * 1000);
wait(10);
/* ohci_dump_status(ohci); */
#endif
@@ -1666,7 +1667,7 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe
while (ohci->irq)
{
/* check whether the controller is done */
flush_data_cache(ohci);
// flush_data_cache(ohci); no need to do that, PCI is uncached, as well as USB memory
#ifndef CONFIG_USB_INTERRUPT_POLLING
if (ohci->irq_enabled)
@@ -1678,10 +1679,12 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe
stat = hc_interrupt(ohci);
if (stat < 0)
{
dbg("USB CRC error\r\n");
stat = USB_ST_CRC_ERR;
break;
}
/* NOTE: since we are not interrupt driven in U-Boot and always
/*
* NOTE: since we are not interrupt driven in U-Boot and always
* handle only one URB at a time, we cannot assume the
* transaction finished on the first successful return from
* hc_interrupt().. unless the flag for current URB is set,
@@ -1689,7 +1692,8 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe
* transferred and processed. If the current URB is not
* finished we need to re-iterate this loop so as
* hc_interrupt() gets called again as there needs to be some
* more TD's to process still */
* more TD's to process still
*/
if ((stat >= 0) && (stat != 0xff) && (urb->finished))
{
/* 0xff is returned for an SF-interrupt */
@@ -1698,9 +1702,9 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe
if (--timeout)
{
wait(1 * 1000);
// if (!urb->finished)
// dbg("*");
wait(10);
if (!urb->finished)
xprintf("*");
}
else
{
@@ -1711,13 +1715,14 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe
break;
}
}
dbg("\n");
dev->status = stat;
dev->act_len = transfer_len;
#ifdef DEBUG_OHCI
pkt_print(ohci, urb, dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe));
#else
if (ohci->irq)
wait(1 * 1000);
wait(10);
#endif
/* free TDs in urb_priv */
if (!usb_pipeint(pipe))
@@ -1744,7 +1749,7 @@ int ohci_submit_control_msg(struct usb_device *dev, uint32_t pipe, void *buffer,
#else
if (ohci->irq)
{
wait(1 * 1000);
wait(10);
}
#endif
@@ -1910,57 +1915,71 @@ static int hc_reset(ohci_t *ohci)
/*-------------------------------------------------------------------------*/
/* Start an OHCI controller, set the BUS operational
/*
* Start an OHCI controller, set the BUS operational
* enable interrupts
* connect the virtual root hub */
* connect the virtual root hub
*/
static int hc_start(ohci_t *ohci)
{
uint32_t mask;
unsigned int fminterval;
ohci->disabled = 1;
/* Tell the controller where the control and bulk lists are
* The lists are empty now. */
/*
* Tell the controller where the control and bulk lists are
* The lists are empty now.
*/
writel(0, &ohci->regs->ed_controlhead);
writel(0, &ohci->regs->ed_bulkhead);
writel((uint32_t)ohci->hcca - ohci->dma_offset, &ohci->regs->hcca); /* a reset clears this */
writel((uint32_t) ohci->hcca - ohci->dma_offset, &ohci->regs->hcca); /* a reset clears this */
fminterval = 0x2edf;
writel((fminterval * 9) / 10, &ohci->regs->periodicstart);
fminterval |= ((((fminterval - 210) * 6) / 7) << 16);
writel(fminterval, &ohci->regs->fminterval);
writel(0x628, &ohci->regs->lsthresh);
/* start controller operations */
ohci->hc_control = OHCI_CONTROL_INIT | OHCI_USB_OPER;
ohci->disabled = 0;
writel(ohci->hc_control, &ohci->regs->control);
/* disable all interrupts */
mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD |
OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC | OHCI_INTR_OC | OHCI_INTR_MIE);
writel(mask, &ohci->regs->intrdisable);
/* clear all interrupts */
mask &= ~OHCI_INTR_MIE;
writel(mask, &ohci->regs->intrstatus);
/* Choose the interrupts we care about now - but w/o MIE */
mask = OHCI_INTR_RHSC | OHCI_INTR_UE | OHCI_INTR_WDH | OHCI_INTR_SO;
writel(mask, &ohci->regs->intrenable);
ohci->ndp = roothub_a(ohci);
#ifdef OHCI_USE_NPS
/* required for AMD-756 and some Mac platforms */
writel((ohci->ndp | RH_A_NPS) & ~RH_A_PSM, &ohci->regs->roothub.a);
writel(RH_HS_LPSC, &ohci->regs->roothub.status);
#endif /* OHCI_USE_NPS */
/* POTPGT delay is bits 24-31, in 2 ms units. */
wait((ohci->ndp >> 23) & 0x1fe);
#define mdelay(n) ({unsigned long msec = (n); while (msec--) wait(1); })
mdelay((ohci->ndp >> 23) & 0x1fe);
ohci->ndp &= RH_A_NDP;
/* connect the virtual root hub */
ohci->rh.devnum = 0;
return 0;
}
static void flush_data_cache(ohci_t *ohci)
{
/* flush caches here */
}
#ifdef CONFIG_USB_INTERRUPT_POLLING
@@ -2104,7 +2123,7 @@ static int hc_interrupt(ohci_t *ohci)
unsigned int frame = swpw(ohci->hcca->frame_no) & 1;
if (ohci->irq)
wait(1 * 1000);
wait(1);
writel(OHCI_INTR_SF, &regs->intrdisable);
if (ohci->ed_rm_list[frame] != NULL)
writel(OHCI_INTR_SF, &regs->intrenable);
@@ -2119,9 +2138,13 @@ static int hc_interrupt(ohci_t *ohci)
static int handle_usb_interrupt(ohci_t *ohci)
{
if (!ohci->irq_enabled)
return 0;
{
dbg("no interrupts enabled\r\n");
flush_data_cache(ohci);
return 0;
}
// flush_data_cache(ohci); no need for that
ohci->irq = 0;
ohci->stat_irq = hc_interrupt(ohci);
ohci->irq = -1;
@@ -2193,49 +2216,55 @@ int ohci_usb_lowlevel_init(int32_t handle, const struct pci_device_id *ent, void
ohci->ent = ent;
}
else if (!ohci->handle) /* for restart USB cmd */
return(-1);
{
return -1;
}
err("ohci %p", ohci);
err("ohci %p, handle = 0x%x, fctn = 0x%x\r\n", ohci, handle, PCI_FUNCTION_FROM_HANDLE(handle));
ohci->controller = PCI_FUNCTION_FROM_HANDLE(ohci->handle);
dbg("handle = 0x%x, function = 0x%x\r\n", ohci->handle, ohci->controller);
// ohci->controller = (ohci->handle >> 16) & 3; /* PCI function */
/* this must be aligned to a 256 byte boundary */
ohci->hcca_unaligned = driver_mem_alloc(sizeof(struct ohci_hcca) + 256);
if (ohci->hcca_unaligned == NULL)
{
err("HCCA malloc failed");
return(-1);
err("HCCA malloc failed\r\n");
return -1;
}
/* align the storage */
ohci->hcca = (struct ohci_hcca *) (((uint32_t) ohci->hcca_unaligned + 255) & ~255);
memset(ohci->hcca, 0, sizeof(struct ohci_hcca));
err("aligned ghcca %p", ohci->hcca);
err("aligned ghcca %p\r\n", ohci->hcca);
ohci->ohci_dev_unaligned = driver_mem_alloc(sizeof(struct ohci_device) + 8);
if (ohci->ohci_dev_unaligned == NULL)
{
err("EDs malloc failed");
err("EDs malloc failed\r\n");
hc_free_buffers(ohci);
return(-1);
return -1;
}
ohci->ohci_dev = (struct ohci_device *) (((uint32_t) ohci->ohci_dev_unaligned + 7) & ~7);
memset(ohci->ohci_dev, 0, sizeof(struct ohci_device));
err("aligned EDs %p", ohci->ohci_dev);
err("aligned EDs %p\r\n", ohci->ohci_dev);
ohci->td_unaligned = driver_mem_alloc(sizeof(struct td) * (NUM_TD + 1));
if (ohci->td_unaligned == NULL)
{
err("TDs malloc failed");
err("TDs malloc failed\r\n");
hc_free_buffers(ohci);
return(-1);
return -1;
}
ptd = (struct td *) (((uint32_t) ohci->td_unaligned + 7) & ~7);
dbg("memset from %p to %p\r\n", ptd, ptd + sizeof(td_t) * NUM_TD);
memset(ptd, 0, sizeof(td_t) * NUM_TD);
err("aligned TDs %p", ptd);
dbg("aligned TDs %p\r\n", ptd);
ohci->disabled = 1;
ohci->sleeping = 0;

View File

@@ -389,7 +389,6 @@ int32_t pci_write_config_longword(int32_t handle, int offset, uint32_t value)
MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E;
chip_errata_135();
return PCI_SUCCESSFUL;
}
@@ -515,7 +514,7 @@ int32_t pci_find_device(uint16_t device_id, uint16_t vendor_id, int index)
{
handle = PCI_HANDLE(bus, device, function);
value = pci_read_config_longword(handle, PCIIDR);
if (value != 0xFFFFFFFF) /* device found */
if (value != 0xffffffff) /* device found */
{
if (vendor_id == 0xffff ||
(PCI_VENDOR_ID(value) == vendor_id && PCI_DEVICE_ID(value) == device_id))

View File

@@ -27,7 +27,7 @@
#error "unknown machine!"
#endif
#define DBG_DM
//#define DBG_DM
#ifdef DBG_DM
#define dbg(fmt, args...) xprintf(fmt, ##args)
#else

View File

@@ -47,7 +47,6 @@
#error "unknown machine"
#endif /* MACHINE_M5484LITE */
#
#include "dma.h"
#include "mod_devicetable.h"
#include "pci_ids.h"
@@ -55,7 +54,7 @@
#include "usb.h"
#include "video.h"
// #define DEBUG_SYSINIT
//#define DEBUG_SYSINIT
#ifdef DEBUG_SYSINIT
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else
@@ -729,13 +728,11 @@ void init_usb(void)
dbg("compare device id 0x%x against 0x%x\r\n", board->device, PCI_DEVICE_ID(id));
if ((board->vendor == PCI_VENDOR_ID(id)) && board->device == PCI_DEVICE_ID(id))
{
#ifdef _NOT_YET_ /* FIXME: usb_init() is broken */
dbg("match. trying to init board\r\n");
if (usb_init(handle, board) >= 0)
{
usb_found++;
}
#endif /* _NOT_YET_ */
}
board++;
}
@@ -752,9 +749,11 @@ void init_usb(void)
dbg("compare device id 0x%x against 0x%x\r\n", board->device, PCI_DEVICE_ID(id));
if ((board->vendor == PCI_VENDOR_ID(id)) && board->device == PCI_DEVICE_ID(id))
{
// if (usb_init(handle, board) >= 0)
if (usb_init(handle, board) >= 0)
{
usb_found++;
}
}
board++;
}
}
@@ -763,7 +762,7 @@ void init_usb(void)
dbg("PCI device handle = %x\r\n", handle);
} while (handle >= 0);
xprintf("finished (found %d USB controller(s))\r\n", usb_found);
xprintf("finished (found %d USB host controller(s))\r\n", usb_found);
}
static bool i2c_transfer_finished(void)

View File

@@ -54,13 +54,14 @@
#include "usb.h"
#include "usb_hub.h"
//#define DEBUG_USB
#define DEBUG_USB
#ifdef DEBUG_USB
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else
#define dbg(format, arg...) do { ; } while (0)
#endif /* DEBUG_USB */
#define err(format, arg...) do { xprintf("ERROR: %s(): " format, __FUNCTION__, ##arg); } while (0)
#define info(format, arg...) do { xprintf("INFO: %s(): " format, __FUNCTION__, ##arg); } while (0)
struct hci
{
@@ -93,6 +94,8 @@ int usb_init(int32_t handle, const struct pci_device_id *ent)
{
struct hci *priv;
int res = 0;
bus_index = 0;
if (bus_index >= USB_MAX_BUS)
{
dbg("bus_index >= USB_MAX_BUS");
@@ -402,7 +405,7 @@ int usb_bulk_msg(struct usb_device *dev, unsigned int pipe, void *data, int len,
{
if (!((volatile uint32_t) dev->status & USB_ST_NOT_PROC)) /* FIXME: this volatile does nothing! */
break;
wait(1 * 1000);
wait(1);
}
*actual_length = dev->act_len;
@@ -1056,6 +1059,7 @@ struct usb_device *usb_alloc_new_device(int bus_index, void *priv)
dev = &usb_dev[(bus_index * USB_MAX_DEVICE) + index];
dev->devnum = index + 1;
dev->maxchild = 0;
for (i = 0; i < USB_MAXCHILDREN; dev->children[i++] = NULL)
;
@@ -1082,6 +1086,7 @@ int usb_new_device(struct usb_device *dev)
int tmp;
unsigned char *tmpbuf;
dbg("\r\n");
#ifndef CONFIG_LEGACY_USB_INIT_SEQ
struct usb_device_descriptor *desc;
int port = -1;
@@ -1170,6 +1175,7 @@ int usb_new_device(struct usb_device *dev)
break;
}
}
dbg("port = %d\r\n", port);
if (port < 0)
{
@@ -1212,7 +1218,7 @@ int usb_new_device(struct usb_device *dev)
return 1;
}
wait(10 * 1000); /* Let the SET_ADDRESS settle */
wait(10); /* Let the SET_ADDRESS settle */
tmp = sizeof(dev->descriptor);
err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, &dev->descriptor, sizeof(dev->descriptor));
if (err < tmp)

View File

@@ -19,6 +19,7 @@
#define dbg(format, arg...) do { ; } while (0)
#endif /* DEBUG_HUB */
#define err(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#define info(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
static struct usb_hub_device hub_dev[USB_MAX_BUS][USB_MAX_HUB];
static int usb_hub_index[USB_MAX_BUS];
@@ -70,7 +71,7 @@ static void usb_hub_power_on(struct usb_hub_device *hub)
for (i = 0; i < dev->maxchild; i++)
{
usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER);
dbg("port %d returns %lX\r\n", i + 1, dev->status);
dbg("port %d returns %lx\r\n", i + 1, dev->status);
wait(hub->desc.bPwrOn2PwrGood * 2 * 1000);
}
}
@@ -116,6 +117,7 @@ int hub_port_reset(struct usb_device *dev, int port, unsigned short *portstat)
struct usb_port_status portsts;
unsigned short portstatus, portchange;
dbg("");
dbg("hub_port_reset: resetting port %d...\r\n", port + 1);
for (tries = 0; tries < MAX_TRIES; tries++)
@@ -127,7 +129,7 @@ int hub_port_reset(struct usb_device *dev, int port, unsigned short *portstat)
vTaskDelay((200 * configTICK_RATE_HZ) / 1000);
else
#endif
wait(10000);
wait(10 * 1000);
if (usb_get_port_status(dev, port + 1, &portsts) < 0)
{
dbg("get_port_status failed status %lX\r\n", dev->status);
@@ -158,7 +160,7 @@ int hub_port_reset(struct usb_device *dev, int port, unsigned short *portstat)
vTaskDelay((200*configTICK_RATE_HZ)/1000);
else
#endif
wait(20000);
wait(20 * 1000);
}
if (tries == MAX_TRIES)
@@ -209,6 +211,7 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
{
dbg("USB %d port %i disconnected\r\n", dev->usbnum, port + 1);
usb_disconnect(&dev->children[port]);
/* Return now if nothing is connected */
if (!(portstatus & USB_PORT_STAT_CONNECTION))
{
@@ -239,13 +242,19 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
usb = usb_alloc_new_device(dev->usbnum, dev->priv_hcd);
if (portstatus & USB_PORT_STAT_HIGH_SPEED)
{
usb->speed = USB_SPEED_HIGH;
}
else if (portstatus & USB_PORT_STAT_LOW_SPEED)
{
usb->speed = USB_SPEED_LOW;
}
else
{
usb->speed = USB_SPEED_FULL;
}
dbg("usb=%p\r\n", usb);
dbg("usb device = %p\r\n", usb);
dev->children[port] = usb;
usb->parent = dev;
@@ -260,12 +269,8 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
#ifdef USB_POLL_HUB
else if (pxCurrentTCB != NULL)
{
#ifdef CONFIG_USB_KEYBOARD
usb_kbd_register(usb);
#endif /* CONFIG_USB_KEYBOARD */
#ifdef CONFIG_USB_MOUSE
usb_mouse_register(usb);
#endif /* CONFIG_USB_MOUSE */
#ifdef CONFIG_USB_STORAGE
usb_stor_register(usb);
#endif /* CONFIG_USB_STORAGE */

View File

@@ -26,7 +26,7 @@
#include "exceptions.h"
#include "driver_mem.h"
//#define DEBUG_USBMOUSE
#define DEBUG_USBMOUSE
#ifdef DEBUG_USBMOUSE
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else
@@ -98,7 +98,9 @@ int drv_usb_mouse_init(void)
struct usb_device *dev = usb_get_dev_index(i, j); /* get device */
if (dev == NULL)
{
break;
}
xprintf("Try to register usb device %d,%d as mouse\r\n", i, j);
if (usb_mouse_register(dev) > 0)