Project

General

Profile

Bug #1010 » freebsd.usb.diff

mneumann, 05/19/2008 11:08 AM

View differences:

/root/src/sys/dev/usb/ehci.c 2008-05-13 20:58:08 +0000
/* $NetBSD: ehci.c,v 1.91 2005/02/27 00:27:51 perry Exp $ */
/* $FreeBSD: src/sys/dev/usb/ehci.c,v 1.36.2.3 2006/09/24 13:39:04 iedowse Exp $ */
/* $DragonFly: src/sys/bus/usb/ehci.c,v 1.32 2007/06/29 22:56:31 hasso Exp $ */
/*
/*-
* Copyright (c) 2004 The NetBSD Foundation, Inc.
* All rights reserved.
*
......
* 3) Command failures are not recovered correctly.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/usb/ehci.c,v 1.63 2008/05/13 20:58:08 marius Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
......
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/lock.h>
#include <sys/lockmgr.h>
#if defined(DIAGNOSTIC) && defined(__i386__) && defined(__FreeBSD__)
#include <machine/cpu.h>
#endif
#include <sys/proc.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
#include <sys/thread2.h>
#include <machine/cpu.h>
#include <machine/bus.h>
#include <machine/endian.h>
#include <bus/usb/usb.h>
#include <bus/usb/usbdi.h>
#include <bus/usb/usbdivar.h>
#include <bus/usb/usb_mem.h>
#include <bus/usb/usb_quirks.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdivar.h>
#include <dev/usb/usb_mem.h>
#include <dev/usb/usb_quirks.h>
#include <bus/usb/ehcireg.h>
#include <bus/usb/ehcivar.h>
#include <dev/usb/ehcireg.h>
#include <dev/usb/ehcivar.h>
#define delay(d) DELAY(d)
#ifdef USB_DEBUG
#define EHCI_DEBUG USB_DEBUG
#define DPRINTF(x) do { if (ehcidebug) kprintf x; } while (0)
#define DPRINTFN(n,x) do { if (ehcidebug>(n)) kprintf x; } while (0)
#define DPRINTF(x) do { if (ehcidebug) printf x; } while (0)
#define DPRINTFN(n,x) do { if (ehcidebug>(n)) printf x; } while (0)
int ehcidebug = 0;
SYSCTL_NODE(_hw_usb, OID_AUTO, ehci, CTLFLAG_RW, 0, "USB ehci");
SYSCTL_INT(_hw_usb_ehci, OID_AUTO, debug, CTLFLAG_RW,
&ehcidebug, 0, "ehci debug level");
#define bitmask_snprintf(q,f,b,l) ksnprintf((b), (l), "%b", (q), (f))
#define bitmask_snprintf(q,f,b,l) snprintf((b), (l), "%b", (q), (f))
#else
#define DPRINTF(x)
#define DPRINTFN(n,x)
......
* Table 2-9 in the EHCI spec says this will result
* in undefined behavior.
*/
kprintf("%s: stop timeout\n",
printf("%s: stop timeout\n",
device_get_nameunit(sc->sc_bus.bdev));
EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET);
......
if (!hcr)
return (USBD_NORMAL_COMPLETION);
}
kprintf("%s: reset timeout\n", device_get_nameunit(sc->sc_bus.bdev));
printf("%s: reset timeout\n", device_get_nameunit(sc->sc_bus.bdev));
return (USBD_IOERROR);
}
......
sc->sc_offs = EREAD1(sc, EHCI_CAPLENGTH);
version = EREAD2(sc, EHCI_HCIVERSION);
kprintf("%s: EHCI version %x.%x\n", device_get_nameunit(sc->sc_bus.bdev),
printf("%s: EHCI version %x.%x\n", device_get_nameunit(sc->sc_bus.bdev),
version >> 8, version & 0xff);
sparams = EREAD4(sc, EHCI_HCSPARAMS);
......
sc->sc_npcomp = EHCI_HCS_N_PCC(sparams);
ncomp = EHCI_HCS_N_CC(sparams);
if (ncomp != sc->sc_ncomp) {
kprintf("%s: wrong number of companions (%d != %d)\n",
printf("%s: wrong number of companions (%d != %d)\n",
device_get_nameunit(sc->sc_bus.bdev),
ncomp, sc->sc_ncomp);
if (ncomp < sc->sc_ncomp)
sc->sc_ncomp = ncomp;
}
if (sc->sc_ncomp > 0) {
kprintf("%s: companion controller%s, %d port%s each:",
printf("%s: companion controller%s, %d port%s each:",
device_get_nameunit(sc->sc_bus.bdev), sc->sc_ncomp!=1 ? "s" : "",
EHCI_HCS_N_PCC(sparams),
EHCI_HCS_N_PCC(sparams)!=1 ? "s" : "");
for (i = 0; i < sc->sc_ncomp; i++)
kprintf(" %s", device_get_nameunit(sc->sc_comps[i]->bdev));
kprintf("\n");
printf(" %s", device_get_nameunit(sc->sc_comps[i]->bdev));
printf("\n");
}
sc->sc_noport = EHCI_HCS_N_PORTS(sparams);
cparams = EREAD4(sc, EHCI_HCCPARAMS);
......
case 3: return (USBD_IOERROR);
}
err = usb_allocmem(&sc->sc_bus, sc->sc_flsize * sizeof(ehci_link_t),
EHCI_FLALIGN_ALIGN, &sc->sc_fldma);
EHCI_FLALIGN_ALIGN, &sc->sc_fldma);
if (err)
return (err);
DPRINTF(("%s: flsize=%d\n", device_get_nameunit(sc->sc_bus.bdev),sc->sc_flsize));
......
sc->sc_bus.methods = &ehci_bus_methods;
sc->sc_bus.pipe_size = sizeof(struct ehci_pipe);
#if defined(__NetBSD__) || defined(__OpenBSD__)
sc->sc_powerhook = powerhook_establish(ehci_power, sc);
sc->sc_shutdownhook = shutdownhook_establish(ehci_shutdown, sc);
#endif
sc->sc_eintrs = EHCI_NORMAL_INTRS;
/*
......
sc->sc_async_head = sqh;
EOWRITE4(sc, EHCI_ASYNCLISTADDR, sqh->physaddr | EHCI_LINK_QH);
callout_init(&sc->sc_tmo_pcd);
callout_init(&sc->sc_tmo_intrlist);
callout_init(&sc->sc_tmo_pcd, 0);
callout_init(&sc->sc_tmo_intrlist, 0);
lockinit(&sc->sc_doorbell_lock, "ehcidb", 0, 0);
lockinit(&sc->sc_doorbell_lock, PZERO, "ehcidb", 0, 0);
/* Enable interrupts */
EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
......
break;
}
if (hcr) {
kprintf("%s: run timeout\n", device_get_nameunit(sc->sc_bus.bdev));
printf("%s: run timeout\n", device_get_nameunit(sc->sc_bus.bdev));
return (USBD_IOERROR);
}
......
/* In case the interrupt occurs before initialization has completed. */
if (sc == NULL) {
#ifdef DIAGNOSTIC
kprintf("ehci_intr1: sc == NULL\n");
printf("ehci_intr1: sc == NULL\n");
#endif
return (0);
}
......
eintrs &= ~(EHCI_STS_INT | EHCI_STS_ERRINT);
}
if (eintrs & EHCI_STS_HSE) {
kprintf("%s: unrecoverable error, controller halted\n",
printf("%s: unrecoverable error, controller halted\n",
device_get_nameunit(sc->sc_bus.bdev));
/* XXX what else */
}
......
/* Block unprocessed interrupts. */
sc->sc_eintrs &= ~eintrs;
EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs);
kprintf("%s: blocking intrs 0x%x\n",
printf("%s: blocking intrs 0x%x\n",
device_get_nameunit(sc->sc_bus.bdev), eintrs);
}
......
DPRINTFN(/*15*/2, ("ehci_check_intr: ex=%p\n", ex));
if (ex->sqtdstart == NULL) {
kprintf("ehci_check_intr: sqtdstart=NULL\n");
printf("ehci_check_intr: sqtdstart=NULL\n");
return;
}
lsqtd = ex->sqtdend;
#ifdef DIAGNOSTIC
if (lsqtd == NULL) {
kprintf("ehci_check_intr: lsqtd==0\n");
printf("ehci_check_intr: lsqtd==0\n");
return;
}
#endif
......
DPRINTFN(/*12*/2, ("ehci_idone: ex=%p\n", ex));
#ifdef DIAGNOSTIC
{
crit_enter();
int s = splhigh();
if (ex->isdone) {
crit_exit();
splx(s);
#ifdef EHCI_DEBUG
kprintf("ehci_idone: ex is done!\n ");
printf("ehci_idone: ex is done!\n ");
ehci_dump_exfer(ex);
#else
kprintf("ehci_idone: ex=%p is done!\n", ex);
printf("ehci_idone: ex=%p is done!\n", ex);
#endif
return;
}
ex->isdone = 1;
crit_exit();
splx(s);
}
#endif
......
callout_stop(&sc->sc_tmo_intrlist);
callout_stop(&sc->sc_tmo_pcd);
#if defined(__NetBSD__) || defined(__OpenBSD__)
if (sc->sc_powerhook != NULL)
powerhook_disestablish(sc->sc_powerhook);
if (sc->sc_shutdownhook != NULL)
shutdownhook_disestablish(sc->sc_shutdownhook);
#endif
usb_delay_ms(&sc->sc_bus, 300); /* XXX let stray task complete */
usb_freemem(&sc->sc_bus, &sc->sc_fldma);
......
{
ehci_softc_t *sc = v;
u_int32_t cmd, hcr;
int i;
int s, i;
#ifdef EHCI_DEBUG
DPRINTF(("ehci_power: sc=%p, why=%d\n", sc, why));
......
ehci_dump_regs(sc);
#endif
crit_enter();
s = splhardusb();
switch (why) {
case PWR_SUSPEND:
case PWR_STANDBY:
......
usb_delay_ms(&sc->sc_bus, 1);
}
if (hcr != 0) {
kprintf("%s: reset timeout\n",
printf("%s: reset timeout\n",
device_get_nameunit(sc->sc_bus.bdev));
}
......
usb_delay_ms(&sc->sc_bus, 1);
}
if (hcr != EHCI_STS_HCH) {
kprintf("%s: config timeout\n",
printf("%s: config timeout\n",
device_get_nameunit(sc->sc_bus.bdev));
}
......
usb_delay_ms(&sc->sc_bus, 1);
}
if (hcr == EHCI_STS_HCH) {
kprintf("%s: config timeout\n",
printf("%s: config timeout\n",
device_get_nameunit(sc->sc_bus.bdev));
}
......
case PWR_SOFTRESUME:
break;
}
crit_exit();
splx(s);
#ifdef EHCI_DEBUG
DPRINTF(("ehci_power: sc=%p\n", sc));
......
err = usb_allocmem(bus, size, 0, dma);
#ifdef EHCI_DEBUG
if (err)
kprintf("ehci_allocm: usb_allocmem()=%d\n", err);
printf("ehci_allocm: usb_allocmem()=%d\n", err);
#endif
return (err);
}
......
STAILQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
#ifdef DIAGNOSTIC
if (xfer->busy_free != XFER_FREE) {
kprintf("ehci_allocx: xfer=%p not free, 0x%08x\n", xfer,
printf("ehci_allocx: xfer=%p not free, 0x%08x\n", xfer,
xfer->busy_free);
}
#endif
} else {
xfer = kmalloc(sizeof(struct ehci_xfer), M_USB, M_NOWAIT);
xfer = malloc(sizeof(struct ehci_xfer), M_USB, M_NOWAIT);
}
if (xfer != NULL) {
memset(xfer, 0, sizeof(struct ehci_xfer));
......
#ifdef DIAGNOSTIC
if (xfer->busy_free != XFER_BUSY) {
kprintf("ehci_freex: xfer=%p not busy, 0x%08x\n", xfer,
printf("ehci_freex: xfer=%p not busy, 0x%08x\n", xfer,
xfer->busy_free);
return;
}
xfer->busy_free = XFER_FREE;
if (!EXFER(xfer)->isdone) {
kprintf("ehci_freex: !isdone\n");
printf("ehci_freex: !isdone\n");
return;
}
#endif
......
ehci_dump_regs(ehci_softc_t *sc)
{
int i;
kprintf("cmd=0x%08x, sts=0x%08x, ien=0x%08x\n",
printf("cmd=0x%08x, sts=0x%08x, ien=0x%08x\n",
EOREAD4(sc, EHCI_USBCMD),
EOREAD4(sc, EHCI_USBSTS),
EOREAD4(sc, EHCI_USBINTR));
kprintf("frindex=0x%08x ctrdsegm=0x%08x periodic=0x%08x async=0x%08x\n",
printf("frindex=0x%08x ctrdsegm=0x%08x periodic=0x%08x async=0x%08x\n",
EOREAD4(sc, EHCI_FRINDEX),
EOREAD4(sc, EHCI_CTRLDSSEGMENT),
EOREAD4(sc, EHCI_PERIODICLISTBASE),
EOREAD4(sc, EHCI_ASYNCLISTADDR));
for (i = 1; i <= sc->sc_noport; i++)
kprintf("port %d status=0x%08x\n", i,
printf("port %d status=0x%08x\n", i,
EOREAD4(sc, EHCI_PORTSC(i)));
}
......
ehci_dump_link(ehci_link_t link, int type)
{
link = le32toh(link);
kprintf("0x%08x", link);
printf("0x%08x", link);
if (link & EHCI_LINK_TERMINATE)
kprintf("<T>");
printf("<T>");
else {
kprintf("<");
printf("<");
if (type) {
switch (EHCI_LINK_TYPE(link)) {
case EHCI_LINK_ITD: kprintf("ITD"); break;
case EHCI_LINK_QH: kprintf("QH"); break;
case EHCI_LINK_SITD: kprintf("SITD"); break;
case EHCI_LINK_FSTN: kprintf("FSTN"); break;
case EHCI_LINK_ITD: printf("ITD"); break;
case EHCI_LINK_QH: printf("QH"); break;
case EHCI_LINK_SITD: printf("SITD"); break;
case EHCI_LINK_FSTN: printf("FSTN"); break;
}
}
kprintf(">");
printf(">");
}
}
......
stop = sqtd->qtd.qtd_next & htole32(EHCI_LINK_TERMINATE);
}
if (sqtd)
kprintf("dump aborted, too many TDs\n");
printf("dump aborted, too many TDs\n");
}
void
ehci_dump_sqtd(ehci_soft_qtd_t *sqtd)
{
kprintf("QTD(%p) at 0x%08x:\n", sqtd, sqtd->physaddr);
printf("QTD(%p) at 0x%08x:\n", sqtd, sqtd->physaddr);
ehci_dump_qtd(&sqtd->qtd);
}
......
u_int32_t s;
char sbuf[128];
kprintf(" next="); ehci_dump_link(qtd->qtd_next, 0);
kprintf(" altnext="); ehci_dump_link(qtd->qtd_altnext, 0);
kprintf("\n");
printf(" next="); ehci_dump_link(qtd->qtd_next, 0);
printf(" altnext="); ehci_dump_link(qtd->qtd_altnext, 0);
printf("\n");
s = le32toh(qtd->qtd_status);
bitmask_snprintf(EHCI_QTD_GET_STATUS(s),
"\20\10ACTIVE\7HALTED\6BUFERR\5BABBLE\4XACTERR"
"\3MISSED\2SPLIT\1PING", sbuf, sizeof(sbuf));
kprintf(" status=0x%08x: toggle=%d bytes=0x%x ioc=%d c_page=0x%x\n",
printf(" status=0x%08x: toggle=%d bytes=0x%x ioc=%d c_page=0x%x\n",
s, EHCI_QTD_GET_TOGGLE(s), EHCI_QTD_GET_BYTES(s),
EHCI_QTD_GET_IOC(s), EHCI_QTD_GET_C_PAGE(s));
kprintf(" cerr=%d pid=%d stat=0x%s\n", EHCI_QTD_GET_CERR(s),
printf(" cerr=%d pid=%d stat=0x%s\n", EHCI_QTD_GET_CERR(s),
EHCI_QTD_GET_PID(s), sbuf);
for (s = 0; s < 5; s++)
kprintf(" buffer[%d]=0x%08x\n", s, le32toh(qtd->qtd_buffer[s]));
printf(" buffer[%d]=0x%08x\n", s, le32toh(qtd->qtd_buffer[s]));
}
void
......
ehci_qh_t *qh = &sqh->qh;
u_int32_t endp, endphub;
kprintf("QH(%p) at 0x%08x:\n", sqh, sqh->physaddr);
kprintf(" sqtd=%p inactivesqtd=%p\n", sqh->sqtd, sqh->inactivesqtd);
kprintf(" link="); ehci_dump_link(qh->qh_link, 1); kprintf("\n");
printf("QH(%p) at 0x%08x:\n", sqh, sqh->physaddr);
printf(" sqtd=%p inactivesqtd=%p\n", sqh->sqtd, sqh->inactivesqtd);
printf(" link="); ehci_dump_link(qh->qh_link, 1); printf("\n");
endp = le32toh(qh->qh_endp);
kprintf(" endp=0x%08x\n", endp);
kprintf(" addr=0x%02x inact=%d endpt=%d eps=%d dtc=%d hrecl=%d\n",
printf(" endp=0x%08x\n", endp);
printf(" addr=0x%02x inact=%d endpt=%d eps=%d dtc=%d hrecl=%d\n",
EHCI_QH_GET_ADDR(endp), EHCI_QH_GET_INACT(endp),
EHCI_QH_GET_ENDPT(endp), EHCI_QH_GET_EPS(endp),
EHCI_QH_GET_DTC(endp), EHCI_QH_GET_HRECL(endp));
kprintf(" mpl=0x%x ctl=%d nrl=%d\n",
printf(" mpl=0x%x ctl=%d nrl=%d\n",
EHCI_QH_GET_MPL(endp), EHCI_QH_GET_CTL(endp),
EHCI_QH_GET_NRL(endp));
endphub = le32toh(qh->qh_endphub);
kprintf(" endphub=0x%08x\n", endphub);
kprintf(" smask=0x%02x cmask=0x%02x huba=0x%02x port=%d mult=%d\n",
printf(" endphub=0x%08x\n", endphub);
printf(" smask=0x%02x cmask=0x%02x huba=0x%02x port=%d mult=%d\n",
EHCI_QH_GET_SMASK(endphub), EHCI_QH_GET_CMASK(endphub),
EHCI_QH_GET_HUBA(endphub), EHCI_QH_GET_PORT(endphub),
EHCI_QH_GET_MULT(endphub));
kprintf(" curqtd="); ehci_dump_link(qh->qh_curqtd, 0); kprintf("\n");
kprintf("Overlay qTD:\n");
printf(" curqtd="); ehci_dump_link(qh->qh_curqtd, 0); printf("\n");
printf("Overlay qTD:\n");
ehci_dump_qtd(&qh->qh_qtd);
}
......
static void
ehci_dump_exfer(struct ehci_xfer *ex)
{
kprintf("ehci_dump_exfer: ex=%p\n", ex);
printf("ehci_dump_exfer: ex=%p\n", ex);
}
#endif
#endif
......
struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
ehci_soft_qh_t *sqh;
usbd_status err;
int s;
int ival, speed, naks;
int hshubaddr, hshubport;
......
default: panic("ehci_open: bad device speed %d", dev->speed);
}
if (speed != EHCI_QH_SPEED_HIGH && xfertype == UE_ISOCHRONOUS) {
kprintf("%s: *** WARNING: opening low/full speed device, this "
printf("%s: *** WARNING: opening low/full speed device, this "
"does not work yet.\n",
device_get_nameunit(sc->sc_bus.bdev));
DPRINTFN(1,("ehci_open: hshubaddr=%d hshubport=%d\n",
......
0, &epipe->u.ctl.reqdma);
#ifdef EHCI_DEBUG
if (err)
kprintf("ehci_open: usb_allocmem()=%d\n", err);
printf("ehci_open: usb_allocmem()=%d\n", err);
#endif
if (err)
goto bad1;
pipe->methods = &ehci_device_ctrl_methods;
crit_enter();
s = splusb();
ehci_add_qh(sqh, sc->sc_async_head);
crit_exit();
splx(s);
break;
case UE_BULK:
pipe->methods = &ehci_device_bulk_methods;
crit_enter();
s = splusb();
ehci_add_qh(sqh, sc->sc_async_head);
crit_exit();
splx(s);
break;
case UE_INTERRUPT:
pipe->methods = &ehci_device_intr_methods;
......
}
/*
* Add an ED to the schedule. Called while in a critical section.
* Add an ED to the schedule. Called at splusb().
* If in the async schedule, it will always have a next.
* If in the intr schedule it may not.
*/
void
ehci_add_qh(ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
{
SPLUSBCHECK;
sqh->next = head->next;
sqh->prev = head;
sqh->qh.qh_link = head->qh.qh_link;
......
#ifdef EHCI_DEBUG
if (ehcidebug > 5) {
kprintf("ehci_add_qh:\n");
printf("ehci_add_qh:\n");
ehci_dump_sqh(sqh);
}
#endif
}
/*
* Remove an ED from the schedule. Called while in a critical section.
* Remove an ED from the schedule. Called at splusb().
* Will always have a 'next' if it's in the async list as it's circular.
*/
void
ehci_rem_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head)
{
SPLUSBCHECK;
/* XXX */
sqh->prev->qh.qh_link = sqh->qh.qh_link;
sqh->prev->next = sqh->next;
......
if (EHCI_LINK_ADDR(le32toh(sqh->qh.qh_qtd.qtd_next)) !=
sqtd->physaddr) {
#ifdef EHCI_DEBUG
kprintf("ehci_activate_qh: unexpected next ptr\n");
printf("ehci_activate_qh: unexpected next ptr\n");
ehci_dump_sqh(sqh);
ehci_dump_sqtds(sqh->sqtd);
#endif
......
void
ehci_sync_hc(ehci_softc_t *sc)
{
int error;
int s, error;
if (sc->sc_dying) {
DPRINTFN(2,("ehci_sync_hc: dying\n"));
......
}
DPRINTFN(2,("ehci_sync_hc: enter\n"));
/* get doorbell */
lockmgr(&sc->sc_doorbell_lock, LK_EXCLUSIVE);
crit_enter();
lockmgr(&sc->sc_doorbell_lock, LK_EXCLUSIVE, NULL);
s = splhardusb();
/* ask for doorbell */
EOWRITE4(sc, EHCI_USBCMD, EOREAD4(sc, EHCI_USBCMD) | EHCI_CMD_IAAD);
DPRINTFN(1,("ehci_sync_hc: cmd=0x%08x sts=0x%08x\n",
EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS)));
error = tsleep(&sc->sc_async_head, 0, "ehcidi", hz); /* bell wait */
error = tsleep(&sc->sc_async_head, PZERO, "ehcidi", hz); /* bell wait */
DPRINTFN(1,("ehci_sync_hc: cmd=0x%08x sts=0x%08x\n",
EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS)));
crit_exit();
splx(s);
/* release doorbell */
lockmgr(&sc->sc_doorbell_lock, LK_RELEASE);
lockmgr(&sc->sc_doorbell_lock, LK_RELEASE, NULL);
#ifdef DIAGNOSTIC
if (error)
kprintf("ehci_sync_hc: tsleep() = %d\n", error);
printf("ehci_sync_hc: tsleep() = %d\n", error);
#endif
DPRINTFN(2,("ehci_sync_hc: exit\n"));
}
......
usb_device_request_t *req;
void *buf = NULL;
int port, i;
int len, value, index, l, totlen = 0;
int s, len, value, index, l, totlen = 0;
usb_port_status_t ps;
usb_hub_descriptor_t hubd;
usbd_status err;
......
goto ret;
}
v = EOREAD4(sc, EHCI_PORTSC(index));
DPRINTFN(8,("ehci_root_ctrl_start: port status=0x%04x\n", v));
DPRINTFN(8,("ehci_root_ctrl_start: port status=0x%04x\n",
v));
i = UPS_HIGH_SPEED;
if (v & EHCI_PS_CS) i |= UPS_CURRENT_CONNECT_STATUS;
if (v & EHCI_PS_PE) i |= UPS_PORT_ENABLED;
......
v = EOREAD4(sc, port);
DPRINTF(("ehci after reset, status=0x%08x\n", v));
if (v & EHCI_PS_PR) {
kprintf("%s: port reset timeout\n",
printf("%s: port reset timeout\n",
device_get_nameunit(sc->sc_bus.bdev));
return (USBD_TIMEOUT);
}
......
err = USBD_NORMAL_COMPLETION;
ret:
xfer->status = err;
crit_enter();
s = splusb();
hacksync(xfer); /* XXX to compensate for usb_transfer_complete */
usb_transfer_complete(xfer);
crit_exit();
splx(s);
return (USBD_IN_PROGRESS);
}
......
if (sc->sc_npcomp != 0) {
int i = (index-1) / sc->sc_npcomp;
if (i >= sc->sc_ncomp)
kprintf("%s: strange port\n",
printf("%s: strange port\n",
device_get_nameunit(sc->sc_bus.bdev));
else
kprintf("%s: handing over %s speed device on "
printf("%s: handing over %s speed device on "
"port %d to %s\n",
device_get_nameunit(sc->sc_bus.bdev),
lowspeed ? "low" : "full",
index, device_get_nameunit(sc->sc_comps[i]->bdev));
} else {
kprintf("%s: npcomp == 0\n", device_get_nameunit(sc->sc_bus.bdev));
printf("%s: npcomp == 0\n", device_get_nameunit(sc->sc_bus.bdev));
}
#endif
port = EHCI_PORTSC(index);
......
static void
ehci_root_intr_abort(usbd_xfer_handle xfer)
{
int s;
if (xfer->pipe->intrxfer == xfer) {
DPRINTF(("ehci_root_intr_abort: remove\n"));
xfer->pipe->intrxfer = NULL;
}
xfer->status = USBD_CANCELLED;
crit_enter();
s = splusb();
usb_transfer_complete(xfer);
crit_exit();
splx(s);
}
/* Close the root pipe. */
......
EHCI_PAGE_SIZE, &dma);
#ifdef EHCI_DEBUG
if (err)
kprintf("ehci_alloc_sqh: usb_allocmem()=%d\n", err);
printf("ehci_alloc_sqh: usb_allocmem()=%d\n", err);
#endif
if (err)
return (NULL);
......
usbd_status err;
int i, offs;
usb_dma_t dma;
int s;
if (sc->sc_freeqtds == NULL) {
DPRINTFN(2, ("ehci_alloc_sqtd: allocating chunk\n"));
......
EHCI_PAGE_SIZE, &dma);
#ifdef EHCI_DEBUG
if (err)
kprintf("ehci_alloc_sqtd: usb_allocmem()=%d\n", err);
printf("ehci_alloc_sqtd: usb_allocmem()=%d\n", err);
#endif
if (err)
return (NULL);
crit_enter();
s = splusb();
for(i = 0; i < EHCI_SQTD_CHUNK; i++) {
offs = i * EHCI_SQTD_SIZE;
sqtd = KERNADDR(&dma, offs);
......
sqtd->nextqtd = sc->sc_freeqtds;
sc->sc_freeqtds = sqtd;
}
crit_exit();
splx(s);
}
crit_enter();
s = splusb();
sqtd = sc->sc_freeqtds;
sc->sc_freeqtds = sqtd->nextqtd;
sqtd->qtd.qtd_next = EHCI_NULL;
......
}
sqtd->nextqtd = NULL;
sqtd->xfer = NULL;
crit_exit();
splx(s);
return (sqtd);
}
......
void
ehci_free_sqtd(ehci_softc_t *sc, ehci_soft_qtd_t *sqtd)
{
crit_enter();
int s;
s = splusb();
sqtd->nextqtd = sc->sc_freeqtds;
sc->sc_freeqtds = sqtd;
crit_exit();
splx(s);
}
usbd_status
......
/*
* Must stop if there is any gap before or after
* the page boundary.
*/
*/
if (EHCI_PAGE_OFFSET(dataphys + pagelen) != 0)
break;
if (seg < dma->nsegs && EHCI_PAGE_OFFSET(segoff +
......
struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;
ehci_softc_t *sc = (ehci_softc_t *)pipe->device->bus;
ehci_soft_qh_t *sqh = epipe->sqh;
int s;
crit_enter();
s = splusb();
ehci_rem_qh(sc, sqh, head);
crit_exit();
splx(s);
pipe->endpoint->savedtoggle =
EHCI_QTD_GET_TOGGLE(le32toh(sqh->qh.qh_qtd.qtd_status));
ehci_free_sqh(sc, epipe->sqh);
......
/*
* Abort a device request.
* If this routine is called from a critical section it guarantees that the
* request will be removed from the hardware scheduling and that the callback
* If this routine is called at splusb() it guarantees that the request
* will be removed from the hardware scheduling and that the callback
* for it will be called with USBD_CANCELLED status.
* It's impossible to guarantee that the requested transfer will not
* have happened since the hardware runs concurrently.
......
ehci_soft_qh_t *sqh = epipe->sqh;
ehci_soft_qtd_t *sqtd, *snext;
ehci_physaddr_t cur, us, next;
int s;
int hit, i;
/* int count = 0; */
ehci_soft_qh_t *psqh;
......
if (sc->sc_dying) {
/* If we're dying, just do the software part. */
crit_enter();
s = splusb();
xfer->status = status; /* make software ignore it */
callout_stop(&xfer->timeout_handle);
usb_rem_task(epipe->pipe.device, &exfer->abort_task);
usb_transfer_complete(xfer);
crit_exit();
splx(s);
return;
}
if (xfer->device->bus->intr_context /* || !curproc REMOVED DFly */)
if (xfer->device->bus->intr_context || !curproc)
panic("ehci_abort_xfer: not in process context");
/*
......
DPRINTFN(2, ("ehci_abort_xfer: waiting for abort to finish\n"));
exfer->ehci_xfer_flags |= EHCI_XFER_ABORTWAIT;
while (exfer->ehci_xfer_flags & EHCI_XFER_ABORTING)
tsleep(&exfer->ehci_xfer_flags, 0, "ehciaw", 0);
tsleep(&exfer->ehci_xfer_flags, PZERO, "ehciaw", 0);
return;
}
/*
* Step 1: Make interrupt routine and timeouts ignore xfer.
*/
crit_enter();
s = splusb();
exfer->ehci_xfer_flags |= EHCI_XFER_ABORTING;
xfer->status = status; /* make software ignore it */
callout_stop(&xfer->timeout_handle);
usb_rem_task(epipe->pipe.device, &exfer->abort_task);
crit_exit();
splx(s);
/*
* Step 2: Wait until we know hardware has finished any possible
......
* The hardware has no reference to completed items (TDs).
* It's safe to remove them at any time.
*/
crit_enter();
s = splusb();
#ifdef USB_USE_SOFTINTR
sc->sc_softwake = 1;
#endif /* USB_USE_SOFTINTR */
usb_schedsoftintr(&sc->sc_bus);
#ifdef USB_USE_SOFTINTR
tsleep(&sc->sc_softwake, 0, "ehciab", 0);
tsleep(&sc->sc_softwake, PZERO, "ehciab", 0);
#endif /* USB_USE_SOFTINTR */
/*
......
}
usb_transfer_complete(xfer);
/* kprintf("%s: %d TDs aborted\n", __func__, count); */
crit_exit();
/* printf("%s: %d TDs aborted\n", __func__, count); */
splx(s);
#undef exfer
}
......
/* Execute the abort in a process context. */
usb_add_task(exfer->xfer.pipe->device, &exfer->abort_task,
USB_TASKQ_HC);
USB_TASKQ_HC);
}
void
ehci_timeout_task(void *addr)
{
usbd_xfer_handle xfer = addr;
int s;
DPRINTF(("ehci_timeout_task: xfer=%p\n", xfer));
crit_enter();
s = splusb();
ehci_abort_xfer(xfer, USBD_TIMEOUT);
crit_exit();
splx(s);
}
/*
......
ehci_intrlist_timeout(void *arg)
{
ehci_softc_t *sc = arg;
int s = splusb();
DPRINTFN(3, ("ehci_intrlist_timeout\n"));
usb_schedsoftintr(&sc->sc_bus);
splx(s);
}
/************************/
......
#ifdef DIAGNOSTIC
if (!(xfer->rqflags & URQ_REQUEST)) {
/* XXX panic */
kprintf("ehci_device_ctrl_transfer: not a request\n");
printf("ehci_device_ctrl_transfer: not a request\n");
return (USBD_INVAL);
}
#endif
......
int isread;
int len;
usbd_status err;
int s;
isread = req->bmRequestType & UT_READ;
len = UGETW(req->wLength);
......
exfer->sqtdend = stat;
#ifdef DIAGNOSTIC
if (!exfer->isdone) {
kprintf("ehci_device_request: not done, exfer=%p\n", exfer);
printf("ehci_device_request: not done, exfer=%p\n", exfer);
}
exfer->isdone = 0;
#endif
/* Activate the new qTD in the QH list. */
crit_enter();
s = splusb();
ehci_activate_qh(sqh, setup);
if (xfer->timeout && !sc->sc_bus.use_polling) {
callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
ehci_timeout, xfer);
ehci_timeout, xfer);
}
ehci_add_intr_list(sc, exfer);
xfer->status = USBD_IN_PROGRESS;
crit_exit();
splx(s);
#ifdef EHCI_DEBUG
if (ehcidebug > 10) {
......
ehci_soft_qh_t *sqh;
usbd_status err;
int len, isread, endpt;
int s;
DPRINTFN(2, ("ehci_device_bulk_start: xfer=%p len=%d flags=%d\n",
xfer, xfer->length, xfer->flags));
......
exfer->sqtdend = dataend;
#ifdef DIAGNOSTIC
if (!exfer->isdone) {
kprintf("ehci_device_bulk_start: not done, ex=%p\n", exfer);
printf("ehci_device_bulk_start: not done, ex=%p\n", exfer);
}
exfer->isdone = 0;
#endif
crit_enter();
s = splusb();
ehci_activate_qh(sqh, data);
if (xfer->timeout && !sc->sc_bus.use_polling) {
callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
ehci_timeout, xfer);
ehci_timeout, xfer);
}
ehci_add_intr_list(sc, exfer);
xfer->status = USBD_IN_PROGRESS;
crit_exit();
splx(s);
#ifdef EHCI_DEBUG
if (ehcidebug > 10) {
......
DPRINTF(("ehci_device_bulk_start: data(3)\n"));
ehci_dump_regs(sc);
#if 0
kprintf("async_head:\n");
printf("async_head:\n");
ehci_dump_sqh(sc->sc_async_head);
#endif
kprintf("sqh:\n");
printf("sqh:\n");
ehci_dump_sqh(sqh);
ehci_dump_sqtds(data);
}
......
/* Pick an interrupt slot at the right level. */
/* XXX could do better than picking at random. */
islot = EHCI_IQHIDX(lev, karc4random());
islot = EHCI_IQHIDX(lev, arc4random());
sqh->islot = islot;
isp = &sc->sc_islots[islot];
......
ehci_soft_qh_t *sqh;
usbd_status err;
int len, isread, endpt;
int s;
DPRINTFN(2, ("ehci_device_intr_start: xfer=%p len=%d flags=%d\n",
xfer, xfer->length, xfer->flags));
......
exfer->sqtdend = dataend;
#ifdef DIAGNOSTIC
if (!exfer->isdone) {
kprintf("ehci_device_intr_start: not done, ex=%p\n", exfer);
printf("ehci_device_intr_start: not done, ex=%p\n", exfer);
}
exfer->isdone = 0;
#endif
crit_enter();
s = splusb();
ehci_activate_qh(sqh, data);
if (xfer->timeout && !sc->sc_bus.use_polling) {
callout_reset(&xfer->timeout_handle, MS_TO_TICKS(xfer->timeout),
......
}
ehci_add_intr_list(sc, exfer);
xfer->status = USBD_IN_PROGRESS;
crit_exit();
splx(s);
#ifdef EHCI_DEBUG
if (ehcidebug > 10) {
......
delay(10000);
DPRINTF(("ehci_device_intr_start: data(3)\n"));
ehci_dump_regs(sc);
kprintf("sqh:\n");
printf("sqh:\n");
ehci_dump_sqh(sqh);
ehci_dump_sqtds(data);
}
......
ehci_soft_qtd_t *data, *dataend, *newinactive;
ehci_soft_qh_t *sqh;
usbd_status err;
int len, isread, endpt;
int len, isread, endpt, s;
DPRINTFN(10, ("ehci_device_intr_done: xfer=%p, actlen=%d\n",
xfer, xfer->actlen));
......
if (xfer->pipe->repeat) {
ehci_free_sqtd_chain(sc, sqh, ex->sqtdstart,
ex->sqtdend->nextqtd);
len = epipe->u.intr.length;
xfer->length = len;
endpt = epipe->pipe.endpoint->edesc->bEndpointAddress;
......
exfer->sqtdend = dataend;
#ifdef DIAGNOSTIC
if (!exfer->isdone) {
kprintf("ehci_device_intr_done: not done, ex=%p\n",
printf("ehci_device_intr_done: not done, ex=%p\n",
exfer);
}
exfer->isdone = 0;
#endif
crit_enter();
s = splusb();
ehci_activate_qh(sqh, data);
if (xfer->timeout && !sc->sc_bus.use_polling) {
callout_reset(&xfer->timeout_handle,
MS_TO_TICKS(xfer->timeout), ehci_timeout, xfer);
}
crit_exit();
splx(s);
xfer->status = USBD_IN_PROGRESS;
} else if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) {
-- ehci_pci.c 2008-05-19 10:32:14 +0000
++ /root/src/sys/dev/usb/ehci_pci.c 2008-04-11 05:50:53 +0000
......
/*
......
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
......
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD: src/sys/dev/usb/ehci_pci.c,v 1.18.2.1 2006/01/26 01:43:13 iedowse Exp $
* $DragonFly: src/sys/bus/usb/ehci_pci.c,v 1.18 2007/08/14 20:06:13 dillon Exp $
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/usb/ehci_pci.c,v 1.32 2008/04/11 05:50:53 benno Exp $");
/*
* USB Enhanced Host Controller Driver, a.k.a. USB 2.0 controller.
*
......
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/bus.h>
#include <sys/queue.h>
#include <sys/lock.h>
#include <sys/lockmgr.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
#include <bus/pci/pcivar.h>
#include <bus/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
#include <bus/usb/usb.h>
#include <bus/usb/usbdi.h>
#include <bus/usb/usbdivar.h>
#include <bus/usb/usb_mem.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdivar.h>
#include <dev/usb/usb_mem.h>
#include <bus/usb/ehcireg.h>
#include <bus/usb/ehcivar.h>
#include <dev/usb/ehcireg.h>
#include <dev/usb/ehcivar.h>
#define PCI_EHCI_VENDORID_ACERLABS 0x10b9
#define PCI_EHCI_VENDORID_AMD 0x1022
......
/* AMD */
#define PCI_EHCI_DEVICEID_8111 0x10227463
#define PCI_EHCI_DEVICEID_CS5536 0x20951022
static const char *ehci_device_8111 = "AMD 8111 USB 2.0 controller";
static const char *ehci_device_CS5536 = "AMD CS5536 USB 2.0 controller";
/* ATI */
#define PCI_EHCI_DEVICEID_SB200 0x43451002
......
#define PCI_EHCI_DEVICEID_ISP156X 0x15621131
static const char *ehci_device_isp156x = "Philips ISP156x USB 2.0 controller";
/* VIA */
#define PCI_EHCI_DEVICEID_VIA 0x31041106
static const char *ehci_device_via = "VIA VT6202 USB 2.0 controller";
/* Generic */
static const char *ehci_device_generic = "EHCI (generic) USB 2.0 controller";
#define PCI_EHCI_BASE_REG 0x10
#ifdef USB_DEBUG
#define EHCI_DEBUG USB_DEBUG
#define DPRINTF(x) do { if (ehcidebug) kprintf x; } while (0)
#define DPRINTF(x) do { if (ehcidebug) printf x; } while (0)
extern int ehcidebug;
#else
#define DPRINTF(x)
......
return (ehci_device_m5239);
case PCI_EHCI_DEVICEID_8111:
return (ehci_device_8111);
case PCI_EHCI_DEVICEID_CS5536:
return (ehci_device_CS5536);
case PCI_EHCI_DEVICEID_SB200:
return (ehci_device_sb200);
case PCI_EHCI_DEVICEID_SB400:
......
device_set_desc(sc->sc_bus.bdev, ehci_pci_match(self));
switch (pci_get_vendor(self)) {
case PCI_EHCI_VENDORID_ACERLABS:
ksprintf(sc->sc_vendor, "AcerLabs");
sprintf(sc->sc_vendor, "AcerLabs");
break;
case PCI_EHCI_VENDORID_AMD:
ksprintf(sc->sc_vendor, "AMD");
sprintf(sc->sc_vendor, "AMD");
break;
case PCI_EHCI_VENDORID_APPLE:
ksprintf(sc->sc_vendor, "Apple");
sprintf(sc->sc_vendor, "Apple");
break;
case PCI_EHCI_VENDORID_ATI:
ksprintf(sc->sc_vendor, "ATI");
sprintf(sc->sc_vendor, "ATI");
break;
case PCI_EHCI_VENDORID_CMDTECH:
ksprintf(sc->sc_vendor, "CMDTECH");
sprintf(sc->sc_vendor, "CMDTECH");
break;
case PCI_EHCI_VENDORID_INTEL:
ksprintf(sc->sc_vendor, "Intel");
sprintf(sc->sc_vendor, "Intel");
break;
case PCI_EHCI_VENDORID_NEC:
ksprintf(sc->sc_vendor, "NEC");
sprintf(sc->sc_vendor, "NEC");
break;
case PCI_EHCI_VENDORID_OPTI:
ksprintf(sc->sc_vendor, "OPTi");
sprintf(sc->sc_vendor, "OPTi");
break;
case PCI_EHCI_VENDORID_SIS:
ksprintf(sc->sc_vendor, "SiS");
sprintf(sc->sc_vendor, "SiS");
break;
case PCI_EHCI_VENDORID_NVIDIA:
case PCI_EHCI_VENDORID_NVIDIA2:
ksprintf(sc->sc_vendor, "nVidia");
sprintf(sc->sc_vendor, "nVidia");
break;
case PCI_EHCI_VENDORID_VIA:
ksprintf(sc->sc_vendor, "VIA");
sprintf(sc->sc_vendor, "VIA");
break;
default:
if (bootverbose)
device_printf(self, "(New EHCI DeviceId=0x%08x)\n",
pci_get_devid(self));
ksprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
sprintf(sc->sc_vendor, "(0x%04x)", pci_get_vendor(self));
}
err = bus_setup_intr(self, sc->irq_res, 0,
(driver_intr_t *) ehci_intr, sc, &sc->ih, NULL);
err = bus_setup_intr(self, sc->irq_res, INTR_TYPE_BIO,
NULL, (driver_intr_t *)ehci_intr, sc, &sc->ih);
if (err) {
device_printf(self, "Could not setup irq, %d\n", err);
sc->ih = NULL;
......
if (res != 0)
continue;
if (buscount != 1) {
kfree(nbus, M_TEMP);
free(nbus, M_TEMP);
continue;
}
if (device_get_devclass(nbus[0]) != dc) {
kfree(nbus, M_TEMP);
free(nbus, M_TEMP);
continue;
}
bsc = device_get_softc(nbus[0]);
kfree(nbus, M_TEMP);
free(nbus, M_TEMP);
DPRINTF(("ehci_pci_attach: companion %s\n",
device_get_nameunit(bsc->bdev)));
sc->sc_comps[ncomp++] = bsc;
......
sc->sc_ncomp = ncomp;
/* Allocate a parent dma tag for DMA maps */
err = bus_dma_tag_create(/*XXX: bus_get_dma_tag(self)*/NULL, 1, 0,
err = bus_dma_tag_create(bus_get_dma_tag(self), 1, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
&sc->sc_bus.parent_dmatag);
NULL, NULL, &sc->sc_bus.parent_dmatag);
if (err) {
device_printf(self, "Could not allocate parent DMA tag (%d)\n",
err);
......
err = bus_dma_tag_create(sc->sc_bus.parent_dmatag, 1, 0,
BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
BUS_SPACE_MAXSIZE_32BIT, USB_DMA_NSEG, BUS_SPACE_MAXSIZE_32BIT, 0,
&sc->sc_bus.buffer_dmatag);
busdma_lock_mutex, &Giant, &sc->sc_bus.buffer_dmatag);
if (err) {
device_printf(self, "Could not allocate buffer DMA tag (%d)\n",
err);
......
bus_dma_tag_destroy(sc->sc_bus.parent_dmatag);
if (sc->sc_bus.buffer_dmatag != NULL)
bus_dma_tag_destroy(sc->sc_bus.buffer_dmatag);
if (sc->irq_res && sc->ih) {
int err = bus_teardown_intr(self, sc->irq_res, sc->ih);
......
/* Synchronise with the BIOS if it owns the controller. */
for (eecp = EHCI_HCC_EECP(cparams); eecp != 0;
eecp = EHCI_EECP_NEXT(eec)) {
eecp = EHCI_EECP_NEXT(eec)) {
eec = pci_read_config(self, eecp, 4);
if (EHCI_EECP_ID(eec) != EHCI_EC_LEGSUP)
continue;
......
if (legsup & EHCI_LEGSUP_BIOSOWNED) {
pci_write_config(self, eecp,
legsup | EHCI_LEGSUP_OSOWNED, 4);
kprintf("%s: waiting for BIOS to give up control\n",
printf("%s: waiting for BIOS to give up control\n",
device_get_nameunit(sc->sc_bus.bdev));
for (i = 0; i < 5000; i++) {
legsup = pci_read_config(self, eecp, 4);
......
DELAY(1000);
}
if (legsup & EHCI_LEGSUP_BIOSOWNED)
kprintf("%s: timed out waiting for BIOS\n",
printf("%s: timed out waiting for BIOS\n",
device_get_nameunit(sc->sc_bus.bdev));
}
}
......
cparams = EREAD4(sc, EHCI_HCCPARAMS);
for (eecp = EHCI_HCC_EECP(cparams); eecp != 0;
eecp = EHCI_EECP_NEXT(eec)) {
eecp = EHCI_EECP_NEXT(eec)) {
eec = pci_read_config(self, eecp, 4);
if (EHCI_EECP_ID(eec) != EHCI_EC_LEGSUP)
continue;
-- ehcireg.h 2007-06-27 12:27:59 +0000
++ /root/src/sys/dev/usb/ehcireg.h 2005-09-18 11:45:39 +0000
......
/* $NetBSD: ehcireg.h,v 1.18 2004/10/22 10:38:17 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/ehcireg.h,v 1.7.2.1 2006/01/26 01:43:13 iedowse Exp $ */
/* $DragonFly: src/sys/bus/usb/ehcireg.h,v 1.7 2007/06/27 12:27:59 hasso Exp $ */
/* $FreeBSD: src/sys/dev/usb/ehcireg.h,v 1.8 2005/09/18 11:45:39 netchild Exp $ */
/*
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
......
#define EHCI_PAGE_SIZE 0x1000
#define EHCI_PAGE(x) ((x) &~ 0xfff)
#define EHCI_PAGE_OFFSET(x) ((x) & 0xfff)
#if defined(__FreeBSD__)
#define EHCI_PAGE_MASK(x) ((x) & 0xfff)
#endif
typedef u_int32_t ehci_link_t;
#define EHCI_LINK_TERMINATE 0x00000001
......
#define EHCI_QTD_SET_TOGGLE(x) ((x) << 31)
#define EHCI_QTD_TOGGLE_MASK 0x80000000
ehci_physaddr_t qtd_buffer[EHCI_QTD_NBUFFERS];
ehci_physaddr_t qtd_buffer_hi[EHCI_QTD_NBUFFERS];
ehci_physaddr_t qtd_buffer_hi[EHCI_QTD_NBUFFERS];
} ehci_qtd_t;
#define EHCI_QTD_ALIGN 32
-- ehcivar.h 2008-05-19 10:17:44 +0000
++ /root/src/sys/dev/usb/ehcivar.h 2007-06-14 16:23:31 +0000
......
/* $NetBSD: ehcivar.h,v 1.19 2005/04/29 15:04:29 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/ehcivar.h,v 1.9.2.1 2006/01/26 01:43:13 iedowse Exp $ */
/* $DragonFly: src/sys/bus/usb/ehcivar.h,v 1.11 2007/06/30 20:39:22 hasso Exp $ */
/* $FreeBSD: src/sys/dev/usb/ehcivar.h,v 1.17 2007/06/14 16:23:31 imp Exp $ */
/*
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
* All rights reserved.
*
......
* Information about an entry in the interrupt list.
*/
struct ehci_soft_islot {
ehci_soft_qh_t *sqh; /* Queue Head. */
ehci_soft_qh_t *sqh; /* Queue Head. */
};
#define EHCI_FRAMELIST_MAXCOUNT 1024
#define EHCI_IPOLLRATES 8 /* Poll rates (1ms, 2, 4, 8 ... 128) */
#define EHCI_INTRQHS ((1 << EHCI_IPOLLRATES) - 1)
#define EHCI_MAX_POLLRATE (1 << (EHCI_IPOLLRATES - 1))
#define EHCI_IQHIDX(lev, pos) \
((((pos) & ((1 << (lev)) - 1)) | (1 << (lev))) - 1)
#define EHCI_IQHIDX(lev, pos) \
((((pos) & ((1 << (lev)) - 1)) | (1 << (lev))) - 1)
#define EHCI_ILEV_IVAL(lev) (1 << (lev))
#define EHCI_HASH_SIZE 128
#define EHCI_COMPANION_MAX 8
......
typedef struct ehci_softc {
struct usbd_bus sc_bus; /* base device */
int sc_flags;
bus_space_tag_t iot;
bus_space_handle_t ioh;
bus_size_t sc_size;
#if defined(__FreeBSD__)
void *ih;
struct resource *io_res;
struct resource *irq_res;
#endif
u_int sc_offs; /* offset to operational regs */
int sc_flags; /* misc flags */
char sc_vendor[32]; /* vendor string for root hub */
int sc_id_vendor; /* vendor ID for root hub */
u_int32_t sc_cmd; /* shadow of cmd reg during suspend */
#if defined(__NetBSD__) || defined(__OpenBSD__)
void *sc_powerhook; /* cookie from power hook */
void *sc_shutdownhook; /* cookie from shutdown hook */
#endif
u_int sc_ncomp;
u_int sc_npcomp;
......
usb_dma_t sc_fldma;
ehci_link_t *sc_flist;
u_int sc_flsize;
#ifndef __FreeBSD__
u_int sc_rand; /* XXX need proper intr scheduling */
#endif
struct ehci_soft_islot sc_islots[EHCI_INTRQHS];
......
struct callout sc_tmo_intrlist;
char sc_dying;
#if defined(__NetBSD__)
struct usb_dma_reserve sc_dma_reserve;
#endif
} ehci_softc_t;
#define EREAD1(sc, a) bus_space_read_1((sc)->iot, (sc)->ioh, (a))
......
usbd_status ehci_init(ehci_softc_t *);
int ehci_intr(void *);
int ehci_detach(ehci_softc_t *, int);
#if defined(__NetBSD__) || defined(__OpenBSD__)
int ehci_activate(device_t, enum devact);
#endif
void ehci_power(int state, void *priv);
void ehci_shutdown(void *v);
-- hid.c 2008-05-18 17:51:14 +0000
++ /root/src/sys/dev/usb/hid.c 2008-05-18 21:28:20 +0000
......
/*
* $NetBSD: hid.c,v 1.17 2001/11/13 06:24:53 lukem Exp $
* $FreeBSD: src/sys/dev/usb/hid.c,v 1.23 2003/08/24 17:55:54 obrien Exp $
* $DragonFly: src/sys/bus/usb/hid.c,v 1.13 2007/06/28 13:55:12 hasso Exp $
*/
/*
......
/* $NetBSD: hid.c,v 1.17 2001/11/13 06:24:53 lukem Exp $ */
#include <sys/cdefs.h>
__FBSDID("$FreeBSD: src/sys/dev/usb/hid.c,v 1.29 2007/06/20 05:10:52 imp Exp $");
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
......
#include <sys/systm.h>
#include <sys/malloc.h>
#include <bus/usb/usb.h>
#include <bus/usb/usbhid.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbhid.h>
#include <bus/usb/hid.h>
#include <dev/usb/hid.h>
#ifdef USB_DEBUG
#define DPRINTF(x) if (usbdebug) kprintf x
#define DPRINTFN(n,x) if (usbdebug>(n)) kprintf x
#define DPRINTF(x) if (usbdebug) printf x
#define DPRINTFN(n,x) if (usbdebug>(n)) printf x
extern int usbdebug;
#else
#define DPRINTF(x)
......
{
struct hid_data *s;
... This diff was truncated because it exceeds the maximum size that can be displayed.
(2-2/2)