summaryrefslogtreecommitdiffstats
path: root/sys/dev/usb/uhci.c
diff options
context:
space:
mode:
authornate <nate@openbsd.org>2001-10-31 04:24:44 +0000
committernate <nate@openbsd.org>2001-10-31 04:24:44 +0000
commit0897b80639e4d661f49433c68add5f402f119556 (patch)
tree92e2c1dd5a3fd2a116e54c8265ac8a2c3351fd7c /sys/dev/usb/uhci.c
parentClarify some struct fields. (diff)
downloadwireguard-openbsd-0897b80639e4d661f49433c68add5f402f119556.tar.xz
wireguard-openbsd-0897b80639e4d661f49433c68add5f402f119556.zip
Synchronize usb code with NetBSD.
Diffstat (limited to 'sys/dev/usb/uhci.c')
-rw-r--r--sys/dev/usb/uhci.c120
1 files changed, 74 insertions, 46 deletions
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c
index 337fbf4aa9b..50f06ec2dbb 100644
--- a/sys/dev/usb/uhci.c
+++ b/sys/dev/usb/uhci.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: uhci.c,v 1.21 2001/06/12 19:11:58 mickey Exp $ */
-/* $NetBSD: uhci.c,v 1.135 2001/04/01 14:59:52 augustss Exp $ */
+/* $OpenBSD: uhci.c,v 1.22 2001/10/31 04:24:44 nate Exp $ */
+/* $NetBSD: uhci.c,v 1.142 2001/10/25 02:08:13 augustss Exp $ */
/* $FreeBSD: src/sys/dev/usb/uhci.c,v 1.33 1999/11/17 22:33:41 n_hibma Exp $ */
/*
@@ -159,9 +159,11 @@ struct uhci_pipe {
} u;
};
-Static void uhci_busreset(uhci_softc_t *);
+Static void uhci_globalreset(uhci_softc_t *);
+Static void uhci_reset(uhci_softc_t *);
Static void uhci_shutdown(void *v);
Static void uhci_power(int, void *);
+Static usbd_status uhci_run(uhci_softc_t *, int run);
Static uhci_soft_td_t *uhci_alloc_std(uhci_softc_t *);
Static void uhci_free_std(uhci_softc_t *, uhci_soft_td_t *);
Static uhci_soft_qh_t *uhci_alloc_sqh(uhci_softc_t *);
@@ -242,7 +244,7 @@ Static void uhci_root_intr_done(usbd_xfer_handle);
Static usbd_status uhci_open(usbd_pipe_handle);
Static void uhci_poll(struct usbd_bus *);
-Static void uhci_softintr(struct usbd_bus *);
+Static void uhci_softintr(void *);
Static usbd_status uhci_device_request(usbd_xfer_handle xfer);
@@ -283,7 +285,7 @@ void uhci_dump(void);
#define UHCICMD(sc, cmd) UWRITE2(sc, UHCI_CMD, cmd)
#define UHCISTS(sc) UREAD2(sc, UHCI_STS)
-#define UHCI_RESET_TIMEOUT 100 /* reset timeout */
+#define UHCI_RESET_TIMEOUT 100 /* ms, reset timeout */
#define UHCI_CURFRAME(sc) (UREAD2(sc, UHCI_FRNUM) & UHCI_FRNUM_MASK)
@@ -375,7 +377,7 @@ uhci_find_prev_qh(uhci_soft_qh_t *pqh, uhci_soft_qh_t *sqh)
}
void
-uhci_busreset(uhci_softc_t *sc)
+uhci_globalreset(uhci_softc_t *sc)
{
UHCICMD(sc, UHCI_CMD_GRESET); /* global reset */
usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY); /* wait a little */
@@ -401,8 +403,8 @@ uhci_init(uhci_softc_t *sc)
uhci_run(sc, 0); /* stop the controller */
UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */
-
- uhci_busreset(sc);
+ uhci_globalreset(sc); /* reset the controller */
+ uhci_reset(sc);
/* Allocate and initialize real frame array. */
err = usb_allocmem(&sc->sc_bus,
@@ -815,13 +817,11 @@ uhci_dump_qh(uhci_soft_qh_t *sqh)
}
-#if 1
void
uhci_dump(void)
{
uhci_dump_all(thesc);
}
-#endif
void
uhci_dump_all(uhci_softc_t *sc)
@@ -910,6 +910,16 @@ uhci_dump_ii(uhci_intr_info_t *ii)
ii, DONE, ii->xfer);
return;
}
+ if (pipe->endpoint == NULL) {
+ printf("ii %p: done=%d xfer=%p pipe=%p pipe->endpoint=NULL\n",
+ ii, DONE, ii->xfer, pipe);
+ return;
+ }
+ if (pipe->device == NULL) {
+ printf("ii %p: done=%d xfer=%p pipe=%p pipe->device=NULL\n",
+ ii, DONE, ii->xfer, pipe);
+ return;
+ }
ed = pipe->endpoint->edesc;
dev = pipe->device;
printf("ii %p: done=%d xfer=%p dev=%p vid=0x%04x pid=0x%04x addr=%d pipe=%p ep=0x%02x attr=0x%02x\n",
@@ -1148,16 +1158,32 @@ uhci_remove_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh)
sc->sc_bulk_end = pqh;
}
+Static int uhci_intr1(uhci_softc_t *);
+
int
uhci_intr(void *arg)
{
uhci_softc_t *sc = arg;
+
+ DPRINTFN(15,("uhci_intr: real interrupt\n"));
+ if (sc->sc_bus.use_polling) {
+#ifdef DIAGNOSTIC
+ printf("uhci_intr: ignored interrupt while polling\n");
+#endif
+ return (0);
+ }
+ return (uhci_intr1(sc));
+}
+
+int
+uhci_intr1(uhci_softc_t *sc)
+{
int status;
int ack;
#ifdef UHCI_DEBUG
if (uhcidebug > 15) {
- DPRINTF(("%s: uhci_intr\n", USBDEVNAME(sc->sc_bus.bdev)));
+ DPRINTF(("%s: uhci_intr1\n", USBDEVNAME(sc->sc_bus.bdev)));
uhci_dumpregs(sc);
}
#endif
@@ -1166,6 +1192,11 @@ uhci_intr(void *arg)
if (status == 0) /* The interrupt was not for us. */
return (0);
+#if defined(DIAGNOSTIC) && defined(__NetBSD__)
+ if (sc->sc_suspend != PWR_RESUME)
+ printf("uhci_intr: suspended sts=0x%x\n", status);
+#endif
+
if (sc->sc_suspend != PWR_RESUME) {
printf("%s: interrupt while not operating ignored\n",
USBDEVNAME(sc->sc_bus.bdev));
@@ -1173,11 +1204,6 @@ uhci_intr(void *arg)
return (0);
}
-#if defined(DIAGNOSTIC) && defined(__NetBSD__)
- if (sc->sc_suspend != PWR_RESUME)
- printf("uhci_intr: suspended sts=0x%x\n", status);
-#endif
-
ack = 0;
if (status & UHCI_STS_USBINT)
ack |= UHCI_STS_USBINT;
@@ -1200,14 +1226,14 @@ uhci_intr(void *arg)
}
if (status & UHCI_STS_HCH) {
/* no acknowledge needed */
- if (!sc->sc_dying)
+ if (!sc->sc_dying) {
printf("%s: host controller halted\n",
USBDEVNAME(sc->sc_bus.bdev));
- sc->sc_dying = 1;
#ifdef UHCI_DEBUG
- uhci_dump_all(sc);
+ uhci_dump_all(sc);
#endif
-
+ }
+ sc->sc_dying = 1;
}
if (!ack)
@@ -1223,12 +1249,13 @@ uhci_intr(void *arg)
}
void
-uhci_softintr(struct usbd_bus *bus)
+uhci_softintr(void *v)
{
- uhci_softc_t *sc = (uhci_softc_t *)bus;
+ uhci_softc_t *sc = v;
uhci_intr_info_t *ii;
- DPRINTFN(10,("%s: uhci_softintr\n", USBDEVNAME(sc->sc_bus.bdev)));
+ DPRINTFN(10,("%s: uhci_softintr (%d)\n", USBDEVNAME(sc->sc_bus.bdev),
+ sc->sc_bus.intr_context));
sc->sc_bus.intr_context++;
@@ -1313,6 +1340,7 @@ uhci_idone(uhci_intr_info_t *ii)
u_int32_t status = 0, nstatus;
int actlen;
+ DPRINTFN(12, ("uhci_idone: ii=%p\n", ii));
#ifdef DIAGNOSTIC
{
int s = splhigh();
@@ -1365,8 +1393,7 @@ uhci_idone(uhci_intr_info_t *ii)
upipe->u.iso.inuse -= nframes;
xfer->actlen = actlen;
xfer->status = USBD_NORMAL_COMPLETION;
- usb_transfer_complete(xfer);
- return;
+ goto end;
}
#ifdef UHCI_DEBUG
@@ -1393,7 +1420,7 @@ uhci_idone(uhci_intr_info_t *ii)
upipe->nexttoggle = UHCI_TD_GET_DT(le32toh(std->td.td_token));
status &= UHCI_TD_ERROR;
- DPRINTFN(10, ("uhci_check_intr: actlen=%d, status=0x%x\n",
+ DPRINTFN(10, ("uhci_idone: actlen=%d, status=0x%x\n",
actlen, status));
xfer->actlen = actlen;
if (status != 0) {
@@ -1419,7 +1446,10 @@ uhci_idone(uhci_intr_info_t *ii)
} else {
xfer->status = USBD_NORMAL_COMPLETION;
}
+
+ end:
usb_transfer_complete(xfer);
+ DPRINTFN(12, ("uhci_idone: ii=%p done\n", ii));
}
/*
@@ -1461,7 +1491,7 @@ uhci_waitintr(uhci_softc_t *sc, usbd_xfer_handle xfer)
usb_delay_ms(&sc->sc_bus, 1);
DPRINTFN(20,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS)));
if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) {
- uhci_intr(sc);
+ uhci_intr1(sc);
if (xfer->status != USBD_IN_PROGRESS)
return;
}
@@ -1486,10 +1516,9 @@ uhci_poll(struct usbd_bus *bus)
uhci_softc_t *sc = (uhci_softc_t *)bus;
if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT)
- uhci_intr(sc);
+ uhci_intr1(sc);
}
-#if 0
void
uhci_reset(uhci_softc_t *sc)
{
@@ -1504,7 +1533,6 @@ uhci_reset(uhci_softc_t *sc)
printf("%s: controller did not reset\n",
USBDEVNAME(sc->sc_bus.bdev));
}
-#endif
usbd_status
uhci_run(uhci_softc_t *sc, int run)
@@ -3055,27 +3083,27 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer)
}
switch(value) {
case UHF_PORT_ENABLE:
- x = UREAD2(sc, port);
+ x = URWMASK(UREAD2(sc, port));
UWRITE2(sc, port, x & ~UHCI_PORTSC_PE);
break;
case UHF_PORT_SUSPEND:
- x = UREAD2(sc, port);
+ x = URWMASK(UREAD2(sc, port));
UWRITE2(sc, port, x & ~UHCI_PORTSC_SUSP);
break;
case UHF_PORT_RESET:
- x = UREAD2(sc, port);
+ x = URWMASK(UREAD2(sc, port));
UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);
break;
case UHF_C_PORT_CONNECTION:
- x = UREAD2(sc, port);
+ x = URWMASK(UREAD2(sc, port));
UWRITE2(sc, port, x | UHCI_PORTSC_CSC);
break;
case UHF_C_PORT_ENABLE:
- x = UREAD2(sc, port);
+ x = URWMASK(UREAD2(sc, port));
UWRITE2(sc, port, x | UHCI_PORTSC_POEDC);
break;
case UHF_C_PORT_OVER_CURRENT:
- x = UREAD2(sc, port);
+ x = URWMASK(UREAD2(sc, port));
UWRITE2(sc, port, x | UHCI_PORTSC_OCIC);
break;
case UHF_C_PORT_RESET:
@@ -3140,21 +3168,21 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer)
}
x = UREAD2(sc, port);
status = change = 0;
- if (x & UHCI_PORTSC_CCS )
+ if (x & UHCI_PORTSC_CCS)
status |= UPS_CURRENT_CONNECT_STATUS;
- if (x & UHCI_PORTSC_CSC )
+ if (x & UHCI_PORTSC_CSC)
change |= UPS_C_CONNECT_STATUS;
- if (x & UHCI_PORTSC_PE )
+ if (x & UHCI_PORTSC_PE)
status |= UPS_PORT_ENABLED;
if (x & UHCI_PORTSC_POEDC)
change |= UPS_C_PORT_ENABLED;
- if (x & UHCI_PORTSC_OCI )
+ if (x & UHCI_PORTSC_OCI)
status |= UPS_OVERCURRENT_INDICATOR;
- if (x & UHCI_PORTSC_OCIC )
+ if (x & UHCI_PORTSC_OCIC)
change |= UPS_C_OVERCURRENT_INDICATOR;
- if (x & UHCI_PORTSC_SUSP )
+ if (x & UHCI_PORTSC_SUSP)
status |= UPS_SUSPEND;
- if (x & UHCI_PORTSC_LSDA )
+ if (x & UHCI_PORTSC_LSDA)
status |= UPS_LOW_SPEED;
status |= UPS_PORT_POWER;
if (sc->sc_isreset)
@@ -3181,15 +3209,15 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer)
}
switch(value) {
case UHF_PORT_ENABLE:
- x = UREAD2(sc, port);
+ x = URWMASK(UREAD2(sc, port));
UWRITE2(sc, port, x | UHCI_PORTSC_PE);
break;
case UHF_PORT_SUSPEND:
- x = UREAD2(sc, port);
+ x = URWMASK(UREAD2(sc, port));
UWRITE2(sc, port, x | UHCI_PORTSC_SUSP);
break;
case UHF_PORT_RESET:
- x = UREAD2(sc, port);
+ x = URWMASK(UREAD2(sc, port));
UWRITE2(sc, port, x | UHCI_PORTSC_PR);
usb_delay_ms(&sc->sc_bus, 50); /*XXX USB v1.1 7.1.7.3 */
UWRITE2(sc, port, x & ~UHCI_PORTSC_PR);