summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/usb/hid.c22
-rw-r--r--sys/dev/usb/hid.h2
-rw-r--r--sys/dev/usb/ohci.c1192
-rw-r--r--sys/dev/usb/ohcireg.h6
-rw-r--r--sys/dev/usb/ohcivar.h25
-rw-r--r--sys/dev/usb/ugen.c338
-rw-r--r--sys/dev/usb/uhci.c1138
-rw-r--r--sys/dev/usb/uhcireg.h2
-rw-r--r--sys/dev/usb/uhcivar.h25
-rw-r--r--sys/dev/usb/uhid.c112
-rw-r--r--sys/dev/usb/uhub.c310
-rw-r--r--sys/dev/usb/ukbd.c17
-rw-r--r--sys/dev/usb/ulpt.c78
-rw-r--r--sys/dev/usb/umass.c16
-rw-r--r--sys/dev/usb/ums.c48
-rw-r--r--sys/dev/usb/usb.c449
-rw-r--r--sys/dev/usb/usb.h31
-rw-r--r--sys/dev/usb/usb_mem.h8
-rw-r--r--sys/dev/usb/usb_port.h59
-rw-r--r--sys/dev/usb/usb_quirks.c8
-rw-r--r--sys/dev/usb/usb_subr.c316
-rw-r--r--sys/dev/usb/usbcdc.h2
-rw-r--r--sys/dev/usb/usbdevs.h7
-rw-r--r--sys/dev/usb/usbdevs_data.h20
-rw-r--r--sys/dev/usb/usbdi.c661
-rw-r--r--sys/dev/usb/usbdi.h42
-rw-r--r--sys/dev/usb/usbdi_util.c130
-rw-r--r--sys/dev/usb/usbdi_util.h2
-rw-r--r--sys/dev/usb/usbdivar.h48
-rw-r--r--sys/dev/usb/usbhid.h2
30 files changed, 2929 insertions, 2187 deletions
diff --git a/sys/dev/usb/hid.c b/sys/dev/usb/hid.c
index c782c50..32b8cf4 100644
--- a/sys/dev/usb/hid.c
+++ b/sys/dev/usb/hid.c
@@ -1,4 +1,4 @@
-/* $NetBSD: hid.c,v 1.8 1999/08/14 14:49:31 augustss Exp $ */
+/* $NetBSD: hid.c,v 1.9 1999/10/13 08:10:55 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -111,7 +111,7 @@ void
hid_end_parse(s)
struct hid_data *s;
{
- while (s->cur.next) {
+ while (s->cur.next != NULL) {
struct hid_item *hi = s->cur.next->next;
free(s->cur.next, M_TEMP);
s->cur.next = hi;
@@ -133,7 +133,7 @@ hid_get_item(s, h)
int i;
top:
- if (s->multimax) {
+ if (s->multimax != 0) {
if (s->multi < s->multimax) {
c->usage = s->usages[min(s->multi, s->nu-1)];
s->multi++;
@@ -380,11 +380,11 @@ hid_report_size(buf, len, k, idp)
id = 0;
for (d = hid_start_parse(buf, len, 1<<k); hid_get_item(d, &h); )
- if (h.report_ID)
+ if (h.report_ID != 0)
id = h.report_ID;
hid_end_parse(d);
size = h.loc.pos;
- if (id) {
+ if (id != 0) {
size += 8;
*idp = id; /* XXX wrong */
} else
@@ -406,9 +406,9 @@ hid_locate(desc, size, u, k, loc, flags)
for (d = hid_start_parse(desc, size, 1<<k); hid_get_item(d, &h); ) {
if (h.kind == k && !(h.flags & HIO_CONST) && h.usage == u) {
- if (loc)
+ if (loc != NULL)
*loc = h.loc;
- if (flags)
+ if (flags != NULL)
*flags = h.flags;
hid_end_parse(d);
return (1);
@@ -456,15 +456,15 @@ hid_is_collection(desc, size, usage)
{
struct hid_data *hd;
struct hid_item hi;
- int r;
+ int err;
hd = hid_start_parse(desc, size, hid_input);
- if (!hd)
+ if (hd == NULL)
return (0);
- r = hid_get_item(hd, &hi) &&
+ err = hid_get_item(hd, &hi) &&
hi.kind == hid_collection &&
hi.usage == usage;
hid_end_parse(hd);
- return (r);
+ return (err);
}
diff --git a/sys/dev/usb/hid.h b/sys/dev/usb/hid.h
index cd3a053..262357e 100644
--- a/sys/dev/usb/hid.h
+++ b/sys/dev/usb/hid.h
@@ -1,4 +1,4 @@
-/* $NetBSD: hid.h,v 1.3 1998/11/25 22:32:04 augustss Exp $ */
+/* $NetBSD: hid.h,v 1.2 1998/07/24 20:57:46 augustss Exp $ */
/* $FreeBSD$ */
/*
diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c
index 0c5855c..b09e029 100644
--- a/sys/dev/usb/ohci.c
+++ b/sys/dev/usb/ohci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ohci.c,v 1.43 1999/09/11 08:19:26 augustss Exp $ */
+/* $NetBSD: ohci.c,v 1.52 1999/10/13 08:10:55 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -47,22 +47,22 @@
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/kernel.h>
#include <sys/malloc.h>
#if defined(__NetBSD__) || defined(__OpenBSD__)
+#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/select.h>
#elif defined(__FreeBSD__)
#include <sys/module.h>
#include <sys/bus.h>
-#endif
-#include <sys/proc.h>
-#include <sys/queue.h>
-
-#if defined(__FreeBSD__)
#include <machine/bus_pio.h>
#include <machine/bus_memio.h>
+#if defined(DIAGNOSTIC) && defined(__i386__)
+#include <machine/cpu.h>
+#endif
#endif
+#include <sys/proc.h>
+#include <sys/queue.h>
#include <machine/bus.h>
#include <machine/endian.h>
@@ -82,6 +82,12 @@
#define delay(d) DELAY(d)
#endif
+#if defined(__OpenBSD__)
+struct cfdriver ohci_cd = {
+ NULL, "ohci", DV_DULL
+};
+#endif
+
#ifdef OHCI_DEBUG
#define DPRINTF(x) if (ohcidebug) logprintf x
#define DPRINTFN(n,x) if (ohcidebug>(n)) logprintf x
@@ -91,13 +97,6 @@ int ohcidebug = 1;
#define DPRINTFN(n,x)
#endif
-
-#if defined(__OpenBSD__)
-struct cfdriver ohci_cd = {
- NULL, "ohci", DV_DULL
-};
-#endif
-
/*
* The OHCI controller is little endian, so on big endian machines
* the data strored in memory needs to be swapped.
@@ -110,87 +109,102 @@ struct cfdriver ohci_cd = {
struct ohci_pipe;
-ohci_soft_ed_t *ohci_alloc_sed __P((ohci_softc_t *));
-void ohci_free_sed __P((ohci_softc_t *, ohci_soft_ed_t *));
-
-ohci_soft_td_t *ohci_alloc_std __P((ohci_softc_t *));
-void ohci_free_std __P((ohci_softc_t *, ohci_soft_td_t *));
-
-void ohci_power __P((int, void *));
-usbd_status ohci_open __P((usbd_pipe_handle));
-void ohci_poll __P((struct usbd_bus *));
-void ohci_waitintr __P((ohci_softc_t *, usbd_request_handle));
-void ohci_rhsc __P((ohci_softc_t *, usbd_request_handle));
-void ohci_process_done __P((ohci_softc_t *, ohci_physaddr_t));
-
-usbd_status ohci_device_request __P((usbd_request_handle reqh));
-void ohci_add_ed __P((ohci_soft_ed_t *, ohci_soft_ed_t *));
-void ohci_rem_ed __P((ohci_soft_ed_t *, ohci_soft_ed_t *));
-void ohci_hash_add_td __P((ohci_softc_t *, ohci_soft_td_t *));
-void ohci_hash_rem_td __P((ohci_softc_t *, ohci_soft_td_t *));
-ohci_soft_td_t *ohci_hash_find_td __P((ohci_softc_t *, ohci_physaddr_t));
-
-usbd_status ohci_allocm __P((struct usbd_bus *, usb_dma_t *, u_int32_t));
-void ohci_freem __P((struct usbd_bus *, usb_dma_t *));
-
-usbd_status ohci_root_ctrl_transfer __P((usbd_request_handle));
-usbd_status ohci_root_ctrl_start __P((usbd_request_handle));
-void ohci_root_ctrl_abort __P((usbd_request_handle));
-void ohci_root_ctrl_close __P((usbd_pipe_handle));
-
-usbd_status ohci_root_intr_transfer __P((usbd_request_handle));
-usbd_status ohci_root_intr_start __P((usbd_request_handle));
-void ohci_root_intr_abort __P((usbd_request_handle));
-void ohci_root_intr_close __P((usbd_pipe_handle));
-void ohci_root_intr_done __P((usbd_request_handle));
-
-usbd_status ohci_device_ctrl_transfer __P((usbd_request_handle));
-usbd_status ohci_device_ctrl_start __P((usbd_request_handle));
-void ohci_device_ctrl_abort __P((usbd_request_handle));
-void ohci_device_ctrl_close __P((usbd_pipe_handle));
-void ohci_device_ctrl_done __P((usbd_request_handle));
-
-usbd_status ohci_device_bulk_transfer __P((usbd_request_handle));
-usbd_status ohci_device_bulk_start __P((usbd_request_handle));
-void ohci_device_bulk_abort __P((usbd_request_handle));
-void ohci_device_bulk_close __P((usbd_pipe_handle));
-void ohci_device_bulk_done __P((usbd_request_handle));
-
-usbd_status ohci_device_intr_transfer __P((usbd_request_handle));
-usbd_status ohci_device_intr_start __P((usbd_request_handle));
-void ohci_device_intr_abort __P((usbd_request_handle));
-void ohci_device_intr_close __P((usbd_pipe_handle));
-void ohci_device_intr_done __P((usbd_request_handle));
-
-usbd_status ohci_device_isoc_transfer __P((usbd_request_handle));
-usbd_status ohci_device_isoc_start __P((usbd_request_handle));
-void ohci_device_isoc_abort __P((usbd_request_handle));
-void ohci_device_isoc_close __P((usbd_pipe_handle));
-void ohci_device_isoc_done __P((usbd_request_handle));
-
-usbd_status ohci_device_setintr __P((ohci_softc_t *sc,
- struct ohci_pipe *pipe, int ival));
-
-int ohci_str __P((usb_string_descriptor_t *, int, char *));
-
-void ohci_timeout __P((void *));
-void ohci_rhsc_able __P((ohci_softc_t *, int));
-
-void ohci_close_pipe __P((usbd_pipe_handle pipe,
- ohci_soft_ed_t *head));
-void ohci_abort_req __P((usbd_request_handle reqh,
- usbd_status status));
-void ohci_abort_req_end __P((void *));
-
-void ohci_device_clear_toggle __P((usbd_pipe_handle pipe));
-void ohci_noop __P((usbd_pipe_handle pipe));
+static ohci_soft_ed_t *ohci_alloc_sed __P((ohci_softc_t *));
+static void ohci_free_sed __P((ohci_softc_t *, ohci_soft_ed_t *));
+
+static ohci_soft_td_t *ohci_alloc_std __P((ohci_softc_t *));
+static void ohci_free_std __P((ohci_softc_t *, ohci_soft_td_t *));
+
+#if 0
+static void ohci_free_std_chain __P((ohci_softc_t *,
+ ohci_soft_td_t *, ohci_soft_td_t *));
+#endif
+static usbd_status ohci_alloc_std_chain __P((struct ohci_pipe *,
+ ohci_softc_t *, int, int, int, usb_dma_t *,
+ ohci_soft_td_t *, ohci_soft_td_t **));
+
+static void ohci_power __P((int, void *));
+static usbd_status ohci_open __P((usbd_pipe_handle));
+static void ohci_poll __P((struct usbd_bus *));
+static void ohci_waitintr __P((ohci_softc_t *,
+ usbd_xfer_handle));
+static void ohci_rhsc __P((ohci_softc_t *, usbd_xfer_handle));
+static void ohci_process_done __P((ohci_softc_t *,
+ ohci_physaddr_t));
+
+static usbd_status ohci_device_request __P((usbd_xfer_handle xfer));
+static void ohci_add_ed __P((ohci_soft_ed_t *, ohci_soft_ed_t *));
+static void ohci_rem_ed __P((ohci_soft_ed_t *, ohci_soft_ed_t *));
+static void ohci_hash_add_td __P((ohci_softc_t *,
+ ohci_soft_td_t *));
+static void ohci_hash_rem_td __P((ohci_softc_t *,
+ ohci_soft_td_t *));
+static ohci_soft_td_t *ohci_hash_find_td __P((ohci_softc_t *,
+ ohci_physaddr_t));
+
+static usbd_status ohci_allocm __P((struct usbd_bus *, usb_dma_t *,
+ u_int32_t));
+static void ohci_freem __P((struct usbd_bus *, usb_dma_t *));
+
+static usbd_status ohci_root_ctrl_transfer __P((usbd_xfer_handle));
+static usbd_status ohci_root_ctrl_start __P((usbd_xfer_handle));
+static void ohci_root_ctrl_abort __P((usbd_xfer_handle));
+static void ohci_root_ctrl_close __P((usbd_pipe_handle));
+
+static usbd_status ohci_root_intr_transfer __P((usbd_xfer_handle));
+static usbd_status ohci_root_intr_start __P((usbd_xfer_handle));
+static void ohci_root_intr_abort __P((usbd_xfer_handle));
+static void ohci_root_intr_close __P((usbd_pipe_handle));
+static void ohci_root_intr_done __P((usbd_xfer_handle));
+
+static usbd_status ohci_device_ctrl_transfer __P((usbd_xfer_handle));
+static usbd_status ohci_device_ctrl_start __P((usbd_xfer_handle));
+static void ohci_device_ctrl_abort __P((usbd_xfer_handle));
+static void ohci_device_ctrl_close __P((usbd_pipe_handle));
+static void ohci_device_ctrl_done __P((usbd_xfer_handle));
+
+static usbd_status ohci_device_bulk_transfer __P((usbd_xfer_handle));
+static usbd_status ohci_device_bulk_start __P((usbd_xfer_handle));
+static void ohci_device_bulk_abort __P((usbd_xfer_handle));
+static void ohci_device_bulk_close __P((usbd_pipe_handle));
+static void ohci_device_bulk_done __P((usbd_xfer_handle));
+
+static usbd_status ohci_device_intr_transfer __P((usbd_xfer_handle));
+static usbd_status ohci_device_intr_start __P((usbd_xfer_handle));
+static void ohci_device_intr_abort __P((usbd_xfer_handle));
+static void ohci_device_intr_close __P((usbd_pipe_handle));
+static void ohci_device_intr_done __P((usbd_xfer_handle));
+
+#if 0
+static usbd_status ohci_device_isoc_transfer __P((usbd_xfer_handle));
+static usbd_status ohci_device_isoc_start __P((usbd_xfer_handle));
+static void ohci_device_isoc_abort __P((usbd_xfer_handle));
+static void ohci_device_isoc_close __P((usbd_pipe_handle));
+static void ohci_device_isoc_done __P((usbd_xfer_handle));
+#endif
+
+static usbd_status ohci_device_setintr __P((ohci_softc_t *sc,
+ struct ohci_pipe *pipe, int ival));
+
+static int ohci_str __P((usb_string_descriptor_t *, int, char *));
+
+static void ohci_timeout __P((void *));
+static void ohci_rhsc_able __P((ohci_softc_t *, int));
+
+static void ohci_close_pipe __P((usbd_pipe_handle pipe,
+ ohci_soft_ed_t *head));
+static void ohci_abort_req __P((usbd_xfer_handle xfer,
+ usbd_status status));
+static void ohci_abort_req_end __P((void *));
+
+static void ohci_device_clear_toggle __P((usbd_pipe_handle pipe));
+static void ohci_noop __P((usbd_pipe_handle pipe));
#ifdef OHCI_DEBUG
-ohci_softc_t *thesc;
-void ohci_dumpregs __P((ohci_softc_t *));
-void ohci_dump_tds __P((ohci_soft_td_t *));
-void ohci_dump_td __P((ohci_soft_td_t *));
-void ohci_dump_ed __P((ohci_soft_ed_t *));
+static void ohci_dumpregs __P((ohci_softc_t *));
+static void ohci_dump_tds __P((ohci_soft_td_t *));
+static void ohci_dump_td __P((ohci_soft_td_t *));
+static void ohci_dump_ed __P((ohci_soft_ed_t *));
#endif
#define OWRITE4(sc, r, x) bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x))
@@ -214,7 +228,7 @@ struct ohci_pipe {
struct {
usb_dma_t reqdma;
u_int length;
- ohci_soft_td_t *setup, *xfer, *stat;
+ ohci_soft_td_t *setup, *data, *stat;
} ctl;
/* Interrupt pipe */
struct {
@@ -235,14 +249,14 @@ struct ohci_pipe {
#define OHCI_INTR_ENDPT 1
-struct usbd_bus_methods ohci_bus_methods = {
+static struct usbd_bus_methods ohci_bus_methods = {
ohci_open,
ohci_poll,
ohci_allocm,
ohci_freem,
};
-struct usbd_pipe_methods ohci_root_ctrl_methods = {
+static struct usbd_pipe_methods ohci_root_ctrl_methods = {
ohci_root_ctrl_transfer,
ohci_root_ctrl_start,
ohci_root_ctrl_abort,
@@ -251,7 +265,7 @@ struct usbd_pipe_methods ohci_root_ctrl_methods = {
0,
};
-struct usbd_pipe_methods ohci_root_intr_methods = {
+static struct usbd_pipe_methods ohci_root_intr_methods = {
ohci_root_intr_transfer,
ohci_root_intr_start,
ohci_root_intr_abort,
@@ -260,7 +274,7 @@ struct usbd_pipe_methods ohci_root_intr_methods = {
ohci_root_intr_done,
};
-struct usbd_pipe_methods ohci_device_ctrl_methods = {
+static struct usbd_pipe_methods ohci_device_ctrl_methods = {
ohci_device_ctrl_transfer,
ohci_device_ctrl_start,
ohci_device_ctrl_abort,
@@ -269,7 +283,7 @@ struct usbd_pipe_methods ohci_device_ctrl_methods = {
ohci_device_ctrl_done,
};
-struct usbd_pipe_methods ohci_device_intr_methods = {
+static struct usbd_pipe_methods ohci_device_intr_methods = {
ohci_device_intr_transfer,
ohci_device_intr_start,
ohci_device_intr_abort,
@@ -278,7 +292,7 @@ struct usbd_pipe_methods ohci_device_intr_methods = {
ohci_device_intr_done,
};
-struct usbd_pipe_methods ohci_device_bulk_methods = {
+static struct usbd_pipe_methods ohci_device_bulk_methods = {
ohci_device_bulk_transfer,
ohci_device_bulk_start,
ohci_device_bulk_abort,
@@ -288,7 +302,7 @@ struct usbd_pipe_methods ohci_device_bulk_methods = {
};
#if 0
-struct usbd_pipe_methods ohci_device_isoc_methods = {
+static struct usbd_pipe_methods ohci_device_isoc_methods = {
ohci_device_isoc_transfer,
ohci_device_isoc_start,
ohci_device_isoc_abort,
@@ -298,20 +312,62 @@ struct usbd_pipe_methods ohci_device_isoc_methods = {
};
#endif
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+int
+ohci_activate(self, act)
+ device_ptr_t self;
+ enum devact act;
+{
+ struct ohci_softc *sc = (struct ohci_softc *)self;
+ int rv = 0;
+
+ switch (act) {
+ case DVACT_ACTIVATE:
+ return (EOPNOTSUPP);
+ break;
+
+ case DVACT_DEACTIVATE:
+ if (sc->sc_child != NULL)
+ rv = config_deactivate(sc->sc_child);
+ break;
+ }
+ return (rv);
+}
+
+int
+ohci_detach(sc, flags)
+ struct ohci_softc *sc;
+ int flags;
+{
+ int rv = 0;
+
+ if (sc->sc_child != NULL)
+ rv = config_detach(sc->sc_child, flags);
+
+ if (rv != 0)
+ return (rv);
+
+ powerhook_disestablish(sc->sc_powerhook);
+ /* free data structures XXX */
+
+ return (rv);
+}
+#endif
+
ohci_soft_ed_t *
ohci_alloc_sed(sc)
ohci_softc_t *sc;
{
ohci_soft_ed_t *sed;
- usbd_status r;
+ usbd_status err;
int i, offs;
usb_dma_t dma;
- if (!sc->sc_freeeds) {
+ if (sc->sc_freeeds == NULL) {
DPRINTFN(2, ("ohci_alloc_sed: allocating chunk\n"));
- r = usb_allocmem(sc->sc_dmatag, OHCI_SED_SIZE * OHCI_SED_CHUNK,
- OHCI_ED_ALIGN, &dma);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usb_allocmem(&sc->sc_bus, OHCI_SED_SIZE * OHCI_SED_CHUNK,
+ OHCI_ED_ALIGN, &dma);
+ if (err)
return (0);
for(i = 0; i < OHCI_SED_CHUNK; i++) {
offs = i * OHCI_SED_SIZE;
@@ -342,15 +398,15 @@ ohci_alloc_std(sc)
ohci_softc_t *sc;
{
ohci_soft_td_t *std;
- usbd_status r;
+ usbd_status err;
int i, offs;
usb_dma_t dma;
- if (!sc->sc_freetds) {
+ if (sc->sc_freetds == NULL) {
DPRINTFN(2, ("ohci_alloc_std: allocating chunk\n"));
- r = usb_allocmem(sc->sc_dmatag, OHCI_STD_SIZE * OHCI_STD_CHUNK,
- OHCI_TD_ALIGN, &dma);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usb_allocmem(&sc->sc_bus, OHCI_STD_SIZE * OHCI_STD_CHUNK,
+ OHCI_TD_ALIGN, &dma);
+ if (err)
return (0);
for(i = 0; i < OHCI_STD_CHUNK; i++) {
offs = i * OHCI_STD_SIZE;
@@ -377,11 +433,92 @@ ohci_free_std(sc, std)
}
usbd_status
+ohci_alloc_std_chain(upipe, sc, len, rd, shortok, dma, sp, ep)
+ struct ohci_pipe *upipe;
+ ohci_softc_t *sc;
+ int len, rd, shortok;
+ usb_dma_t *dma;
+ ohci_soft_td_t *sp, **ep;
+{
+ ohci_soft_td_t *next, *cur;
+ ohci_physaddr_t dataphys, dataphysend;
+ u_int32_t intr;
+ int curlen;
+
+ DPRINTFN(len < 4096,("ohci_alloc_std_chain: start len=%d\n", len));
+ cur = sp;
+ dataphys = DMAADDR(dma);
+ dataphysend = OHCI_PAGE(dataphys + len - 1);
+ for (;;) {
+ next = ohci_alloc_std(sc);
+ if (next == 0) {
+ /* XXX free chain */
+ return (USBD_NOMEM);
+ }
+
+ /* The OHCI hardware can handle at most one page crossing. */
+ if (OHCI_PAGE(dataphys) == dataphysend ||
+ OHCI_PAGE(dataphys) + OHCI_PAGE_SIZE == dataphysend) {
+ /* we can handle it in this TD */
+ curlen = len;
+ } else {
+ /* must use multiple TDs, fill as much as possible. */
+ curlen = 2 * OHCI_PAGE_SIZE -
+ (dataphys & (OHCI_PAGE_SIZE-1));
+ }
+ DPRINTFN(4,("ohci_alloc_std_chain: dataphys=0x%08x "
+ "dataphysend=0x%08x len=%d curlen=%d\n",
+ dataphys, dataphysend,
+ len, curlen));
+ len -= curlen;
+
+ intr = len == 0 ? OHCI_TD_SET_DI(1) : OHCI_TD_NOINTR;
+ cur->td.td_flags = LE(
+ (rd ? OHCI_TD_IN : OHCI_TD_OUT) | OHCI_TD_NOCC |
+ intr | OHCI_TD_TOGGLE_CARRY |
+ (shortok ? OHCI_TD_R : 0));
+ cur->td.td_cbp = LE(dataphys);
+ cur->nexttd = next;
+ cur->td.td_nexttd = LE(next->physaddr);
+ cur->td.td_be = LE(dataphys + curlen - 1);
+ cur->len = curlen;
+ cur->flags = OHCI_ADD_LEN;
+ DPRINTFN(10,("ohci_alloc_std_chain: cbp=0x%08x be=0x%08x\n",
+ dataphys, dataphys + curlen - 1));
+ if (len == 0)
+ break;
+ DPRINTFN(10,("ohci_alloc_std_chain: extend chain\n"));
+ dataphys += curlen;
+ cur = next;
+ }
+ cur->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
+ *ep = next;
+
+ return (USBD_NORMAL_COMPLETION);
+}
+
+#if 0
+static void
+ohci_free_std_chain(sc, std, stdend)
+ ohci_softc_t *sc;
+ ohci_soft_td_t *std;
+ ohci_soft_td_t *stdend;
+{
+ ohci_soft_td_t *p;
+
+ for (; std != stdend; std = p) {
+ p = std->nexttd;
+ ohci_free_std(sc, std);
+ }
+}
+#endif
+
+usbd_status
ohci_init(sc)
ohci_softc_t *sc;
{
ohci_soft_ed_t *sed, *psed;
- usbd_status r;
+ usbd_status err;
int rev;
int i;
u_int32_t s, ctl, ival, hcr, fm, per;
@@ -389,12 +526,13 @@ ohci_init(sc)
DPRINTF(("ohci_init: start\n"));
rev = OREAD4(sc, OHCI_REVISION);
#if defined(__OpenBSD__)
- printf(", OHCI version %d.%d%s\n",
+ printf(",");
#else
- printf("%s: OHCI version %d.%d%s\n", USBDEVNAME(sc->sc_bus.bdev),
+ printf("%s", USBDEVNAME(sc->sc_bus.bdev));
#endif
- OHCI_REV_HI(rev), OHCI_REV_LO(rev),
+ printf(" OHCI version %d.%d%s\n", OHCI_REV_HI(rev), OHCI_REV_LO(rev),
OHCI_REV_LEGACY(rev) ? ", legacy support" : "");
+
if (OHCI_REV_HI(rev) != 1 || OHCI_REV_LO(rev) != 0) {
printf("%s: unsupported OHCI revision\n",
USBDEVNAME(sc->sc_bus.bdev));
@@ -405,25 +543,25 @@ ohci_init(sc)
LIST_INIT(&sc->sc_hash_tds[i]);
/* Allocate the HCCA area. */
- r = usb_allocmem(sc->sc_dmatag, OHCI_HCCA_SIZE,
- OHCI_HCCA_ALIGN, &sc->sc_hccadma);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usb_allocmem(&sc->sc_bus, OHCI_HCCA_SIZE,
+ OHCI_HCCA_ALIGN, &sc->sc_hccadma);
+ if (err)
+ return (err);
sc->sc_hcca = (struct ohci_hcca *)KERNADDR(&sc->sc_hccadma);
memset(sc->sc_hcca, 0, OHCI_HCCA_SIZE);
sc->sc_eintrs = OHCI_NORMAL_INTRS;
sc->sc_ctrl_head = ohci_alloc_sed(sc);
- if (!sc->sc_ctrl_head) {
- r = USBD_NOMEM;
+ if (sc->sc_ctrl_head == NULL) {
+ err = USBD_NOMEM;
goto bad1;
}
sc->sc_ctrl_head->ed.ed_flags |= LE(OHCI_ED_SKIP);
sc->sc_bulk_head = ohci_alloc_sed(sc);
- if (!sc->sc_bulk_head) {
- r = USBD_NOMEM;
+ if (sc->sc_bulk_head == NULL) {
+ err = USBD_NOMEM;
goto bad2;
}
sc->sc_bulk_head->ed.ed_flags |= LE(OHCI_ED_SKIP);
@@ -431,10 +569,10 @@ ohci_init(sc)
/* Allocate all the dummy EDs that make up the interrupt tree. */
for (i = 0; i < OHCI_NO_EDS; i++) {
sed = ohci_alloc_sed(sc);
- if (!sed) {
+ if (sed == NULL) {
while (--i >= 0)
ohci_free_sed(sc, sc->sc_eds[i]);
- r = USBD_NOMEM;
+ err = USBD_NOMEM;
goto bad3;
}
/* All ED fields are set to 0. */
@@ -462,7 +600,7 @@ ohci_init(sc)
s = OREAD4(sc, OHCI_COMMAND_STATUS);
OWRITE4(sc, OHCI_COMMAND_STATUS, s | OHCI_OCR);
for (i = 0; i < 100 && (ctl & OHCI_IR); i++) {
- delay(1000);
+ usb_delay_ms(&sc->sc_bus, 1);
ctl = OREAD4(sc, OHCI_CONTROL);
}
if ((ctl & OHCI_IR) == 0) {
@@ -476,13 +614,13 @@ ohci_init(sc)
DPRINTF(("ohci_init: BIOS active\n"));
if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_OPERATIONAL) {
OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_OPERATIONAL);
- delay(USB_RESUME_DELAY * 1000);
+ usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY);
}
} else {
DPRINTF(("ohci_init: cold started\n"));
reset:
/* Controller was cold started. */
- delay(USB_BUS_RESET_DELAY * 1000);
+ usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY);
}
/*
@@ -491,7 +629,7 @@ ohci_init(sc)
*/
DPRINTF(("%s: resetting\n", USBDEVNAME(sc->sc_bus.bdev)));
OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET);
- delay(USB_BUS_RESET_DELAY * 1000);
+ usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY);
/* We now own the host controller and the bus has been reset. */
ival = OHCI_GET_IVAL(OREAD4(sc, OHCI_FM_INTERVAL));
@@ -506,11 +644,10 @@ ohci_init(sc)
}
if (hcr) {
printf("%s: reset timeout\n", USBDEVNAME(sc->sc_bus.bdev));
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto bad3;
}
#ifdef OHCI_DEBUG
- thesc = sc;
if (ohcidebug > 15)
ohci_dumpregs(sc);
#endif
@@ -521,8 +658,10 @@ ohci_init(sc)
OWRITE4(sc, OHCI_HCCA, DMAADDR(&sc->sc_hccadma));
OWRITE4(sc, OHCI_CONTROL_HEAD_ED, sc->sc_ctrl_head->physaddr);
OWRITE4(sc, OHCI_BULK_HEAD_ED, sc->sc_bulk_head->physaddr);
+ /* disable all interrupts and then switch on all desired interrupts */
OWRITE4(sc, OHCI_INTERRUPT_DISABLE, OHCI_ALL_INTRS);
OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_eintrs | OHCI_MIE);
+ /* switch on desired functional features */
ctl = OREAD4(sc, OHCI_CONTROL);
ctl &= ~(OHCI_CBSR_MASK | OHCI_LES | OHCI_HCFS_MASK | OHCI_IR);
ctl |= OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE |
@@ -554,9 +693,7 @@ ohci_init(sc)
sc->sc_bus.methods = &ohci_bus_methods;
sc->sc_bus.pipe_size = sizeof(struct ohci_pipe);
-#if defined(__NetBSD__)
- powerhook_establish(ohci_power, sc);
-#endif
+ sc->sc_powerhook = powerhook_establish(ohci_power, sc);
return (USBD_NORMAL_COMPLETION);
@@ -565,8 +702,8 @@ ohci_init(sc)
bad2:
ohci_free_sed(sc, sc->sc_bulk_head);
bad1:
- usb_freemem(sc->sc_dmatag, &sc->sc_hccadma);
- return (r);
+ usb_freemem(&sc->sc_bus, &sc->sc_hccadma);
+ return (err);
}
usbd_status
@@ -579,7 +716,7 @@ ohci_allocm(bus, dma, size)
struct ohci_softc *sc = (struct ohci_softc *)bus;
#endif
- return (usb_allocmem(sc->sc_dmatag, size, 0, dma));
+ return (usb_allocmem(&sc->sc_bus, size, 0, dma));
}
void
@@ -591,7 +728,7 @@ ohci_freem(bus, dma)
struct ohci_softc *sc = (struct ohci_softc *)bus;
#endif
- usb_freemem(sc->sc_dmatag, dma);
+ usb_freemem(&sc->sc_bus, dma);
}
#if defined(__NetBSD__)
@@ -608,12 +745,9 @@ ohci_power(why, v)
ohci_dumpregs(sc);
#endif
}
-#endif /* !defined(__OpenBSD__) */
+#endif /* defined(__NetBSD__) */
#ifdef OHCI_DEBUG
-void ohcidump(void);
-void ohcidump(void) { ohci_dumpregs(thesc); }
-
void
ohci_dumpregs(sc)
ohci_softc_t *sc;
@@ -655,11 +789,25 @@ ohci_dumpregs(sc)
}
#endif
+static int ohci_intr1 __P((ohci_softc_t *));
+
int
ohci_intr(p)
void *p;
{
ohci_softc_t *sc = p;
+
+ /* If we get an interrupt while polling, then just ignore it. */
+ if (sc->sc_bus.use_polling)
+ return (0);
+
+ return (ohci_intr1(sc));
+}
+
+static int
+ohci_intr1(sc)
+ ohci_softc_t *sc;
+{
u_int32_t intrs, eintrs;
ohci_physaddr_t done;
@@ -681,15 +829,18 @@ ohci_intr(p)
intrs |= OREAD4(sc, OHCI_INTERRUPT_STATUS);
} else
intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS);
+
if (!intrs)
return (0);
+
intrs &= ~OHCI_MIE;
OWRITE4(sc, OHCI_INTERRUPT_STATUS, intrs); /* Acknowledge */
eintrs = intrs & sc->sc_eintrs;
if (!eintrs)
return (0);
- sc->sc_intrs++;
+ sc->sc_bus.intr_context++;
+ sc->sc_bus.no_intrs++;
DPRINTFN(7, ("ohci_intr: sc=%p intrs=%x(%x) eintr=%x\n",
sc, (u_int)intrs, OREAD4(sc, OHCI_INTERRUPT_STATUS),
(u_int)eintrs));
@@ -714,7 +865,7 @@ ohci_intr(p)
/* XXX what else */
}
if (eintrs & OHCI_RHSC) {
- ohci_rhsc(sc, sc->sc_intrreqh);
+ ohci_rhsc(sc, sc->sc_intrxfer);
intrs &= ~OHCI_RHSC;
/*
@@ -724,6 +875,8 @@ ohci_intr(p)
ohci_rhsc_able(sc, 0);
}
+ sc->sc_bus.intr_context--;
+
/* Block unprocessed interrupts. XXX */
OWRITE4(sc, OHCI_INTERRUPT_DISABLE, intrs);
sc->sc_eintrs &= ~intrs;
@@ -769,8 +922,8 @@ ohci_process_done(sc, done)
ohci_softc_t *sc;
ohci_physaddr_t done;
{
- ohci_soft_td_t *std, *sdone;
- usbd_request_handle reqh;
+ ohci_soft_td_t *std, *sdone, *stdnext;
+ usbd_xfer_handle xfer;
int len, cc;
DPRINTFN(10,("ohci_process_done: done=0x%08lx\n", (u_long)done));
@@ -789,133 +942,138 @@ ohci_process_done(sc, done)
}
#endif
- for (std = sdone; std; std = std->dnext) {
- reqh = std->reqh;
- DPRINTFN(10, ("ohci_process_done: std=%p reqh=%p hcpriv=%p\n",
- std, reqh, reqh->hcpriv));
+ for (std = sdone; std; std = stdnext) {
+ xfer = std->xfer;
+ stdnext = std->dnext;
+ DPRINTFN(10, ("ohci_process_done: std=%p xfer=%p hcpriv=%p\n",
+ std, xfer, xfer->hcpriv));
cc = OHCI_TD_GET_CC(LE(std->td.td_flags));
- usb_untimeout(ohci_timeout, reqh, reqh->timo_handle);
- if (reqh->status == USBD_CANCELLED ||
- reqh->status == USBD_TIMEOUT) {
+ usb_untimeout(ohci_timeout, xfer, xfer->timo_handle);
+ if (xfer->status == USBD_CANCELLED ||
+ xfer->status == USBD_TIMEOUT) {
DPRINTF(("ohci_process_done: cancel/timeout %p\n",
- reqh));
+ xfer));
/* Handled by abort routine. */
- continue;
} else if (cc == OHCI_CC_NO_ERROR) {
len = std->len;
if (std->td.td_cbp != 0)
len -= LE(std->td.td_be) -
LE(std->td.td_cbp) + 1;
- if (std->flags & OHCI_SET_LEN)
- reqh->actlen = len;
+ if (std->flags & OHCI_ADD_LEN)
+ xfer->actlen += len;
if (std->flags & OHCI_CALL_DONE) {
- reqh->status = USBD_NORMAL_COMPLETION;
- usb_transfer_complete(reqh);
+ xfer->status = USBD_NORMAL_COMPLETION;
+ usb_transfer_complete(xfer);
}
+ ohci_hash_rem_td(sc, std);
+ ohci_free_std(sc, std);
} else {
- ohci_soft_td_t *p, *n;
- struct ohci_pipe *opipe =
- (struct ohci_pipe *)reqh->pipe;
- DPRINTFN(-1,("ohci_process_done: error cc=%d (%s)\n",
- OHCI_TD_GET_CC(LE(std->td.td_flags)),
- ohci_cc_strs[OHCI_TD_GET_CC(LE(std->td.td_flags))]));
/*
* Endpoint is halted. First unlink all the TDs
* belonging to the failed transfer, and then restart
* the endpoint.
*/
- for (p = std->nexttd; p->reqh == reqh; p = n) {
+ ohci_soft_td_t *p, *n;
+ struct ohci_pipe *opipe =
+ (struct ohci_pipe *)xfer->pipe;
+
+ DPRINTF(("ohci_process_done: error cc=%d (%s)\n",
+ OHCI_TD_GET_CC(LE(std->td.td_flags)),
+ ohci_cc_strs[OHCI_TD_GET_CC(LE(std->td.td_flags))]));
+
+ /* remove TDs */
+ for (p = std; p->xfer == xfer; p = n) {
n = p->nexttd;
ohci_hash_rem_td(sc, p);
ohci_free_std(sc, p);
}
+
/* clear halt */
opipe->sed->ed.ed_headp = LE(p->physaddr);
OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
-
+
if (cc == OHCI_CC_STALL)
- reqh->status = USBD_STALLED;
+ xfer->status = USBD_STALLED;
else
- reqh->status = USBD_IOERROR;
- usb_transfer_complete(reqh);
+ xfer->status = USBD_IOERROR;
+ usb_transfer_complete(xfer);
}
- ohci_hash_rem_td(sc, std);
- ohci_free_std(sc, std);
}
}
void
-ohci_device_ctrl_done(reqh)
- usbd_request_handle reqh;
+ohci_device_ctrl_done(xfer)
+ usbd_xfer_handle xfer;
{
- DPRINTFN(10,("ohci_ctrl_done: reqh=%p\n", reqh));
+ DPRINTFN(10,("ohci_ctrl_done: xfer=%p\n", xfer));
#ifdef DIAGNOSTIC
- if (!(reqh->rqflags & URQ_REQUEST)) {
+ if (!(xfer->rqflags & URQ_REQUEST)) {
panic("ohci_ctrl_done: not a request\n");
}
#endif
- reqh->hcpriv = 0;
+ xfer->hcpriv = NULL;
}
void
-ohci_device_intr_done(reqh)
- usbd_request_handle reqh;
+ohci_device_intr_done(xfer)
+ usbd_xfer_handle xfer;
{
- struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
+ struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
ohci_soft_ed_t *sed = opipe->sed;
- ohci_soft_td_t *xfer, *tail;
+ ohci_soft_td_t *data, *tail;
- DPRINTFN(10,("ohci_intr_done: reqh=%p, actlen=%d\n",
- reqh, reqh->actlen));
+ DPRINTFN(10,("ohci_intr_done: xfer=%p, actlen=%d\n",
+ xfer, xfer->actlen));
- reqh->hcpriv = 0;
+ xfer->hcpriv = NULL;
- if (reqh->pipe->repeat) {
- xfer = opipe->tail;
+ if (xfer->pipe->repeat) {
+ data = opipe->tail;
tail = ohci_alloc_std(sc); /* XXX should reuse TD */
- if (!tail) {
- reqh->status = USBD_NOMEM;
+ if (tail == NULL) {
+ xfer->status = USBD_NOMEM;
return;
}
- tail->reqh = 0;
+ tail->xfer = NULL;
- xfer->td.td_flags = LE(
+ data->td.td_flags = LE(
OHCI_TD_IN | OHCI_TD_NOCC |
OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY);
- if (reqh->flags & USBD_SHORT_XFER_OK)
- xfer->td.td_flags |= LE(OHCI_TD_R);
- xfer->td.td_cbp = LE(DMAADDR(&reqh->dmabuf));
- xfer->nexttd = tail;
- xfer->td.td_nexttd = LE(tail->physaddr);
- xfer->td.td_be = LE(LE(xfer->td.td_cbp) + reqh->length - 1);
- xfer->len = reqh->length;
- xfer->reqh = reqh;
- xfer->flags = OHCI_CALL_DONE | OHCI_SET_LEN;
- reqh->hcpriv = xfer;
-
- ohci_hash_add_td(sc, xfer);
+ if (xfer->flags & USBD_SHORT_XFER_OK)
+ data->td.td_flags |= LE(OHCI_TD_R);
+ data->td.td_cbp = LE(DMAADDR(&xfer->dmabuf));
+ data->nexttd = tail;
+ data->td.td_nexttd = LE(tail->physaddr);
+ data->td.td_be = LE(LE(data->td.td_cbp) + xfer->length - 1);
+ data->len = xfer->length;
+ data->xfer = xfer;
+ data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
+ xfer->hcpriv = data;
+ xfer->actlen = 0;
+
+ ohci_hash_add_td(sc, data);
sed->ed.ed_tailp = LE(tail->physaddr);
opipe->tail = tail;
}
}
void
-ohci_device_bulk_done(reqh)
- usbd_request_handle reqh;
+ohci_device_bulk_done(xfer)
+ usbd_xfer_handle xfer;
{
- DPRINTFN(10,("ohci_bulk_done: reqh=%p, actlen=%d\n",
- reqh, reqh->actlen));
+ DPRINTFN(10,("ohci_bulk_done: xfer=%p, actlen=%d\n",
+ xfer, xfer->actlen));
- reqh->hcpriv = 0;
+ xfer->hcpriv = NULL;
}
void
-ohci_rhsc(sc, reqh)
+ohci_rhsc(sc, xfer)
ohci_softc_t *sc;
- usbd_request_handle reqh;
+ usbd_xfer_handle xfer;
{
usbd_pipe_handle pipe;
struct ohci_pipe *opipe;
@@ -924,36 +1082,36 @@ ohci_rhsc(sc, reqh)
int hstatus;
hstatus = OREAD4(sc, OHCI_RH_STATUS);
- DPRINTF(("ohci_rhsc: sc=%p reqh=%p hstatus=0x%08x\n",
- sc, reqh, hstatus));
+ DPRINTF(("ohci_rhsc: sc=%p xfer=%p hstatus=0x%08x\n",
+ sc, xfer, hstatus));
- if (reqh == 0) {
+ if (xfer == NULL) {
/* Just ignore the change. */
return;
}
- pipe = reqh->pipe;
+ pipe = xfer->pipe;
opipe = (struct ohci_pipe *)pipe;
- p = KERNADDR(&reqh->dmabuf);
- m = min(sc->sc_noport, reqh->length * 8 - 1);
- memset(p, 0, reqh->length);
+ p = KERNADDR(&xfer->dmabuf);
+ m = min(sc->sc_noport, xfer->length * 8 - 1);
+ memset(p, 0, xfer->length);
for (i = 1; i <= m; i++) {
if (OREAD4(sc, OHCI_RH_PORT_STATUS(i)) >> 16)
p[i/8] |= 1 << (i%8);
}
DPRINTF(("ohci_rhsc: change=0x%02x\n", *p));
- reqh->actlen = reqh->length;
- reqh->status = USBD_NORMAL_COMPLETION;
+ xfer->actlen = xfer->length;
+ xfer->status = USBD_NORMAL_COMPLETION;
- usb_transfer_complete(reqh);
+ usb_transfer_complete(xfer);
}
void
-ohci_root_intr_done(reqh)
- usbd_request_handle reqh;
+ohci_root_intr_done(xfer)
+ usbd_xfer_handle xfer;
{
- reqh->hcpriv = 0;
+ xfer->hcpriv = NULL;
}
/*
@@ -962,15 +1120,15 @@ ohci_root_intr_done(reqh)
* too long.
*/
void
-ohci_waitintr(sc, reqh)
+ohci_waitintr(sc, xfer)
ohci_softc_t *sc;
- usbd_request_handle reqh;
+ usbd_xfer_handle xfer;
{
- int timo = reqh->timeout;
+ int timo = xfer->timeout;
int usecs;
u_int32_t intrs;
- reqh->status = USBD_IN_PROGRESS;
+ xfer->status = USBD_IN_PROGRESS;
for (usecs = timo * 1000000 / hz; usecs > 0; usecs -= 1000) {
usb_delay_ms(&sc->sc_bus, 1);
intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs;
@@ -980,16 +1138,16 @@ ohci_waitintr(sc, reqh)
ohci_dumpregs(sc);
#endif
if (intrs) {
- ohci_intr(sc);
- if (reqh->status != USBD_IN_PROGRESS)
+ ohci_intr1(sc);
+ if (xfer->status != USBD_IN_PROGRESS)
return;
}
}
/* Timeout */
DPRINTF(("ohci_waitintr: timeout\n"));
- reqh->status = USBD_TIMEOUT;
- usb_transfer_complete(reqh);
+ xfer->status = USBD_TIMEOUT;
+ usb_transfer_complete(xfer);
/* XXX should free TD */
}
@@ -1000,23 +1158,23 @@ ohci_poll(bus)
ohci_softc_t *sc = (ohci_softc_t *)bus;
if (OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs)
- ohci_intr(sc);
+ ohci_intr1(sc);
}
usbd_status
-ohci_device_request(reqh)
- usbd_request_handle reqh;
+ohci_device_request(xfer)
+ usbd_xfer_handle xfer;
{
- struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
- usb_device_request_t *req = &reqh->request;
+ struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
+ usb_device_request_t *req = &xfer->request;
usbd_device_handle dev = opipe->pipe.device;
ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
int addr = dev->address;
- ohci_soft_td_t *setup, *xfer = 0, *stat, *next, *tail;
+ ohci_soft_td_t *setup, *data = 0, *stat, *next, *tail;
ohci_soft_ed_t *sed;
int isread;
int len;
- usbd_status r;
+ usbd_status err;
int s;
isread = req->bmRequestType & UT_READ;
@@ -1030,16 +1188,16 @@ ohci_device_request(reqh)
setup = opipe->tail;
stat = ohci_alloc_std(sc);
- if (!stat) {
- r = USBD_NOMEM;
+ if (stat == NULL) {
+ err = USBD_NOMEM;
goto bad1;
}
tail = ohci_alloc_std(sc);
- if (!tail) {
- r = USBD_NOMEM;
+ if (tail == NULL) {
+ err = USBD_NOMEM;
goto bad2;
}
- tail->reqh = 0;
+ tail->xfer = NULL;
sed = opipe->sed;
opipe->u.ctl.length = len;
@@ -1053,28 +1211,29 @@ ohci_device_request(reqh)
/* Set up data transaction */
if (len != 0) {
- xfer = ohci_alloc_std(sc);
- if (!xfer) {
- r = USBD_NOMEM;
+ data = ohci_alloc_std(sc);
+ if (data == NULL) {
+ err = USBD_NOMEM;
goto bad3;
}
- xfer->td.td_flags = LE(
+ data->td.td_flags = LE(
(isread ? OHCI_TD_IN : OHCI_TD_OUT) | OHCI_TD_NOCC |
OHCI_TD_TOGGLE_1 | OHCI_TD_NOINTR |
- (reqh->flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0));
- xfer->td.td_cbp = LE(DMAADDR(&reqh->dmabuf));
- xfer->nexttd = stat;
- xfer->td.td_nexttd = LE(stat->physaddr);
- xfer->td.td_be = LE(LE(xfer->td.td_cbp) + len - 1);
- xfer->len = len;
- xfer->reqh = reqh;
- xfer->flags = OHCI_SET_LEN;
-
- next = xfer;
+ (xfer->flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0));
+ data->td.td_cbp = LE(DMAADDR(&xfer->dmabuf));
+ data->nexttd = stat;
+ data->td.td_nexttd = LE(stat->physaddr);
+ data->td.td_be = LE(LE(data->td.td_cbp) + len - 1);
+ data->len = len;
+ data->xfer = xfer;
+ data->flags = OHCI_ADD_LEN;
+
+ next = data;
stat->flags = OHCI_CALL_DONE;
} else {
next = stat;
- stat->flags = OHCI_CALL_DONE | OHCI_SET_LEN;
+ /* XXX ADD_LEN? */
+ stat->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
}
memcpy(KERNADDR(&opipe->u.ctl.reqdma), req, sizeof *req);
@@ -1086,9 +1245,9 @@ ohci_device_request(reqh)
setup->td.td_nexttd = LE(next->physaddr);
setup->td.td_be = LE(LE(setup->td.td_cbp) + sizeof *req - 1);
setup->len = 0; /* XXX The number of byte we count */
- setup->reqh = reqh;
+ setup->xfer = xfer;
setup->flags = 0;
- reqh->hcpriv = setup;
+ xfer->hcpriv = setup;
stat->td.td_flags = LE(
(isread ? OHCI_TD_OUT : OHCI_TD_IN) | OHCI_TD_NOCC |
@@ -1098,7 +1257,7 @@ ohci_device_request(reqh)
stat->td.td_nexttd = LE(tail->physaddr);
stat->td.td_be = 0;
stat->len = 0;
- stat->reqh = reqh;
+ stat->xfer = xfer;
#ifdef OHCI_DEBUG
if (ohcidebug > 5) {
@@ -1112,31 +1271,26 @@ ohci_device_request(reqh)
s = splusb();
ohci_hash_add_td(sc, setup);
if (len != 0)
- ohci_hash_add_td(sc, xfer);
+ ohci_hash_add_td(sc, data);
ohci_hash_add_td(sc, stat);
sed->ed.ed_tailp = LE(tail->physaddr);
opipe->tail = tail;
OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF);
- if (reqh->timeout && !sc->sc_bus.use_polling) {
- usb_timeout(ohci_timeout, reqh,
- MS_TO_TICKS(reqh->timeout), reqh->timo_handle);
+ if (xfer->timeout && !sc->sc_bus.use_polling) {
+ usb_timeout(ohci_timeout, xfer,
+ MS_TO_TICKS(xfer->timeout), xfer->timo_handle);
}
splx(s);
-#if 0
- This goes horribly wrong, printing thousands of descriptors,
- because false references are followed due to the fact that the
- TD is gone.
#ifdef OHCI_DEBUG
if (ohcidebug > 5) {
- delay(5000);
+ usb_delay_ms(&sc->sc_bus, 5);
DPRINTF(("ohci_device_request: status=%x\n",
OREAD4(sc, OHCI_COMMAND_STATUS)));
ohci_dump_ed(sed);
ohci_dump_tds(setup);
}
#endif
-#endif
return (USBD_NORMAL_COMPLETION);
@@ -1145,7 +1299,7 @@ ohci_device_request(reqh)
bad2:
ohci_free_std(sc, stat);
bad1:
- return (r);
+ return (err);
}
/*
@@ -1156,6 +1310,7 @@ ohci_add_ed(sed, head)
ohci_soft_ed_t *sed;
ohci_soft_ed_t *head;
{
+ SPLUSBCHECK;
sed->next = head->next;
sed->ed.ed_nexted = head->ed.ed_nexted;
head->next = sed;
@@ -1172,10 +1327,12 @@ ohci_rem_ed(sed, head)
{
ohci_soft_ed_t *p;
+ SPLUSBCHECK;
+
/* XXX */
- for (p = head; p && p->next != sed; p = p->next)
+ for (p = head; p == NULL && p->next != sed; p = p->next)
;
- if (!p)
+ if (p == NULL)
panic("ohci_rem_ed: ED not found\n");
p->next = sed->next;
p->ed.ed_nexted = sed->ed.ed_nexted;
@@ -1200,6 +1357,8 @@ ohci_hash_add_td(sc, std)
{
int h = HASH(std->physaddr);
+ SPLUSBCHECK;
+
LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext);
}
@@ -1209,6 +1368,8 @@ ohci_hash_rem_td(sc, std)
ohci_softc_t *sc;
ohci_soft_td_t *std;
{
+ SPLUSBCHECK;
+
LIST_REMOVE(std, hnext);
}
@@ -1221,7 +1382,7 @@ ohci_hash_find_td(sc, a)
ohci_soft_td_t *std;
for (std = LIST_FIRST(&sc->sc_hash_tds[h]);
- std != 0;
+ std != NULL;
std = LIST_NEXT(std, hnext))
if (std->physaddr == a)
return (std);
@@ -1232,10 +1393,16 @@ void
ohci_timeout(addr)
void *addr;
{
- usbd_request_handle reqh = addr;
+ usbd_xfer_handle xfer = addr;
+ int s;
+
+ DPRINTF(("ohci_timeout: xfer=%p\n", xfer));
- DPRINTF(("ohci_timeout: reqh=%p\n", reqh));
- ohci_abort_req(reqh, USBD_TIMEOUT);
+ s = splusb();
+ xfer->device->bus->intr_context++;
+ ohci_abort_req(xfer, USBD_TIMEOUT);
+ xfer->device->bus->intr_context--;
+ splx(s);
}
#ifdef OHCI_DEBUG
@@ -1276,7 +1443,7 @@ ohci_dump_ed(sed)
(int)LE(sed->ed.ed_flags),
"\20\14OUT\15IN\16LOWSPEED\17SKIP\20ISO",
(u_long)LE(sed->ed.ed_tailp),
- (int)LE(sed->ed.ed_headp),
+ (u_long)LE(sed->ed.ed_headp),
"\20\1HALT\2CARRY",
(u_long)LE(sed->ed.ed_nexted)));
}
@@ -1293,7 +1460,7 @@ ohci_open(pipe)
u_int8_t addr = dev->address;
ohci_soft_ed_t *sed;
ohci_soft_td_t *std;
- usbd_status r;
+ usbd_status err;
int s;
DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
@@ -1311,10 +1478,10 @@ ohci_open(pipe)
}
} else {
sed = ohci_alloc_sed(sc);
- if (sed == 0)
+ if (sed == NULL)
goto bad0;
std = ohci_alloc_std(sc);
- if (std == 0)
+ if (std == NULL)
goto bad1;
opipe->sed = sed;
opipe->tail = std;
@@ -1331,10 +1498,10 @@ ohci_open(pipe)
switch (ed->bmAttributes & UE_XFERTYPE) {
case UE_CONTROL:
pipe->methods = &ohci_device_ctrl_methods;
- r = usb_allocmem(sc->sc_dmatag,
- sizeof(usb_device_request_t),
- 0, &opipe->u.ctl.reqdma);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usb_allocmem(&sc->sc_bus,
+ sizeof(usb_device_request_t),
+ 0, &opipe->u.ctl.reqdma);
+ if (err)
goto bad;
s = splusb();
ohci_add_ed(sed, sc->sc_ctrl_head);
@@ -1387,7 +1554,7 @@ ohci_close_pipe(pipe, head)
ohci_physaddr_t td = sed->ed.ed_headp;
ohci_soft_td_t *std;
for (std = LIST_FIRST(&sc->sc_hash_tds[HASH(td)]);
- std != 0;
+ std != NULL;
std = LIST_NEXT(std, hnext))
if (std->physaddr == td)
break;
@@ -1418,28 +1585,33 @@ ohci_close_pipe(pipe, head)
* interrupt processing to process it.
*/
void
-ohci_abort_req(reqh, status)
- usbd_request_handle reqh;
+ohci_abort_req(xfer, status)
+ usbd_xfer_handle xfer;
usbd_status status;
{
- struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
+ struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
ohci_soft_ed_t *sed;
- DPRINTF(("ohci_abort_req: reqh=%p pipe=%p\n", reqh, opipe));
+ DPRINTF(("ohci_abort_req: xfer=%p pipe=%p\n", xfer, opipe));
- reqh->status = status;
+ xfer->status = status;
- usb_untimeout(ohci_timeout, reqh, reqh->timo_handle);
+ usb_untimeout(ohci_timeout, xfer, xfer->timo_handle);
sed = opipe->sed;
DPRINTFN(1,("ohci_abort_req: stop ed=%p\n", sed));
sed->ed.ed_flags |= LE(OHCI_ED_SKIP); /* force hardware skip */
- if (curproc) {
- usb_delay_ms(opipe->pipe.device->bus, 1);
- ohci_abort_req_end(reqh);
+ if (xfer->device->bus->intr_context) {
+ /* We have no process context, so we can't use tsleep(). */
+ timeout(ohci_abort_req_end, xfer, hz / USB_FRAMES_PER_SECOND);
} else {
- timeout(ohci_abort_req_end, reqh, hz / USB_FRAMES_PER_SECOND);
+#if defined(DIAGNOSTIC) && defined(__i386__)
+ KASSERT(intr_nesting_level == 0,
+ ("ohci_abort_req in interrupt context"));
+#endif
+ usb_delay_ms(opipe->pipe.device->bus, 1);
+ ohci_abort_req_end(xfer);
}
}
@@ -1447,8 +1619,8 @@ void
ohci_abort_req_end(v)
void *v;
{
- usbd_request_handle reqh = v;
- struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
+ usbd_xfer_handle xfer = v;
+ struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
ohci_softc_t *sc = (ohci_softc_t *)opipe->pipe.device->bus;
ohci_soft_ed_t *sed;
ohci_soft_td_t *p, *n;
@@ -1456,14 +1628,14 @@ ohci_abort_req_end(v)
s = splusb();
- p = reqh->hcpriv;
+ p = xfer->hcpriv;
#ifdef DIAGNOSTIC
- if (!p) {
+ if (p == NULL) {
printf("ohci_abort_req: hcpriv==0\n");
return;
}
#endif
- for (; p->reqh == reqh; p = n) {
+ for (; p->xfer == xfer; p = n) {
n = p->nexttd;
ohci_hash_rem_td(sc, p);
ohci_free_std(sc, p);
@@ -1475,7 +1647,7 @@ ohci_abort_req_end(v)
sed->ed.ed_headp = p->physaddr; /* unlink TDs */
sed->ed.ed_flags &= LE(~OHCI_ED_SKIP); /* remove hardware skip */
- usb_transfer_complete(reqh);
+ usb_transfer_complete(xfer);
splx(s);
}
@@ -1483,7 +1655,7 @@ ohci_abort_req_end(v)
/*
* Data structures and routines to emulate the root hub.
*/
-usb_device_descriptor_t ohci_devd = {
+static usb_device_descriptor_t ohci_devd = {
USB_DEVICE_DESCRIPTOR_SIZE,
UDESC_DEVICE, /* type */
{0x00, 0x01}, /* USB version */
@@ -1496,7 +1668,7 @@ usb_device_descriptor_t ohci_devd = {
1 /* # of configurations */
};
-usb_config_descriptor_t ohci_confd = {
+static usb_config_descriptor_t ohci_confd = {
USB_CONFIG_DESCRIPTOR_SIZE,
UDESC_CONFIG,
{USB_CONFIG_DESCRIPTOR_SIZE +
@@ -1509,7 +1681,7 @@ usb_config_descriptor_t ohci_confd = {
0 /* max power */
};
-usb_interface_descriptor_t ohci_ifcd = {
+static usb_interface_descriptor_t ohci_ifcd = {
USB_INTERFACE_DESCRIPTOR_SIZE,
UDESC_INTERFACE,
0,
@@ -1521,7 +1693,7 @@ usb_interface_descriptor_t ohci_ifcd = {
0
};
-usb_endpoint_descriptor_t ohci_endpd = {
+static usb_endpoint_descriptor_t ohci_endpd = {
USB_ENDPOINT_DESCRIPTOR_SIZE,
UDESC_ENDPOINT,
UE_DIR_IN | OHCI_INTR_ENDPT,
@@ -1530,7 +1702,7 @@ usb_endpoint_descriptor_t ohci_endpd = {
255
};
-usb_hub_descriptor_t ohci_hubd = {
+static usb_hub_descriptor_t ohci_hubd = {
USB_HUB_DESCRIPTOR_SIZE,
UDESC_HUB,
0,
@@ -1540,7 +1712,7 @@ usb_hub_descriptor_t ohci_hubd = {
{0},
};
-int
+static int
ohci_str(p, l, s)
usb_string_descriptor_t *p;
int l;
@@ -1563,39 +1735,41 @@ ohci_str(p, l, s)
/*
* Simulate a hardware hub by handling all the necessary requests.
*/
-usbd_status
-ohci_root_ctrl_transfer(reqh)
- usbd_request_handle reqh;
+static usbd_status
+ohci_root_ctrl_transfer(xfer)
+ usbd_xfer_handle xfer;
{
- usbd_status r;
+ usbd_status err;
+
+ /* Insert last in queue. */
+ err = usb_insert_transfer(xfer);
+ if (err)
+ return (err);
- r = usb_insert_transfer(reqh);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- else
- return (ohci_root_ctrl_start(reqh));
+ /* Pipe isn't running, start first */
+ return (ohci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
}
-usbd_status
-ohci_root_ctrl_start(reqh)
- usbd_request_handle reqh;
+static usbd_status
+ohci_root_ctrl_start(xfer)
+ usbd_xfer_handle xfer;
{
- ohci_softc_t *sc = (ohci_softc_t *)reqh->pipe->device->bus;
+ ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
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 r;
+ usbd_status err;
u_int32_t v;
#ifdef DIAGNOSTIC
- if (!(reqh->rqflags & URQ_REQUEST))
+ if (!(xfer->rqflags & URQ_REQUEST))
/* XXX panic */
return (USBD_INVAL);
#endif
- req = &reqh->request;
+ req = &xfer->request;
DPRINTFN(4,("ohci_root_ctrl_control type=0x%02x request=%02x\n",
req->bmRequestType, req->bRequest));
@@ -1605,7 +1779,7 @@ ohci_root_ctrl_start(reqh)
index = UGETW(req->wIndex);
if (len != 0)
- buf = KERNADDR(&reqh->dmabuf);
+ buf = KERNADDR(&xfer->dmabuf);
#define C(x,y) ((x) | ((y) << 8))
switch(C(req->bRequest, req->bmRequestType)) {
@@ -1628,7 +1802,7 @@ ohci_root_ctrl_start(reqh)
switch(value >> 8) {
case UDESC_DEVICE:
if ((value & 0xff) != 0) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
@@ -1637,7 +1811,7 @@ ohci_root_ctrl_start(reqh)
break;
case UDESC_CONFIG:
if ((value & 0xff) != 0) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
@@ -1668,7 +1842,7 @@ ohci_root_ctrl_start(reqh)
}
break;
default:
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
break;
@@ -1693,14 +1867,14 @@ ohci_root_ctrl_start(reqh)
break;
case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
if (value >= USB_MAX_DEVICES) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
sc->sc_addr = value;
break;
case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
if (value != 0 && value != 1) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
sc->sc_conf = value;
@@ -1710,7 +1884,7 @@ ohci_root_ctrl_start(reqh)
case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
break;
@@ -1724,7 +1898,7 @@ ohci_root_ctrl_start(reqh)
"port=%d feature=%d\n",
index, value));
if (index < 1 || index > sc->sc_noport) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
port = OHCI_RH_PORT_STATUS(index);
@@ -1754,7 +1928,7 @@ ohci_root_ctrl_start(reqh)
OWRITE4(sc, port, UPS_C_PORT_RESET << 16);
break;
default:
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
switch(value) {
@@ -1773,7 +1947,7 @@ ohci_root_ctrl_start(reqh)
break;
case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
if (value != 0) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
v = OREAD4(sc, OHCI_RH_DESCRIPTOR_A);
@@ -1795,7 +1969,7 @@ ohci_root_ctrl_start(reqh)
break;
case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
if (len != 4) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
memset(buf, 0, len); /* ? XXX */
@@ -1805,11 +1979,11 @@ ohci_root_ctrl_start(reqh)
DPRINTFN(8,("ohci_root_ctrl_transfer: get port status i=%d\n",
index));
if (index < 1 || index > sc->sc_noport) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
if (len != 4) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
v = OREAD4(sc, OHCI_RH_PORT_STATUS(index));
@@ -1822,13 +1996,13 @@ ohci_root_ctrl_start(reqh)
totlen = l;
break;
case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
break;
case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
if (index < 1 || index > sc->sc_noport) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
port = OHCI_RH_PORT_STATUS(index);
@@ -1857,32 +2031,34 @@ ohci_root_ctrl_start(reqh)
OWRITE4(sc, port, UPS_PORT_POWER);
break;
default:
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
break;
default:
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
- reqh->actlen = totlen;
- r = USBD_NORMAL_COMPLETION;
+ xfer->actlen = totlen;
+ err = USBD_NORMAL_COMPLETION;
ret:
- reqh->status = r;
- usb_transfer_complete(reqh);
+ xfer->status = err;
+ s = splusb();
+ usb_transfer_complete(xfer);
+ splx(s);
return (USBD_IN_PROGRESS);
}
/* Abort a root control request. */
-void
-ohci_root_ctrl_abort(reqh)
- usbd_request_handle reqh;
+static void
+ohci_root_ctrl_abort(xfer)
+ usbd_xfer_handle xfer;
{
/* Nothing to do, all transfers are synchronous. */
}
/* Close the root pipe. */
-void
+static void
ohci_root_ctrl_close(pipe)
usbd_pipe_handle pipe;
{
@@ -1890,41 +2066,52 @@ ohci_root_ctrl_close(pipe)
/* Nothing to do. */
}
-usbd_status
-ohci_root_intr_transfer(reqh)
- usbd_request_handle reqh;
+static usbd_status
+ohci_root_intr_transfer(xfer)
+ usbd_xfer_handle xfer;
{
- usbd_status r;
+ usbd_status err;
+
+ /* Insert last in queue. */
+ err = usb_insert_transfer(xfer);
+ if (err)
+ return (err);
- r = usb_insert_transfer(reqh);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- else
- return (ohci_root_intr_start(reqh));
+ /* Pipe isn't running, start first */
+ return (ohci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
}
-usbd_status
-ohci_root_intr_start(reqh)
- usbd_request_handle reqh;
+static usbd_status
+ohci_root_intr_start(xfer)
+ usbd_xfer_handle xfer;
{
- usbd_pipe_handle pipe = reqh->pipe;
+ usbd_pipe_handle pipe = xfer->pipe;
ohci_softc_t *sc = (ohci_softc_t *)pipe->device->bus;
- sc->sc_intrreqh = reqh;
+ sc->sc_intrxfer = xfer;
return (USBD_IN_PROGRESS);
}
/* Abort a root interrupt request. */
-void
-ohci_root_intr_abort(reqh)
- usbd_request_handle reqh;
+static void
+ohci_root_intr_abort(xfer)
+ usbd_xfer_handle xfer;
{
- /* No need to abort. */
+ int s;
+
+ if (xfer->pipe->intrxfer == xfer) {
+ DPRINTF(("ohci_root_intr_abort: remove\n"));
+ xfer->pipe->intrxfer = NULL;
+ }
+ xfer->status = USBD_CANCELLED;
+ s = splusb();
+ usb_transfer_complete(xfer);
+ splx(s);
}
/* Close the root pipe. */
-void
+static void
ohci_root_intr_close(pipe)
usbd_pipe_handle pipe;
{
@@ -1932,59 +2119,61 @@ ohci_root_intr_close(pipe)
DPRINTF(("ohci_root_intr_close\n"));
- sc->sc_intrreqh = 0;
+ sc->sc_intrxfer = NULL;
}
/************************/
-usbd_status
-ohci_device_ctrl_transfer(reqh)
- usbd_request_handle reqh;
+static usbd_status
+ohci_device_ctrl_transfer(xfer)
+ usbd_xfer_handle xfer;
{
- usbd_status r;
+ usbd_status err;
- r = usb_insert_transfer(reqh);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- else
- return (ohci_device_ctrl_start(reqh));
+ /* Insert last in queue. */
+ err = usb_insert_transfer(xfer);
+ if (err)
+ return (err);
+
+ /* Pipe isn't running, start first */
+ return (ohci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
}
-usbd_status
-ohci_device_ctrl_start(reqh)
- usbd_request_handle reqh;
+static usbd_status
+ohci_device_ctrl_start(xfer)
+ usbd_xfer_handle xfer;
{
- ohci_softc_t *sc = (ohci_softc_t *)reqh->pipe->device->bus;
- usbd_status r;
+ ohci_softc_t *sc = (ohci_softc_t *)xfer->pipe->device->bus;
+ usbd_status err;
#ifdef DIAGNOSTIC
- if (!(reqh->rqflags & URQ_REQUEST)) {
+ if (!(xfer->rqflags & URQ_REQUEST)) {
/* XXX panic */
printf("ohci_device_ctrl_transfer: not a request\n");
return (USBD_INVAL);
}
#endif
- r = ohci_device_request(reqh);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = ohci_device_request(xfer);
+ if (err)
+ return (err);
if (sc->sc_bus.use_polling)
- ohci_waitintr(sc, reqh);
+ ohci_waitintr(sc, xfer);
return (USBD_IN_PROGRESS);
}
/* Abort a device control request. */
-void
-ohci_device_ctrl_abort(reqh)
- usbd_request_handle reqh;
+static void
+ohci_device_ctrl_abort(xfer)
+ usbd_xfer_handle xfer;
{
- DPRINTF(("ohci_device_ctrl_abort: reqh=%p\n", reqh));
- ohci_abort_req(reqh, USBD_CANCELLED);
+ DPRINTF(("ohci_device_ctrl_abort: xfer=%p\n", xfer));
+ ohci_abort_req(xfer, USBD_CANCELLED);
}
/* Close a device control pipe. */
-void
+static void
ohci_device_ctrl_close(pipe)
usbd_pipe_handle pipe;
{
@@ -1996,7 +2185,7 @@ ohci_device_ctrl_close(pipe)
/************************/
-void
+static void
ohci_device_clear_toggle(pipe)
usbd_pipe_handle pipe;
{
@@ -2005,113 +2194,111 @@ ohci_device_clear_toggle(pipe)
opipe->sed->ed.ed_tailp &= LE(~OHCI_TOGGLECARRY);
}
-void
+static void
ohci_noop(pipe)
usbd_pipe_handle pipe;
{
}
-usbd_status
-ohci_device_bulk_transfer(reqh)
- usbd_request_handle reqh;
+static usbd_status
+ohci_device_bulk_transfer(xfer)
+ usbd_xfer_handle xfer;
{
- usbd_status r;
+ usbd_status err;
- r = usb_insert_transfer(reqh);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- else
- return (ohci_device_bulk_start(reqh));
+ /* Insert last in queue. */
+ err = usb_insert_transfer(xfer);
+ if (err)
+ return (err);
+
+ /* Pipe isn't running, start first */
+ return (ohci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
}
-usbd_status
-ohci_device_bulk_start(reqh)
- usbd_request_handle reqh;
+static usbd_status
+ohci_device_bulk_start(xfer)
+ usbd_xfer_handle xfer;
{
- struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
+ struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
usbd_device_handle dev = opipe->pipe.device;
ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
int addr = dev->address;
- ohci_soft_td_t *xfer, *tail;
+ ohci_soft_td_t *data, *tail, *tdp;
ohci_soft_ed_t *sed;
int s, len, isread, endpt;
+ usbd_status err;
#ifdef DIAGNOSTIC
- if (reqh->rqflags & URQ_REQUEST) {
+ if (xfer->rqflags & URQ_REQUEST) {
/* XXX panic */
printf("ohci_device_bulk_start: a request\n");
return (USBD_INVAL);
}
#endif
- len = reqh->length;
- endpt = reqh->pipe->endpoint->edesc->bEndpointAddress;
+ len = xfer->length;
+ endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
isread = UE_GET_DIR(endpt) == UE_DIR_IN;
sed = opipe->sed;
- DPRINTFN(4,("ohci_device_bulk_start: reqh=%p len=%d isread=%d "
- "flags=%d endpt=%d\n", reqh, len, isread, reqh->flags,
+ DPRINTFN(4,("ohci_device_bulk_start: xfer=%p len=%d isread=%d "
+ "flags=%d endpt=%d\n", xfer, len, isread, xfer->flags,
endpt));
opipe->u.bulk.isread = isread;
opipe->u.bulk.length = len;
- tail = ohci_alloc_std(sc);
- if (!tail)
- return (USBD_NOMEM);
- tail->reqh = 0;
-
/* Update device address */
sed->ed.ed_flags = LE(
(LE(sed->ed.ed_flags) & ~OHCI_ED_ADDRMASK) |
OHCI_ED_SET_FA(addr));
- /* Set up data transaction */
- xfer = opipe->tail;
- xfer->td.td_flags = LE(
- (isread ? OHCI_TD_IN : OHCI_TD_OUT) | OHCI_TD_NOCC |
- OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY |
- (reqh->flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0));
- xfer->td.td_cbp = LE(DMAADDR(&reqh->dmabuf));
- xfer->nexttd = tail;
- xfer->td.td_nexttd = LE(tail->physaddr);
- xfer->td.td_be = LE(LE(xfer->td.td_cbp) + len - 1);
- xfer->len = len;
- xfer->reqh = reqh;
- xfer->flags = OHCI_CALL_DONE | OHCI_SET_LEN;
- reqh->hcpriv = xfer;
+ /* Allocate a chain of new TDs (including a new tail). */
+ data = opipe->tail;
+ err = ohci_alloc_std_chain(opipe, sc, len, isread,
+ xfer->flags & USBD_SHORT_XFER_OK,
+ &xfer->dmabuf, data, &tail);
+ if (err)
+ return (err);
+
+ tail->xfer = NULL;
+ xfer->hcpriv = data;
DPRINTFN(4,("ohci_device_bulk_start: ed_flags=0x%08x td_flags=0x%08x "
"td_cbp=0x%08x td_be=0x%08x\n",
- (int)LE(sed->ed.ed_flags), (int)LE(xfer->td.td_flags),
- (int)LE(xfer->td.td_cbp), (int)LE(xfer->td.td_be)));
+ (int)LE(sed->ed.ed_flags), (int)LE(data->td.td_flags),
+ (int)LE(data->td.td_cbp), (int)LE(data->td.td_be)));
#ifdef OHCI_DEBUG
if (ohcidebug > 4) {
ohci_dump_ed(sed);
- ohci_dump_tds(xfer);
+ ohci_dump_tds(data);
}
#endif
/* Insert ED in schedule */
s = splusb();
- ohci_hash_add_td(sc, xfer);
+ for (tdp = data; tdp != tail; tdp = tdp->nexttd) {
+ tdp->xfer = xfer;
+ ohci_hash_add_td(sc, tdp);
+ }
sed->ed.ed_tailp = LE(tail->physaddr);
opipe->tail = tail;
sed->ed.ed_flags &= LE(~OHCI_ED_SKIP);
OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF);
- if (reqh->timeout && !sc->sc_bus.use_polling) {
- usb_timeout(ohci_timeout, reqh,
- MS_TO_TICKS(reqh->timeout), reqh->timo_handle);
+ if (xfer->timeout && !sc->sc_bus.use_polling) {
+ usb_timeout(ohci_timeout, xfer,
+ MS_TO_TICKS(xfer->timeout), xfer->timo_handle);
}
-#ifdef OHCI_DEBUG
+#if 0
+/* This goes wrong if we are too slow. */
if (ohcidebug > 5) {
- delay(5000);
+ usb_delay_ms(&sc->sc_bus, 5);
DPRINTF(("ohci_device_intr_transfer: status=%x\n",
OREAD4(sc, OHCI_COMMAND_STATUS)));
ohci_dump_ed(sed);
- ohci_dump_tds(xfer);
+ ohci_dump_tds(data);
}
#endif
@@ -2120,18 +2307,18 @@ ohci_device_bulk_start(reqh)
return (USBD_IN_PROGRESS);
}
-void
-ohci_device_bulk_abort(reqh)
- usbd_request_handle reqh;
+static void
+ohci_device_bulk_abort(xfer)
+ usbd_xfer_handle xfer;
{
- DPRINTF(("ohci_device_bulk_abort: reqh=%p\n", reqh));
- ohci_abort_req(reqh, USBD_CANCELLED);
+ DPRINTF(("ohci_device_bulk_abort: xfer=%p\n", xfer));
+ ohci_abort_req(xfer, USBD_CANCELLED);
}
/*
* Close a device bulk pipe.
*/
-void
+static void
ohci_device_bulk_close(pipe)
usbd_pipe_handle pipe;
{
@@ -2143,108 +2330,112 @@ ohci_device_bulk_close(pipe)
/************************/
-usbd_status
-ohci_device_intr_transfer(reqh)
- usbd_request_handle reqh;
+static usbd_status
+ohci_device_intr_transfer(xfer)
+ usbd_xfer_handle xfer;
{
- usbd_status r;
+ usbd_status err;
- r = usb_insert_transfer(reqh);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- else
- return (ohci_device_intr_start(reqh));
+ /* Insert last in queue. */
+ err = usb_insert_transfer(xfer);
+ if (err)
+ return (err);
+
+ /* Pipe isn't running, start first */
+ return (ohci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
}
-usbd_status
-ohci_device_intr_start(reqh)
- usbd_request_handle reqh;
+static usbd_status
+ohci_device_intr_start(xfer)
+ usbd_xfer_handle xfer;
{
- struct ohci_pipe *opipe = (struct ohci_pipe *)reqh->pipe;
+ struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe;
usbd_device_handle dev = opipe->pipe.device;
ohci_softc_t *sc = (ohci_softc_t *)dev->bus;
ohci_soft_ed_t *sed = opipe->sed;
- ohci_soft_td_t *xfer, *tail;
+ ohci_soft_td_t *data, *tail;
int len;
int s;
- DPRINTFN(3, ("ohci_device_intr_transfer: reqh=%p len=%d "
+ DPRINTFN(3, ("ohci_device_intr_transfer: xfer=%p len=%d "
"flags=%d priv=%p\n",
- reqh, reqh->length, reqh->flags, reqh->priv));
+ xfer, xfer->length, xfer->flags, xfer->priv));
#ifdef DIAGNOSTIC
- if (reqh->rqflags & URQ_REQUEST)
+ if (xfer->rqflags & URQ_REQUEST)
panic("ohci_device_intr_transfer: a request\n");
#endif
- len = reqh->length;
+ len = xfer->length;
- xfer = opipe->tail;
+ data = opipe->tail;
tail = ohci_alloc_std(sc);
- if (!tail)
+ if (tail == NULL)
return (USBD_NOMEM);
- tail->reqh = 0;
+ tail->xfer = NULL;
- xfer->td.td_flags = LE(
+ data->td.td_flags = LE(
OHCI_TD_IN | OHCI_TD_NOCC |
OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY);
- if (reqh->flags & USBD_SHORT_XFER_OK)
- xfer->td.td_flags |= LE(OHCI_TD_R);
- xfer->td.td_cbp = LE(DMAADDR(&reqh->dmabuf));
- xfer->nexttd = tail;
- xfer->td.td_nexttd = LE(tail->physaddr);
- xfer->td.td_be = LE(LE(xfer->td.td_cbp) + len - 1);
- xfer->len = len;
- xfer->reqh = reqh;
- xfer->flags = OHCI_CALL_DONE | OHCI_SET_LEN;
- reqh->hcpriv = xfer;
+ if (xfer->flags & USBD_SHORT_XFER_OK)
+ data->td.td_flags |= LE(OHCI_TD_R);
+ data->td.td_cbp = LE(DMAADDR(&xfer->dmabuf));
+ data->nexttd = tail;
+ data->td.td_nexttd = LE(tail->physaddr);
+ data->td.td_be = LE(LE(data->td.td_cbp) + len - 1);
+ data->len = len;
+ data->xfer = xfer;
+ data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN;
+ xfer->hcpriv = data;
#ifdef OHCI_DEBUG
if (ohcidebug > 5) {
DPRINTF(("ohci_device_intr_transfer:\n"));
ohci_dump_ed(sed);
- ohci_dump_tds(xfer);
+ ohci_dump_tds(data);
}
#endif
/* Insert ED in schedule */
s = splusb();
- ohci_hash_add_td(sc, xfer);
+ ohci_hash_add_td(sc, data);
sed->ed.ed_tailp = LE(tail->physaddr);
opipe->tail = tail;
sed->ed.ed_flags &= LE(~OHCI_ED_SKIP);
#if 0
- this goes wrong if we are too slow with dumping the TDs
-#ifdef OHCI_DEBUG
+/*
+ * This goes horribly wrong, printing thousands of descriptors,
+ * because false references are followed due to the fact that the
+ * TD is gone.
+ */
if (ohcidebug > 5) {
- delay(5000);
+ usb_delay_ms(&sc->sc_bus, 5);
DPRINTF(("ohci_device_intr_transfer: status=%x\n",
OREAD4(sc, OHCI_COMMAND_STATUS)));
ohci_dump_ed(sed);
- ohci_dump_tds(xfer);
+ ohci_dump_tds(data);
}
#endif
-#endif
splx(s);
return (USBD_IN_PROGRESS);
}
/* Abort a device control request. */
-void
-ohci_device_intr_abort(reqh)
- usbd_request_handle reqh;
+static void
+ohci_device_intr_abort(xfer)
+ usbd_xfer_handle xfer;
{
- if (reqh->pipe->intrreqh == reqh) {
+ if (xfer->pipe->intrxfer == xfer) {
DPRINTF(("ohci_device_intr_abort: remove\n"));
- reqh->pipe->intrreqh = 0;
+ xfer->pipe->intrxfer = NULL;
}
- ohci_abort_req(reqh, USBD_CANCELLED);
+ ohci_abort_req(xfer, USBD_CANCELLED);
}
/* Close a device interrupt pipe. */
-void
+static void
ohci_device_intr_close(pipe)
usbd_pipe_handle pipe;
{
@@ -2266,8 +2457,10 @@ ohci_device_intr_close(pipe)
for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next)
;
- if (!p)
+#ifdef DIAGNOSTIC
+ if (p == NULL)
panic("ohci_device_intr_close: ED not found\n");
+#endif
p->next = sed->next;
p->ed.ed_nexted = sed->ed.ed_nexted;
splx(s);
@@ -2279,7 +2472,7 @@ ohci_device_intr_close(pipe)
ohci_free_sed(sc, opipe->sed);
}
-usbd_status
+static usbd_status
ohci_device_setintr(sc, opipe, ival)
ohci_softc_t *sc;
struct ohci_pipe *opipe;
@@ -2343,4 +2536,3 @@ ohci_device_setintr(sc, opipe, ival)
DPRINTFN(5, ("ohci_setintr: returns %p\n", opipe));
return (USBD_NORMAL_COMPLETION);
}
-
diff --git a/sys/dev/usb/ohcireg.h b/sys/dev/usb/ohcireg.h
index b56b017..ba75709 100644
--- a/sys/dev/usb/ohcireg.h
+++ b/sys/dev/usb/ohcireg.h
@@ -1,5 +1,6 @@
/* $NetBSD: ohcireg.h,v 1.8 1999/08/22 23:41:00 augustss Exp $ */
-/* $FreeBSD$ */
+/* $FreeBSD$ */
+
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -140,6 +141,9 @@ struct ohci_hcca {
#define OHCI_HCCA_SIZE 256
#define OHCI_HCCA_ALIGN 256
+#define OHCI_PAGE_SIZE 0x1000
+#define OHCI_PAGE(x) ((x) &~ 0xfff)
+
typedef struct {
u_int32_t ed_flags;
#define OHCI_ED_GET_FA(s) ((s) & 0x7f)
diff --git a/sys/dev/usb/ohcivar.h b/sys/dev/usb/ohcivar.h
index b0abd15..cd61ee6 100644
--- a/sys/dev/usb/ohcivar.h
+++ b/sys/dev/usb/ohcivar.h
@@ -1,5 +1,5 @@
-/* $NetBSD: ohcivar.h,v 1.8 1999/08/22 23:41:00 augustss Exp $ */
-/* $FreeBSD$ */
+/* $NetBSD: ohcivar.h,v 1.13 1999/10/13 08:10:55 augustss Exp $ */
+/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -52,11 +52,11 @@ typedef struct ohci_soft_td {
struct ohci_soft_td *dnext; /* next in done list */
ohci_physaddr_t physaddr;
LIST_ENTRY(ohci_soft_td) hnext;
- usbd_request_handle reqh;
+ usbd_xfer_handle xfer;
u_int16_t len;
u_int16_t flags;
#define OHCI_CALL_DONE 0x0001
-#define OHCI_SET_LEN 0x0002
+#define OHCI_ADD_LEN 0x0002
} ohci_soft_td_t;
#define OHCI_STD_SIZE ((sizeof (struct ohci_soft_td) + OHCI_TD_ALIGN - 1) / OHCI_TD_ALIGN * OHCI_TD_ALIGN)
#define OHCI_STD_CHUNK 128
@@ -69,12 +69,6 @@ typedef struct ohci_softc {
struct usbd_bus sc_bus; /* base device */
bus_space_tag_t iot;
bus_space_handle_t ioh;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- void *sc_ih; /* interrupt vectoring */
-
- bus_dma_tag_t sc_dmatag; /* DMA tag */
- /* XXX should keep track of all DMA memory */
-#endif /* __NetBSD__ || defined(__OpenBSD__) */
usb_dma_t sc_hccadma;
struct ohci_hcca *sc_hcca;
@@ -94,15 +88,20 @@ typedef struct ohci_softc {
ohci_soft_ed_t *sc_freeeds;
ohci_soft_td_t *sc_freetds;
- usbd_request_handle sc_intrreqh;
-
- int sc_intrs;
+ usbd_xfer_handle sc_intrxfer;
char sc_vendor[16];
int sc_id_vendor;
+
+ void *sc_powerhook;
+ device_ptr_t sc_child;
} ohci_softc_t;
usbd_status ohci_init __P((ohci_softc_t *));
int ohci_intr __P((void *));
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+int ohci_detach __P((ohci_softc_t *, int));
+int ohci_activate __P((device_ptr_t, enum devact));
+#endif
#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c
index 2d433d4..5c39160 100644
--- a/sys/dev/usb/ugen.c
+++ b/sys/dev/usb/ugen.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ugen.c,v 1.23 1999/09/09 12:26:44 augustss Exp $ */
+/* $NetBSD: ugen.c,v 1.27 1999/10/28 12:08:38 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -97,7 +97,7 @@ struct ugen_softc {
USBBASEDEVICE sc_dev; /* base device */
usbd_device_handle sc_udev;
- char sc_is_open[USB_MAX_ENDPOINTS][2];
+ char sc_is_open[USB_MAX_ENDPOINTS];
struct ugen_endpoint sc_endpoints[USB_MAX_ENDPOINTS][2];
#define OUT 0
#define IN 1
@@ -136,18 +136,18 @@ static struct cdevsw ugen_cdevsw = {
};
#endif
-void ugenintr __P((usbd_request_handle reqh, usbd_private_handle addr,
- usbd_status status));
+static void ugenintr __P((usbd_xfer_handle xfer, usbd_private_handle addr,
+ usbd_status status));
-int ugen_do_read __P((struct ugen_softc *, int, struct uio *, int));
-int ugen_do_write __P((struct ugen_softc *, int, struct uio *, int));
-int ugen_do_ioctl __P((struct ugen_softc *, int, u_long,
- caddr_t, int, struct proc *));
-int ugen_set_config __P((struct ugen_softc *sc, int configno));
-usb_config_descriptor_t *ugen_get_cdesc __P((struct ugen_softc *sc, int index,
- int *lenp));
-usbd_status ugen_set_interface __P((struct ugen_softc *, int, int));
-int ugen_get_alt_index __P((struct ugen_softc *sc, int ifaceidx));
+static int ugen_do_read __P((struct ugen_softc *, int, struct uio *, int));
+static int ugen_do_write __P((struct ugen_softc *, int, struct uio *, int));
+static int ugen_do_ioctl __P((struct ugen_softc *, int, u_long,
+ caddr_t, int, struct proc *));
+static int ugen_set_config __P((struct ugen_softc *sc, int configno));
+static usb_config_descriptor_t *ugen_get_cdesc __P((struct ugen_softc *sc,
+ int index, int *lenp));
+static usbd_status ugen_set_interface __P((struct ugen_softc *, int, int));
+static int ugen_get_alt_index __P((struct ugen_softc *sc, int ifaceidx));
#define UGENUNIT(n) ((minor(n) >> 4) & 0xf)
#define UGENENDPOINT(n) (minor(n) & 0xf)
@@ -169,7 +169,7 @@ USB_ATTACH(ugen)
{
USB_ATTACH_START(ugen, sc, uaa);
char devinfo[1024];
- usbd_status r;
+ usbd_status err;
int conf;
usbd_devinfo(uaa->device, 0, devinfo);
@@ -178,8 +178,8 @@ USB_ATTACH(ugen)
sc->sc_udev = uaa->device;
conf = 1; /* XXX should not hard code 1 */
- r = ugen_set_config(sc, conf);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = ugen_set_config(sc, conf);
+ if (err) {
printf("%s: setting configuration %d failed\n",
USBDEVNAME(sc->sc_dev), conf);
sc->sc_dying = 1;
@@ -195,10 +195,11 @@ USB_ATTACH(ugen)
}
}
#endif
+
USB_ATTACH_SUCCESS_RETURN;
}
-int
+static int
ugen_set_config(sc, configno)
struct ugen_softc *sc;
int configno;
@@ -209,30 +210,30 @@ ugen_set_config(sc, configno)
struct ugen_endpoint *sce;
u_int8_t niface, nendpt;
int ifaceno, endptno, endpt;
- usbd_status r;
+ usbd_status err;
int dir;
DPRINTFN(1,("ugen_set_config: %s to configno %d, sc=%p\n",
USBDEVNAME(sc->sc_dev), configno, sc));
if (usbd_get_config_descriptor(dev)->bConfigurationValue != configno) {
/* Avoid setting the current value. */
- r = usbd_set_config_no(dev, configno, 0);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_set_config_no(dev, configno, 0);
+ if (err)
+ return (err);
}
- r = usbd_interface_count(dev, &niface);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_interface_count(dev, &niface);
+ if (err)
+ return (err);
memset(sc->sc_endpoints, 0, sizeof sc->sc_endpoints);
for (ifaceno = 0; ifaceno < niface; ifaceno++) {
DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno));
- r = usbd_device2interface_handle(dev, ifaceno, &iface);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- r = usbd_endpoint_count(iface, &nendpt);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_device2interface_handle(dev, ifaceno, &iface);
+ if (err)
+ return (err);
+ err = usbd_endpoint_count(iface, &nendpt);
+ if (err)
+ return (err);
for (endptno = 0; endptno < nendpt; endptno++) {
ed = usbd_interface2endpoint_descriptor(iface,endptno);
endpt = ed->bEndpointAddress;
@@ -257,29 +258,31 @@ ugenopen(dev, flag, mode, p)
int mode;
struct proc *p;
{
+ struct ugen_softc *sc;
int unit = UGENUNIT(dev);
int endpt = UGENENDPOINT(dev);
usb_endpoint_descriptor_t *edesc;
struct ugen_endpoint *sce;
int dir, isize;
- usbd_status r;
+ usbd_status err;
USB_GET_SC_OPEN(ugen, unit, sc);
+
DPRINTFN(5, ("ugenopen: flag=%d, mode=%d, unit=%d endpt=%d\n",
flag, mode, unit, endpt));
- if (!sc || sc->sc_dying)
+ if (sc == NULL || sc->sc_dying)
return (ENXIO);
+ if (sc->sc_is_open[endpt])
+ return (EBUSY);
+
if (endpt == USB_CONTROL_ENDPOINT) {
- sc->sc_is_open[USB_CONTROL_ENDPOINT][IN] = 1;
+ sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1;
return (0);
}
/* Make sure there are pipes for all directions. */
for (dir = OUT; dir <= IN; dir++) {
- if (sc->sc_is_open[endpt][dir])
- return (EBUSY);
-
if (flag & (dir == OUT ? FWRITE : FREAD)) {
sce = &sc->sc_endpoints[endpt][dir];
if (sce == 0 || sce->edesc == 0)
@@ -298,8 +301,6 @@ ugenopen(dev, flag, mode, p)
DPRINTFN(5, ("ugenopen: sc=%p, endpt=%d, dir=%d, sce=%p\n",
sc, endpt, dir, sce));
edesc = sce->edesc;
- if (!edesc)
- return (ENXIO);
switch (edesc->bmAttributes & UE_XFERTYPE) {
case UE_INTERRUPT:
isize = UGETW(edesc->wMaxPacketSize);
@@ -308,40 +309,31 @@ ugenopen(dev, flag, mode, p)
sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK);
DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n",
endpt, isize));
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1)
- return (ENOMEM);
-#elif defined(__FreeBSD__)
- clist_alloc_cblocks(&sce->q, UGEN_IBSIZE, 0);
-#endif
- r = usbd_open_pipe_intr(sce->iface,
+ if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1)
+ return (ENOMEM);
+ err = usbd_open_pipe_intr(sce->iface,
edesc->bEndpointAddress,
USBD_SHORT_XFER_OK, &sce->pipeh, sce,
sce->ibuf, isize, ugenintr);
- if (r != USBD_NORMAL_COMPLETION) {
+ if (err) {
free(sce->ibuf, M_USBDEV);
-#if defined(__NetBSD__) || defined(__OpenBSD__)
clfree(&sce->q);
-#elif defined(__FreeBSD__)
- clist_free_cblocks(&sce->q);
-#endif
return (EIO);
}
DPRINTFN(5, ("ugenopen: interrupt open done\n"));
break;
case UE_BULK:
- r = usbd_open_pipe(sce->iface,
- edesc->bEndpointAddress, 0,
- &sce->pipeh);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_open_pipe(sce->iface,
+ edesc->bEndpointAddress, 0, &sce->pipeh);
+ if (err)
return (EIO);
break;
case UE_CONTROL:
case UE_ISOCHRONOUS:
return (EINVAL);
}
- sc->sc_is_open[endpt][dir] = 1;
}
+ sc->sc_is_open[endpt] = 1;
return (0);
}
@@ -352,16 +344,18 @@ ugenclose(dev, flag, mode, p)
int mode;
struct proc *p;
{
- USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
+ struct ugen_softc *sc;
struct ugen_endpoint *sce;
int dir;
+ USB_GET_SC(ugen, UGENUNIT(dev), sc);
+
DPRINTFN(5, ("ugenclose: flag=%d, mode=%d, unit=%d, endpt=%d\n",
flag, mode, UGENUNIT(dev), endpt));
#ifdef DIAGNOSTIC
- if (!sc->sc_is_open[endpt][IN] || !sc->sc_is_open[endpt][OUT] ) {
+ if (!sc->sc_is_open[endpt]) {
printf("ugenclose: not open\n");
return (EINVAL);
}
@@ -369,7 +363,7 @@ ugenclose(dev, flag, mode, p)
if (endpt == USB_CONTROL_ENDPOINT) {
DPRINTFN(5, ("ugenclose: close control\n"));
- sc->sc_is_open[USB_CONTROL_ENDPOINT][IN] = 0;
+ sc->sc_is_open[endpt] = 0;
return (0);
}
@@ -377,31 +371,28 @@ ugenclose(dev, flag, mode, p)
if (!(flag & (dir == OUT ? FWRITE : FREAD)))
continue;
sce = &sc->sc_endpoints[endpt][dir];
- if (!sce || !sce->pipeh)
+ if (sce == NULL || sce->pipeh == NULL)
continue;
DPRINTFN(5, ("ugenclose: endpt=%d dir=%d sce=%p\n",
endpt, dir, sce));
usbd_abort_pipe(sce->pipeh);
usbd_close_pipe(sce->pipeh);
- sce->pipeh = 0;
+ sce->pipeh = NULL;
- if (sce->ibuf) {
+ if (sce->ibuf != NULL) {
free(sce->ibuf, M_USBDEV);
- sce->ibuf = 0;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
+ sce->ibuf = NULL;
clfree(&sce->q);
-#elif defined(__FreeBSD__)
- clist_free_cblocks(&sce->q);
-#endif
+
}
- sc->sc_is_open[endpt][dir] = 0;
}
+ sc->sc_is_open[endpt] = 0;
return (0);
}
-int
+static int
ugen_do_read(sc, endpt, uio, flag)
struct ugen_softc *sc;
int endpt;
@@ -411,8 +402,8 @@ ugen_do_read(sc, endpt, uio, flag)
struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN];
u_int32_t n, tn;
char buf[UGEN_BBSIZE];
- usbd_request_handle reqh;
- usbd_status r;
+ usbd_xfer_handle xfer;
+ usbd_status err;
int s;
int error = 0;
u_char buffer[UGEN_CHUNK];
@@ -420,15 +411,19 @@ ugen_do_read(sc, endpt, uio, flag)
#ifdef __NetBSD__
DPRINTFN(5, ("ugenread: %d:%d\n", sc->sc_dev.dv_unit, endpt));
#endif
+
if (sc->sc_dying)
return (EIO);
+ if (endpt == USB_CONTROL_ENDPOINT)
+ return (ENODEV);
+
#ifdef DIAGNOSTIC
- if (!sce->edesc) {
+ if (sce->edesc == NULL) {
printf("ugenread: no edesc\n");
return (EIO);
}
- if (!sce->pipeh) {
+ if (sce->pipeh == NULL) {
printf("ugenread: no pipe\n");
return (EIO);
}
@@ -473,21 +468,21 @@ ugen_do_read(sc, endpt, uio, flag)
}
break;
case UE_BULK:
- reqh = usbd_alloc_request(sc->sc_udev);
- if (reqh == 0)
+ xfer = usbd_alloc_request(sc->sc_udev);
+ if (xfer == 0)
return (ENOMEM);
while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
tn = n;
- r = usbd_bulk_transfer(
- reqh, sce->pipeh,
+ err = usbd_bulk_transfer(
+ xfer, sce->pipeh,
sce->state & UGEN_SHORT_OK ?
USBD_SHORT_XFER_OK : 0,
sce->timeout, buf, &tn, "ugenrb");
- if (r != USBD_NORMAL_COMPLETION) {
- if (r == USBD_INTERRUPTED)
+ if (err) {
+ if (err == USBD_INTERRUPTED)
error = EINTR;
- else if (r == USBD_TIMEOUT)
+ else if (err == USBD_TIMEOUT)
error = ETIMEDOUT;
else
error = EIO;
@@ -498,7 +493,7 @@ ugen_do_read(sc, endpt, uio, flag)
if (error || tn < n)
break;
}
- usbd_free_request(reqh);
+ usbd_free_request(xfer);
break;
default:
return (ENXIO);
@@ -512,10 +507,12 @@ ugenread(dev, uio, flag)
struct uio *uio;
int flag;
{
- USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
+ struct ugen_softc *sc;
int error;
+ USB_GET_SC(ugen, UGENUNIT(dev), sc);
+
sc->sc_refcnt++;
error = ugen_do_read(sc, endpt, uio, flag);
if (--sc->sc_refcnt < 0)
@@ -523,7 +520,7 @@ ugenread(dev, uio, flag)
return (error);
}
-int
+static int
ugen_do_write(sc, endpt, uio, flag)
struct ugen_softc *sc;
int endpt;
@@ -534,45 +531,49 @@ ugen_do_write(sc, endpt, uio, flag)
u_int32_t n;
int error = 0;
char buf[UGEN_BBSIZE];
- usbd_request_handle reqh;
- usbd_status r;
+ usbd_xfer_handle xfer;
+ usbd_status err;
+
+ DPRINTFN(5, ("%s: ugenwrite: %d\n", USBDEVNAME(sc->sc_dev), endpt));
if (sc->sc_dying)
return (EIO);
+ if (endpt == USB_CONTROL_ENDPOINT)
+ return (ENODEV);
+
#ifdef DIAGNOSTIC
- if (!sce->edesc) {
+ if (sce->edesc == NULL) {
printf("ugenwrite: no edesc\n");
return (EIO);
}
- if (!sce->pipeh) {
+ if (sce->pipeh == NULL) {
printf("ugenwrite: no pipe\n");
return (EIO);
}
#endif
- DPRINTF(("ugenwrite\n"));
switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
case UE_BULK:
- reqh = usbd_alloc_request(sc->sc_udev);
- if (reqh == 0)
+ xfer = usbd_alloc_request(sc->sc_udev);
+ if (xfer == 0)
return (EIO);
while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
error = uiomove(buf, n, uio);
if (error)
break;
DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n));
- r = usbd_bulk_transfer(reqh, sce->pipeh, 0,
- sce->timeout, buf, &n,"ugenwb");
- if (r != USBD_NORMAL_COMPLETION) {
- if (r == USBD_INTERRUPTED)
+ err = usbd_bulk_transfer(xfer, sce->pipeh, 0,
+ sce->timeout, buf, &n,"ugenwb");
+ if (err) {
+ if (err == USBD_INTERRUPTED)
error = EINTR;
else
error = EIO;
break;
}
}
- usbd_free_request(reqh);
+ usbd_free_request(xfer);
break;
default:
return (ENXIO);
@@ -586,10 +587,12 @@ ugenwrite(dev, uio, flag)
struct uio *uio;
int flag;
{
- USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
+ struct ugen_softc *sc;
int error;
+ USB_GET_SC(ugen, UGENUNIT(dev), sc);
+
sc->sc_refcnt++;
error = ugen_do_write(sc, endpt, uio, flag);
if (--sc->sc_refcnt < 0)
@@ -597,7 +600,6 @@ ugenwrite(dev, uio, flag)
return (error);
}
-
#if defined(__NetBSD__) || defined(__OpenBSD__)
int
ugen_activate(self, act)
@@ -669,9 +671,9 @@ USB_DETACH(ugen)
return (0);
}
-void
-ugenintr(reqh, addr, status)
- usbd_request_handle reqh;
+static void
+ugenintr(xfer, addr, status)
+ usbd_xfer_handle xfer;
usbd_private_handle addr;
usbd_status status;
{
@@ -689,11 +691,11 @@ ugenintr(reqh, addr, status)
return;
}
- usbd_get_request_status(reqh, 0, 0, &count, 0);
+ usbd_get_request_status(xfer, 0, 0, &count, 0);
ibuf = sce->ibuf;
- DPRINTFN(5, ("ugenintr: reqh=%p status=%d count=%d\n",
- reqh, status, count));
+ DPRINTFN(5, ("ugenintr: xfer=%p status=%d count=%d\n",
+ xfer, status, count));
DPRINTFN(5, (" data = %02x %02x %02x\n",
ibuf[0], ibuf[1], ibuf[2]));
@@ -707,32 +709,32 @@ ugenintr(reqh, addr, status)
selwakeup(&sce->rsel);
}
-usbd_status
+static usbd_status
ugen_set_interface(sc, ifaceidx, altno)
struct ugen_softc *sc;
int ifaceidx, altno;
{
usbd_interface_handle iface;
usb_endpoint_descriptor_t *ed;
- usbd_status r;
+ usbd_status err;
struct ugen_endpoint *sce;
u_int8_t niface, nendpt, endptno, endpt;
int dir;
DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno));
- r = usbd_interface_count(sc->sc_udev, &niface);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_interface_count(sc->sc_udev, &niface);
+ if (err)
+ return (err);
if (ifaceidx < 0 || ifaceidx >= niface)
return (USBD_INVAL);
- r = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- r = usbd_endpoint_count(iface, &nendpt);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
+ if (err)
+ return (err);
+ err = usbd_endpoint_count(iface, &nendpt);
+ if (err)
+ return (err);
for (endptno = 0; endptno < nendpt; endptno++) {
ed = usbd_interface2endpoint_descriptor(iface,endptno);
endpt = ed->bEndpointAddress;
@@ -744,13 +746,13 @@ ugen_set_interface(sc, ifaceidx, altno)
}
/* change setting */
- r = usbd_set_interface(iface, altno);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_set_interface(iface, altno);
+ if (err)
+ return (err);
- r = usbd_endpoint_count(iface, &nendpt);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_endpoint_count(iface, &nendpt);
+ if (err)
+ return (err);
for (endptno = 0; endptno < nendpt; endptno++) {
ed = usbd_interface2endpoint_descriptor(iface,endptno);
endpt = ed->bEndpointAddress;
@@ -764,7 +766,7 @@ ugen_set_interface(sc, ifaceidx, altno)
}
/* Retrieve a complete descriptor for a certain device and index. */
-usb_config_descriptor_t *
+static usb_config_descriptor_t *
ugen_get_cdesc(sc, index, lenp)
struct ugen_softc *sc;
int index;
@@ -772,7 +774,7 @@ ugen_get_cdesc(sc, index, lenp)
{
usb_config_descriptor_t *cdesc, *tdesc, cdescr;
int len;
- usbd_status r;
+ usbd_status err;
if (index == USB_CURRENT_CONFIG_INDEX) {
tdesc = usbd_get_config_descriptor(sc->sc_udev);
@@ -783,16 +785,16 @@ ugen_get_cdesc(sc, index, lenp)
memcpy(cdesc, tdesc, len);
DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len));
} else {
- r = usbd_get_config_desc(sc->sc_udev, index, &cdescr);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_get_config_desc(sc->sc_udev, index, &cdescr);
+ if (err)
return (0);
len = UGETW(cdescr.wTotalLength);
DPRINTFN(5,("ugen_get_cdesc: index=%d, len=%d\n", index, len));
if (lenp)
*lenp = len;
cdesc = malloc(len, M_TEMP, M_WAITOK);
- r = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len);
+ if (err) {
free(cdesc, M_TEMP);
return (0);
}
@@ -800,21 +802,21 @@ ugen_get_cdesc(sc, index, lenp)
return (cdesc);
}
-int
+static int
ugen_get_alt_index(sc, ifaceidx)
struct ugen_softc *sc;
int ifaceidx;
{
usbd_interface_handle iface;
- usbd_status r;
+ usbd_status err;
- r = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface);
+ if (err)
return (-1);
return (usbd_get_interface_altindex(iface));
}
-int
+static int
ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
struct ugen_softc *sc;
int endpt;
@@ -824,7 +826,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
struct proc *p;
{
struct ugen_endpoint *sce;
- usbd_status r;
+ usbd_status err;
usbd_interface_handle iface;
struct usb_config_desc *cd;
usb_config_descriptor_t *cdesc;
@@ -849,8 +851,10 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
if (endpt == USB_CONTROL_ENDPOINT)
return (EINVAL);
sce = &sc->sc_endpoints[endpt][IN];
+ if (sce == NULL)
+ return (EINVAL);
#ifdef DIAGNOSTIC
- if (!sce->pipeh) {
+ if (sce->pipeh == NULL) {
printf("ugenioctl: USB_SET_SHORT_XFER, no pipe\n");
return (EIO);
}
@@ -862,8 +866,10 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
return (0);
case USB_SET_TIMEOUT:
sce = &sc->sc_endpoints[endpt][IN];
+ if (sce == NULL)
+ return (EINVAL);
#ifdef DIAGNOSTIC
- if (!sce->pipeh) {
+ if (sce->pipeh == NULL) {
printf("ugenioctl: USB_SET_TIMEOUT, no pipe\n");
return (EIO);
}
@@ -884,26 +890,26 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
break;
#endif
case USB_GET_CONFIG:
- r = usbd_get_config(sc->sc_udev, &conf);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_get_config(sc->sc_udev, &conf);
+ if (err)
return (EIO);
*(int *)addr = conf;
break;
case USB_SET_CONFIG:
if (!(flag & FWRITE))
return (EPERM);
- r = ugen_set_config(sc, *(int *)addr);
- if (r != USBD_NORMAL_COMPLETION)
+ err = ugen_set_config(sc, *(int *)addr);
+ if (err)
return (EIO);
break;
case USB_GET_ALTINTERFACE:
ai = (struct usb_alt_interface *)addr;
- r = usbd_device2interface_handle(sc->sc_udev,
- ai->interface_index, &iface);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_device2interface_handle(sc->sc_udev,
+ ai->interface_index, &iface);
+ if (err)
return (EINVAL);
idesc = usbd_get_interface_descriptor(iface);
- if (!idesc)
+ if (idesc == NULL)
return (EIO);
ai->alt_no = idesc->bAlternateSetting;
break;
@@ -911,21 +917,21 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
if (!(flag & FWRITE))
return (EPERM);
ai = (struct usb_alt_interface *)addr;
- r = usbd_device2interface_handle(sc->sc_udev,
- ai->interface_index, &iface);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_device2interface_handle(sc->sc_udev,
+ ai->interface_index, &iface);
+ if (err)
return (EINVAL);
- r = ugen_set_interface(sc, ai->interface_index, ai->alt_no);
- if (r != USBD_NORMAL_COMPLETION)
+ err = ugen_set_interface(sc, ai->interface_index, ai->alt_no);
+ if (err)
return (EINVAL);
break;
case USB_GET_NO_ALT:
ai = (struct usb_alt_interface *)addr;
cdesc = ugen_get_cdesc(sc, ai->config_index, 0);
- if (!cdesc)
+ if (cdesc == NULL)
return (EINVAL);
idesc = usbd_find_idesc(cdesc, ai->interface_index, 0);
- if (!idesc) {
+ if (idesc == NULL) {
free(cdesc, M_TEMP);
return (EINVAL);
}
@@ -939,7 +945,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
case USB_GET_CONFIG_DESC:
cd = (struct usb_config_desc *)addr;
cdesc = ugen_get_cdesc(sc, cd->config_index, 0);
- if (!cdesc)
+ if (cdesc == NULL)
return (EINVAL);
cd->desc = *cdesc;
free(cdesc, M_TEMP);
@@ -947,7 +953,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
case USB_GET_INTERFACE_DESC:
id = (struct usb_interface_desc *)addr;
cdesc = ugen_get_cdesc(sc, id->config_index, 0);
- if (!cdesc)
+ if (cdesc == NULL)
return (EINVAL);
if (id->config_index == USB_CURRENT_CONFIG_INDEX &&
id->alt_index == USB_CURRENT_ALT_INDEX)
@@ -955,7 +961,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
else
alt = id->alt_index;
idesc = usbd_find_idesc(cdesc, id->interface_index, alt);
- if (!idesc) {
+ if (idesc == NULL) {
free(cdesc, M_TEMP);
return (EINVAL);
}
@@ -965,7 +971,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
case USB_GET_ENDPOINT_DESC:
ed = (struct usb_endpoint_desc *)addr;
cdesc = ugen_get_cdesc(sc, ed->config_index, 0);
- if (!cdesc)
+ if (cdesc == NULL)
return (EINVAL);
if (ed->config_index == USB_CURRENT_CONFIG_INDEX &&
ed->alt_index == USB_CURRENT_ALT_INDEX)
@@ -974,7 +980,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
alt = ed->alt_index;
edesc = usbd_find_edesc(cdesc, ed->interface_index,
alt, ed->endpoint_index);
- if (!edesc) {
+ if (edesc == NULL) {
free(cdesc, M_TEMP);
return (EINVAL);
}
@@ -1011,9 +1017,9 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
}
case USB_GET_STRING_DESC:
si = (struct usb_string_desc *)addr;
- r = usbd_get_string_desc(sc->sc_udev, si->string_index,
- si->language_id, &si->desc);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_get_string_desc(sc->sc_udev, si->string_index,
+ si->language_id, &si->desc);
+ if (err)
return (EINVAL);
break;
case USB_DO_REQUEST:
@@ -1023,7 +1029,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
struct iovec iov;
struct uio uio;
void *ptr = 0;
- usbd_status r;
+ usbd_status err;
int error = 0;
if (!(flag & FWRITE))
@@ -1058,9 +1064,9 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
goto ret;
}
}
- r = usbd_do_request_flags(sc->sc_udev, &ur->request,
- ptr, ur->flags, &ur->actlen);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_do_request_flags(sc->sc_udev, &ur->request,
+ ptr, ur->flags, &ur->actlen);
+ if (err) {
error = EIO;
goto ret;
}
@@ -1078,7 +1084,7 @@ ugen_do_ioctl(sc, endpt, cmd, addr, flag, p)
}
case USB_GET_DEVICEINFO:
usbd_fill_deviceinfo(sc->sc_udev,
- (struct usb_device_info *)addr);
+ (struct usb_device_info *)addr);
break;
default:
return (EINVAL);
@@ -1094,10 +1100,12 @@ ugenioctl(dev, cmd, addr, flag, p)
int flag;
struct proc *p;
{
- USB_GET_SC(ugen, UGENUNIT(dev), sc);
int endpt = UGENENDPOINT(dev);
+ struct ugen_softc *sc;
int error;
+ USB_GET_SC(ugen, UGENUNIT(dev), sc);
+
sc->sc_refcnt++;
error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, p);
if (--sc->sc_refcnt < 0)
@@ -1111,16 +1119,20 @@ ugenpoll(dev, events, p)
int events;
struct proc *p;
{
- USB_GET_SC(ugen, UGENUNIT(dev), sc);
+ struct ugen_softc *sc;
struct ugen_endpoint *sce;
int revents = 0;
int s;
+ USB_GET_SC(ugen, UGENUNIT(dev), sc);
+
if (sc->sc_dying)
return (EIO);
/* XXX always IN */
sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN];
+ if (sce == NULL)
+ return (EINVAL);
#ifdef DIAGNOSTIC
if (!sce->edesc) {
printf("ugenwrite: no edesc\n");
diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c
index ba8b15e..db8726a 100644
--- a/sys/dev/usb/uhci.c
+++ b/sys/dev/usb/uhci.c
@@ -1,4 +1,4 @@
-/* $NetBSD: uhci.c,v 1.49 1999/09/11 08:19:26 augustss Exp $ */
+/* $NetBSD: uhci.c,v 1.63 1999/11/12 00:34:57 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -58,13 +58,14 @@
#elif defined(__FreeBSD__)
#include <sys/module.h>
#include <sys/bus.h>
+#include <machine/bus_pio.h>
+#if defined(DIAGNOSTIC) && defined(__i386__)
+#include <machine/cpu.h>
+#endif
#endif
#include <sys/proc.h>
#include <sys/queue.h>
-#if defined(__FreeBSD__)
-#include <machine/bus_pio.h>
-#endif
#include <machine/bus.h>
#include <machine/endian.h>
@@ -83,6 +84,14 @@
#define delay(d) DELAY(d)
#endif
+#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
+
+#if defined(__OpenBSD__)
+struct cfdriver uhci_cd = {
+ NULL, "uhci", DV_DULL
+};
+#endif
+
#ifdef UHCI_DEBUG
#define DPRINTF(x) if (uhcidebug) printf x
#define DPRINTFN(n,x) if (uhcidebug>(n)) printf x
@@ -92,15 +101,6 @@ int uhcidebug = 0;
#define DPRINTFN(n,x)
#endif
-
-#define MS_TO_TICKS(ms) ((ms) * hz / 1000)
-
-#if defined(__OpenBSD__)
-struct cfdriver uhci_cd = {
- NULL, "uhci", DV_DULL
-};
-#endif
-
/*
* The UHCI controller is little endian, so on big endian machines
* the data strored in memory needs to be swapped.
@@ -149,104 +149,108 @@ struct uhci_pipe {
*/
LIST_HEAD(, uhci_intr_info) uhci_ii_free;
-void uhci_busreset __P((uhci_softc_t *));
-void uhci_power __P((int, void *));
-usbd_status uhci_run __P((uhci_softc_t *, int run));
-uhci_soft_td_t *uhci_alloc_std __P((uhci_softc_t *));
-void uhci_free_std __P((uhci_softc_t *, uhci_soft_td_t *));
-uhci_soft_qh_t *uhci_alloc_sqh __P((uhci_softc_t *));
-void uhci_free_sqh __P((uhci_softc_t *, uhci_soft_qh_t *));
-uhci_intr_info_t *uhci_alloc_intr_info __P((uhci_softc_t *));
-void uhci_free_intr_info __P((uhci_intr_info_t *ii));
+static void uhci_busreset __P((uhci_softc_t *));
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+static void uhci_power __P((int, void *));
+#endif
+static usbd_status uhci_run __P((uhci_softc_t *, int run));
+static uhci_soft_td_t *uhci_alloc_std __P((uhci_softc_t *));
+static void uhci_free_std __P((uhci_softc_t *, uhci_soft_td_t *));
+static uhci_soft_qh_t *uhci_alloc_sqh __P((uhci_softc_t *));
+static void uhci_free_sqh __P((uhci_softc_t *, uhci_soft_qh_t *));
+static uhci_intr_info_t *uhci_alloc_intr_info __P((uhci_softc_t *));
+static void uhci_free_intr_info __P((uhci_intr_info_t *ii));
#if 0
-void uhci_enter_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *,
- uhci_intr_info_t *));
-void uhci_exit_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *));
+static void uhci_enter_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *,
+ uhci_intr_info_t *));
+static void uhci_exit_ctl_q __P((uhci_softc_t *, uhci_soft_qh_t *));
#endif
-void uhci_free_std_chain __P((uhci_softc_t *,
- uhci_soft_td_t *, uhci_soft_td_t *));
-usbd_status uhci_alloc_std_chain __P((struct uhci_pipe *, uhci_softc_t *,
- int, int, int, usb_dma_t *,
- uhci_soft_td_t **,
- uhci_soft_td_t **));
-void uhci_timo __P((void *));
-void uhci_waitintr __P((uhci_softc_t *, usbd_request_handle));
-void uhci_check_intr __P((uhci_softc_t *, uhci_intr_info_t *));
-void uhci_idone __P((uhci_intr_info_t *));
-void uhci_abort_req __P((usbd_request_handle, usbd_status status));
-void uhci_abort_req_end __P((void *v));
-void uhci_timeout __P((void *));
-void uhci_wakeup_ctrl __P((void *, int, int, void *, int));
-void uhci_lock_frames __P((uhci_softc_t *));
-void uhci_unlock_frames __P((uhci_softc_t *));
-void uhci_add_ctrl __P((uhci_softc_t *, uhci_soft_qh_t *));
-void uhci_add_bulk __P((uhci_softc_t *, uhci_soft_qh_t *));
-void uhci_remove_ctrl __P((uhci_softc_t *, uhci_soft_qh_t *));
-void uhci_remove_bulk __P((uhci_softc_t *, uhci_soft_qh_t *));
-int uhci_str __P((usb_string_descriptor_t *, int, char *));
-usbd_status uhci_setup_isoc __P((usbd_pipe_handle pipe));
-void uhci_device_isoc_enter __P((usbd_request_handle));
-
-void uhci_wakeup_cb __P((usbd_request_handle reqh));
-
-usbd_status uhci_allocm __P((struct usbd_bus *, usb_dma_t *, u_int32_t));
-void uhci_freem __P((struct usbd_bus *, usb_dma_t *));
-
-usbd_status uhci_device_ctrl_transfer __P((usbd_request_handle));
-usbd_status uhci_device_ctrl_start __P((usbd_request_handle));
-void uhci_device_ctrl_abort __P((usbd_request_handle));
-void uhci_device_ctrl_close __P((usbd_pipe_handle));
-void uhci_device_ctrl_done __P((usbd_request_handle));
-
-usbd_status uhci_device_intr_transfer __P((usbd_request_handle));
-usbd_status uhci_device_intr_start __P((usbd_request_handle));
-void uhci_device_intr_abort __P((usbd_request_handle));
-void uhci_device_intr_close __P((usbd_pipe_handle));
-void uhci_device_intr_done __P((usbd_request_handle));
-
-usbd_status uhci_device_bulk_transfer __P((usbd_request_handle));
-usbd_status uhci_device_bulk_start __P((usbd_request_handle));
-void uhci_device_bulk_abort __P((usbd_request_handle));
-void uhci_device_bulk_close __P((usbd_pipe_handle));
-void uhci_device_bulk_done __P((usbd_request_handle));
-
-usbd_status uhci_device_isoc_transfer __P((usbd_request_handle));
-usbd_status uhci_device_isoc_start __P((usbd_request_handle));
-void uhci_device_isoc_abort __P((usbd_request_handle));
-void uhci_device_isoc_close __P((usbd_pipe_handle));
-void uhci_device_isoc_done __P((usbd_request_handle));
-
-usbd_status uhci_root_ctrl_transfer __P((usbd_request_handle));
-usbd_status uhci_root_ctrl_start __P((usbd_request_handle));
-void uhci_root_ctrl_abort __P((usbd_request_handle));
-void uhci_root_ctrl_close __P((usbd_pipe_handle));
-
-usbd_status uhci_root_intr_transfer __P((usbd_request_handle));
-usbd_status uhci_root_intr_start __P((usbd_request_handle));
-void uhci_root_intr_abort __P((usbd_request_handle));
-void uhci_root_intr_close __P((usbd_pipe_handle));
-void uhci_root_intr_done __P((usbd_request_handle));
-
-usbd_status uhci_open __P((usbd_pipe_handle));
-void uhci_poll __P((struct usbd_bus *));
-
-usbd_status uhci_device_request __P((usbd_request_handle reqh));
-
-void uhci_add_intr __P((uhci_softc_t *, int, uhci_soft_qh_t *));
-void uhci_remove_intr __P((uhci_softc_t *, int, uhci_soft_qh_t *));
-usbd_status uhci_device_setintr __P((uhci_softc_t *sc,
- struct uhci_pipe *pipe, int ival));
-
-void uhci_device_clear_toggle __P((usbd_pipe_handle pipe));
-void uhci_noop __P((usbd_pipe_handle pipe));
+static void uhci_free_std_chain __P((uhci_softc_t *,
+ uhci_soft_td_t *, uhci_soft_td_t *));
+static usbd_status uhci_alloc_std_chain __P((struct uhci_pipe *,
+ uhci_softc_t *, int, int, int, usb_dma_t *,
+ uhci_soft_td_t **, uhci_soft_td_t **));
+static void uhci_timo __P((void *));
+static void uhci_waitintr __P((uhci_softc_t *,
+ usbd_xfer_handle));
+static void uhci_check_intr __P((uhci_softc_t *,
+ uhci_intr_info_t *));
+static void uhci_idone __P((uhci_intr_info_t *));
+static void uhci_abort_req __P((usbd_xfer_handle,
+ usbd_status status));
+static void uhci_abort_req_end __P((void *v));
+static void uhci_timeout __P((void *));
+static void uhci_lock_frames __P((uhci_softc_t *));
+static void uhci_unlock_frames __P((uhci_softc_t *));
+static void uhci_add_ctrl __P((uhci_softc_t *, uhci_soft_qh_t *));
+static void uhci_add_bulk __P((uhci_softc_t *, uhci_soft_qh_t *));
+static void uhci_remove_ctrl __P((uhci_softc_t *,uhci_soft_qh_t *));
+static void uhci_remove_bulk __P((uhci_softc_t *,uhci_soft_qh_t *));
+static int uhci_str __P((usb_string_descriptor_t *, int, char *));
+static usbd_status uhci_setup_isoc __P((usbd_pipe_handle pipe));
+static void uhci_device_isoc_enter __P((usbd_xfer_handle));
+
+static usbd_status uhci_allocm __P((struct usbd_bus *, usb_dma_t *,
+ u_int32_t));
+static void uhci_freem __P((struct usbd_bus *, usb_dma_t *));
+
+static usbd_status uhci_device_ctrl_transfer __P((usbd_xfer_handle));
+static usbd_status uhci_device_ctrl_start __P((usbd_xfer_handle));
+static void uhci_device_ctrl_abort __P((usbd_xfer_handle));
+static void uhci_device_ctrl_close __P((usbd_pipe_handle));
+static void uhci_device_ctrl_done __P((usbd_xfer_handle));
+
+static usbd_status uhci_device_intr_transfer __P((usbd_xfer_handle));
+static usbd_status uhci_device_intr_start __P((usbd_xfer_handle));
+static void uhci_device_intr_abort __P((usbd_xfer_handle));
+static void uhci_device_intr_close __P((usbd_pipe_handle));
+static void uhci_device_intr_done __P((usbd_xfer_handle));
+
+static usbd_status uhci_device_bulk_transfer __P((usbd_xfer_handle));
+static usbd_status uhci_device_bulk_start __P((usbd_xfer_handle));
+static void uhci_device_bulk_abort __P((usbd_xfer_handle));
+static void uhci_device_bulk_close __P((usbd_pipe_handle));
+static void uhci_device_bulk_done __P((usbd_xfer_handle));
+
+static usbd_status uhci_device_isoc_transfer __P((usbd_xfer_handle));
+static usbd_status uhci_device_isoc_start __P((usbd_xfer_handle));
+static void uhci_device_isoc_abort __P((usbd_xfer_handle));
+static void uhci_device_isoc_close __P((usbd_pipe_handle));
+static void uhci_device_isoc_done __P((usbd_xfer_handle));
+
+static usbd_status uhci_root_ctrl_transfer __P((usbd_xfer_handle));
+static usbd_status uhci_root_ctrl_start __P((usbd_xfer_handle));
+static void uhci_root_ctrl_abort __P((usbd_xfer_handle));
+static void uhci_root_ctrl_close __P((usbd_pipe_handle));
+
+static usbd_status uhci_root_intr_transfer __P((usbd_xfer_handle));
+static usbd_status uhci_root_intr_start __P((usbd_xfer_handle));
+static void uhci_root_intr_abort __P((usbd_xfer_handle));
+static void uhci_root_intr_close __P((usbd_pipe_handle));
+static void uhci_root_intr_done __P((usbd_xfer_handle));
+
+static usbd_status uhci_open __P((usbd_pipe_handle));
+static void uhci_poll __P((struct usbd_bus *));
+
+static usbd_status uhci_device_request __P((usbd_xfer_handle xfer));
+
+static void uhci_add_intr __P((uhci_softc_t *, int,
+ uhci_soft_qh_t *));
+static void uhci_remove_intr __P((uhci_softc_t *, int,
+ uhci_soft_qh_t *));
+static usbd_status uhci_device_setintr __P((uhci_softc_t *sc,
+ struct uhci_pipe *pipe, int ival));
+
+static void uhci_device_clear_toggle __P((usbd_pipe_handle pipe));
+static void uhci_noop __P((usbd_pipe_handle pipe));
#ifdef UHCI_DEBUG
-static void uhci_dumpregs __P((uhci_softc_t *));
-void uhci_dump_tds __P((uhci_soft_td_t *));
-void uhci_dump_qh __P((uhci_soft_qh_t *));
-void uhci_dump __P((void));
-void uhci_dump_td __P((uhci_soft_td_t *));
+static void uhci_dumpregs __P((uhci_softc_t *));
+static void uhci_dump_qhs __P((uhci_soft_qh_t *));
+static void uhci_dump_qh __P((uhci_soft_qh_t *));
+static void uhci_dump_tds __P((uhci_soft_td_t *));
+static void uhci_dump_td __P((uhci_soft_td_t *));
#endif
#define UWRITE2(sc, r, x) bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x))
@@ -338,7 +342,7 @@ usbd_status
uhci_init(sc)
uhci_softc_t *sc;
{
- usbd_status r;
+ usbd_status err;
int i, j;
uhci_soft_qh_t *csqh, *bsqh, *sqh;
uhci_soft_td_t *std;
@@ -356,18 +360,18 @@ uhci_init(sc)
uhci_busreset(sc);
/* Allocate and initialize real frame array. */
- r = usb_allocmem(sc->sc_dmatag,
- UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t),
- UHCI_FRAMELIST_ALIGN, &sc->sc_dma);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usb_allocmem(&sc->sc_bus,
+ UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t),
+ UHCI_FRAMELIST_ALIGN, &sc->sc_dma);
+ if (err)
+ return (err);
sc->sc_pframes = KERNADDR(&sc->sc_dma);
UWRITE2(sc, UHCI_FRNUM, 0); /* set frame number to 0 */
UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma)); /* set frame list*/
/* Allocate the dummy QH where bulk traffic will be queued. */
bsqh = uhci_alloc_sqh(sc);
- if (!bsqh)
+ if (bsqh == NULL)
return (USBD_NOMEM);
bsqh->qh.qh_hlink = LE(UHCI_PTR_T); /* end of QH chain */
bsqh->qh.qh_elink = LE(UHCI_PTR_T);
@@ -375,7 +379,7 @@ uhci_init(sc)
/* Allocate the dummy QH where control traffic will be queued. */
csqh = uhci_alloc_sqh(sc);
- if (!csqh)
+ if (csqh == NULL)
return (USBD_NOMEM);
csqh->hlink = bsqh;
csqh->qh.qh_hlink = LE(bsqh->physaddr | UHCI_PTR_Q);
@@ -390,7 +394,7 @@ uhci_init(sc)
for(i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
std = uhci_alloc_std(sc);
sqh = uhci_alloc_sqh(sc);
- if (!std || !sqh)
+ if (std == NULL || sqh == NULL)
return (USBD_NOMEM);
std->link.sqh = sqh;
std->td.td_link = LE(sqh->physaddr | UHCI_PTR_Q);
@@ -417,10 +421,8 @@ uhci_init(sc)
sc->sc_bus.methods = &uhci_bus_methods;
sc->sc_bus.pipe_size = sizeof(struct uhci_pipe);
-#if defined(__NetBSD__)
sc->sc_suspend = PWR_RESUME;
- powerhook_establish(uhci_power, sc);
-#endif
+ sc->sc_powerhook = powerhook_establish(uhci_power, sc);
DPRINTFN(1,("uhci_init: enabling\n"));
UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE |
@@ -429,17 +431,56 @@ uhci_init(sc)
return (uhci_run(sc, 1)); /* and here we go... */
}
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+int
+uhci_activate(self, act)
+ device_ptr_t self;
+ enum devact act;
+{
+ struct uhci_softc *sc = (struct uhci_softc *)self;
+ int rv = 0;
+
+ switch (act) {
+ case DVACT_ACTIVATE:
+ return (EOPNOTSUPP);
+ break;
+
+ case DVACT_DEACTIVATE:
+ if (sc->sc_child != NULL)
+ rv = config_deactivate(sc->sc_child);
+ break;
+ }
+ return (rv);
+}
+
+int
+uhci_detach(sc, flags)
+ struct uhci_softc *sc;
+ int flags;
+{
+ int rv = 0;
+
+ if (sc->sc_child != NULL)
+ rv = config_detach(sc->sc_child, flags);
+
+ if (rv != 0)
+ return (rv);
+
+ powerhook_disestablish(sc->sc_powerhook);
+ /* free data structures XXX */
+
+ return (rv);
+}
+#endif
+
usbd_status
uhci_allocm(bus, dma, size)
struct usbd_bus *bus;
usb_dma_t *dma;
u_int32_t size;
{
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- struct uhci_softc *sc = (struct uhci_softc *)bus;
-#endif
-
- return (usb_allocmem(sc->sc_dmatag, size, 0, dma));
+ return (usb_allocmem(&((struct uhci_softc *)bus)->sc_bus, size, 0,
+ dma));
}
void
@@ -447,11 +488,7 @@ uhci_freem(bus, dma)
struct usbd_bus *bus;
usb_dma_t *dma;
{
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- struct uhci_softc *sc = (struct uhci_softc *)bus;
-#endif
-
- usb_freemem(sc->sc_dmatag, dma);
+ usb_freemem(&((struct uhci_softc *)bus)->sc_bus, dma);
}
#if defined(__NetBSD__)
@@ -485,11 +522,12 @@ uhci_power(why, v)
if (sc->sc_has_timo)
usb_untimeout(uhci_timo, sc->sc_has_timo,
sc->sc_has_timo->timo_handle);
- sc->sc_bus.use_polling = 1;
+ sc->sc_bus.use_polling++;
uhci_run(sc, 0); /* stop the controller */
UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter global suspend */
usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT);
sc->sc_suspend = why;
+ sc->sc_bus.use_polling--;
DPRINTF(("uhci_power: cmd=0x%x\n", UREAD2(sc, UHCI_CMD)));
} else {
/*
@@ -497,6 +535,11 @@ uhci_power(why, v)
* controller registers have been lost and BIOS has
* not restored them.
*/
+#ifdef DIAGNOSTIC
+ if (sc->sc_suspend == PWR_RESUME)
+ printf("uhci_power: weird, resume without suspend.\n");
+#endif
+ sc->sc_bus.use_polling++;
sc->sc_suspend = why;
if (cmd & UHCI_CMD_RS)
uhci_run(sc, 0); /* in case BIOS has started it */
@@ -507,7 +550,7 @@ uhci_power(why, v)
UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* re-enable intrs */
uhci_run(sc, 1); /* and start traffic again */
usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY);
- sc->sc_bus.use_polling = 0;
+ sc->sc_bus.use_polling--;
if (sc->sc_has_timo)
usb_timeout(uhci_timo, sc->sc_has_timo,
sc->sc_ival, sc->sc_has_timo->timo_handle);
@@ -518,7 +561,7 @@ uhci_power(why, v)
}
splx(s);
}
-#endif /* !defined(__OpenBSD__) */
+#endif /* defined(__NetBSD__) */
#ifdef UHCI_DEBUG
static void
@@ -566,11 +609,11 @@ uhci_dump_td(p)
}
void
-uhci_dump_qh(p)
- uhci_soft_qh_t *p;
+uhci_dump_qh(sqh)
+ uhci_soft_qh_t *sqh;
{
- DPRINTFN(-1,("QH(%p) at %08x: hlink=%08x elink=%08x\n", p,
- (int)p->physaddr, LE(p->qh.qh_hlink), LE(p->qh.qh_elink)));
+ DPRINTFN(-1,("QH(%p) at %08x: hlink=%08x elink=%08x\n", sqh,
+ (int)sqh->physaddr, LE(sqh->qh.qh_hlink), LE(sqh->qh.qh_elink)));
}
@@ -581,20 +624,63 @@ uhci_dump()
uhci_softc_t *sc = uhci;
uhci_dumpregs(sc);
- printf("intrs=%d\n", sc->sc_intrs);
+ printf("intrs=%d\n", sc->sc_bus.no_intrs);
printf("framelist[i].link = %08x\n", sc->sc_framelist[0].link);
uhci_dump_qh(sc->sc_ctl_start->qh.hlink);
}
#endif
+
+void
+uhci_dump_qhs(sqh)
+ uhci_soft_qh_t *sqh;
+{
+ uhci_dump_qh(sqh);
+
+ /* uhci_dump_qhs displays all the QHs and TDs from the given QH onwards
+ * Traverses sideways first, then down.
+ *
+ * QH1
+ * QH2
+ * No QH
+ * TD2.1
+ * TD2.2
+ * TD1.1
+ * etc.
+ *
+ * TD2.x being the TDs queued at QH2 and QH1 being referenced from QH1.
+ */
+
+
+ if (sqh->hlink != NULL && !(sqh->qh.qh_hlink & UHCI_PTR_T))
+ uhci_dump_qhs(sqh->hlink);
+ else
+ DPRINTF(("No QH\n"));
+
+ if (sqh->elink != NULL && !(sqh->qh.qh_elink & UHCI_PTR_T))
+ uhci_dump_tds(sqh->elink);
+ else
+ DPRINTF(("No TD\n"));
+}
+
void
uhci_dump_tds(std)
uhci_soft_td_t *std;
{
- uhci_soft_td_t *p;
+ uhci_soft_td_t *td;
+
+ for(td = std; td != NULL; td = td->link.std) {
+ uhci_dump_td(td);
- for(p = std; p; p = p->link.std)
- uhci_dump_td(p);
+ /* Check whether the link pointer in this TD marks
+ * the link pointer as end of queue. This avoids
+ * printing the free list in case the queue/TD has
+ * already been moved there (seatbelt).
+ */
+ if (td->td.td_link & UHCI_PTR_T ||
+ td->td.td_link == 0)
+ break;
+ }
}
#endif
@@ -606,17 +692,17 @@ void
uhci_timo(addr)
void *addr;
{
- usbd_request_handle reqh = addr;
- usbd_pipe_handle pipe = reqh->pipe;
+ usbd_xfer_handle xfer = addr;
+ usbd_pipe_handle pipe = xfer->pipe;
uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
int s;
u_char *p;
- DPRINTFN(15, ("uhci_timo\n"));
+ DPRINTFN(20, ("uhci_timo\n"));
- usb_timeout(uhci_timo, reqh, sc->sc_ival, reqh->timo_handle);
+ usb_timeout(uhci_timo, xfer, sc->sc_ival, xfer->timo_handle);
- p = KERNADDR(&reqh->dmabuf);
+ p = KERNADDR(&xfer->dmabuf);
p[0] = 0;
if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC))
p[0] |= 1<<1;
@@ -626,17 +712,19 @@ uhci_timo(addr)
/* No change, try again in a while */
return;
- reqh->actlen = 1;
- reqh->status = USBD_NORMAL_COMPLETION;
+ xfer->actlen = 1;
+ xfer->status = USBD_NORMAL_COMPLETION;
s = splusb();
- reqh->hcpriv = 0;
- usb_transfer_complete(reqh);
+ xfer->hcpriv = 0;
+ xfer->device->bus->intr_context++;
+ usb_transfer_complete(xfer);
+ xfer->device->bus->intr_context--;
splx(s);
}
void
-uhci_root_intr_done(reqh)
- usbd_request_handle reqh;
+uhci_root_intr_done(xfer)
+ usbd_xfer_handle xfer;
{
}
@@ -646,6 +734,7 @@ uhci_lock_frames(sc)
uhci_softc_t *sc;
{
int s = splusb();
+
while (sc->sc_vflock) {
sc->sc_vflock |= UHCI_WANT_LOCK;
tsleep(&sc->sc_vflock, PRIBIO, "uhcqhl", 0);
@@ -659,6 +748,7 @@ uhci_unlock_frames(sc)
uhci_softc_t *sc;
{
int s = splusb();
+
sc->sc_vflock &= ~UHCI_HAS_LOCK;
if (sc->sc_vflock & UHCI_WANT_LOCK)
wakeup(&sc->sc_vflock);
@@ -704,6 +794,8 @@ uhci_add_ctrl(sc, sqh)
{
uhci_soft_qh_t *eqh;
+ SPLUSBCHECK;
+
DPRINTFN(10, ("uhci_add_ctrl: sqh=%p\n", sqh));
eqh = sc->sc_ctl_end;
sqh->hlink = eqh->hlink;
@@ -721,6 +813,8 @@ uhci_remove_ctrl(sc, sqh)
{
uhci_soft_qh_t *pqh;
+ SPLUSBCHECK;
+
DPRINTFN(10, ("uhci_remove_ctrl: sqh=%p\n", sqh));
for (pqh = sc->sc_ctl_start; pqh->hlink != sqh; pqh=pqh->hlink)
#if defined(DIAGNOSTIC) || defined(UHCI_DEBUG)
@@ -745,6 +839,8 @@ uhci_add_bulk(sc, sqh)
{
uhci_soft_qh_t *eqh;
+ SPLUSBCHECK;
+
DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh));
eqh = sc->sc_bulk_end;
sqh->hlink = eqh->hlink;
@@ -762,6 +858,8 @@ uhci_remove_bulk(sc, sqh)
{
uhci_soft_qh_t *pqh;
+ SPLUSBCHECK;
+
DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh));
for (pqh = sc->sc_bulk_start; pqh->hlink != sqh; pqh = pqh->hlink)
#if defined(DIAGNOSTIC) || defined(UHCI_DEBUG)
@@ -787,8 +885,6 @@ uhci_intr(arg)
int ack;
uhci_intr_info_t *ii;
- sc->sc_intrs++;
-
#ifdef UHCI_DEBUG
if (uhcidebug > 15) {
DPRINTF(("%s: uhci_intr\n", USBDEVNAME(sc->sc_bus.bdev)));
@@ -796,12 +892,15 @@ uhci_intr(arg)
}
#endif
+ status = UREAD2(sc, UHCI_STS);
+ 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
- status = UREAD2(sc, UHCI_STS);
ack = 0;
if (status & UHCI_STS_USBINT)
ack |= UHCI_STS_USBINT;
@@ -831,6 +930,9 @@ uhci_intr(arg)
else /* nothing to acknowledge */
return (0);
+ sc->sc_bus.intr_context++;
+ sc->sc_bus.no_intrs++;
+
/*
* Interrupts on UHCI really suck. When the host controller
* interrupts because a transfer is completed there is no
@@ -845,7 +947,9 @@ uhci_intr(arg)
for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = LIST_NEXT(ii, list))
uhci_check_intr(sc, ii);
- DPRINTFN(10, ("uhci_intr: exit\n"));
+ DPRINTFN(10, ("%s: uhci_intr: exit\n", USBDEVNAME(sc->sc_bus.bdev)));
+
+ sc->sc_bus.intr_context--;
return (1);
}
@@ -861,16 +965,16 @@ uhci_check_intr(sc, ii)
DPRINTFN(15, ("uhci_check_intr: ii=%p\n", ii));
#ifdef DIAGNOSTIC
- if (!ii) {
+ if (ii == NULL) {
printf("uhci_check_intr: no ii? %p\n", ii);
return;
}
#endif
- if (!ii->stdstart)
+ if (ii->stdstart == NULL)
return;
lstd = ii->stdend;
#ifdef DIAGNOSTIC
- if (!lstd) {
+ if (lstd == NULL) {
printf("uhci_check_intr: std==0\n");
return;
}
@@ -898,14 +1002,15 @@ uhci_check_intr(sc, ii)
uhci_idone(ii);
}
+/* Called at splusb() */
void
uhci_idone(ii)
uhci_intr_info_t *ii;
{
- usbd_request_handle reqh = ii->reqh;
- struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
+ usbd_xfer_handle xfer = ii->xfer;
+ struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
uhci_soft_td_t *std;
- u_int32_t status = 0;
+ u_int32_t status = 0, nstatus;
int actlen;
#ifdef DIAGNOSTIC
@@ -921,22 +1026,22 @@ uhci_idone(ii)
}
#endif
- if (reqh->status == USBD_CANCELLED ||
- reqh->status == USBD_TIMEOUT) {
- DPRINTF(("uhci_idone: aborted reqh=%p\n", reqh));
+ if (xfer->status == USBD_CANCELLED ||
+ xfer->status == USBD_TIMEOUT) {
+ DPRINTF(("uhci_idone: aborted xfer=%p\n", xfer));
return;
}
- if (reqh->nframes) {
+ if (xfer->nframes != 0) {
/* Isoc transfer, do things differently. */
uhci_soft_td_t **stds = upipe->u.iso.stds;
int i, n, nframes;
DPRINTFN(5,("uhci_idone: ii=%p isoc ready\n", ii));
- nframes = reqh->nframes;
+ nframes = xfer->nframes;
actlen = 0;
- n = reqh->hcprivint;
+ n = xfer->hcprivint;
for (i = 0; i < nframes; i++) {
std = stds[n];
#ifdef UHCI_DEBUG
@@ -951,10 +1056,10 @@ uhci_idone(ii)
actlen += UHCI_TD_GET_ACTLEN(status);
}
upipe->u.iso.inuse -= nframes;
- reqh->actlen = actlen;
- reqh->status = USBD_NORMAL_COMPLETION;
- reqh->hcpriv = ii;
- usb_transfer_complete(reqh);
+ xfer->actlen = actlen;
+ xfer->status = USBD_NORMAL_COMPLETION;
+ xfer->hcpriv = ii;
+ usb_transfer_complete(xfer);
return;
}
@@ -965,43 +1070,42 @@ uhci_idone(ii)
#endif
/* The transfer is done, compute actual length and status. */
- /* XXX Is this correct for control xfers? */
actlen = 0;
- status = 0;
- for (std = ii->stdstart; std; std = std->link.std) {
- if (LE(std->td.td_status) & UHCI_TD_ACTIVE)
+ for (std = ii->stdstart; std != NULL; std = std->link.std) {
+ nstatus = LE(std->td.td_status);
+ if (nstatus & UHCI_TD_ACTIVE)
break;
- status = LE(std->td.td_status);
+ status = nstatus;
if (UHCI_TD_GET_PID(LE(std->td.td_token)) != UHCI_TD_PID_SETUP)
actlen += UHCI_TD_GET_ACTLEN(status);
}
/* If there are left over TDs we need to update the toggle. */
- if (std)
+ if (std != NULL)
upipe->nexttoggle = UHCI_TD_GET_DT(LE(std->td.td_token));
status &= UHCI_TD_ERROR;
DPRINTFN(10, ("uhci_check_intr: actlen=%d, status=0x%x\n",
actlen, status));
- reqh->actlen = actlen;
+ xfer->actlen = actlen;
if (status != 0) {
DPRINTFN((status&UHCI_TD_STALLED)*10,
("uhci_idone: error, addr=%d, endpt=0x%02x, "
"status 0x%b\n",
- reqh->pipe->device->address,
- reqh->pipe->endpoint->edesc->bEndpointAddress,
+ xfer->pipe->device->address,
+ xfer->pipe->endpoint->edesc->bEndpointAddress,
(int)status,
"\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27"
"STALLED\30ACTIVE"));
if (status == UHCI_TD_STALLED)
- reqh->status = USBD_STALLED;
+ xfer->status = USBD_STALLED;
else
- reqh->status = USBD_IOERROR; /* more info XXX */
+ xfer->status = USBD_IOERROR; /* more info XXX */
} else {
- reqh->status = USBD_NORMAL_COMPLETION;
+ xfer->status = USBD_NORMAL_COMPLETION;
}
- reqh->hcpriv = ii;
- usb_transfer_complete(reqh);
+ xfer->hcpriv = ii;
+ usb_transfer_complete(xfer);
}
/*
@@ -1014,7 +1118,15 @@ uhci_timeout(addr)
uhci_intr_info_t *ii = addr;
DPRINTF(("uhci_timeout: ii=%p\n", ii));
- uhci_abort_req(ii->reqh, USBD_TIMEOUT);
+
+#ifdef UHCI_DEBUG
+ if (uhcidebug > 10)
+ uhci_dump_tds(ii->stdstart);
+#endif
+
+ ii->xfer->device->bus->intr_context++;
+ uhci_abort_req(ii->xfer, USBD_TIMEOUT);
+ ii->xfer->device->bus->intr_context--;
}
/*
@@ -1024,22 +1136,22 @@ uhci_timeout(addr)
* Only used during boot when interrupts are not enabled yet.
*/
void
-uhci_waitintr(sc, reqh)
+uhci_waitintr(sc, xfer)
uhci_softc_t *sc;
- usbd_request_handle reqh;
+ usbd_xfer_handle xfer;
{
- int timo = reqh->timeout;
+ int timo = xfer->timeout;
uhci_intr_info_t *ii;
DPRINTFN(10,("uhci_waitintr: timeout = %dms\n", timo));
- reqh->status = USBD_IN_PROGRESS;
+ xfer->status = USBD_IN_PROGRESS;
for (; timo >= 0; timo--) {
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);
- if (reqh->status != USBD_IN_PROGRESS)
+ if (xfer->status != USBD_IN_PROGRESS)
return;
}
}
@@ -1047,11 +1159,11 @@ uhci_waitintr(sc, reqh)
/* Timeout */
DPRINTF(("uhci_waitintr: timeout\n"));
for (ii = LIST_FIRST(&sc->sc_intrhead);
- ii && ii->reqh != reqh;
+ ii != NULL && ii->xfer != xfer;
ii = LIST_NEXT(ii, list))
;
#ifdef DIAGNOSTIC
- if (!ii)
+ if (ii == NULL)
panic("uhci_waitintr: lost intr_info\n");
#endif
uhci_idone(ii);
@@ -1129,19 +1241,19 @@ uhci_alloc_std(sc)
uhci_softc_t *sc;
{
uhci_soft_td_t *std;
- usbd_status r;
+ usbd_status err;
int i, offs;
usb_dma_t dma;
- if (!sc->sc_freetds) {
+ if (sc->sc_freetds == NULL) {
DPRINTFN(2,("uhci_alloc_std: allocating chunk\n"));
- r = usb_allocmem(sc->sc_dmatag, UHCI_STD_SIZE * UHCI_STD_CHUNK,
- UHCI_TD_ALIGN, &dma);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usb_allocmem(&sc->sc_bus, UHCI_STD_SIZE * UHCI_STD_CHUNK,
+ UHCI_TD_ALIGN, &dma);
+ if (err)
return (0);
for(i = 0; i < UHCI_STD_CHUNK; i++) {
offs = i * UHCI_STD_SIZE;
- std = (uhci_soft_td_t *)((char *)KERNADDR(&dma) +offs);
+ std = (uhci_soft_td_t *)((char *)KERNADDR(&dma) + offs);
std->physaddr = DMAADDR(&dma) + offs;
std->link.std = sc->sc_freetds;
sc->sc_freetds = std;
@@ -1160,7 +1272,7 @@ uhci_free_std(sc, std)
{
#ifdef DIAGNOSTIC
#define TD_IS_FREE 0x12345678
- if (LE(std->td.td_token) == TD_IS_FREE) {
+ if (std->td.td_token == LE(TD_IS_FREE)) {
printf("uhci_free_std: freeing free TD %p\n", std);
return;
}
@@ -1175,16 +1287,16 @@ uhci_alloc_sqh(sc)
uhci_softc_t *sc;
{
uhci_soft_qh_t *sqh;
- usbd_status r;
+ usbd_status err;
int i, offs;
usb_dma_t dma;
- if (!sc->sc_freeqhs) {
+ if (sc->sc_freeqhs == NULL) {
DPRINTFN(2, ("uhci_alloc_sqh: allocating chunk\n"));
- r = usb_allocmem(sc->sc_dmatag, UHCI_SQH_SIZE * UHCI_SQH_CHUNK,
- UHCI_QH_ALIGN, &dma);
- if (r != USBD_NORMAL_COMPLETION)
- return 0;
+ err = usb_allocmem(&sc->sc_bus, UHCI_SQH_SIZE * UHCI_SQH_CHUNK,
+ UHCI_QH_ALIGN, &dma);
+ if (err)
+ return (0);
for(i = 0; i < UHCI_SQH_CHUNK; i++) {
offs = i * UHCI_SQH_SIZE;
sqh = (uhci_soft_qh_t *)((char *)KERNADDR(&dma) +offs);
@@ -1282,20 +1394,12 @@ uhci_alloc_std_chain(upipe, sc, len, rd, shortok, dma, sp, ep)
status |= UHCI_TD_SPD;
for (i = ntd; i >= 0; i--) {
p = uhci_alloc_std(sc);
- if (!p) {
+ if (p == NULL) {
uhci_free_std_chain(sc, lastp, 0);
return (USBD_NOMEM);
}
p->link.std = lastp;
- /* The if statement might be necessary to avoid confusing the
- * VIA chipset. It doesn't like extra bits when UHCI_PTR_T
- * is set.
- */
- if (lastlink != UHCI_PTR_T)
- p->td.td_link = LE(lastlink|UHCI_PTR_VF);
- else
- p->td.td_link = LE(lastlink);
-
+ p->td.td_link = LE(lastlink);
lastp = p;
lastlink = p->physaddr;
p->td.td_status = LE(status);
@@ -1333,66 +1437,70 @@ uhci_noop(pipe)
}
usbd_status
-uhci_device_bulk_transfer(reqh)
- usbd_request_handle reqh;
+uhci_device_bulk_transfer(xfer)
+ usbd_xfer_handle xfer;
{
- usbd_status r;
+ usbd_status err;
- r = usb_insert_transfer(reqh);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- else
- return (uhci_device_bulk_start(reqh));
+ /* Insert last in queue. */
+ err = usb_insert_transfer(xfer);
+ if (err)
+ return (err);
+
+ /* Pipe isn't running (otherwise err would be USBD_INPROG),
+ * start first
+ */
+ return (uhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
}
usbd_status
-uhci_device_bulk_start(reqh)
- usbd_request_handle reqh;
+uhci_device_bulk_start(xfer)
+ usbd_xfer_handle xfer;
{
- struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
+ struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
usbd_device_handle dev = upipe->pipe.device;
uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
uhci_intr_info_t *ii = upipe->iinfo;
- uhci_soft_td_t *xfer, *xferend;
+ uhci_soft_td_t *data, *dataend;
uhci_soft_qh_t *sqh;
- usbd_status r;
+ usbd_status err;
int len, isread, endpt;
int s;
- DPRINTFN(3, ("uhci_device_bulk_transfer: reqh=%p len=%d flags=%d\n",
- reqh, reqh->length, reqh->flags));
+ DPRINTFN(3, ("uhci_device_bulk_transfer: xfer=%p len=%d flags=%d\n",
+ xfer, xfer->length, xfer->flags));
#ifdef DIAGNOSTIC
- if (reqh->rqflags & URQ_REQUEST)
+ if (xfer->rqflags & URQ_REQUEST)
panic("uhci_device_bulk_transfer: a request\n");
#endif
- len = reqh->length;
- endpt = reqh->pipe->endpoint->edesc->bEndpointAddress;
+ len = xfer->length;
+ endpt = xfer->pipe->endpoint->edesc->bEndpointAddress;
isread = UE_GET_DIR(endpt) == UE_DIR_IN;
sqh = upipe->u.bulk.sqh;
upipe->u.bulk.isread = isread;
upipe->u.bulk.length = len;
- r = uhci_alloc_std_chain(upipe, sc, len, isread,
- reqh->flags & USBD_SHORT_XFER_OK,
- &reqh->dmabuf, &xfer, &xferend);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- xferend->td.td_status |= LE(UHCI_TD_IOC);
+ err = uhci_alloc_std_chain(upipe, sc, len, isread,
+ xfer->flags & USBD_SHORT_XFER_OK,
+ &xfer->dmabuf, &data, &dataend);
+ if (err)
+ return (err);
+ dataend->td.td_status |= LE(UHCI_TD_IOC);
#ifdef UHCI_DEBUG
if (uhcidebug > 8) {
- DPRINTF(("uhci_device_bulk_transfer: xfer(1)\n"));
- uhci_dump_tds(xfer);
+ DPRINTF(("uhci_device_bulk_transfer: data(1)\n"));
+ uhci_dump_tds(data);
}
#endif
/* Set up interrupt info. */
- ii->reqh = reqh;
- ii->stdstart = xfer;
- ii->stdend = xferend;
+ ii->xfer = xfer;
+ ii->stdstart = data;
+ ii->stdend = dataend;
#if defined(__FreeBSD__)
callout_handle_init(&ii->timeout_handle);
#endif
@@ -1400,53 +1508,53 @@ uhci_device_bulk_start(reqh)
ii->isdone = 0;
#endif
- sqh->elink = xfer;
- sqh->qh.qh_elink = LE(xfer->physaddr);
+ sqh->elink = data;
+ sqh->qh.qh_elink = LE(data->physaddr);
sqh->intr_info = ii;
s = splusb();
uhci_add_bulk(sc, sqh);
LIST_INSERT_HEAD(&sc->sc_intrhead, ii, list);
- if (reqh->timeout && !sc->sc_bus.use_polling) {
- usb_timeout(uhci_timeout, ii, MS_TO_TICKS(reqh->timeout),
+ if (xfer->timeout && !sc->sc_bus.use_polling) {
+ usb_timeout(uhci_timeout, ii, MS_TO_TICKS(xfer->timeout),
ii->timeout_handle);
}
splx(s);
#ifdef UHCI_DEBUG
if (uhcidebug > 10) {
- DPRINTF(("uhci_device_bulk_transfer: xfer(2)\n"));
- uhci_dump_tds(xfer);
+ DPRINTF(("uhci_device_bulk_transfer: data(2)\n"));
+ uhci_dump_tds(data);
}
#endif
if (sc->sc_bus.use_polling)
- uhci_waitintr(sc, reqh);
+ uhci_waitintr(sc, xfer);
return (USBD_IN_PROGRESS);
}
/* Abort a device bulk request. */
void
-uhci_device_bulk_abort(reqh)
- usbd_request_handle reqh;
+uhci_device_bulk_abort(xfer)
+ usbd_xfer_handle xfer;
{
DPRINTF(("uhci_device_bulk_abort:\n"));
- uhci_abort_req(reqh, USBD_CANCELLED);
+ uhci_abort_req(xfer, USBD_CANCELLED);
}
void
-uhci_abort_req(reqh, status)
- usbd_request_handle reqh;
+uhci_abort_req(xfer, status)
+ usbd_xfer_handle xfer;
usbd_status status;
{
- struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
+ struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
uhci_intr_info_t *ii = upipe->iinfo;
uhci_soft_td_t *std;
/* Make interrupt routine ignore it, */
- reqh->status = status;
+ xfer->status = status;
/* don't timeout, */
usb_untimeout(uhci_timeout, ii, ii->timeout_handle);
@@ -1455,16 +1563,20 @@ uhci_abort_req(reqh, status)
for (std = ii->stdstart; std != 0; std = std->link.std)
std->td.td_status &= LE(~(UHCI_TD_ACTIVE | UHCI_TD_IOC));
- reqh->hcpriv = ii;
+ xfer->hcpriv = ii;
/* make sure hardware has completed, */
- if (curproc) {
- usb_delay_ms(reqh->pipe->device->bus, 1);
- /* and call final part of interrupt handler. */
- uhci_abort_req_end(reqh);
- } else {
+ if (xfer->device->bus->intr_context) {
/* We have no process context, so we can't use tsleep(). */
- timeout(uhci_abort_req_end, reqh, hz / USB_FRAMES_PER_SECOND);
+ timeout(uhci_abort_req_end, xfer, hz / USB_FRAMES_PER_SECOND);
+ } else {
+#if defined(DIAGNOSTIC) && defined(__i386__)
+ KASSERT(intr_nesting_level == 0,
+ ("ohci_abort_req in interrupt context"));
+#endif
+ usb_delay_ms(xfer->pipe->device->bus, 1);
+ /* and call final part of interrupt handler. */
+ uhci_abort_req_end(xfer);
}
}
@@ -1472,11 +1584,11 @@ void
uhci_abort_req_end(v)
void *v;
{
- usbd_request_handle reqh = v;
+ usbd_xfer_handle xfer = v;
int s;
s = splusb();
- usb_transfer_complete(reqh);
+ usb_transfer_complete(xfer);
splx(s);
}
@@ -1495,93 +1607,101 @@ uhci_device_bulk_close(pipe)
}
usbd_status
-uhci_device_ctrl_transfer(reqh)
- usbd_request_handle reqh;
+uhci_device_ctrl_transfer(xfer)
+ usbd_xfer_handle xfer;
{
- usbd_status r;
+ usbd_status err;
- r = usb_insert_transfer(reqh);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- else
- return (uhci_device_ctrl_start(reqh));
+ /* Insert last in queue. */
+ err = usb_insert_transfer(xfer);
+ if (err)
+ return (err);
+
+ /* Pipe isn't running (otherwise err would be USBD_INPROG),
+ * start first
+ */
+ return (uhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
}
usbd_status
-uhci_device_ctrl_start(reqh)
- usbd_request_handle reqh;
+uhci_device_ctrl_start(xfer)
+ usbd_xfer_handle xfer;
{
- uhci_softc_t *sc = (uhci_softc_t *)reqh->pipe->device->bus;
- usbd_status r;
+ uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
+ usbd_status err;
#ifdef DIAGNOSTIC
- if (!(reqh->rqflags & URQ_REQUEST))
+ if (!(xfer->rqflags & URQ_REQUEST))
panic("uhci_device_ctrl_transfer: not a request\n");
#endif
- r = uhci_device_request(reqh);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = uhci_device_request(xfer);
+ if (err)
+ return (err);
if (sc->sc_bus.use_polling)
- uhci_waitintr(sc, reqh);
+ uhci_waitintr(sc, xfer);
return (USBD_IN_PROGRESS);
}
usbd_status
-uhci_device_intr_transfer(reqh)
- usbd_request_handle reqh;
+uhci_device_intr_transfer(xfer)
+ usbd_xfer_handle xfer;
{
- usbd_status r;
+ usbd_status err;
- r = usb_insert_transfer(reqh);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- else
- return (uhci_device_intr_start(reqh));
+ /* Insert last in queue. */
+ err = usb_insert_transfer(xfer);
+ if (err)
+ return (err);
+
+ /* Pipe isn't running (otherwise err would be USBD_INPROG),
+ * start first
+ */
+ return (uhci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
}
usbd_status
-uhci_device_intr_start(reqh)
- usbd_request_handle reqh;
+uhci_device_intr_start(xfer)
+ usbd_xfer_handle xfer;
{
- struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
+ struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
usbd_device_handle dev = upipe->pipe.device;
uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
uhci_intr_info_t *ii = upipe->iinfo;
- uhci_soft_td_t *xfer, *xferend;
+ uhci_soft_td_t *data, *dataend;
uhci_soft_qh_t *sqh;
- usbd_status r;
+ usbd_status err;
int i, s;
- DPRINTFN(3,("uhci_device_intr_transfer: reqh=%p len=%d flags=%d\n",
- reqh, reqh->length, reqh->flags));
+ DPRINTFN(3,("uhci_device_intr_transfer: xfer=%p len=%d flags=%d\n",
+ xfer, xfer->length, xfer->flags));
#ifdef DIAGNOSTIC
- if (reqh->rqflags & URQ_REQUEST)
+ if (xfer->rqflags & URQ_REQUEST)
panic("uhci_device_intr_transfer: a request\n");
#endif
- r = uhci_alloc_std_chain(upipe, sc, reqh->length, 1,
- reqh->flags & USBD_SHORT_XFER_OK,
- &reqh->dmabuf, &xfer, &xferend);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- xferend->td.td_status |= LE(UHCI_TD_IOC);
+ err = uhci_alloc_std_chain(upipe, sc, xfer->length, 1,
+ xfer->flags & USBD_SHORT_XFER_OK,
+ &xfer->dmabuf, &data, &dataend);
+ if (err)
+ return (err);
+ dataend->td.td_status |= LE(UHCI_TD_IOC);
#ifdef UHCI_DEBUG
if (uhcidebug > 10) {
- DPRINTF(("uhci_device_intr_transfer: xfer(1)\n"));
- uhci_dump_tds(xfer);
+ DPRINTF(("uhci_device_intr_transfer: data(1)\n"));
+ uhci_dump_tds(data);
uhci_dump_qh(upipe->u.intr.qhs[0]);
}
#endif
s = splusb();
/* Set up interrupt info. */
- ii->reqh = reqh;
- ii->stdstart = xfer;
- ii->stdend = xferend;
+ ii->xfer = xfer;
+ ii->stdstart = data;
+ ii->stdend = dataend;
#if defined(__FreeBSD__)
callout_handle_init(&ii->timeout_handle);
#endif
@@ -1593,15 +1713,15 @@ uhci_device_intr_start(reqh)
upipe->u.intr.qhs[0]));
for (i = 0; i < upipe->u.intr.npoll; i++) {
sqh = upipe->u.intr.qhs[i];
- sqh->elink = xfer;
- sqh->qh.qh_elink = LE(xfer->physaddr);
+ sqh->elink = data;
+ sqh->qh.qh_elink = LE(data->physaddr);
}
splx(s);
#ifdef UHCI_DEBUG
if (uhcidebug > 10) {
- DPRINTF(("uhci_device_intr_transfer: xfer(2)\n"));
- uhci_dump_tds(xfer);
+ DPRINTF(("uhci_device_intr_transfer: data(2)\n"));
+ uhci_dump_tds(data);
uhci_dump_qh(upipe->u.intr.qhs[0]);
}
#endif
@@ -1611,11 +1731,11 @@ uhci_device_intr_start(reqh)
/* Abort a device control request. */
void
-uhci_device_ctrl_abort(reqh)
- usbd_request_handle reqh;
+uhci_device_ctrl_abort(xfer)
+ usbd_xfer_handle xfer;
{
DPRINTF(("uhci_device_ctrl_abort:\n"));
- uhci_abort_req(reqh, USBD_CANCELLED);
+ uhci_abort_req(xfer, USBD_CANCELLED);
}
/* Close a device control pipe. */
@@ -1626,20 +1746,20 @@ uhci_device_ctrl_close(pipe)
struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
uhci_free_intr_info(upipe->iinfo);
- /* XXX free other resources */
+ /* XXX free other resources? */
}
/* Abort a device interrupt request. */
void
-uhci_device_intr_abort(reqh)
- usbd_request_handle reqh;
+uhci_device_intr_abort(xfer)
+ usbd_xfer_handle xfer;
{
- DPRINTFN(1,("uhci_device_intr_abort: reqh=%p\n", reqh));
- if (reqh->pipe->intrreqh == reqh) {
+ DPRINTFN(1,("uhci_device_intr_abort: xfer=%p\n", xfer));
+ if (xfer->pipe->intrxfer == xfer) {
DPRINTFN(1,("uhci_device_intr_abort: remove\n"));
- reqh->pipe->intrreqh = 0;
+ xfer->pipe->intrxfer = 0;
}
- uhci_abort_req(reqh, USBD_CANCELLED);
+ uhci_abort_req(xfer, USBD_CANCELLED);
}
/* Close a device interrupt pipe. */
@@ -1680,21 +1800,21 @@ uhci_device_intr_close(pipe)
}
usbd_status
-uhci_device_request(reqh)
- usbd_request_handle reqh;
+uhci_device_request(xfer)
+ usbd_xfer_handle xfer;
{
- struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
- usb_device_request_t *req = &reqh->request;
+ struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
+ usb_device_request_t *req = &xfer->request;
usbd_device_handle dev = upipe->pipe.device;
uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
int addr = dev->address;
int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress;
uhci_intr_info_t *ii = upipe->iinfo;
- uhci_soft_td_t *setup, *xfer, *stat, *next, *xferend;
+ uhci_soft_td_t *setup, *data, *stat, *next, *dataend;
uhci_soft_qh_t *sqh;
int len;
u_int32_t ls;
- usbd_status r;
+ usbd_status err;
int isread;
int s;
@@ -1715,14 +1835,14 @@ uhci_device_request(reqh)
/* Set up data transaction */
if (len != 0) {
upipe->nexttoggle = 1;
- r = uhci_alloc_std_chain(upipe, sc, len, isread,
- reqh->flags & USBD_SHORT_XFER_OK,
- &reqh->dmabuf, &xfer, &xferend);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- next = xfer;
- xferend->link.std = stat;
- xferend->td.td_link = LE(stat->physaddr|UHCI_PTR_VF);
+ err = uhci_alloc_std_chain(upipe, sc, len, isread,
+ xfer->flags & USBD_SHORT_XFER_OK,
+ &xfer->dmabuf, &data, &dataend);
+ if (err)
+ return (err);
+ next = data;
+ dataend->link.std = stat;
+ dataend->td.td_link = LE(stat->physaddr);
} else {
next = stat;
}
@@ -1731,7 +1851,7 @@ uhci_device_request(reqh)
memcpy(KERNADDR(&upipe->u.ctl.reqdma), req, sizeof *req);
setup->link.std = next;
- setup->td.td_link = LE(next->physaddr|UHCI_PTR_VF);
+ setup->td.td_link = LE(next->physaddr);
setup->td.td_status = LE(UHCI_TD_SET_ERRCNT(3) | ls | UHCI_TD_ACTIVE);
setup->td.td_token = LE(UHCI_TD_SETUP(sizeof *req, endpt, addr));
setup->td.td_buffer = LE(DMAADDR(&upipe->u.ctl.reqdma));
@@ -1746,16 +1866,19 @@ uhci_device_request(reqh)
stat->td.td_buffer = LE(0);
#ifdef UHCI_DEBUG
- if (uhcidebug > 20) {
+ if (uhcidebug > 10) {
DPRINTF(("uhci_device_request: before transfer\n"));
uhci_dump_tds(setup);
}
#endif
/* Set up interrupt info. */
- ii->reqh = reqh;
+ ii->xfer = xfer;
ii->stdstart = setup;
ii->stdend = stat;
+#if defined(__FreeBSD__)
+ callout_handle_init(&ii->timeout_handle);
+#endif
#ifdef DIAGNOSTIC
ii->isdone = 0;
#endif
@@ -1781,21 +1904,22 @@ uhci_device_request(reqh)
link = LE(std->td.td_link);
uhci_dump_td(std);
}
- for (sxqh = xqh = (uhci_soft_qh_t *)std;
- xqh;
+ sxqh = (uhci_soft_qh_t *)std;
+ uhci_dump_qh(sxqh);
+ for (xqh = sxqh;
+ xqh != NULL;
xqh = (maxqh++ == 5 || xqh->hlink==sxqh ||
xqh->hlink==xqh ? NULL : xqh->hlink)) {
uhci_dump_qh(xqh);
- uhci_dump_qh(sxqh);
}
DPRINTF(("Enqueued QH:\n"));
uhci_dump_qh(sqh);
uhci_dump_tds(sqh->elink);
}
#endif
- if (reqh->timeout && !sc->sc_bus.use_polling) {
+ if (xfer->timeout && !sc->sc_bus.use_polling) {
usb_timeout(uhci_timeout, ii,
- MS_TO_TICKS(reqh->timeout), ii->timeout_handle);
+ MS_TO_TICKS(xfer->timeout), ii->timeout_handle);
}
splx(s);
@@ -1803,37 +1927,37 @@ uhci_device_request(reqh)
}
usbd_status
-uhci_device_isoc_transfer(reqh)
- usbd_request_handle reqh;
+uhci_device_isoc_transfer(xfer)
+ usbd_xfer_handle xfer;
{
- usbd_status r;
+ usbd_status err;
- DPRINTFN(5,("uhci_device_isoc_transfer: reqh=%p\n", reqh));
+ DPRINTFN(5,("uhci_device_isoc_transfer: xfer=%p\n", xfer));
/* Put it on our queue, */
- r = usb_insert_transfer(reqh);
+ err = usb_insert_transfer(xfer);
/* bail out on error, */
- if (r != USBD_NORMAL_COMPLETION && r != USBD_IN_PROGRESS)
- return (r);
+ if (err && err != USBD_IN_PROGRESS)
+ return (err);
/* XXX should check inuse here */
/* insert into schedule, */
- uhci_device_isoc_enter(reqh);
+ uhci_device_isoc_enter(xfer);
/* and put on interrupt list if the pipe wasn't running */
- if (r == USBD_NORMAL_COMPLETION)
- uhci_device_isoc_start(reqh);
+ if (!err)
+ uhci_device_isoc_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
- return (r);
+ return (err);
}
void
-uhci_device_isoc_enter(reqh)
- usbd_request_handle reqh;
+uhci_device_isoc_enter(xfer)
+ usbd_xfer_handle xfer;
{
- struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
+ struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
usbd_device_handle dev = upipe->pipe.device;
uhci_softc_t *sc = (uhci_softc_t *)dev->bus;
struct iso *iso = &upipe->u.iso;
@@ -1841,11 +1965,11 @@ uhci_device_isoc_enter(reqh)
u_int32_t buf, len, status;
int s, i, next, nframes;
- DPRINTFN(5,("uhci_device_isoc_enter: used=%d next=%d reqh=%p "
+ DPRINTFN(5,("uhci_device_isoc_enter: used=%d next=%d xfer=%p "
"nframes=%d\n",
- iso->inuse, iso->next, reqh, reqh->nframes));
+ iso->inuse, iso->next, xfer, xfer->nframes));
- if (reqh->status == USBD_IN_PROGRESS) {
+ if (xfer->status == USBD_IN_PROGRESS) {
/* This request has already been entered into the frame list */
}
@@ -1861,20 +1985,20 @@ uhci_device_isoc_enter(reqh)
DPRINTFN(2,("uhci_device_isoc_enter: start next=%d\n", next));
}
- reqh->status = USBD_IN_PROGRESS;
- reqh->hcprivint = next;
+ xfer->status = USBD_IN_PROGRESS;
+ xfer->hcprivint = next;
- buf = DMAADDR(&reqh->dmabuf);
+ buf = DMAADDR(&xfer->dmabuf);
status = LE(UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(0) |
UHCI_TD_ACTIVE |
UHCI_TD_IOS));
- nframes = reqh->nframes;
+ nframes = xfer->nframes;
s = splusb();
for (i = 0; i < nframes; i++) {
std = iso->stds[next];
if (++next >= UHCI_VFRAMELIST_COUNT)
next = 0;
- len = reqh->frlengths[i];
+ len = xfer->frlengths[i];
std->td.td_buffer = LE(buf);
if (i == nframes - 1)
status |= LE(UHCI_TD_IOC);
@@ -1890,28 +2014,28 @@ uhci_device_isoc_enter(reqh)
buf += len;
}
iso->next = next;
- iso->inuse += reqh->nframes;
+ iso->inuse += xfer->nframes;
splx(s);
}
usbd_status
-uhci_device_isoc_start(reqh)
- usbd_request_handle reqh;
+uhci_device_isoc_start(xfer)
+ usbd_xfer_handle xfer;
{
- struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
+ struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
uhci_softc_t *sc = (uhci_softc_t *)upipe->pipe.device->bus;
uhci_intr_info_t *ii = upipe->iinfo;
uhci_soft_td_t *end;
int s, i;
#ifdef DIAGNOSTIC
- if (reqh->status != USBD_IN_PROGRESS)
- printf("uhci_device_isoc_start: not in progress %p\n", reqh);
+ if (xfer->status != USBD_IN_PROGRESS)
+ printf("uhci_device_isoc_start: not in progress %p\n", xfer);
#endif
/* Find the last TD */
- i = reqh->hcprivint + reqh->nframes;
+ i = xfer->hcprivint + xfer->nframes;
if (i >= UHCI_VFRAMELIST_COUNT)
i -= UHCI_VFRAMELIST_COUNT;
end = upipe->u.iso.stds[i];
@@ -1919,9 +2043,12 @@ uhci_device_isoc_start(reqh)
s = splusb();
/* Set up interrupt info. */
- ii->reqh = reqh;
+ ii->xfer = xfer;
ii->stdstart = end;
ii->stdend = end;
+#if defined(__FreeBSD__)
+ callout_handle_init(&ii->timeout_handle);
+#endif
#ifdef DIAGNOSTIC
ii->isdone = 0;
#endif
@@ -1933,21 +2060,21 @@ uhci_device_isoc_start(reqh)
}
void
-uhci_device_isoc_abort(reqh)
- usbd_request_handle reqh;
+uhci_device_isoc_abort(xfer)
+ usbd_xfer_handle xfer;
{
- struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
+ struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
uhci_intr_info_t *ii = upipe->iinfo;
uhci_soft_td_t **stds = upipe->u.iso.stds;
uhci_soft_td_t *std;
int i, n, nframes;
/* Make interrupt routine ignore it, */
- reqh->status = USBD_CANCELLED;
+ xfer->status = USBD_CANCELLED;
/* make hardware ignore it, */
- nframes = reqh->nframes;
- n = reqh->hcprivint;
+ nframes = xfer->nframes;
+ n = xfer->hcprivint;
for (i = 0; i < nframes; i++) {
std = stds[n];
std->td.td_status &= LE(~(UHCI_TD_ACTIVE | UHCI_TD_IOC));
@@ -1955,16 +2082,16 @@ uhci_device_isoc_abort(reqh)
n = 0;
}
- reqh->hcpriv = ii;
+ xfer->hcpriv = ii;
/* make sure hardware has completed, */
- if (curproc) {
- usb_delay_ms(reqh->pipe->device->bus, 1);
- /* and call final part of interrupt handler. */
- uhci_abort_req_end(reqh);
- } else {
+ if (xfer->device->bus->intr_context) {
/* We have no process context, so we can't use tsleep(). */
- timeout(uhci_abort_req_end, reqh, hz / USB_FRAMES_PER_SECOND);
+ timeout(uhci_abort_req_end, xfer, hz / USB_FRAMES_PER_SECOND);
+ } else {
+ usb_delay_ms(xfer->pipe->device->bus, 1);
+ /* and call final part of interrupt handler. */
+ uhci_abort_req_end(xfer);
}
}
@@ -1995,10 +2122,10 @@ uhci_device_isoc_close(pipe)
for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) {
std = iso->stds[i];
for (vstd = sc->sc_vframes[i].htd;
- vstd && vstd->link.std != std;
+ vstd != NULL && vstd->link.std != std;
vstd = vstd->link.std)
;
- if (!vstd) {
+ if (vstd == NULL) {
/*panic*/
printf("uhci_device_isoc_close: %p not found\n", std);
uhci_unlock_frames(sc);
@@ -2070,12 +2197,12 @@ uhci_setup_isoc(pipe)
}
void
-uhci_device_isoc_done(reqh)
- usbd_request_handle reqh;
+uhci_device_isoc_done(xfer)
+ usbd_xfer_handle xfer;
{
- uhci_intr_info_t *ii = reqh->hcpriv;
+ uhci_intr_info_t *ii = xfer->hcpriv;
- DPRINTFN(4, ("uhci_isoc_done: length=%d\n", reqh->actlen));
+ DPRINTFN(4, ("uhci_isoc_done: length=%d\n", xfer->actlen));
/* Turn off the interrupt since it is active even if the TD is not. */
ii->stdend->td.td_status &= LE(~UHCI_TD_IOC);
@@ -2084,16 +2211,16 @@ uhci_device_isoc_done(reqh)
}
void
-uhci_device_intr_done(reqh)
- usbd_request_handle reqh;
+uhci_device_intr_done(xfer)
+ usbd_xfer_handle xfer;
{
- uhci_intr_info_t *ii = reqh->hcpriv;
+ uhci_intr_info_t *ii = xfer->hcpriv;
uhci_softc_t *sc = ii->sc;
- struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
+ struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
uhci_soft_qh_t *sqh;
int i, npoll;
- DPRINTFN(5, ("uhci_intr_done: length=%d\n", reqh->actlen));
+ DPRINTFN(5, ("uhci_intr_done: length=%d\n", xfer->actlen));
npoll = upipe->u.intr.npoll;
for(i = 0; i < npoll; i++) {
@@ -2104,32 +2231,35 @@ uhci_device_intr_done(reqh)
uhci_free_std_chain(sc, ii->stdstart, 0);
/* XXX Wasteful. */
- if (reqh->pipe->repeat) {
- uhci_soft_td_t *xfer, *xferend;
+ if (xfer->pipe->repeat) {
+ uhci_soft_td_t *data, *dataend;
/* This alloc cannot fail since we freed the chain above. */
- uhci_alloc_std_chain(upipe, sc, reqh->length, 1,
- reqh->flags & USBD_SHORT_XFER_OK,
- &reqh->dmabuf, &xfer, &xferend);
- xferend->td.td_status |= LE(UHCI_TD_IOC);
+ uhci_alloc_std_chain(upipe, sc, xfer->length, 1,
+ xfer->flags & USBD_SHORT_XFER_OK,
+ &xfer->dmabuf, &data, &dataend);
+ dataend->td.td_status |= LE(UHCI_TD_IOC);
#ifdef UHCI_DEBUG
if (uhcidebug > 10) {
- DPRINTF(("uhci_device_intr_done: xfer(1)\n"));
- uhci_dump_tds(xfer);
+ DPRINTF(("uhci_device_intr_done: data(1)\n"));
+ uhci_dump_tds(data);
uhci_dump_qh(upipe->u.intr.qhs[0]);
}
#endif
- ii->stdstart = xfer;
- ii->stdend = xferend;
+ ii->stdstart = data;
+ ii->stdend = dataend;
+#if defined(__FreeBSD__)
+ callout_handle_init(&ii->timeout_handle);
+#endif
#ifdef DIAGNOSTIC
ii->isdone = 0;
#endif
for (i = 0; i < npoll; i++) {
sqh = upipe->u.intr.qhs[i];
- sqh->elink = xfer;
- sqh->qh.qh_elink = LE(xfer->physaddr);
+ sqh->elink = data;
+ sqh->qh.qh_elink = LE(data->physaddr);
}
} else {
ii->stdstart = 0; /* mark as inactive */
@@ -2138,15 +2268,15 @@ uhci_device_intr_done(reqh)
/* Deallocate request data structures */
void
-uhci_device_ctrl_done(reqh)
- usbd_request_handle reqh;
+uhci_device_ctrl_done(xfer)
+ usbd_xfer_handle xfer;
{
- uhci_intr_info_t *ii = reqh->hcpriv;
+ uhci_intr_info_t *ii = xfer->hcpriv;
uhci_softc_t *sc = ii->sc;
- struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
+ struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
#ifdef DIAGNOSTIC
- if (!(reqh->rqflags & URQ_REQUEST))
+ if (!(xfer->rqflags & URQ_REQUEST))
panic("uhci_ctrl_done: not a request\n");
#endif
@@ -2157,17 +2287,17 @@ uhci_device_ctrl_done(reqh)
if (upipe->u.ctl.length != 0)
uhci_free_std_chain(sc, ii->stdstart->link.std, ii->stdend);
- DPRINTFN(5, ("uhci_ctrl_done: length=%d\n", reqh->actlen));
+ DPRINTFN(5, ("uhci_ctrl_done: length=%d\n", xfer->actlen));
}
/* Deallocate request data structures */
void
-uhci_device_bulk_done(reqh)
- usbd_request_handle reqh;
+uhci_device_bulk_done(xfer)
+ usbd_xfer_handle xfer;
{
- uhci_intr_info_t *ii = reqh->hcpriv;
+ uhci_intr_info_t *ii = xfer->hcpriv;
uhci_softc_t *sc = ii->sc;
- struct uhci_pipe *upipe = (struct uhci_pipe *)reqh->pipe;
+ struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe;
LIST_REMOVE(ii, list); /* remove from active list */
@@ -2175,7 +2305,7 @@ uhci_device_bulk_done(reqh)
uhci_free_std_chain(sc, ii->stdstart, 0);
- DPRINTFN(5, ("uhci_bulk_done: length=%d\n", reqh->actlen));
+ DPRINTFN(5, ("uhci_bulk_done: length=%d\n", xfer->actlen));
}
/* Add interrupt QH, called with vflock. */
@@ -2299,7 +2429,7 @@ uhci_open(pipe)
uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
struct uhci_pipe *upipe = (struct uhci_pipe *)pipe;
usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
- usbd_status r;
+ usbd_status err;
DPRINTFN(1, ("uhci_open: pipe=%p, addr=%d, endpt=%d (%d)\n",
pipe, pipe->device->address,
@@ -2323,23 +2453,23 @@ uhci_open(pipe)
case UE_CONTROL:
pipe->methods = &uhci_device_ctrl_methods;
upipe->u.ctl.sqh = uhci_alloc_sqh(sc);
- if (upipe->u.ctl.sqh == 0)
+ if (upipe->u.ctl.sqh == NULL)
goto bad;
upipe->u.ctl.setup = uhci_alloc_std(sc);
- if (upipe->u.ctl.setup == 0) {
+ if (upipe->u.ctl.setup == NULL) {
uhci_free_sqh(sc, upipe->u.ctl.sqh);
goto bad;
}
upipe->u.ctl.stat = uhci_alloc_std(sc);
- if (upipe->u.ctl.stat == 0) {
+ if (upipe->u.ctl.stat == NULL) {
uhci_free_sqh(sc, upipe->u.ctl.sqh);
uhci_free_std(sc, upipe->u.ctl.setup);
goto bad;
}
- r = usb_allocmem(sc->sc_dmatag,
- sizeof(usb_device_request_t),
- 0, &upipe->u.ctl.reqdma);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usb_allocmem(&sc->sc_bus,
+ sizeof(usb_device_request_t),
+ 0, &upipe->u.ctl.reqdma);
+ if (err) {
uhci_free_sqh(sc, upipe->u.ctl.sqh);
uhci_free_std(sc, upipe->u.ctl.setup);
uhci_free_std(sc, upipe->u.ctl.stat);
@@ -2355,7 +2485,7 @@ uhci_open(pipe)
case UE_BULK:
pipe->methods = &uhci_device_bulk_methods;
upipe->u.bulk.sqh = uhci_alloc_sqh(sc);
- if (upipe->u.bulk.sqh == 0)
+ if (upipe->u.bulk.sqh == NULL)
goto bad;
break;
}
@@ -2451,35 +2581,39 @@ uhci_str(p, l, s)
* Simulate a hardware hub by handling all the necessary requests.
*/
usbd_status
-uhci_root_ctrl_transfer(reqh)
- usbd_request_handle reqh;
+uhci_root_ctrl_transfer(xfer)
+ usbd_xfer_handle xfer;
{
- usbd_status r;
+ usbd_status err;
- r = usb_insert_transfer(reqh);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- else
- return (uhci_root_ctrl_start(reqh));
+ /* Insert last in queue. */
+ err = usb_insert_transfer(xfer);
+ if (err)
+ return (err);
+
+ /* Pipe isn't running (otherwise err would be USBD_INPROG),
+ * start first
+ */
+ return (uhci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
}
usbd_status
-uhci_root_ctrl_start(reqh)
- usbd_request_handle reqh;
+uhci_root_ctrl_start(xfer)
+ usbd_xfer_handle xfer;
{
- uhci_softc_t *sc = (uhci_softc_t *)reqh->pipe->device->bus;
+ uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
usb_device_request_t *req;
void *buf = NULL;
int port, x;
- int len, value, index, status, change, l, totlen = 0;
+ int s, len, value, index, status, change, l, totlen = 0;
usb_port_status_t ps;
- usbd_status r;
+ usbd_status err;
#ifdef DIAGNOSTIC
- if (!(reqh->rqflags & URQ_REQUEST))
+ if (!(xfer->rqflags & URQ_REQUEST))
panic("uhci_root_ctrl_transfer: not a request\n");
#endif
- req = &reqh->request;
+ req = &xfer->request;
DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n",
req->bmRequestType, req->bRequest));
@@ -2489,7 +2623,7 @@ uhci_root_ctrl_start(reqh)
index = UGETW(req->wIndex);
if (len != 0)
- buf = KERNADDR(&reqh->dmabuf);
+ buf = KERNADDR(&xfer->dmabuf);
#define C(x,y) ((x) | ((y) << 8))
switch(C(req->bRequest, req->bmRequestType)) {
@@ -2512,7 +2646,7 @@ uhci_root_ctrl_start(reqh)
switch(value >> 8) {
case UDESC_DEVICE:
if ((value & 0xff) != 0) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
@@ -2521,7 +2655,7 @@ uhci_root_ctrl_start(reqh)
break;
case UDESC_CONFIG:
if ((value & 0xff) != 0) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
@@ -2552,7 +2686,7 @@ uhci_root_ctrl_start(reqh)
}
break;
default:
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
break;
@@ -2577,14 +2711,14 @@ uhci_root_ctrl_start(reqh)
break;
case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
if (value >= USB_MAX_DEVICES) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
sc->sc_addr = value;
break;
case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
if (value != 0 && value != 1) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
sc->sc_conf = value;
@@ -2594,7 +2728,7 @@ uhci_root_ctrl_start(reqh)
case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
break;
@@ -2612,7 +2746,7 @@ uhci_root_ctrl_start(reqh)
else if (index == 2)
port = UHCI_PORTSC2;
else {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
switch(value) {
@@ -2642,7 +2776,7 @@ uhci_root_ctrl_start(reqh)
break;
case UHF_C_PORT_RESET:
sc->sc_isreset = 0;
- r = USBD_NORMAL_COMPLETION;
+ err = USBD_NORMAL_COMPLETION;
goto ret;
case UHF_PORT_CONNECTION:
case UHF_PORT_OVER_CURRENT:
@@ -2650,7 +2784,7 @@ uhci_root_ctrl_start(reqh)
case UHF_PORT_LOW_SPEED:
case UHF_C_PORT_SUSPEND:
default:
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
break;
@@ -2660,7 +2794,7 @@ uhci_root_ctrl_start(reqh)
else if (index == 2)
port = UHCI_PORTSC2;
else {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
if (len > 0) {
@@ -2672,7 +2806,7 @@ uhci_root_ctrl_start(reqh)
break;
case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
if (value != 0) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
l = min(len, USB_HUB_DESCRIPTOR_SIZE);
@@ -2681,7 +2815,7 @@ uhci_root_ctrl_start(reqh)
break;
case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
if (len != 4) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
memset(buf, 0, len);
@@ -2693,11 +2827,11 @@ uhci_root_ctrl_start(reqh)
else if (index == 2)
port = UHCI_PORTSC2;
else {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
if (len != 4) {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
x = UREAD2(sc, port);
@@ -2728,7 +2862,7 @@ uhci_root_ctrl_start(reqh)
totlen = l;
break;
case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
break;
@@ -2738,7 +2872,7 @@ uhci_root_ctrl_start(reqh)
else if (index == 2)
port = UHCI_PORTSC2;
else {
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
switch(value) {
@@ -2773,27 +2907,29 @@ uhci_root_ctrl_start(reqh)
case UHF_C_PORT_SUSPEND:
case UHF_C_PORT_RESET:
default:
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
break;
default:
- r = USBD_IOERROR;
+ err = USBD_IOERROR;
goto ret;
}
- reqh->actlen = totlen;
- r = USBD_NORMAL_COMPLETION;
+ xfer->actlen = totlen;
+ err = USBD_NORMAL_COMPLETION;
ret:
- reqh->status = r;
- reqh->hcpriv = 0;
- usb_transfer_complete(reqh);
+ xfer->status = err;
+ xfer->hcpriv = 0;
+ s = splusb();
+ usb_transfer_complete(xfer);
+ splx(s);
return (USBD_IN_PROGRESS);
}
/* Abort a root control request. */
void
-uhci_root_ctrl_abort(reqh)
- usbd_request_handle reqh;
+uhci_root_ctrl_abort(xfer)
+ usbd_xfer_handle xfer;
{
/* Nothing to do, all transfers are syncronous. */
}
@@ -2811,42 +2947,53 @@ uhci_root_ctrl_close(pipe)
/* Abort a root interrupt request. */
void
-uhci_root_intr_abort(reqh)
- usbd_request_handle reqh;
+uhci_root_intr_abort(xfer)
+ usbd_xfer_handle xfer;
{
- uhci_softc_t *sc = (uhci_softc_t *)reqh->pipe->device->bus;
+ uhci_softc_t *sc = (uhci_softc_t *)xfer->pipe->device->bus;
- usb_untimeout(uhci_timo, reqh, reqh->timo_handle);
+ usb_untimeout(uhci_timo, xfer, xfer->timo_handle);
sc->sc_has_timo = 0;
+
+ if (xfer->pipe->intrxfer == xfer) {
+ DPRINTF(("uhci_root_intr_abort: remove\n"));
+ xfer->pipe->intrxfer = 0;
+ }
+ xfer->status = USBD_CANCELLED;
+ usb_transfer_complete(xfer);
}
usbd_status
-uhci_root_intr_transfer(reqh)
- usbd_request_handle reqh;
+uhci_root_intr_transfer(xfer)
+ usbd_xfer_handle xfer;
{
- usbd_status r;
+ usbd_status err;
- r = usb_insert_transfer(reqh);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- else
- return (uhci_root_intr_start(reqh));
+ /* Insert last in queue. */
+ err = usb_insert_transfer(xfer);
+ if (err)
+ return (err);
+
+ /* Pipe isn't running (otherwise err would be USBD_INPROG),
+ * start first
+ */
+ return (uhci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue)));
}
/* Start a transfer on the root interrupt pipe */
usbd_status
-uhci_root_intr_start(reqh)
- usbd_request_handle reqh;
+uhci_root_intr_start(xfer)
+ usbd_xfer_handle xfer;
{
- usbd_pipe_handle pipe = reqh->pipe;
+ usbd_pipe_handle pipe = xfer->pipe;
uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
- DPRINTFN(3, ("uhci_root_intr_transfer: reqh=%p len=%d flags=%d\n",
- reqh, reqh->length, reqh->flags));
+ DPRINTFN(3, ("uhci_root_intr_transfer: xfer=%p len=%d flags=%d\n",
+ xfer, xfer->length, xfer->flags));
- sc->sc_ival = MS_TO_TICKS(reqh->pipe->endpoint->edesc->bInterval);
- usb_timeout(uhci_timo, reqh, sc->sc_ival, reqh->timo_handle);
- sc->sc_has_timo = reqh;
+ sc->sc_ival = MS_TO_TICKS(xfer->pipe->endpoint->edesc->bInterval);
+ usb_timeout(uhci_timo, xfer, sc->sc_ival, xfer->timo_handle);
+ sc->sc_has_timo = xfer;
return (USBD_IN_PROGRESS);
}
@@ -2857,8 +3004,7 @@ uhci_root_intr_close(pipe)
{
uhci_softc_t *sc = (uhci_softc_t *)pipe->device->bus;
- usb_untimeout(uhci_timo, pipe->intrreqh, pipe->intrreqh->timo_handle);
+ usb_untimeout(uhci_timo, pipe->intrxfer, pipe->intrxfer->timo_handle);
sc->sc_has_timo = 0;
DPRINTF(("uhci_root_intr_close\n"));
}
-
diff --git a/sys/dev/usb/uhcireg.h b/sys/dev/usb/uhcireg.h
index dfdff27..bcb5fca 100644
--- a/sys/dev/usb/uhcireg.h
+++ b/sys/dev/usb/uhcireg.h
@@ -1,4 +1,4 @@
-/* $NetBSD: uhcireg.h,v 1.7 1999/08/22 23:19:57 augustss Exp $ */
+/* $NetBSD: uhcireg.h,v 1.6 1999/04/03 19:01:20 augustss Exp $ */
/* $FreeBSD$ */
/*
diff --git a/sys/dev/usb/uhcivar.h b/sys/dev/usb/uhcivar.h
index 1c2ad1b..682a495 100644
--- a/sys/dev/usb/uhcivar.h
+++ b/sys/dev/usb/uhcivar.h
@@ -1,5 +1,5 @@
-/* $NetBSD: uhcivar.h,v 1.12 1999/08/22 23:41:00 augustss Exp $ */
-/* $FreeBSD$ */
+/* $NetBSD: uhcivar.h,v 1.16 1999/10/13 08:10:56 augustss Exp $ */
+/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -70,7 +70,7 @@ typedef union {
*/
typedef struct uhci_intr_info {
struct uhci_softc *sc;
- usbd_request_handle reqh;
+ usbd_xfer_handle xfer;
uhci_soft_td_t *stdstart;
uhci_soft_td_t *stdend;
LIST_ENTRY(uhci_intr_info) list;
@@ -130,12 +130,6 @@ typedef struct uhci_softc {
struct usbd_bus sc_bus; /* base device */
bus_space_tag_t iot;
bus_space_handle_t ioh;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
- void *sc_ih; /* interrupt vectoring */
-
- bus_dma_tag_t sc_dmatag; /* DMA tag */
- /* XXX should keep track of all DMA memory */
-#endif /* defined(__FreeBSD__) */
uhci_physaddr_t *sc_pframes;
usb_dma_t sc_dma;
@@ -154,12 +148,9 @@ typedef struct uhci_softc {
char sc_isreset;
-#if defined(__NetBSD__)
char sc_suspend;
-#endif
- usbd_request_handle sc_has_timo;
+ usbd_xfer_handle sc_has_timo;
- int sc_intrs;
LIST_HEAD(, uhci_intr_info) sc_intrhead;
/* Info for the root hub interrupt channel. */
@@ -171,11 +162,15 @@ typedef struct uhci_softc {
char sc_vendor[16];
int sc_id_vendor;
+
+ void *sc_powerhook;
+ device_ptr_t sc_child;
} uhci_softc_t;
usbd_status uhci_init __P((uhci_softc_t *));
int uhci_intr __P((void *));
-#if 0
-void uhci_reset __P((void *));
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+int uhci_detach __P((uhci_softc_t *, int));
+int uhci_activate __P((device_ptr_t, enum devact));
#endif
diff --git a/sys/dev/usb/uhid.c b/sys/dev/usb/uhid.c
index 719341c..a38fbf4 100644
--- a/sys/dev/usb/uhid.c
+++ b/sys/dev/usb/uhid.c
@@ -1,4 +1,4 @@
-/* $NetBSD: uhid.c,v 1.24 1999/09/05 19:32:18 augustss Exp $ */
+/* $NetBSD: uhid.c,v 1.26 1999/10/13 08:10:56 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -146,11 +146,13 @@ static struct cdevsw uhid_cdevsw = {
};
#endif
-void uhid_intr __P((usbd_request_handle, usbd_private_handle, usbd_status));
+static void uhid_intr __P((usbd_xfer_handle, usbd_private_handle,
+ usbd_status));
-int uhid_do_read __P((struct uhid_softc *, struct uio *uio, int));
-int uhid_do_write __P((struct uhid_softc *, struct uio *uio, int));
-int uhid_do_ioctl __P((struct uhid_softc *, u_long, caddr_t, int, struct proc *));
+static int uhid_do_read __P((struct uhid_softc *, struct uio *uio, int));
+static int uhid_do_write __P((struct uhid_softc *, struct uio *uio, int));
+static int uhid_do_ioctl __P((struct uhid_softc *, u_long, caddr_t, int,
+ struct proc *));
USB_DECLARE_DRIVER(uhid);
@@ -159,10 +161,10 @@ USB_MATCH(uhid)
USB_MATCH_START(uhid, uaa);
usb_interface_descriptor_t *id;
- if (!uaa->iface)
+ if (uaa->iface == NULL)
return (UMATCH_NONE);
id = usbd_get_interface_descriptor(uaa->iface);
- if (!id || id->bInterfaceClass != UCLASS_HID)
+ if (id == NULL || id->bInterfaceClass != UCLASS_HID)
return (UMATCH_NONE);
return (UMATCH_IFACECLASS_GENERIC);
}
@@ -175,7 +177,7 @@ USB_ATTACH(uhid)
usb_endpoint_descriptor_t *ed;
int size;
void *desc;
- usbd_status r;
+ usbd_status err;
char devinfo[1024];
sc->sc_iface = iface;
@@ -186,7 +188,7 @@ USB_ATTACH(uhid)
devinfo, id->bInterfaceClass, id->bInterfaceSubClass);
ed = usbd_interface2endpoint_descriptor(iface, 0);
- if (!ed) {
+ if (ed == NULL) {
printf("%s: could not read endpoint descriptor\n",
USBDEVNAME(sc->sc_dev));
sc->sc_dying = 1;
@@ -212,11 +214,11 @@ USB_ATTACH(uhid)
sc->sc_ep_addr = ed->bEndpointAddress;
desc = 0;
- r = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_USBDEV);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_USBDEV);
+ if (err) {
printf("%s: no report descriptor\n", USBDEVNAME(sc->sc_dev));
sc->sc_dying = 1;
- if (desc)
+ if (desc != NULL)
free(desc, M_USBDEV);
USB_ATTACH_ERROR_RETURN;
}
@@ -272,12 +274,12 @@ USB_DETACH(uhid)
int maj, mn;
DPRINTF(("uhid_detach: sc=%p flags=%d\n", sc, flags));
-#elif defined(__FreeBSD__)
+#else
DPRINTF(("uhid_detach: sc=%p\n", sc));
#endif
sc->sc_dying = 1;
- if (sc->sc_intrpipe)
+ if (sc->sc_intrpipe != NULL)
usbd_abort_pipe(sc->sc_intrpipe);
if (sc->sc_state & UHID_OPEN) {
@@ -310,8 +312,8 @@ USB_DETACH(uhid)
}
void
-uhid_intr(reqh, addr, status)
- usbd_request_handle reqh;
+uhid_intr(xfer, addr, status)
+ usbd_xfer_handle xfer;
usbd_private_handle addr;
usbd_status status;
{
@@ -347,7 +349,9 @@ uhidopen(dev, flag, mode, p)
int mode;
struct proc *p;
{
- usbd_status r;
+ struct uhid_softc *sc;
+ usbd_status err;
+
USB_GET_SC_OPEN(uhid, UHIDUNIT(dev), sc);
DPRINTF(("uhidopen: sc=%p\n", sc));
@@ -359,26 +363,21 @@ uhidopen(dev, flag, mode, p)
return (EBUSY);
sc->sc_state |= UHID_OPEN;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
if (clalloc(&sc->sc_q, UHID_BSIZE, 0) == -1) {
sc->sc_state &= ~UHID_OPEN;
return (ENOMEM);
}
-#elif defined(__FreeBSD__)
- clist_alloc_cblocks(&sc->sc_q, UHID_BSIZE, 0);
-#endif
sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK);
sc->sc_obuf = malloc(sc->sc_osize, M_USBDEV, M_WAITOK);
/* Set up interrupt pipe. */
- r = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr,
- USBD_SHORT_XFER_OK,
- &sc->sc_intrpipe, sc, sc->sc_ibuf,
- sc->sc_isize, uhid_intr);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr,
+ USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc, sc->sc_ibuf,
+ sc->sc_isize, uhid_intr);
+ if (err) {
DPRINTF(("uhidopen: usbd_open_pipe_intr failed, "
- "error=%d\n",r));
+ "error=%d\n",err));
free(sc->sc_ibuf, M_USBDEV);
free(sc->sc_obuf, M_USBDEV);
sc->sc_state &= ~UHID_OPEN;
@@ -397,6 +396,8 @@ uhidclose(dev, flag, mode, p)
int mode;
struct proc *p;
{
+ struct uhid_softc *sc;
+
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
DPRINTF(("uhidclose: sc=%p\n", sc));
@@ -406,11 +407,7 @@ uhidclose(dev, flag, mode, p)
usbd_close_pipe(sc->sc_intrpipe);
sc->sc_intrpipe = 0;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
clfree(&sc->sc_q);
-#elif defined(__FreeBSD__)
- clist_free_cblocks(&sc->sc_q);
-#endif
free(sc->sc_ibuf, M_USBDEV);
free(sc->sc_obuf, M_USBDEV);
@@ -430,15 +427,15 @@ uhid_do_read(sc, uio, flag)
int error = 0;
size_t length;
u_char buffer[UHID_CHUNK];
- usbd_status r;
+ usbd_status err;
DPRINTFN(1, ("uhidread\n"));
if (sc->sc_state & UHID_IMMED) {
DPRINTFN(1, ("uhidread immed\n"));
- r = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
- sc->sc_iid, buffer, sc->sc_isize);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
+ sc->sc_iid, buffer, sc->sc_isize);
+ if (err)
return (EIO);
return (uiomove(buffer, sc->sc_isize, uio));
}
@@ -491,9 +488,11 @@ uhidread(dev, uio, flag)
struct uio *uio;
int flag;
{
- USB_GET_SC(uhid, UHIDUNIT(dev), sc);
+ struct uhid_softc *sc;
int error;
+ USB_GET_SC(uhid, UHIDUNIT(dev), sc);
+
sc->sc_refcnt++;
error = uhid_do_read(sc, uio, flag);
if (--sc->sc_refcnt < 0)
@@ -509,7 +508,7 @@ uhid_do_write(sc, uio, flag)
{
int error;
int size;
- usbd_status r;
+ usbd_status err;
DPRINTFN(1, ("uhidwrite\n"));
@@ -523,15 +522,13 @@ uhid_do_write(sc, uio, flag)
error = uiomove(sc->sc_obuf, size, uio);
if (!error) {
if (sc->sc_oid)
- r = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
- sc->sc_obuf[0],
- sc->sc_obuf+1, size-1);
+ err = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
+ sc->sc_obuf[0], sc->sc_obuf+1, size-1);
else
- r = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
- 0, sc->sc_obuf, size);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_set_report(sc->sc_iface, UHID_OUTPUT_REPORT,
+ 0, sc->sc_obuf, size);
+ if (err)
error = EIO;
- }
}
return (error);
@@ -543,9 +540,11 @@ uhidwrite(dev, uio, flag)
struct uio *uio;
int flag;
{
- USB_GET_SC(uhid, UHIDUNIT(dev), sc);
+ struct uhid_softc *sc;
int error;
+ USB_GET_SC(uhid, UHIDUNIT(dev), sc);
+
sc->sc_refcnt++;
error = uhid_do_write(sc, uio, flag);
if (--sc->sc_refcnt < 0)
@@ -564,7 +563,7 @@ uhid_do_ioctl(sc, cmd, addr, flag, p)
struct usb_ctl_report_desc *rd;
struct usb_ctl_report *re;
int size, id;
- usbd_status r;
+ usbd_status err;
DPRINTFN(2, ("uhidioctl: cmd=%lx\n", cmd));
@@ -585,11 +584,10 @@ uhid_do_ioctl(sc, cmd, addr, flag, p)
case USB_SET_IMMED:
if (*(int *)addr) {
- /* XXX should read into ibuf, but does it matter */
- r = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
- sc->sc_iid, sc->sc_ibuf,
- sc->sc_isize);
- if (r != USBD_NORMAL_COMPLETION)
+ /* XXX should read into ibuf, but does it matter? */
+ err = usbd_get_report(sc->sc_iface, UHID_INPUT_REPORT,
+ sc->sc_iid, sc->sc_ibuf, sc->sc_isize);
+ if (err)
return (EOPNOTSUPP);
sc->sc_state |= UHID_IMMED;
@@ -615,9 +613,9 @@ uhid_do_ioctl(sc, cmd, addr, flag, p)
default:
return (EINVAL);
}
- r = usbd_get_report(sc->sc_iface, re->report, id,
- re->data, size);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_get_report(sc->sc_iface, re->report, id, re->data,
+ size);
+ if (err)
return (EIO);
break;
@@ -635,9 +633,11 @@ uhidioctl(dev, cmd, addr, flag, p)
int flag;
struct proc *p;
{
- USB_GET_SC(uhid, UHIDUNIT(dev), sc);
+ struct uhid_softc *sc;
int error;
+ USB_GET_SC(uhid, UHIDUNIT(dev), sc);
+
sc->sc_refcnt++;
error = uhid_do_ioctl(sc, cmd, addr, flag, p);
if (--sc->sc_refcnt < 0)
@@ -651,8 +651,10 @@ uhidpoll(dev, events, p)
int events;
struct proc *p;
{
+ struct uhid_softc *sc;
int revents = 0;
int s;
+
USB_GET_SC(uhid, UHIDUNIT(dev), sc);
if (sc->sc_dying)
diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c
index 6b859b9..015dce9 100644
--- a/sys/dev/usb/uhub.c
+++ b/sys/dev/usb/uhub.c
@@ -1,4 +1,4 @@
-/* $NetBSD: uhub.c,v 1.26 1999/09/05 19:32:18 augustss Exp $ */
+/* $NetBSD: uhub.c,v 1.32 1999/10/13 08:10:56 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -52,9 +52,10 @@
#elif defined(__FreeBSD__)
#include <sys/module.h>
#include <sys/bus.h>
+#include "bus_if.h"
#endif
-#include "bus_if.h"
+#include <machine/bus.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -78,22 +79,23 @@ struct uhub_softc {
u_char sc_running;
};
-usbd_status uhub_init_port __P((struct usbd_port *));
-void uhub_disconnect_port __P((struct usbd_port *up));
-usbd_status uhub_explore __P((usbd_device_handle hub));
-void uhub_intr __P((usbd_request_handle, usbd_private_handle, usbd_status));
+static usbd_status uhub_init_port __P((struct usbd_port *));
+static usbd_status uhub_explore __P((usbd_device_handle hub));
+static void uhub_intr __P((usbd_xfer_handle, usbd_private_handle, usbd_status));
#if defined(__FreeBSD__)
static bus_child_detached_t uhub_child_detached;
#endif
-/* We need two attachment points:
+
+/*
+ * We need two attachment points:
* hub to usb and hub to hub
* Every other driver only connects to hubs
*/
#if defined(__NetBSD__) || defined(__OpenBSD__)
-USB_DECLARE_DRIVER(uhub);
+USB_DECLARE_DRIVER(uhub)
/* Create the driver instance for the hub connected to hub case */
struct cfattach uhub_uhub_ca = {
@@ -101,8 +103,9 @@ struct cfattach uhub_uhub_ca = {
uhub_detach, uhub_activate
};
#elif defined(__FreeBSD__)
-USB_DECLARE_DRIVER_INIT(uhub, DEVMETHOD(bus_child_detached, uhub_child_detached));
-
+USB_DECLARE_DRIVER_INIT(uhub,
+ DEVMETHOD(bus_child_detached, uhub_child_detached));
+
/* Create the driver instance for the hub connected to usb case. */
devclass_t uhubroot_devclass;
@@ -121,7 +124,6 @@ static driver_t uhubroot_driver = {
};
#endif
-
USB_MATCH(uhub)
{
USB_MATCH_START(uhub, uaa);
@@ -132,7 +134,7 @@ USB_MATCH(uhub)
* The subclass for hubs seems to be 0 for some and 1 for others,
* so we just ignore the subclass.
*/
- if (uaa->iface == 0 && dd->bDeviceClass == UCLASS_HUB)
+ if (uaa->iface == NULL && dd->bDeviceClass == UCLASS_HUB)
return (UMATCH_DEVCLASS_DEVSUBCLASS);
return (UMATCH_NONE);
}
@@ -142,7 +144,7 @@ USB_ATTACH(uhub)
USB_ATTACH_START(uhub, sc, uaa);
usbd_device_handle dev = uaa->device;
char devinfo[1024];
- usbd_status r;
+ usbd_status err;
struct usbd_hub *hub;
usb_device_request_t req;
usb_hub_descriptor_t hubdesc;
@@ -156,10 +158,10 @@ USB_ATTACH(uhub)
USB_ATTACH_SETUP;
printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
- r = usbd_set_config_index(dev, 0, 1);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_set_config_index(dev, 0, 1);
+ if (err) {
DPRINTF(("%s: configuration failed, error=%s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(r)));
+ USBDEVNAME(sc->sc_dev), usbd_errstr(err)));
USB_ATTACH_ERROR_RETURN;
}
@@ -176,15 +178,15 @@ USB_ATTACH(uhub)
USETW(req.wIndex, 0);
USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE);
DPRINTFN(1,("usb_init_hub: getting hub descriptor\n"));
- r = usbd_do_request(dev, &req, &hubdesc);
+ err = usbd_do_request(dev, &req, &hubdesc);
nports = hubdesc.bNbrPorts;
- if (r == USBD_NORMAL_COMPLETION && nports > 7) {
+ if (!err && nports > 7) {
USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE + (nports+1) / 8);
- r = usbd_do_request(dev, &req, &hubdesc);
+ err = usbd_do_request(dev, &req, &hubdesc);
}
- if (r != USBD_NORMAL_COMPLETION) {
+ if (err) {
DPRINTF(("%s: getting hub descriptor failed, error=%s\n",
- USBDEVNAME(sc->sc_dev), usbd_errstr(r)));
+ USBDEVNAME(sc->sc_dev), usbd_errstr(err)));
USB_ATTACH_ERROR_RETURN;
}
@@ -194,11 +196,10 @@ USB_ATTACH(uhub)
printf("%s: %d port%s with %d removable, %s powered\n",
USBDEVNAME(sc->sc_dev), nports, nports != 1 ? "s" : "",
nremov, dev->self_powered ? "self" : "bus");
-
hub = malloc(sizeof(*hub) + (nports-1) * sizeof(struct usbd_port),
M_USBDEV, M_NOWAIT);
- if (hub == 0)
+ if (hub == NULL)
USB_ATTACH_ERROR_RETURN;
dev->hub = hub;
dev->hub->hubsoftc = sc;
@@ -211,7 +212,7 @@ USB_ATTACH(uhub)
dev->powersrc->parent ?
dev->powersrc->parent->self_powered : 0));
- if (!dev->self_powered && dev->powersrc->parent &&
+ if (!dev->self_powered && dev->powersrc->parent != NULL &&
!dev->powersrc->parent->self_powered) {
printf("%s: bus powered hub connected to bus powered hub, "
"ignored\n", USBDEVNAME(sc->sc_dev));
@@ -219,13 +220,13 @@ USB_ATTACH(uhub)
}
/* Set up interrupt pipe. */
- r = usbd_device2interface_handle(dev, 0, &iface);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_device2interface_handle(dev, 0, &iface);
+ if (err) {
printf("%s: no interface handle\n", USBDEVNAME(sc->sc_dev));
goto bad;
}
ed = usbd_interface2endpoint_descriptor(iface, 0);
- if (ed == 0) {
+ if (ed == NULL) {
printf("%s: no endpoint descriptor\n", USBDEVNAME(sc->sc_dev));
goto bad;
}
@@ -234,11 +235,10 @@ USB_ATTACH(uhub)
goto bad;
}
- r = usbd_open_pipe_intr(iface, ed->bEndpointAddress,USBD_SHORT_XFER_OK,
- &sc->sc_ipipe, sc, sc->sc_status,
- sizeof(sc->sc_status),
- uhub_intr);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_open_pipe_intr(iface, ed->bEndpointAddress,
+ USBD_SHORT_XFER_OK, &sc->sc_ipipe, sc, sc->sc_status,
+ sizeof(sc->sc_status), uhub_intr);
+ if (err) {
printf("%s: cannot open interrupt pipe\n",
USBDEVNAME(sc->sc_dev));
goto bad;
@@ -252,16 +252,16 @@ USB_ATTACH(uhub)
up->device = 0;
up->parent = dev;
up->portno = p+1;
- r = uhub_init_port(up);
- if (r != USBD_NORMAL_COMPLETION)
+ err = uhub_init_port(up);
+ if (err)
printf("%s: init of port %d failed\n",
- USBDEVNAME(sc->sc_dev), up->portno);
+ USBDEVNAME(sc->sc_dev), up->portno);
}
sc->sc_running = 1;
USB_ATTACH_SUCCESS_RETURN;
-bad:
+ bad:
free(hub, M_USBDEV);
dev->hub = 0;
USB_ATTACH_ERROR_RETURN;
@@ -273,12 +273,12 @@ uhub_init_port(up)
{
int port = up->portno;
usbd_device_handle dev = up->parent;
- usbd_status r;
+ usbd_status err;
u_int16_t pstatus;
- r = usbd_get_port_status(dev, port, &up->status);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_get_port_status(dev, port, &up->status);
+ if (err)
+ return (err);
pstatus = UGETW(up->status.wPortStatus);
DPRINTF(("usbd_init_port: adding hub port=%d status=0x%04x "
"change=0x%04x\n",
@@ -295,9 +295,9 @@ usbd_clear_port_feature(dev, port, UHF_C_PORT_OVER_CURRENT);
#endif
/* then turn the power on. */
- r = usbd_set_port_feature(dev, port, UHF_PORT_POWER);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_set_port_feature(dev, port, UHF_PORT_POWER);
+ if (err)
+ return (err);
DPRINTF(("usb_init_port: turn on port %d power status=0x%04x "
"change=0x%04x\n",
port, UGETW(up->status.wPortStatus),
@@ -306,9 +306,9 @@ usbd_clear_port_feature(dev, port, UHF_C_PORT_OVER_CURRENT);
usbd_delay_ms(dev, dev->hub->hubdesc.bPwrOn2PwrGood *
UHD_PWRON_FACTOR);
/* Get the port status again. */
- r = usbd_get_port_status(dev, port, &up->status);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_get_port_status(dev, port, &up->status);
+ if (err)
+ return (err);
DPRINTF(("usb_init_port: after power on status=0x%04x "
"change=0x%04x\n",
UGETW(up->status.wPortStatus),
@@ -341,7 +341,7 @@ uhub_explore(dev)
usb_hub_descriptor_t *hd = &dev->hub->hubdesc;
struct uhub_softc *sc = dev->hub->hubsoftc;
struct usbd_port *up;
- usbd_status r;
+ usbd_status err;
int port;
int change, status;
@@ -356,11 +356,10 @@ uhub_explore(dev)
for(port = 1; port <= hd->bNbrPorts; port++) {
up = &dev->hub->ports[port-1];
- r = usbd_get_port_status(dev, port, &up->status);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_get_port_status(dev, port, &up->status);
+ if (err) {
DPRINTF(("uhub_explore: get port status failed, "
- "error=%s\n",
- usbd_errstr(r)));
+ "error=%s\n", usbd_errstr(err)));
continue;
}
status = UGETW(up->status.wPortStatus);
@@ -404,13 +403,11 @@ uhub_explore(dev)
* the disconnect.
*/
disco:
- if (up->device) {
+ if (up->device != NULL) {
/* Disconnected */
DPRINTF(("uhub_explore: device %d disappeared "
- "on port %d\n",
- up->device->address, port));
- uhub_disconnect_port(up);
-
+ "on port %d\n", up->device->address, port));
+ usb_disconnect_port(up, USBDEV(sc->sc_dev));
usbd_clear_port_feature(dev, port,
UHF_C_PORT_CONNECTION);
}
@@ -429,32 +426,26 @@ uhub_explore(dev)
continue;
/* Get device info and set its address. */
- r = usbd_new_device(USBDEV(sc->sc_dev), dev->bus,
- dev->depth + 1, status & UPS_LOW_SPEED,
- port, up);
+ err = usbd_new_device(USBDEV(sc->sc_dev), dev->bus,
+ dev->depth + 1, status & UPS_LOW_SPEED,
+ port, up);
/* XXX retry a few times? */
- if (r != USBD_NORMAL_COMPLETION) {
+ if (err) {
DPRINTFN(-1,("uhub_explore: usb_new_device failed, "
- "error=%s\n", usbd_errstr(r)));
+ "error=%s\n", usbd_errstr(err)));
/* Avoid addressing problems by disabling. */
/* usbd_reset_port(dev, port, &up->status); */
-/* XXX
- * What should we do. The device may or may not be at its
- * assigned address. In any case we'd like to ignore it.
- */
- if (r == USBD_SET_ADDR_FAILED || 1) {/* XXX */
- /* The unit refused to accept a new
- * address, and since we cannot leave
- * at 0 we have to disable the port
- * instead. */
- printf("%s: device problem, disabling "
- "port %d\n",
- USBDEVNAME(sc->sc_dev), port);
- usbd_clear_port_feature(dev, port,
- UHF_PORT_ENABLE);
- /* Make sure we don't try to restart it. */
- up->restartcnt = USBD_RESTART_MAX;
- }
+
+ /*
+ * The unit refused to accept a new address, or had
+ * some other serious problem. Since we cannot leave
+ * at 0 we have to disable the port instead.
+ */
+ printf("%s: device problem, disabling port %d\n",
+ USBDEVNAME(sc->sc_dev), port);
+ usbd_clear_port_feature(dev, port, UHF_PORT_ENABLE);
+ /* Make sure we don't try to restart it infinitely. */
+ up->restartcnt = USBD_RESTART_MAX;
} else {
if (up->device->hub)
up->device->hub->explore(up->device);
@@ -463,112 +454,31 @@ uhub_explore(dev)
return (USBD_NORMAL_COMPLETION);
}
-/*
- * The general mechanism for detaching drivers works as follows: Each
- * driver is responsible for maintaining a reference count on the
- * number of outstanding references to its softc (e.g. from
- * processing hanging in a read or write). The detach method of the
- * driver decrements this counter and flags in the softc that the
- * driver is dying and then wakes any sleepers. It then sleeps on the
- * softc. Each place that can sleep must maintain the reference
- * count. When the reference count drops to -1 (0 is the normal value
- * of the reference count) the a wakeup on the softc is performed
- * signaling to the detach waiter that all references are gone.
- */
-
-/*
- * Called from process context when we discover that a port has
- * been disconnected.
- */
-void
-uhub_disconnect_port(up)
- struct usbd_port *up;
-{
- usbd_device_handle dev = up->device;
- int i;
-
- DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
- up, dev, up->portno));
-
- if (!dev) /* not even generic device was attached */
- return;
-
- if (!dev->cdesc) {
- /* Partially attached device, just drop it. */
- dev->bus->devices[dev->address] = 0;
- up->device = 0;
- return;
- }
-
- if (dev->subdevs) {
- for (i = 0; dev->subdevs[i]; i++) {
- if (!dev->subdevs[i]) /* skip empty elements */
- continue;
-
- printf("%s: at %s port %d (addr %d) disconnected\n",
- USBDEVPTRNAME(dev->subdevs[i]),
- USBDEVPTRNAME(up->parent->subdevs[0]),
- up->portno, dev->address);
#if defined(__NetBSD__) || defined(__OpenBSD__)
- config_detach(dev->subdevs[i], DETACH_FORCE);
-#elif defined(__FreeBSD__)
- device_delete_child(device_get_parent(dev->subdevs[i]),
- dev->subdevs[i]);
-#endif
- }
- }
-
- dev->bus->devices[dev->address] = 0;
- up->device = 0;
- usb_free_device(dev);
-}
-
-#if defined(__FreeBSD__)
-/* Called when a device has been detached from it */
-static void
-uhub_child_detached(self, child)
- device_t self;
- device_t child;
-{
- struct uhub_softc *sc = device_get_softc(self);
- usbd_device_handle dev = sc->sc_hub;
- struct usbd_port *up;
- int nports;
- int port;
- int i;
-
- if (!dev->hub)
- /* should never happen; children are only created after init */
- panic("hub not fully initialised, but child deleted?");
-
- nports = dev->hub->hubdesc.bNbrPorts;
- for (port = 0; port < nports; port++) {
- up = &dev->hub->ports[port];
- if (up->device && up->device->subdevs) {
- for (i = 0; up->device->subdevs[i]; i++) {
- if (up->device->subdevs[i] == child) {
- up->device->subdevs[i] = NULL;
- return;
- }
- }
- }
- }
-}
-#endif
-
-
-#if defined(__NetBSD__)
int
uhub_activate(self, act)
device_ptr_t self;
enum devact act;
{
+ struct uhub_softc *sc = (struct uhub_softc *)self;
+ usbd_device_handle devhub = sc->sc_hub;
+ usbd_device_handle dev;
+ int nports, port, i;
+
switch (act) {
case DVACT_ACTIVATE:
return (EOPNOTSUPP);
break;
case DVACT_DEACTIVATE:
+ nports = devhub->hub->hubdesc.bNbrPorts;
+ for(port = 0; port < nports; port++) {
+ dev = devhub->hub->ports[port].device;
+ if (dev != NULL) {
+ for (i = 0; dev->subdevs[i]; i++)
+ config_deactivate(dev->subdevs[i]);
+ }
+ }
break;
}
return (0);
@@ -583,16 +493,16 @@ USB_DETACH(uhub)
{
USB_DETACH_START(uhub, sc);
usbd_device_handle dev = sc->sc_hub;
- struct usbd_port *up;
+ struct usbd_port *rup;
int port, nports;
#if defined(__NetBSD__) || defined(__OpenBSD__)
- DPRINTF(("uhub_detach: sc=%port flags=%d\n", sc, flags));
+ DPRINTF(("uhub_detach: sc=%p flags=%d\n", sc, flags));
#elif defined(__FreeBSD__)
DPRINTF(("uhub_detach: sc=%port\n", sc));
#endif
- if (!dev->hub) /* Must be partially working */
+ if (dev->hub == NULL) /* Must be partially working */
return (0);
usbd_abort_pipe(sc->sc_ipipe);
@@ -600,21 +510,51 @@ USB_DETACH(uhub)
nports = dev->hub->hubdesc.bNbrPorts;
for(port = 0; port < nports; port++) {
- up = &dev->hub->ports[port];
- if (up->device) {
- DPRINTF(("uhub_detach: device %d disappeared "
- "on port %d\n",
- up->device->address, port));
- uhub_disconnect_port(up);
- }
+ rup = &dev->hub->ports[port];
+ if (rup->device)
+ usb_disconnect_port(rup, self);
}
free(dev->hub, M_USBDEV);
- dev->hub = 0;
+ dev->hub = NULL;
return (0);
}
+#if defined(__FreeBSD__)
+/* Called when a device has been detached from it */
+static void
+uhub_child_detached(self, child)
+ device_t self;
+ device_t child;
+{
+ struct uhub_softc *sc = device_get_softc(self);
+ usbd_device_handle devhub = sc->sc_hub;
+ usbd_device_handle dev;
+ int nports;
+ int port;
+ int i;
+
+ if (!devhub->hub)
+ /* should never happen; children are only created after init */
+ panic("hub not fully initialised, but child deleted?");
+
+ nports = devhub->hub->hubdesc.bNbrPorts;
+ for (port = 0; port < nports; port++) {
+ dev = devhub->hub->ports[port].device;
+ if (dev && dev->subdevs) {
+ for (i = 0; dev->subdevs[i]; i++) {
+ if (dev->subdevs[i] == child) {
+ dev->subdevs[i] = NULL;
+ return;
+ }
+ }
+ }
+ }
+}
+#endif
+
+
/*
* Hub interrupt.
* This an indication that some port has changed status.
@@ -622,8 +562,8 @@ USB_DETACH(uhub)
* to be explored again.
*/
void
-uhub_intr(reqh, addr, status)
- usbd_request_handle reqh;
+uhub_intr(xfer, addr, status)
+ usbd_xfer_handle xfer;
usbd_private_handle addr;
usbd_status status;
{
diff --git a/sys/dev/usb/ukbd.c b/sys/dev/usb/ukbd.c
index 5ff4af6..2870031 100644
--- a/sys/dev/usb/ukbd.c
+++ b/sys/dev/usb/ukbd.c
@@ -1,4 +1,3 @@
-/* $NetBSD: ukbd.c,v 1.22 1999/01/09 12:10:36 drochner Exp $ */
/* $FreeBSD$ */
/*
@@ -112,7 +111,7 @@ typedef struct ukbd_softc {
#define UKBD_CHUNK 128 /* chunk size for read */
#define UKBD_BSIZE 1020 /* buffer size */
-typedef void usbd_intr_t(usbd_request_handle, usbd_private_handle, usbd_status);
+typedef void usbd_intr_t(usbd_xfer_handle, usbd_private_handle, usbd_status);
typedef void usbd_disco_t(void *);
static usbd_intr_t ukbd_intr;
@@ -209,7 +208,7 @@ ukbd_detach(device_t self)
}
void
-ukbd_intr(usbd_request_handle reqh, usbd_private_handle addr, usbd_status status)
+ukbd_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status)
{
keyboard_t *kbd = (keyboard_t *)addr;
@@ -582,7 +581,7 @@ static int
ukbd_enable_intr(keyboard_t *kbd, int on, usbd_intr_t *func)
{
ukbd_state_t *state = (ukbd_state_t *)kbd->kb_data;
- usbd_status r;
+ usbd_status err;
if (on) {
/* Set up interrupt pipe. */
@@ -590,12 +589,12 @@ ukbd_enable_intr(keyboard_t *kbd, int on, usbd_intr_t *func)
return EBUSY;
state->ks_ifstate |= INTRENABLED;
- r = usbd_open_pipe_intr(state->ks_iface, state->ks_ep_addr,
+ err = usbd_open_pipe_intr(state->ks_iface, state->ks_ep_addr,
USBD_SHORT_XFER_OK,
&state->ks_intrpipe, kbd,
&state->ks_ndata,
sizeof(state->ks_ndata), func);
- if (r != USBD_NORMAL_COMPLETION)
+ if (err)
return (EIO);
} else {
/* Disable interrupts. */
@@ -1333,7 +1332,7 @@ static int
init_keyboard(ukbd_state_t *state, int *type, int flags)
{
usb_endpoint_descriptor_t *ed;
- usbd_status r;
+ usbd_status err;
*type = KB_OTHER;
@@ -1360,9 +1359,9 @@ bLength=%d bDescriptorType=%d bEndpointAddress=%d-%s bmAttributes=%d wMaxPacketS
}
if ((usbd_get_quirks(state->ks_uaa->device)->uq_flags & UQ_NO_SET_PROTO) == 0) {
- r = usbd_set_protocol(state->ks_iface, 0);
+ err = usbd_set_protocol(state->ks_iface, 0);
DPRINTFN(5, ("ukbd:init_keyboard: protocol set\n"));
- if (r != USBD_NORMAL_COMPLETION) {
+ if (err) {
printf("ukbd: set protocol failed\n");
return EIO;
}
diff --git a/sys/dev/usb/ulpt.c b/sys/dev/usb/ulpt.c
index f2cd741..d183b00 100644
--- a/sys/dev/usb/ulpt.c
+++ b/sys/dev/usb/ulpt.c
@@ -1,4 +1,4 @@
-/* $NetBSD: ulpt.c,v 1.23 1999/09/11 10:40:07 augustss Exp $ */
+/* $NetBSD: ulpt.c,v 1.27 1999/10/13 08:10:57 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -71,7 +71,7 @@
#define STEP hz/4
#define LPTPRI (PZERO+8)
-#define ULPT_BSIZE 1024
+#define ULPT_BSIZE 16384
#ifdef ULPT_DEBUG
#define DPRINTF(x) if (ulptdebug) logprintf x
@@ -118,10 +118,7 @@ struct ulpt_softc {
};
#if defined(__NetBSD__) || defined(__OpenBSD__)
-int ulptopen __P((dev_t, int, int, struct proc *));
-int ulptclose __P((dev_t, int, int, struct proc *p));
-int ulptwrite __P((dev_t, struct uio *uio, int));
-int ulptioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
+cdev_decl(ulpt);
#elif defined(__FreeBSD__)
static d_open_t ulptopen;
static d_close_t ulptclose;
@@ -169,10 +166,10 @@ USB_MATCH(ulpt)
usb_interface_descriptor_t *id;
DPRINTFN(10,("ulpt_match\n"));
- if (!uaa->iface)
+ if (uaa->iface == NULL)
return (UMATCH_NONE);
id = usbd_get_interface_descriptor(uaa->iface);
- if (id &&
+ if (id != NULL &&
id->bInterfaceClass == UCLASS_PRINTER &&
id->bInterfaceSubClass == USUBCLASS_PRINTER &&
(id->bInterfaceProtocol == UPROTO_PRINTER_UNI ||
@@ -189,7 +186,7 @@ USB_ATTACH(ulpt)
usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
char devinfo[1024];
usb_endpoint_descriptor_t *ed;
- usbd_status r;
+ usbd_status err;
DPRINTFN(10,("ulpt_attach: sc=%p\n", sc));
usbd_devinfo(dev, 0, devinfo);
@@ -199,13 +196,13 @@ USB_ATTACH(ulpt)
/* Figure out which endpoint is the bulk out endpoint. */
ed = usbd_interface2endpoint_descriptor(iface, 0);
- if (!ed)
+ if (ed == NULL)
goto nobulk;
if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_OUT ||
(ed->bmAttributes & UE_XFERTYPE) != UE_BULK) {
/* In case we are using a bidir protocol... */
ed = usbd_interface2endpoint_descriptor(iface, 1);
- if (!ed)
+ if (ed == NULL)
goto nobulk;
if (UE_GET_DIR(ed->bEndpointAddress) != UE_DIR_OUT ||
(ed->bmAttributes & UE_XFERTYPE) != UE_BULK)
@@ -215,8 +212,8 @@ USB_ATTACH(ulpt)
DPRINTFN(10, ("ulpt_attach: bulk=%d\n", sc->sc_bulk));
sc->sc_iface = iface;
- r = usbd_interface2device_handle(iface, &sc->sc_udev);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_interface2device_handle(iface, &sc->sc_udev);
+ if (err) {
sc->sc_dying = 1;
USB_ATTACH_ERROR_RETURN;
}
@@ -238,8 +235,9 @@ USB_ATTACH(ulpt)
USETW(req.wValue, cd->bConfigurationValue);
USETW2(req.wIndex, id->bInterfaceNumber, id->bAlternateSetting);
USETW(req.wLength, sizeof devinfo - 1);
- r = usbd_do_request_flags(dev, &req, devinfo,USBD_SHORT_XFER_OK,&alen);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_do_request_flags(dev, &req, devinfo, USBD_SHORT_XFER_OK,
+ &alen);
+ if (err) {
printf("%s: cannot get device id\n", USBDEVNAME(sc->sc_dev));
} else if (alen <= 2) {
printf("%s: empty device id, no printer connected?\n",
@@ -307,7 +305,7 @@ USB_DETACH(ulpt)
#endif
sc->sc_dying = 1;
- if (sc->sc_bulkpipe)
+ if (sc->sc_bulkpipe != NULL)
usbd_abort_pipe(sc->sc_bulkpipe);
s = splusb();
@@ -342,7 +340,7 @@ ulpt_status(sc)
struct ulpt_softc *sc;
{
usb_device_request_t req;
- usbd_status r;
+ usbd_status err;
u_char status;
req.bmRequestType = UT_READ_CLASS_INTERFACE;
@@ -350,9 +348,9 @@ ulpt_status(sc)
USETW(req.wValue, 0);
USETW(req.wIndex, sc->sc_ifaceno);
USETW(req.wLength, 1);
- r = usbd_do_request(sc->sc_udev, &req, &status);
- DPRINTFN(1, ("ulpt_status: status=0x%02x r=%d\n", status, r));
- if (r == USBD_NORMAL_COMPLETION)
+ err = usbd_do_request(sc->sc_udev, &req, &status);
+ DPRINTFN(1, ("ulpt_status: status=0x%02x err=%d\n", status, err));
+ if (!err)
return (status);
else
return (0);
@@ -384,11 +382,13 @@ ulptopen(dev, flag, mode, p)
struct proc *p;
{
u_char flags = ULPTFLAGS(dev);
- usbd_status r;
+ struct ulpt_softc *sc;
+ usbd_status err;
int spin, error;
+
USB_GET_SC_OPEN(ulpt, ULPTUNIT(dev), sc);
- if (!sc || !sc->sc_iface || sc->sc_dying)
+ if (sc == NULL || sc->sc_iface == NULL || sc->sc_dying)
return (ENXIO);
if (sc->sc_state)
@@ -423,8 +423,8 @@ ulptopen(dev, flag, mode, p)
}
}
- r = usbd_open_pipe(sc->sc_iface, sc->sc_bulk, 0, &sc->sc_bulkpipe);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_open_pipe(sc->sc_iface, sc->sc_bulk, 0, &sc->sc_bulkpipe);
+ if (err) {
sc->sc_state = 0;
return (EIO);
}
@@ -463,6 +463,8 @@ ulptclose(dev, flag, mode, p)
int mode;
struct proc *p;
{
+ struct ulpt_softc *sc;
+
USB_GET_SC(ulpt, ULPTUNIT(dev), sc);
if (sc->sc_state != ULPT_OPEN)
@@ -487,16 +489,16 @@ ulpt_do_write(sc, uio, flags)
u_int32_t n;
int error = 0;
void *bufp;
- usbd_request_handle reqh;
- usbd_status r;
+ usbd_xfer_handle xfer;
+ usbd_status err;
DPRINTF(("ulptwrite\n"));
- reqh = usbd_alloc_request(sc->sc_udev);
- if (reqh == 0)
+ xfer = usbd_alloc_request(sc->sc_udev);
+ if (xfer == NULL)
return (ENOMEM);
- bufp = usbd_alloc_buffer(reqh, ULPT_BSIZE);
- if (bufp == 0) {
- usbd_free_request(reqh);
+ bufp = usbd_alloc_buffer(xfer, ULPT_BSIZE);
+ if (bufp == NULL) {
+ usbd_free_request(xfer);
return (ENOMEM);
}
while ((n = min(ULPT_BSIZE, uio->uio_resid)) != 0) {
@@ -505,15 +507,15 @@ ulpt_do_write(sc, uio, flags)
if (error)
break;
DPRINTFN(1, ("ulptwrite: transfer %d bytes\n", n));
- r = usbd_bulk_transfer(reqh, sc->sc_bulkpipe, 0,
- USBD_NO_TIMEOUT, bufp, &n, "ulptwr");
- if (r != USBD_NORMAL_COMPLETION) {
- DPRINTF(("ulptwrite: error=%d\n", r));
+ err = usbd_bulk_transfer(xfer, sc->sc_bulkpipe, USBD_NO_COPY,
+ USBD_NO_TIMEOUT, bufp, &n, "ulptwr");
+ if (err) {
+ DPRINTF(("ulptwrite: error=%d\n", err));
error = EIO;
break;
}
}
- usbd_free_request(reqh);
+ usbd_free_request(xfer);
return (error);
}
@@ -524,9 +526,11 @@ ulptwrite(dev, uio, flags)
struct uio *uio;
int flags;
{
- USB_GET_SC(ulpt, ULPTUNIT(dev), sc);
+ struct ulpt_softc *sc;
int error;
+ USB_GET_SC(ulpt, ULPTUNIT(dev), sc);
+
if (sc->sc_dying)
return (EIO);
diff --git a/sys/dev/usb/umass.c b/sys/dev/usb/umass.c
index 42fb25b..867d049 100644
--- a/sys/dev/usb/umass.c
+++ b/sys/dev/usb/umass.c
@@ -288,7 +288,7 @@ umass_usb_transfer(usbd_interface_handle iface, usbd_pipe_handle pipe,
void *buf, int buflen, int flags, int *xfer_size)
{
usbd_device_handle dev;
- usbd_request_handle reqh;
+ usbd_xfer_handle xfer;
usbd_private_handle priv;
void *buffer;
int size;
@@ -300,28 +300,28 @@ umass_usb_transfer(usbd_interface_handle iface, usbd_pipe_handle pipe,
usbd_interface2device_handle(iface, &dev);
- reqh = usbd_alloc_request(dev);
- if (!reqh) {
+ xfer = usbd_alloc_request(dev);
+ if (!xfer) {
DPRINTF(UDMASS_USB, ("Not enough memory\n"));
return USBD_NOMEM;
}
- (void) usbd_setup_request(reqh, pipe, 0, buf, buflen,
+ (void) usbd_setup_request(xfer, pipe, 0, buf, buflen,
flags, 3000 /*ms*/, NULL);
- err = usbd_sync_transfer(reqh);
+ err = usbd_sync_transfer(xfer);
if (err) {
DPRINTF(UDMASS_USB, ("transfer failed, %s\n",
usbd_errstr(err)));
- usbd_free_request(reqh);
+ usbd_free_request(xfer);
return(err);
}
- usbd_get_request_status(reqh, &priv, &buffer, &size, &err);
+ usbd_get_request_status(xfer, &priv, &buffer, &size, &err);
if (xfer_size)
*xfer_size = size;
- usbd_free_request(reqh);
+ usbd_free_request(xfer);
return(USBD_NORMAL_COMPLETION);
}
diff --git a/sys/dev/usb/ums.c b/sys/dev/usb/ums.c
index 20e6fcf..3a997e0 100644
--- a/sys/dev/usb/ums.c
+++ b/sys/dev/usb/ums.c
@@ -123,7 +123,7 @@ struct ums_softc {
#define MOUSE_FLAGS_MASK (HIO_CONST|HIO_RELATIVE)
#define MOUSE_FLAGS (HIO_RELATIVE)
-static void ums_intr __P((usbd_request_handle reqh,
+static void ums_intr __P((usbd_xfer_handle xfer,
usbd_private_handle priv, usbd_status status));
static void ums_add_to_queue __P((struct ums_softc *sc,
@@ -166,7 +166,7 @@ USB_MATCH(ums)
usb_interface_descriptor_t *id;
int size, ret;
void *desc;
- usbd_status r;
+ usbd_status err;
if (!uaa->iface)
return (UMATCH_NONE);
@@ -174,8 +174,8 @@ USB_MATCH(ums)
if (!id || id->bInterfaceClass != UCLASS_HID)
return (UMATCH_NONE);
- r = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_TEMP);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_TEMP);
+ if (err)
return (UMATCH_NONE);
if (hid_is_collection(desc, size,
@@ -196,7 +196,7 @@ USB_ATTACH(ums)
usb_endpoint_descriptor_t *ed;
int size;
void *desc;
- usbd_status r;
+ usbd_status err;
char devinfo[1024];
u_int32_t flags;
int i;
@@ -232,8 +232,8 @@ USB_ATTACH(ums)
USB_ATTACH_ERROR_RETURN;
}
- r = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_TEMP);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_alloc_report_desc(uaa->iface, &desc, &size, M_TEMP);
+ if (err)
USB_ATTACH_ERROR_RETURN;
if (!hid_locate(desc, size, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X),
@@ -395,8 +395,8 @@ ums_detach(device_t self)
}
void
-ums_intr(reqh, addr, status)
- usbd_request_handle reqh;
+ums_intr(xfer, addr, status)
+ usbd_xfer_handle xfer;
usbd_private_handle addr;
usbd_status status;
{
@@ -444,6 +444,12 @@ ums_intr(reqh, addr, status)
sc->status.dy += dy;
sc->status.dz += dz;
+ /* Discard data in case of full buffer */
+ if (sc->qcount == sizeof(sc->qbuf)) {
+ DPRINTF(("Buffer full, discarded packet"));
+ return;
+ }
+
/*
* The Qtronix keyboard has a built in PS/2 port for a mouse.
* The firmware once in a while posts a spurious button up
@@ -528,7 +534,7 @@ ums_enable(v)
{
struct ums_softc *sc = v;
- usbd_status r;
+ usbd_status err;
if (sc->sc_enabled)
return EBUSY;
@@ -543,12 +549,12 @@ ums_enable(v)
callout_handle_init(&sc->timeout_handle);
/* Set up interrupt pipe. */
- r = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr,
+ err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ep_addr,
USBD_SHORT_XFER_OK, &sc->sc_intrpipe, sc,
sc->sc_ibuf, sc->sc_isize, ums_intr);
- if (r != USBD_NORMAL_COMPLETION) {
+ if (err) {
DPRINTF(("ums_enable: usbd_open_pipe_intr failed, error=%d\n",
- r));
+ err));
sc->sc_enabled = 0;
return (EIO);
}
@@ -576,6 +582,8 @@ ums_disable(priv)
static int
ums_open(dev_t dev, int flag, int fmt, struct proc *p)
{
+ struct ums_softc *sc;
+
USB_GET_SC_OPEN(ums, UMSUNIT(dev), sc);
return ums_enable(sc);
@@ -584,6 +592,8 @@ ums_open(dev_t dev, int flag, int fmt, struct proc *p)
static int
ums_close(dev_t dev, int flag, int fmt, struct proc *p)
{
+ struct ums_softc *sc;
+
USB_GET_SC(ums, UMSUNIT(dev), sc);
if (!sc)
@@ -598,12 +608,14 @@ ums_close(dev_t dev, int flag, int fmt, struct proc *p)
static int
ums_read(dev_t dev, struct uio *uio, int flag)
{
- USB_GET_SC(ums, UMSUNIT(dev), sc);
+ struct ums_softc *sc;
int s;
char buf[sizeof(sc->qbuf)];
int l = 0;
int error;
+ USB_GET_SC(ums, UMSUNIT(dev), sc);
+
s = splusb();
if (!sc) {
splx(s);
@@ -666,10 +678,12 @@ ums_read(dev_t dev, struct uio *uio, int flag)
static int
ums_poll(dev_t dev, int events, struct proc *p)
{
- USB_GET_SC(ums, UMSUNIT(dev), sc);
+ struct ums_softc *sc;
int revents = 0;
int s;
+ USB_GET_SC(ums, UMSUNIT(dev), sc);
+
if (!sc)
return 0;
@@ -690,11 +704,13 @@ ums_poll(dev_t dev, int events, struct proc *p)
int
ums_ioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
{
- USB_GET_SC(ums, UMSUNIT(dev), sc);
+ struct ums_softc *sc;
int error = 0;
int s;
mousemode_t mode;
+ USB_GET_SC(ums, UMSUNIT(dev), sc);
+
if (!sc)
return EIO;
diff --git a/sys/dev/usb/usb.c b/sys/dev/usb/usb.c
index f774835..5005a4d 100644
--- a/sys/dev/usb/usb.c
+++ b/sys/dev/usb/usb.c
@@ -1,4 +1,4 @@
-/* $NetBSD: usb.c,v 1.19 1999/09/05 19:32:19 augustss Exp $ */
+/* $NetBSD: usb.c,v 1.28 1999/10/13 08:10:57 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -55,17 +55,21 @@
#elif defined(__FreeBSD__)
#include <sys/module.h>
#include <sys/bus.h>
-#include <sys/ioccom.h>
+#include <sys/filio.h>
#include <sys/uio.h>
-#include <sys/conf.h>
#endif
+#include <sys/conf.h>
#include <sys/poll.h>
#include <sys/select.h>
+#include <sys/vnode.h>
+#include <sys/signalvar.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <dev/usb/usbdi_util.h>
+#define USB_DEV_MINOR 255
+
#if defined(__FreeBSD__)
MALLOC_DEFINE(M_USB, "USB", "USB");
MALLOC_DEFINE(M_USBDEV, "USBdev", "USB device");
@@ -74,6 +78,8 @@ MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller");
#include "usb_if.h"
#endif /* defined(__FreeBSD__) */
+#include <machine/bus.h>
+
#include <dev/usb/usbdivar.h>
#include <dev/usb/usb_quirks.h>
@@ -81,35 +87,39 @@ MALLOC_DEFINE(M_USBHC, "USBHC", "USB host controller");
#define DPRINTF(x) if (usbdebug) logprintf x
#define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x
int usbdebug = 0;
-extern int uhcidebug;
-extern int ohcidebug;
+#ifdef UHCI_DEBUG
+extern int uhcidebug;
+#endif
+#ifdef OHCI_DEBUG
+extern int ohcidebug;
+#endif
+int usb_noexplore = 0;
#else
#define DPRINTF(x)
#define DPRINTFN(n,x)
#endif
-#define USBUNIT(dev) (minor(dev))
-
struct usb_softc {
- USBBASEDEVICE sc_dev; /* base device */
+ USBBASEDEVICE sc_dev; /* base device */
usbd_bus_handle sc_bus; /* USB controller */
struct usbd_port sc_port; /* dummy port for root hub */
- char sc_running;
- char sc_exploring;
- struct selinfo sc_consel; /* waiting for connect change */
- int shutdown;
- struct proc *event_thread;
+
+#if defined(__FreeBSD__)
+ /* This part should be deleted when kthreads is available */
+ struct selinfo sc_consel; /* waiting for connect change */
+#else
+ struct proc *sc_event_thread;
+#endif
+
+ char sc_dying;
};
#if defined(__NetBSD__) || defined(__OpenBSD__)
-int usbopen __P((dev_t, int, int, struct proc *));
-int usbclose __P((dev_t, int, int, struct proc *));
-int usbioctl __P((dev_t, u_long, caddr_t, int, struct proc *));
-int usbpoll __P((dev_t, int, struct proc *));
-
+cdev_decl(usb);
#elif defined(__FreeBSD__)
d_open_t usbopen;
d_close_t usbclose;
+d_read_t usbread;
d_ioctl_t usbioctl;
int usbpoll __P((dev_t, int, struct proc *));
@@ -131,9 +141,28 @@ struct cdevsw usb_cdevsw = {
};
#endif
-usbd_status usb_discover __P((struct usb_softc *));
-void usb_create_event_thread __P((void *));
-void usb_event_thread __P((void *));
+static usbd_status usb_discover __P((struct usb_softc *));
+static void usb_create_event_thread __P((void *));
+static void usb_event_thread __P((void *));
+
+#define USB_MAX_EVENTS 50
+struct usb_event_q {
+ struct usb_event ue;
+ SIMPLEQ_ENTRY(usb_event_q) next;
+};
+static SIMPLEQ_HEAD(, usb_event_q) usb_events =
+ SIMPLEQ_HEAD_INITIALIZER(usb_events);
+static int usb_nevents = 0;
+static struct selinfo usb_selevent;
+static struct proc *usb_async_proc; /* process who wants USB SIGIO */
+static int usb_dev_open = 0;
+
+static int usb_get_next_event __P((struct usb_event *));
+
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+/* Flag to see if we are in the cold boot process. */
+extern int cold;
+#endif
USB_DECLARE_DRIVER(usb);
@@ -152,7 +181,7 @@ USB_ATTACH(usb)
void *aux = device_get_ivars(self);
#endif
usbd_device_handle dev;
- usbd_status r;
+ usbd_status err;
#if defined(__NetBSD__) || defined(__OpenBSD__)
printf("\n");
@@ -161,38 +190,45 @@ USB_ATTACH(usb)
#endif
DPRINTF(("usbd_attach\n"));
-
+ usbd_init();
sc->sc_bus = aux;
sc->sc_bus->usbctl = sc;
- sc->sc_running = 1;
- sc->sc_bus->use_polling = 1;
sc->sc_port.power = USB_MAX_POWER;
- r = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0,0,0, &sc->sc_port);
+ err = usbd_new_device(USBDEV(sc->sc_dev), sc->sc_bus, 0, 0, 0,
+ &sc->sc_port);
- if (r == USBD_NORMAL_COMPLETION) {
+ if (!err) {
dev = sc->sc_port.device;
- if (!dev->hub) {
- sc->sc_running = 0;
+ if (dev->hub == NULL) {
+ sc->sc_dying = 1;
printf("%s: root device is not a hub\n",
USBDEVNAME(sc->sc_dev));
USB_ATTACH_ERROR_RETURN;
}
sc->sc_bus->root_hub = dev;
- dev->hub->explore(sc->sc_bus->root_hub);
+#if 1
+ /*
+ * Turning this code off will delay attachment of USB devices
+ * until the USB event thread is running, which means that
+ * the keyboard will not work until after cold boot.
+ */
+ if (cold) {
+ sc->sc_bus->use_polling++;
+ dev->hub->explore(sc->sc_bus->root_hub);
+ sc->sc_bus->use_polling--;
+ }
+#endif
} else {
printf("%s: root hub problem, error=%d\n",
- USBDEVNAME(sc->sc_dev), r);
- sc->sc_running = 0;
+ USBDEVNAME(sc->sc_dev), err);
+ sc->sc_dying = 1;
}
- sc->sc_bus->use_polling = 0;
-#if defined(__NetBSD__) || defined(__OpenBSD__)
kthread_create(usb_create_event_thread, sc);
-#endif
#if defined(__FreeBSD__)
make_dev(&usb_cdevsw, device_get_unit(self), UID_ROOT, GID_OPERATOR,
- 0644, "usb%d", device_get_unit(self));
+ 0644, "usb%d", device_get_unit(self));
#endif
USB_ATTACH_SUCCESS_RETURN;
@@ -205,7 +241,7 @@ usb_create_event_thread(arg)
{
struct usb_softc *sc = arg;
- if (kthread_create1(usb_event_thread, sc, &sc->event_thread,
+ if (kthread_create1(usb_event_thread, sc, &sc->sc_event_thread,
"%s", sc->sc_dev.dv_xname)) {
printf("%s: unable to create event thread for\n",
sc->sc_dev.dv_xname);
@@ -219,17 +255,23 @@ usb_event_thread(arg)
{
struct usb_softc *sc = arg;
- while (!sc->shutdown) {
+ DPRINTF(("usb_event_thread: start\n"));
+
+ while (!sc->sc_dying) {
+#ifdef USB_DEBUG
+ if (!usb_noexplore)
+#endif
+ usb_discover(sc);
(void)tsleep(&sc->sc_bus->needs_explore,
- PWAIT, "usbevt", hz*30);
+ PWAIT, "usbevt", hz*60);
DPRINTFN(2,("usb_event_thread: woke up\n"));
- usb_discover(sc);
}
- sc->event_thread = 0;
+ sc->sc_event_thread = 0;
/* In case parent is waiting for us to exit. */
wakeup(sc);
+ DPRINTF(("usb_event_thread: exit\n"));
kthread_exit(0);
}
@@ -244,7 +286,7 @@ usbctlprint(aux, pnp)
return (UNCONF);
}
-#endif /* NetBSD && OpenBSD */
+#endif /* defined(__NetBSD__) || defined(__OpenBSD__) */
int
usbopen(dev, flag, mode, p)
@@ -252,20 +294,74 @@ usbopen(dev, flag, mode, p)
int flag, mode;
struct proc *p;
{
- USB_GET_SC_OPEN(usb, USBUNIT(dev), sc);
+ int unit = minor(dev);
+ struct usb_softc *sc;
- if (sc == 0 || !sc->sc_running)
- return (ENXIO);
+ if (unit == USB_DEV_MINOR) {
+ if (usb_dev_open)
+ return (EBUSY);
+ usb_dev_open = 1;
+ usb_async_proc = 0;
+ return (0);
+ }
+
+ USB_GET_SC_OPEN(usb, unit, sc);
+
+ if (sc->sc_dying)
+ return (EIO);
return (0);
}
int
+usbread(dev, uio, flag)
+ dev_t dev;
+ struct uio *uio;
+ int flag;
+{
+ struct usb_event ue;
+ int s, error, n;
+
+ if (minor(dev) != USB_DEV_MINOR)
+ return (ENXIO);
+
+ if (uio->uio_resid != sizeof(struct usb_event))
+ return (EINVAL);
+
+ error = 0;
+ s = splusb();
+ for (;;) {
+ n = usb_get_next_event(&ue);
+ if (n != 0)
+ break;
+ if (flag & IO_NDELAY) {
+ error = EWOULDBLOCK;
+ break;
+ }
+ error = tsleep(&usb_events, PZERO | PCATCH, "usbrea", 0);
+ if (error)
+ break;
+ }
+ splx(s);
+ if (!error)
+ error = uiomove((void *)&ue, uio->uio_resid, uio);
+
+ return (error);
+}
+
+int
usbclose(dev, flag, mode, p)
dev_t dev;
int flag, mode;
struct proc *p;
{
+ int unit = minor(dev);
+
+ if (unit == USB_DEV_MINOR) {
+ usb_async_proc = 0;
+ usb_dev_open = 0;
+ }
+
return (0);
}
@@ -277,19 +373,48 @@ usbioctl(devt, cmd, data, flag, p)
int flag;
struct proc *p;
{
- USB_GET_SC(usb, USBUNIT(devt), sc);
+ struct usb_softc *sc;
+ int unit = minor(devt);
+
+ if (unit == USB_DEV_MINOR) {
+ switch (cmd) {
+ case FIONBIO:
+ /* All handled in the upper FS layer. */
+ return (0);
+
+ case FIOASYNC:
+ if (*(int *)data)
+ usb_async_proc = p;
+ else
+ usb_async_proc = 0;
+ return (0);
+
+ default:
+ return (EINVAL);
+ }
+ }
+
+ USB_GET_SC(usb, unit, sc);
+
+ if (sc->sc_dying)
+ return (EIO);
- if (sc == 0 || !sc->sc_running)
- return (ENXIO);
switch (cmd) {
+#if defined(__FreeBSD__)
+ /* This part should be deleted when kthreads is available */
+ case USB_DISCOVER:
+ usb_discover(sc);
+ break;
+#endif
#ifdef USB_DEBUG
case USB_SETDEBUG:
- usbdebug = uhcidebug = ohcidebug = *(int *)data;
- break;
+ usbdebug = ((*(int *)data) & 0x000000ff);
+#ifdef UHCI_DEBUG
+ uhcidebug = ((*(int *)data) & 0x0000ff00) >> 8;
+#endif
+#ifdef OHCI_DEBUG
+ ohcidebug = ((*(int *)data) & 0x00ff0000) >> 16;
#endif
-#if defined(__FreeBSD__)
- case USB_DISCOVER:
- usb_discover(sc);
break;
#endif
case USB_REQUEST:
@@ -300,7 +425,7 @@ usbioctl(devt, cmd, data, flag, p)
struct uio uio;
void *ptr = 0;
int addr = ur->addr;
- usbd_status r;
+ usbd_status err;
int error = 0;
DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len));
@@ -328,10 +453,9 @@ usbioctl(devt, cmd, data, flag, p)
goto ret;
}
}
- r = usbd_do_request_flags(sc->sc_bus->devices[addr],
- &ur->request, ptr,
- ur->flags, &ur->actlen);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_do_request_flags(sc->sc_bus->devices[addr],
+ &ur->request, ptr, ur->flags, &ur->actlen);
+ if (err) {
error = EIO;
goto ret;
}
@@ -368,7 +492,7 @@ usbioctl(devt, cmd, data, flag, p)
break;
default:
- return (ENXIO);
+ return (EINVAL);
}
return (0);
}
@@ -379,79 +503,77 @@ usbpoll(dev, events, p)
int events;
struct proc *p;
{
- int revents, s;
- USB_GET_SC(usb, USBUNIT(dev), sc);
+ int revents, mask, s;
- DPRINTFN(15, ("usbpoll: sc=%p events=0x%x\n", sc, events));
- s = splusb();
- revents = 0;
- if (events & (POLLOUT | POLLWRNORM))
- if (sc->sc_bus->needs_explore)
- revents |= events & (POLLOUT | POLLWRNORM);
- DPRINTFN(15, ("usbpoll: revents=0x%x\n", revents));
- if (revents == 0) {
- if (events & (POLLOUT | POLLWRNORM)) {
- DPRINTFN(2, ("usbpoll: selrecord\n"));
- selrecord(p, &sc->sc_consel);
- }
- }
- splx(s);
- return (revents);
-}
+ if (minor(dev) == USB_DEV_MINOR) {
+ revents = 0;
+ mask = POLLIN | POLLRDNORM;
-#if 0
-int
-usb_bus_count()
-{
- int i, n;
+ s = splusb();
+ if (events & mask && usb_nevents > 0)
+ revents |= events & mask;
+ if (revents == 0 && events & mask)
+ selrecord(p, &usb_selevent);
+ splx(s);
- for (i = n = 0; i < usb_cd.cd_ndevs; i++)
- if (usb_cd.cd_devs[i])
- n++;
- return (n);
-}
-#endif
+ return (revents);
+ } else {
+#if defined(__FreeBSD__)
+ /* This part should be deleted when kthreads is available */
+ struct usb_softc *sc;
+ int unit = minor(dev);
-#if 0
-usbd_status
-usb_get_bus_handle(n, h)
- int n;
- usbd_bus_handle *h;
-{
- int i;
+ USB_GET_SC(usb, unit, sc);
- for (i = 0; i < usb_cd.cd_ndevs; i++)
- if (usb_cd.cd_devs[i] && n-- == 0) {
- *h = usb_cd.cd_devs[i];
- return (USBD_NORMAL_COMPLETION);
- }
- return (USBD_INVAL);
-}
+ revents = 0;
+ mask = POLLOUT | POLLRDNORM;
+
+ s = splusb();
+ if (events & mask && sc->sc_bus->needs_explore)
+ revents |= events & mask;
+ if (revents == 0 && events & mask)
+ selrecord(p, &sc->sc_consel);
+ splx(s);
+
+ return (revents);
+#else
+ return (ENXIO);
#endif
+ }
+}
+/* Explore device tree from the root. */
usbd_status
usb_discover(sc)
struct usb_softc *sc;
{
+#if defined(__FreeBSD__)
+ /* The splxxx parts should be deleted when kthreads is available */
int s;
+#endif
- /* Explore device tree from the root */
- /* We need mutual exclusion while traversing the device tree. */
- do {
- s = splusb();
- while (sc->sc_exploring)
- tsleep(&sc->sc_exploring, PRIBIO, "usbdis", 0);
- sc->sc_exploring = 1;
+ /*
+ * We need mutual exclusion while traversing the device tree,
+ * but this is guaranteed since this function is only called
+ * from the event thread for the controller.
+ */
+#if defined(__FreeBSD__)
+ s = splusb();
+#endif
+ while (sc->sc_bus->needs_explore && !sc->sc_dying) {
sc->sc_bus->needs_explore = 0;
+#if defined(__FreeBSD__)
splx(s);
-
+#endif
sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub);
-
+#if defined(__FreeBSD__)
s = splusb();
- sc->sc_exploring = 0;
- wakeup(&sc->sc_exploring);
- splx(s);
- } while (sc->sc_bus->needs_explore);
+#endif
+ }
+#if defined(__FreeBSD__)
+ splx(s);
+#endif
+
return (USBD_NORMAL_COMPLETION);
}
@@ -460,18 +582,90 @@ usb_needs_explore(bus)
usbd_bus_handle bus;
{
bus->needs_explore = 1;
+#if defined(__FreeBSD__)
+ /* This part should be deleted when kthreads is available */
selwakeup(&bus->usbctl->sc_consel);
+#endif
wakeup(&bus->needs_explore);
}
+/* Called at splusb() */
+int
+usb_get_next_event(ue)
+ struct usb_event *ue;
+{
+ struct usb_event_q *ueq;
+
+ if (usb_nevents <= 0)
+ return (0);
+ ueq = SIMPLEQ_FIRST(&usb_events);
+ *ue = ueq->ue;
+ SIMPLEQ_REMOVE_HEAD(&usb_events, ueq, next);
+ free(ueq, M_USBDEV);
+ usb_nevents--;
+ return (1);
+}
+
+void
+usbd_add_event(type, dev)
+ int type;
+ usbd_device_handle dev;
+{
+ struct usb_event_q *ueq;
+ struct usb_event ue;
+ struct timeval thetime;
+ int s;
+
+ s = splusb();
+ if (++usb_nevents >= USB_MAX_EVENTS) {
+ /* Too many queued events, drop an old one. */
+ DPRINTFN(-1,("usb: event dropped\n"));
+ (void)usb_get_next_event(&ue);
+ }
+ /* Don't want to wait here inside splusb() */
+ ueq = malloc(sizeof *ueq, M_USBDEV, M_NOWAIT);
+ if (ueq == NULL) {
+ printf("usb: no memory, event dropped\n");
+ splx(s);
+ return;
+ }
+ ueq->ue.ue_type = type;
+ ueq->ue.ue_cookie = dev->cookie;
+ usbd_fill_deviceinfo(dev, &ueq->ue.ue_device);
+ microtime(&thetime);
+ TIMEVAL_TO_TIMESPEC(&thetime, &ueq->ue.ue_time);
+ SIMPLEQ_INSERT_TAIL(&usb_events, ueq, next);
+ wakeup(&usb_events);
+ selwakeup(&usb_selevent);
+ if (usb_async_proc != NULL)
+ psignal(usb_async_proc, SIGIO);
+ splx(s);
+}
+
#if defined(__NetBSD__) || defined(__OpenBSD__)
int
usb_activate(self, act)
device_ptr_t self;
enum devact act;
{
- panic("usb_activate\n");
- return (0);
+ struct usb_softc *sc = (struct usb_softc *)self;
+ usbd_device_handle dev = sc->sc_port.device;
+ int i, rv = 0;
+
+ switch (act) {
+ case DVACT_ACTIVATE:
+ return (EOPNOTSUPP);
+ break;
+
+ case DVACT_DEACTIVATE:
+ sc->sc_dying = 1;
+ if (dev && dev->cdesc && dev->subdevs) {
+ for (i = 0; dev->subdevs[i]; i++)
+ rv |= config_deactivate(dev->subdevs[i]);
+ }
+ break;
+ }
+ return (rv);
}
int
@@ -479,7 +673,26 @@ usb_detach(self, flags)
device_ptr_t self;
int flags;
{
- panic("usb_detach\n");
+ struct usb_softc *sc = (struct usb_softc *)self;
+
+ DPRINTF(("usb_detach: start\n"));
+
+ sc->sc_dying = 1;
+
+ /* Make all devices disconnect. */
+ if (sc->sc_port.device)
+ usb_disconnect_port(&sc->sc_port, self);
+
+ /* Kill off event thread. */
+ if (sc->sc_event_thread) {
+ wakeup(&sc->sc_bus->needs_explore);
+ if (tsleep(sc, PWAIT, "usbdet", hz * 60))
+ printf("%s: event thread didn't die\n",
+ USBDEVNAME(sc->sc_dev));
+ DPRINTF(("usb_detach: event thread dead\n"));
+ }
+
+ usbd_finish();
return (0);
}
#elif defined(__FreeBSD__)
diff --git a/sys/dev/usb/usb.h b/sys/dev/usb/usb.h
index 4152b72..0d4703b 100644
--- a/sys/dev/usb/usb.h
+++ b/sys/dev/usb/usb.h
@@ -1,4 +1,4 @@
-/* $NetBSD: usb.h,v 1.33 1999/09/11 08:19:27 augustss Exp $ */
+/* $NetBSD: usb.h,v 1.37 1999/10/13 18:52:54 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -43,6 +43,7 @@
#define _USB_H_
#include <sys/types.h>
+#include <sys/time.h>
#if defined(__NetBSD__) || defined(__OpenBSD__)
#include <sys/ioctl.h>
@@ -244,6 +245,7 @@ typedef struct {
#define UE_ISO_ASYNC 0x04
#define UE_ISO_ADAPT 0x08
#define UE_ISO_SYNC 0x0c
+#define UE_GET_ISO_TYPE(a) ((a) & UE_ISO_TYPE)
uWord wMaxPacketSize;
uByte bInterval;
} usb_endpoint_descriptor_t;
@@ -339,13 +341,13 @@ typedef struct {
#define USUBCLASS_AUDIOSTREAM 2
#define USUBCLASS_MIDISTREAM 3
#define UCLASS_CDC 2 /* communication */
-#define USUBCLASS_DIRECT_LINE_CONTROL_MODEL 1
+#define USUBCLASS_DIRECT_LINE_CONTROL_MODEL 1
#define USUBCLASS_ABSTRACT_CONTROL_MODEL 2
-#define USUBCLASS_TELEPHONE_CONTROL_MODEL 3
-#define USUBCLASS_MULTICHANNEL_CONTROL_MODEL 4
-#define USUBCLASS_CAPI_CONTROLMODEL 5
-#define USUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6
-#define USUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7
+#define USUBCLASS_TELEPHONE_CONTROL_MODEL 3
+#define USUBCLASS_MULTICHANNEL_CONTROL_MODEL 4
+#define USUBCLASS_CAPI_CONTROLMODEL 5
+#define USUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL 6
+#define USUBCLASS_ATM_NETWORKING_CONTROL_MODEL 7
#define UPROTO_CDC_AT 1
#define UCLASS_HID 3
#define USUBCLASS_BOOT 1
@@ -379,7 +381,7 @@ typedef struct {
#define UPROTO_DATA_V120 0x92 /* V.24 rate adaption */
#define UPROTO_DATA_CAPI 0x93 /* CAPI 2.0 commands */
#define UPROTO_DATA_HOST_BASED 0xfd /* Host based driver */
-#define UPROTO_DATA_PUF 0xfe /* see Prot. Unit Func. Desc. */
+#define UPROTO_DATA_PUF 0xfe /* see Prot. Unit Func. Desc.*/
#define UPROTO_DATA_VENDOR 0xff /* Vendor specific */
@@ -494,7 +496,7 @@ struct usb_device_info {
};
struct usb_ctl_report {
- int report;
+ int report;
u_char data[1024]; /* filled data size will vary */
};
@@ -502,6 +504,17 @@ struct usb_device_stats {
u_long requests[4]; /* indexed by transfer type UE_* */
};
+typedef struct { u_int32_t cookie; } usb_event_cookie_t;
+/* Events that can be read from /dev/usb */
+struct usb_event {
+ int ue_type;
+#define USB_EVENT_ATTACH 1
+#define USB_EVENT_DETACH 2
+ struct usb_device_info ue_device;
+ struct timespec ue_time;
+ usb_event_cookie_t ue_cookie;
+};
+
/* USB controller */
#define USB_REQUEST _IOWR('U', 1, struct usb_ctl_request)
#define USB_SETDEBUG _IOW ('U', 2, int)
diff --git a/sys/dev/usb/usb_mem.h b/sys/dev/usb/usb_mem.h
index e254fb4..2c12aab 100644
--- a/sys/dev/usb/usb_mem.h
+++ b/sys/dev/usb/usb_mem.h
@@ -1,5 +1,5 @@
-/* $NetBSD: usb_mem.h,v 1.7 1999/09/09 12:26:47 augustss Exp $ */
-/* $FreeBSD$ */
+/* $NetBSD: usb_mem.h,v 1.9 1999/10/13 08:10:58 augustss Exp $ */
+/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -54,8 +54,8 @@ typedef struct usb_dma_block {
#define DMAADDR(dma) ((dma)->block->segs[0].ds_addr + (dma)->offs)
#define KERNADDR(dma) ((void *)((dma)->block->kaddr + (dma)->offs))
-usbd_status usb_allocmem __P((bus_dma_tag_t, size_t, size_t, usb_dma_t *));
-void usb_freemem __P((bus_dma_tag_t, usb_dma_t *));
+usbd_status usb_allocmem __P((usbd_bus_handle,size_t,size_t, usb_dma_t *));
+void usb_freemem __P((usbd_bus_handle, usb_dma_t *));
#elif defined(__FreeBSD__)
diff --git a/sys/dev/usb/usb_port.h b/sys/dev/usb/usb_port.h
index 55b4db2..82e072d 100644
--- a/sys/dev/usb/usb_port.h
+++ b/sys/dev/usb/usb_port.h
@@ -1,4 +1,4 @@
-/* $NetBSD: usb_port.h,v 1.11 1999/09/11 08:19:27 augustss Exp $ */
+/* $NetBSD: usb_port.h,v 1.13 1999/10/13 08:10:58 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -50,6 +50,16 @@
#include "opt_usbverbose.h"
+#ifdef USB_DEBUG
+#define UHID_DEBUG 1
+#define OHCI_DEBUG 1
+#define UGEN_DEBUG 1
+#define UHCI_DEBUG 1
+#define UHUB_DEBUG 1
+#define ULPT_DEBUG 1
+#define UAUDIO_DEBUG 1
+#endif
+
typedef struct device *device_ptr_t;
#define USBBASEDEVICE struct device
#define USBDEV(bdev) (&(bdev))
@@ -123,7 +133,6 @@ __CONCAT(dname,_detach)(self, flags) \
(struct __CONCAT(dname,_softc) *)self
#define USB_GET_SC_OPEN(dname, unit, sc) \
- struct __CONCAT(dname,_softc) *sc; \
if (unit >= __CONCAT(dname,_cd).cd_ndevs) \
return (ENXIO); \
sc = __CONCAT(dname,_cd).cd_devs[unit]; \
@@ -131,7 +140,7 @@ __CONCAT(dname,_detach)(self, flags) \
return (ENXIO)
#define USB_GET_SC(dname, unit, sc) \
- struct __CONCAT(dname,_softc) *sc = __CONCAT(dname,_cd).cd_devs[unit]
+ sc = __CONCAT(dname,_cd).cd_devs[unit]
#define USB_DO_ATTACH(dev, bdev, parent, args, print, sub) \
(config_found_sm(parent, args, print, sub))
@@ -140,6 +149,15 @@ __CONCAT(dname,_detach)(self, flags) \
/*
* OpenBSD
*/
+#ifdef USB_DEBUG
+#define UHID_DEBUG 1
+#define OHCI_DEBUG 1
+#define UGEN_DEBUG 1
+#define UHCI_DEBUG 1
+#define UHUB_DEBUG 1
+#define ULPT_DEBUG 1
+#endif
+
#define memcpy(d, s, l) bcopy((s),(d),(l))
#define memset(d, v, l) bzero((d),(l))
#define bswap32(x) swap32(x)
@@ -150,6 +168,10 @@ __CONCAT(dname,_detach)(self, flags) \
#define uhidpoll uhidselect
#define ugenpoll ugenselect
+#define powerhook_establish(fn, sc) 0
+#define powerhook_disestablish(hdl)
+#define PWR_RESUME 0
+
typedef struct device device_ptr_t;
#define USBBASEDEVICE struct device
#define USBDEV(bdev) (&(bdev))
@@ -223,7 +245,6 @@ __CONCAT(dname,_detach)(self, flags) \
(struct __CONCAT(dname,_softc) *)self
#define USB_GET_SC_OPEN(dname, unit, sc) \
- struct __CONCAT(dname,_softc) *sc; \
if (unit >= __CONCAT(dname,_cd).cd_ndevs) \
return (ENXIO); \
sc = __CONCAT(dname,_cd).cd_devs[unit]; \
@@ -231,7 +252,7 @@ __CONCAT(dname,_detach)(self, flags) \
return (ENXIO)
#define USB_GET_SC(dname, unit, sc) \
- struct __CONCAT(dname,_softc) *sc = __CONCAT(dname,_cd).cd_devs[unit]
+ sc = __CONCAT(dname,_cd).cd_devs[unit]
#define USB_DO_ATTACH(dev, bdev, parent, args, print, sub) \
(config_found_sm(parent, args, print, sub))
@@ -257,15 +278,22 @@ __CONCAT(dname,_detach)(self, flags) \
*/
#define memcpy(d, s, l) bcopy((s),(d),(l))
#define memset(d, v, l) bzero((d),(l))
-#define bswap32(x) swap32(x) /* XXX not available in FreeBSD */
-#define kthread_create1
-#define kthread_create
-
+#define bswap32(x) swap32(x)
+#define kthread_create1(function, sc, priv, string, name)
+#define kthread_create(create_function, sc)
+#define kthread_exit(err)
#define usb_timeout(f, d, t, h) ((h) = timeout((f), (d), (t)))
#define usb_untimeout(f, d, h) untimeout((f), (d), (h))
-#define USB_DECLARE_DRIVER_INIT(dname, init...) \
+#define clalloc(p, s, x) (clist_alloc_cblocks((p), (s), (x)), 0)
+#define clfree(p) clist_free_cblocks((p))
+
+#define powerhook_establish(fn, sc) 0
+#define powerhook_disestablish(hdl)
+#define PWR_RESUME 0
+
+#define USB_DECLARE_DRIVER_INIT(dname, init) \
static device_probe_t __CONCAT(dname,_match); \
static device_attach_t __CONCAT(dname,_attach); \
static device_detach_t __CONCAT(dname,_detach); \
@@ -288,6 +316,7 @@ static driver_t __CONCAT(dname,_driver) = { \
#define METHODS_NONE {0,0}
#define USB_DECLARE_DRIVER(dname) USB_DECLARE_DRIVER_INIT(dname, METHODS_NONE)
+
#define USB_MATCH(dname) \
static int \
__CONCAT(dname,_match)(device_t self)
@@ -319,14 +348,12 @@ __CONCAT(dname,_detach)(device_t self)
struct __CONCAT(dname,_softc) *sc = device_get_softc(self)
#define USB_GET_SC_OPEN(dname, unit, sc) \
- struct __CONCAT(dname,_softc) *sc = \
- devclass_get_softc(__CONCAT(dname,_devclass), unit); \
+ sc = devclass_get_softc(__CONCAT(dname,_devclass), unit); \
if (!sc) \
return (ENXIO)
#define USB_GET_SC(dname, unit, sc) \
- struct __CONCAT(dname,_softc) *sc = \
- devclass_get_softc(__CONCAT(dname,_devclass), unit)
+ sc = devclass_get_softc(__CONCAT(dname,_devclass), unit)
#define USB_DO_ATTACH(dev, bdev, parent, args, print, sub) \
(device_probe_and_attach((bdev)) == 0 ? (bdev) : 0)
@@ -355,7 +382,3 @@ __CONCAT(dname,_detach)(device_t self)
#define logprintf printf
#endif /* __FreeBSD__ */
-
-#if defined(__NetBSD__) || defined(__OpenBSD__)
-#elif defined(__FreeBSD__)
-#endif
diff --git a/sys/dev/usb/usb_quirks.c b/sys/dev/usb/usb_quirks.c
index b596433..1075cfd 100644
--- a/sys/dev/usb/usb_quirks.c
+++ b/sys/dev/usb/usb_quirks.c
@@ -1,4 +1,4 @@
-/* $NetBSD: usb_quirks.c,v 1.13 1999/09/15 12:30:59 augustss Exp $ */
+/* $NetBSD: usb_quirks.c,v 1.14 1999/09/15 13:57:09 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -50,12 +50,12 @@
extern int usbdebug;
#endif
-struct usbd_quirk_entry {
+static struct usbd_quirk_entry {
u_int16_t idVendor;
u_int16_t idProduct;
u_int16_t bcdDevice;
struct usbd_quirks quirks;
-} quirks[] = {
+} usb_quirks[] = {
{ USB_VENDOR_KYE, USB_PRODUCT_KYE_NICHE, 0x100, { UQ_NO_SET_PROTO}},
{ USB_VENDOR_INSIDEOUT,USB_PRODUCT_INSIDEOUT_EDGEPORT4,
0x094, { UQ_SWAP_UNICODE}},
@@ -76,7 +76,7 @@ usbd_find_quirk(d)
{
struct usbd_quirk_entry *t;
- for (t = quirks; t->idVendor != 0; t++) {
+ for (t = usb_quirks; t->idVendor != 0; t++) {
if (t->idVendor == UGETW(d->idVendor) &&
t->idProduct == UGETW(d->idProduct) &&
t->bcdDevice == UGETW(d->bcdDevice))
diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c
index fb4ef4b..b985a5e 100644
--- a/sys/dev/usb/usb_subr.c
+++ b/sys/dev/usb/usb_subr.c
@@ -1,4 +1,4 @@
-/* $NetBSD: usb_subr.c,v 1.45 1999/09/09 12:26:47 augustss Exp $ */
+/* $NetBSD: usb_subr.c,v 1.52 1999/10/13 08:10:58 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -51,6 +51,8 @@
#endif
#include <sys/proc.h>
+#include <machine/bus.h>
+
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -74,19 +76,20 @@ extern int usbdebug;
#endif
static usbd_status usbd_set_config __P((usbd_device_handle, int));
-char *usbd_get_string __P((usbd_device_handle, int, char *));
-int usbd_getnewaddr __P((usbd_bus_handle bus));
-int usbd_print __P((void *aux, const char *pnp));
+static char *usbd_get_string __P((usbd_device_handle, int, char *));
+static int usbd_getnewaddr __P((usbd_bus_handle bus));
#if defined(__NetBSD__)
-int usbd_submatch __P((device_ptr_t, struct cfdata *cf, void *));
+static int usbd_print __P((void *aux, const char *pnp));
+static int usbd_submatch __P((device_ptr_t, struct cfdata *cf, void *));
#elif defined(__OpenBSD__)
-int usbd_submatch __P((device_ptr_t, void *, void *));
+static int usbd_submatch __P((device_ptr_t, void *, void *));
#endif
-void usbd_free_iface_data __P((usbd_device_handle dev, int ifcno));
-void usbd_kill_pipe __P((usbd_pipe_handle));
-usbd_status usbd_probe_and_attach
+static void usbd_free_iface_data __P((usbd_device_handle dev, int ifcno));
+static void usbd_kill_pipe __P((usbd_pipe_handle));
+static usbd_status usbd_probe_and_attach
__P((device_ptr_t parent, usbd_device_handle dev, int port, int addr));
+static u_int32_t usb_cookie_no = 0;
#ifdef USBVERBOSE
typedef u_int16_t usb_vendor_id_t;
@@ -104,9 +107,9 @@ struct usb_knowndev {
#define USB_KNOWNDEV_NOPROD 0x01 /* match on vendor only */
#include <dev/usb/usbdevs_data.h>
-#endif
+#endif /* USBVERBOSE */
-const char *usbd_error_strs[] = {
+static const char *usbd_error_strs[] = {
"NORMAL_COMPLETION",
"IN_PROGRESS",
"PENDING_REQUESTS",
@@ -151,16 +154,16 @@ usbd_get_string_desc(dev, sindex, langid, sdesc)
usb_string_descriptor_t *sdesc;
{
usb_device_request_t req;
- usbd_status r;
+ usbd_status err;
req.bmRequestType = UT_READ_DEVICE;
req.bRequest = UR_GET_DESCRIPTOR;
USETW2(req.wValue, UDESC_STRING, sindex);
USETW(req.wIndex, langid);
USETW(req.wLength, 1); /* only size byte first */
- r = usbd_do_request(dev, &req, sdesc);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_do_request(dev, &req, sdesc);
+ if (err)
+ return (err);
USETW(req.wLength, sdesc->bLength); /* the whole string */
return (usbd_do_request(dev, &req, sdesc));
}
@@ -176,7 +179,7 @@ usbd_get_string(dev, si, buf)
char *s;
int i, n;
u_int16_t c;
- usbd_status r;
+ usbd_status err;
if (si == 0)
return (0);
@@ -184,16 +187,16 @@ usbd_get_string(dev, si, buf)
return (0);
if (dev->langid == USBD_NOLANG) {
/* Set up default language */
- r = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us);
- if (r != USBD_NORMAL_COMPLETION || us.bLength < 4) {
+ err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us);
+ if (err || us.bLength < 4) {
dev->langid = 0; /* Well, just pick English then */
} else {
/* Pick the first language as the default. */
dev->langid = UGETW(us.bString[0]);
}
}
- r = usbd_get_string_desc(dev, si, dev->langid, &us);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_get_string_desc(dev, si, dev->langid, &us);
+ if (err)
return (0);
s = buf;
n = us.bLength / 2 - 1;
@@ -208,7 +211,7 @@ usbd_get_string(dev, si, buf)
*s++ = '?';
}
*s++ = 0;
- return buf;
+ return (buf);
}
void
@@ -222,7 +225,7 @@ usbd_devinfo_vp(dev, v, p)
struct usb_knowndev *kdp;
#endif
- if (!dev) {
+ if (dev == NULL) {
v[0] = p[0] = '\0';
return;
}
@@ -230,7 +233,7 @@ usbd_devinfo_vp(dev, v, p)
vendor = usbd_get_string(dev, udd->iManufacturer, v);
product = usbd_get_string(dev, udd->iProduct, p);
#ifdef USBVERBOSE
- if (!vendor) {
+ if (vendor == NULL) {
for(kdp = usb_knowndevs;
kdp->vendorname != NULL;
kdp++) {
@@ -248,12 +251,11 @@ usbd_devinfo_vp(dev, v, p)
}
}
#endif
-
- if (vendor)
+ if (vendor != NULL)
strcpy(v, vendor);
else
sprintf(v, "vendor 0x%04x", UGETW(udd->idVendor));
- if (product)
+ if (product != NULL)
strcpy(p, product);
else
sprintf(p, "product 0x%04x", UGETW(udd->idProduct));
@@ -322,7 +324,7 @@ usbd_reset_port(dev, port, ps)
usb_port_status_t *ps;
{
usb_device_request_t req;
- usbd_status r;
+ usbd_status err;
int n;
req.bmRequestType = UT_WRITE_CLASS_OTHER;
@@ -330,34 +332,36 @@ usbd_reset_port(dev, port, ps)
USETW(req.wValue, UHF_PORT_RESET);
USETW(req.wIndex, port);
USETW(req.wLength, 0);
- r = usbd_do_request(dev, &req, 0);
+ err = usbd_do_request(dev, &req, 0);
DPRINTFN(1,("usbd_reset_port: port %d reset done, error=%s\n",
- port, usbd_errstr(r)));
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ port, usbd_errstr(err)));
+ if (err)
+ return (err);
n = 10;
do {
/* Wait for device to recover from reset. */
usbd_delay_ms(dev, USB_PORT_RESET_DELAY);
- r = usbd_get_port_status(dev, port, ps);
- if (r != USBD_NORMAL_COMPLETION) {
- DPRINTF(("usbd_reset_port: get status failed %d\n",r));
- return (r);
+ err = usbd_get_port_status(dev, port, ps);
+ if (err) {
+ DPRINTF(("usbd_reset_port: get status failed %d\n",
+ err));
+ return (err);
}
} while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0);
if (n == 0) {
printf("usbd_reset_port: timeout\n");
return (USBD_IOERROR);
}
- r = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET);
+ err = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET);
#ifdef USB_DEBUG
- if (r != USBD_NORMAL_COMPLETION)
- DPRINTF(("usbd_reset_port: clear port feature failed %d\n",r));
+ if (err)
+ DPRINTF(("usbd_reset_port: clear port feature failed %d\n",
+ err));
#endif
/* Wait for the device to recover from reset. */
usbd_delay_ms(dev, USB_PORT_RESET_RECOVERY);
- return (r);
+ return (err);
}
usb_interface_descriptor_t *
@@ -408,7 +412,7 @@ usbd_find_edesc(cd, ifaceidx, altidx, endptidx)
int curidx;
d = usbd_find_idesc(cd, ifaceidx, altidx);
- if (!d)
+ if (d == NULL)
return (0);
if (endptidx >= d->bNumEndpoints) /* quick exit */
return (0);
@@ -524,14 +528,14 @@ usbd_set_config_no(dev, no, msg)
{
int index;
usb_config_descriptor_t cd;
- usbd_status r;
+ usbd_status err;
DPRINTFN(5,("usbd_set_config_no: %d\n", no));
/* Figure out what config index to use. */
for (index = 0; index < dev->ddesc.bNumConfigurations; index++) {
- r = usbd_get_config_desc(dev, index, &cd);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_get_config_desc(dev, index, &cd);
+ if (err)
+ return (err);
if (cd.bConfigurationValue == no)
return (usbd_set_config_index(dev, index, msg));
}
@@ -546,7 +550,7 @@ usbd_set_config_index(dev, index, msg)
{
usb_status_t ds;
usb_config_descriptor_t cd, *cdp;
- usbd_status r;
+ usbd_status err;
int ifcidx, nifc, len, selfpowered, power;
DPRINTFN(5,("usbd_set_config_index: dev=%p index=%d\n", dev, index));
@@ -566,34 +570,34 @@ usbd_set_config_index(dev, index, msg)
}
/* Figure out what config number to use. */
- r = usbd_get_config_desc(dev, index, &cd);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_get_config_desc(dev, index, &cd);
+ if (err)
+ return (err);
len = UGETW(cd.wTotalLength);
cdp = malloc(len, M_USB, M_NOWAIT);
- if (cdp == 0)
+ if (cdp == NULL)
return (USBD_NOMEM);
- r = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp);
+ if (err)
goto bad;
if (cdp->bDescriptorType != UDESC_CONFIG) {
DPRINTFN(-1,("usbd_set_config_index: bad desc %d\n",
cdp->bDescriptorType));
- r = USBD_INVAL;
+ err = USBD_INVAL;
goto bad;
}
selfpowered = 0;
- if (cdp->bmAttributes & UC_SELF_POWERED) {
+ if (!(dev->quirks->uq_flags & UQ_BUS_POWERED) &&
+ cdp->bmAttributes & UC_SELF_POWERED) {
/* May be self powered. */
if (cdp->bmAttributes & UC_BUS_POWERED) {
/* Must ask device. */
- r = usbd_get_device_status(dev, &ds);
- if (r == USBD_NORMAL_COMPLETION &&
- (UGETW(ds.wStatus) & UDS_SELF_POWERED))
+ err = usbd_get_device_status(dev, &ds);
+ if (!err && (UGETW(ds.wStatus) & UDS_SELF_POWERED))
selfpowered = 1;
DPRINTF(("usbd_set_config_index: status=0x%04x, "
"error=%s\n",
- UGETW(ds.wStatus), usbd_errstr(r)));
+ UGETW(ds.wStatus), usbd_errstr(err)));
} else
selfpowered = 1;
}
@@ -602,7 +606,7 @@ usbd_set_config_index(dev, index, msg)
dev->address, cdp->bmAttributes,
selfpowered, cdp->bMaxPower * 2));
#ifdef USB_DEBUG
- if (!dev->powersrc) {
+ if (dev->powersrc == NULL) {
DPRINTF(("usbd_set_config_index: No power source?\n"));
return (USBD_IOERROR);
}
@@ -616,7 +620,7 @@ usbd_set_config_index(dev, index, msg)
USBDEVNAME(dev->bus->bdev), dev->address,
cdp->bConfigurationValue,
power, dev->powersrc->power);
- r = USBD_NO_POWER;
+ err = USBD_NO_POWER;
goto bad;
}
dev->power = power;
@@ -624,11 +628,11 @@ usbd_set_config_index(dev, index, msg)
DPRINTF(("usbd_set_config_index: set config %d\n",
cdp->bConfigurationValue));
- r = usbd_set_config(dev, cdp->bConfigurationValue);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_set_config(dev, cdp->bConfigurationValue);
+ if (err) {
DPRINTF(("usbd_set_config_index: setting config=%d failed, "
"error=%s\n",
- cdp->bConfigurationValue, usbd_errstr(r)));
+ cdp->bConfigurationValue, usbd_errstr(err)));
goto bad;
}
DPRINTF(("usbd_set_config_index: setting new config %d\n",
@@ -637,15 +641,15 @@ usbd_set_config_index(dev, index, msg)
dev->ifaces = malloc(nifc * sizeof(struct usbd_interface),
M_USB, M_NOWAIT);
if (dev->ifaces == 0) {
- r = USBD_NOMEM;
+ err = USBD_NOMEM;
goto bad;
}
DPRINTFN(5,("usbd_set_config_index: dev=%p cdesc=%p\n", dev, cdp));
dev->cdesc = cdp;
dev->config = cdp->bConfigurationValue;
for (ifcidx = 0; ifcidx < nifc; ifcidx++) {
- r = usbd_fill_iface_data(dev, ifcidx, 0);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_fill_iface_data(dev, ifcidx, 0);
+ if (err) {
while (--ifcidx >= 0)
usbd_free_iface_data(dev, ifcidx);
goto bad;
@@ -656,7 +660,7 @@ usbd_set_config_index(dev, index, msg)
bad:
free(cdp, M_USB);
- return (r);
+ return (err);
}
/* XXX add function for alternate settings */
@@ -669,29 +673,29 @@ usbd_setup_pipe(dev, iface, ep, pipe)
usbd_pipe_handle *pipe;
{
usbd_pipe_handle p;
- usbd_status r;
+ usbd_status err;
DPRINTFN(1,("usbd_setup_pipe: dev=%p iface=%p ep=%p pipe=%p\n",
dev, iface, ep, pipe));
p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT);
- if (p == 0)
+ if (p == NULL)
return (USBD_NOMEM);
p->device = dev;
p->iface = iface;
p->endpoint = ep;
ep->refcnt++;
p->refcnt = 1;
- p->intrreqh = 0;
+ p->intrxfer = 0;
p->running = 0;
p->repeat = 0;
SIMPLEQ_INIT(&p->queue);
- r = dev->bus->methods->open_pipe(p);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = dev->bus->methods->open_pipe(p);
+ if (err) {
DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error="
"%s\n",
- ep->edesc->bEndpointAddress, usbd_errstr(r)));
+ ep->edesc->bEndpointAddress, usbd_errstr(err)));
free(p, M_USB);
- return (r);
+ return (err);
}
/* Clear any stall and make sure DATA0 toggle will be used next. */
if (UE_GET_ADDR(ep->edesc->bEndpointAddress) != USB_CONTROL_ENDPOINT)
@@ -732,7 +736,8 @@ usbd_probe_and_attach(parent, dev, port, addr)
{
struct usb_attach_arg uaa;
usb_device_descriptor_t *dd = &dev->ddesc;
- int r, found, i, confi, nifaces;
+ int found, i, confi, nifaces;
+ usbd_status err;
device_ptr_t dv;
usbd_interface_handle ifaces[256]; /* 256 is the absolute max */
@@ -779,12 +784,12 @@ usbd_probe_and_attach(parent, dev, port, addr)
for (confi = 0; confi < dd->bNumConfigurations; confi++) {
DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n",
confi));
- r = usbd_set_config_index(dev, confi, 1);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_set_config_index(dev, confi, 1);
+ if (err) {
#ifdef USB_DEBUG
DPRINTF(("%s: port %d, set config at addr %d failed, "
"error=%s\n", USBDEVPTRNAME(parent), port,
- addr, usbd_errstr(r)));
+ addr, usbd_errstr(err)));
#else
printf("%s: port %d, set config at addr %d failed\n",
USBDEVPTRNAME(parent), port, addr);
@@ -792,8 +797,8 @@ usbd_probe_and_attach(parent, dev, port, addr)
#if defined(__FreeBSD__)
device_delete_child(parent, bdev);
#endif
-
- return (r);
+
+ return (err);
}
nifaces = dev->cdesc->bNumInterface;
uaa.configno = dev->cdesc->bConfigurationValue;
@@ -801,7 +806,6 @@ usbd_probe_and_attach(parent, dev, port, addr)
ifaces[i] = &dev->ifaces[i];
uaa.ifaces = ifaces;
uaa.nifaces = nifaces;
-
dev->subdevs = malloc((nifaces+1) * sizeof dv, M_USB,M_NOWAIT);
if (dev->subdevs == 0) {
#if defined(__FreeBSD__)
@@ -812,21 +816,20 @@ usbd_probe_and_attach(parent, dev, port, addr)
found = 0;
for (i = 0; i < nifaces; i++) {
- if (!ifaces[i])
+ if (ifaces[i] == NULL)
continue; /* interface already claimed */
-
uaa.iface = ifaces[i];
uaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber;
dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print,
usbd_submatch);
- if (dv) {
+ if (dv != NULL) {
dev->subdevs[found++] = dv;
dev->subdevs[found] = 0;
ifaces[i] = 0; /* consumed */
#if defined(__FreeBSD__)
/* create another child for the next iface */
- bdev = device_add_child(parent, NULL, -1, &uaa);
+ bdev = device_add_child(parent, NULL, -1,&uaa);
if (!bdev) {
printf("%s: Device creation failed\n",
USBDEVNAME(dev->bus->bdev));
@@ -836,7 +839,6 @@ usbd_probe_and_attach(parent, dev, port, addr)
#endif
}
}
-
if (found != 0) {
#if defined(__FreeBSD__)
/* remove the last created child again; it is unused */
@@ -844,7 +846,6 @@ usbd_probe_and_attach(parent, dev, port, addr)
#endif
return (USBD_NORMAL_COMPLETION);
}
-
free(dev->subdevs, M_USB);
dev->subdevs = 0;
}
@@ -864,7 +865,7 @@ usbd_probe_and_attach(parent, dev, port, addr)
uaa.product = UHUB_UNK_PRODUCT;
uaa.release = UHUB_UNK_RELEASE;
dv = USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch);
- if (dv) {
+ if (dv != NULL) {
dev->subdevs = malloc(2 * sizeof dv, M_USB, M_NOWAIT);
if (dev->subdevs == 0)
return (USBD_NOMEM);
@@ -886,7 +887,6 @@ usbd_probe_and_attach(parent, dev, port, addr)
}
-
/*
* Called when a new device has been put in the powered state,
* but not yet in the addressed state.
@@ -904,7 +904,7 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up)
{
usbd_device_handle dev;
usb_device_descriptor_t *dd;
- usbd_status r;
+ usbd_status err;
int addr;
int i;
@@ -918,7 +918,7 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up)
}
dev = malloc(sizeof *dev, M_USB, M_NOWAIT);
- if (dev == 0)
+ if (dev == NULL)
return (USBD_NOMEM);
memset(dev, 0, sizeof(*dev));
@@ -942,30 +942,31 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up)
dev->depth = depth;
dev->powersrc = up;
dev->langid = USBD_NOLANG;
+ dev->cookie.cookie = ++usb_cookie_no;
/* Establish the the default pipe. */
- r = usbd_setup_pipe(dev, 0, &dev->def_ep, &dev->default_pipe);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_setup_pipe(dev, 0, &dev->def_ep, &dev->default_pipe);
+ if (err) {
usbd_remove_device(dev, up);
- return (r);
+ return (err);
}
up->device = dev;
dd = &dev->ddesc;
/* Try a few times in case the device is slow (i.e. outside specs.) */
- for (i = 0; i < 5; i++) {
+ /* for (i = 0; i < 5; i++) { */
+ for (i = 0; i < 3; i++) {
/* Get the first 8 bytes of the device descriptor. */
- r = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd);
- if (r == USBD_NORMAL_COMPLETION)
+ err = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd);
+ if (!err)
break;
usbd_delay_ms(dev, 200);
}
- if (r != USBD_NORMAL_COMPLETION) {
+ if (err) {
DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc "
- "failed\n",
- addr));
+ "failed\n", addr));
usbd_remove_device(dev, up);
- return (r);
+ return (err);
}
DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, "
@@ -991,24 +992,24 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up)
USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize);
/* Get the full device descriptor. */
- r = usbd_get_device_desc(dev, dd);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_get_device_desc(dev, dd);
+ if (err) {
DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc "
"failed\n", addr));
usbd_remove_device(dev, up);
- return (r);
+ return (err);
}
/* Figure out what's wrong with this device. */
dev->quirks = usbd_find_quirk(dd);
/* Set the address */
- r = usbd_set_address(dev, addr);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_set_address(dev, addr);
+ if (err) {
DPRINTFN(-1,("usb_new_device: set address %d failed\n",addr));
- r = USBD_SET_ADDR_FAILED;
+ err = USBD_SET_ADDR_FAILED;
usbd_remove_device(dev, up);
- return (r);
+ return (err);
}
/* Allow device time to set new address */
usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE);
@@ -1023,12 +1024,13 @@ usbd_new_device(parent, bus, depth, lowspeed, port, up)
DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n",
addr, dev, parent));
- r = usbd_probe_and_attach(parent, dev, port, addr);
- if (r != USBD_NORMAL_COMPLETION) {
+ err = usbd_probe_and_attach(parent, dev, port, addr);
+ if (err) {
usbd_remove_device(dev, up);
- return (r);
+ return (err);
}
+ usbd_add_event(USB_EVENT_ATTACH, dev);
return (USBD_NORMAL_COMPLETION);
}
@@ -1039,7 +1041,7 @@ usbd_remove_device(dev, up)
{
DPRINTF(("usbd_remove_device: %p\n", dev));
- if (dev->default_pipe)
+ if (dev->default_pipe != NULL)
usbd_kill_pipe(dev->default_pipe);
up->device = 0;
dev->bus->devices[dev->address] = 0;
@@ -1134,7 +1136,7 @@ usbd_fill_deviceinfo(dev, di)
struct usb_device_info *di;
{
struct usbd_port *p;
- int i, r, s;
+ int i, err, s;
di->config = dev->config;
usbd_devinfo_vp(dev, di->vendor, di->product);
@@ -1152,19 +1154,19 @@ usbd_fill_deviceinfo(dev, di)
i++) {
p = &dev->hub->ports[i];
if (p->device)
- r = p->device->address;
+ err = p->device->address;
else {
s = UGETW(p->status.wPortStatus);
if (s & UPS_PORT_ENABLED)
- r = USB_PORT_ENABLED;
+ err = USB_PORT_ENABLED;
else if (s & UPS_SUSPEND)
- r = USB_PORT_SUSPENDED;
+ err = USB_PORT_SUSPENDED;
else if (s & UPS_PORT_POWER)
- r = USB_PORT_POWERED;
+ err = USB_PORT_POWERED;
else
- r = USB_PORT_DISABLED;
+ err = USB_PORT_DISABLED;
}
- di->ports[i] = r;
+ di->ports[i] = err;
}
di->nports = dev->hub->hubdesc.bNbrPorts;
} else
@@ -1177,17 +1179,87 @@ usb_free_device(dev)
{
int ifcidx, nifc;
- if (dev->default_pipe)
+ if (dev->default_pipe != NULL)
usbd_kill_pipe(dev->default_pipe);
- if (dev->ifaces) {
+ if (dev->ifaces != NULL) {
nifc = dev->cdesc->bNumInterface;
for (ifcidx = 0; ifcidx < nifc; ifcidx++)
usbd_free_iface_data(dev, ifcidx);
free(dev->ifaces, M_USB);
}
- if (dev->cdesc)
+ if (dev->cdesc != NULL)
free(dev->cdesc, M_USB);
- if (dev->subdevs)
+ if (dev->subdevs != NULL)
free(dev->subdevs, M_USB);
free(dev, M_USB);
}
+
+/*
+ * The general mechanism for detaching drivers works as follows: Each
+ * driver is responsible for maintaining a reference count on the
+ * number of outstanding references to its softc (e.g. from
+ * processing hanging in a read or write). The detach method of the
+ * driver decrements this counter and flags in the softc that the
+ * driver is dying and then wakes any sleepers. It then sleeps on the
+ * softc. Each place that can sleep must maintain the reference
+ * count. When the reference count drops to -1 (0 is the normal value
+ * of the reference count) the a wakeup on the softc is performed
+ * signaling to the detach waiter that all references are gone.
+ */
+
+/*
+ * Called from process context when we discover that a port has
+ * been disconnected.
+ */
+void
+usb_disconnect_port(up, parent)
+ struct usbd_port *up;
+ device_ptr_t parent;
+{
+ usbd_device_handle dev = up->device;
+ char *hubname = USBDEVPTRNAME(parent);
+ int i;
+
+ DPRINTFN(3,("uhub_disconnect: up=%p dev=%p port=%d\n",
+ up, dev, up->portno));
+
+#ifdef DIAGNOSTIC
+ if (!dev) {
+ printf("usb_disconnect_port: no device\n");
+ return;
+ }
+#endif
+
+ if (!dev->cdesc) {
+ /* Partially attached device, just drop it. */
+ dev->bus->devices[dev->address] = 0;
+ up->device = 0;
+ return;
+ }
+
+ if (dev->subdevs != NULL) {
+ for (i = 0; dev->subdevs[i]; i++) {
+ if (!dev->subdevs[i]) /* skip empty elements */
+ continue;
+
+ printf("%s: at %s", USBDEVPTRNAME(dev->subdevs[i]),
+ hubname);
+ if (up->portno != 0)
+ printf(" port %d", up->portno);
+ printf(" (addr %d) disconnected\n", dev->address);
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+ config_detach(dev->subdevs[i], DETACH_FORCE);
+#elif defined(__FreeBSD__)
+ device_delete_child(device_get_parent(dev->subdevs[i]),
+ dev->subdevs[i]);
+#endif
+
+ }
+ }
+
+ usbd_add_event(USB_EVENT_DETACH, dev);
+ dev->bus->devices[dev->address] = 0;
+ up->device = 0;
+ usb_free_device(dev);
+}
+
diff --git a/sys/dev/usb/usbcdc.h b/sys/dev/usb/usbcdc.h
index 97bec79..e51fcc9 100644
--- a/sys/dev/usb/usbcdc.h
+++ b/sys/dev/usb/usbcdc.h
@@ -1,4 +1,4 @@
-/* $NetBSD: usbcdc.h,v 1.4 1999/08/16 20:20:19 augustss Exp $ */
+/* $NetBSD: usbcdc.h,v 1.3 1999/01/03 01:09:18 augustss Exp $ */
/* $FreeBSD$ */
/*
diff --git a/sys/dev/usb/usbdevs.h b/sys/dev/usb/usbdevs.h
index 46c1cf1..a9e765e 100644
--- a/sys/dev/usb/usbdevs.h
+++ b/sys/dev/usb/usbdevs.h
@@ -4,7 +4,7 @@
* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* generated from:
- * NetBSD: usbdevs,v 1.58 1999/11/10 15:55:51 matt Exp
+ * NetBSD: usbdevs,v 1.59 1999/11/10 19:46:40 augustss Exp
*/
/*
@@ -99,6 +99,7 @@
#define USB_VENDOR_INSYSTEM 0x05ab /* In-System Design */
#define USB_VENDOR_APPLE 0x05ac /* Apple Computer */
#define USB_VENDOR_QTRONIX 0x05c7 /* Qtronix Corp */
+#define USB_VENDOR_ELSA 0x05cc /* ELSA Gmbh */
#define USB_VENDOR_EIZONANAO 0x05e7 /* EIZO Nanao */
#define USB_VENDOR_PIENGINEERING 0x05f3 /* P.I. Engineering */
#define USB_VENDOR_CHIC 0x05fe /* Chic Technology */
@@ -135,6 +136,7 @@
/* CATC products */
#define USB_PRODUCT_CATC_ANDROMEDA 0x1237 /* Andromeda hub */
+#define USB_PRODUCT_CATC_CHIEF 0x000d /* USB Chief Bus & Protocol Analyzer */
/* Gravis products */
#define USB_PRODUCT_GRAVIS_GAMEPADPRO 0x4001 /* GamePad Pro */
@@ -276,6 +278,9 @@
/* Qtronix products */
#define USB_PRODUCT_QTRONIX_980N 0x2011 /* Scorpion-980N keyboard */
+/* Elsa products */
+#define USB_PRODUCT_ELSA_MODEM1 0x2265 /* ELSA Modem Board */
+
/* Logitech products */
#define USB_PRODUCT_LOGITECH_M2452 0x0203 /* M2452 keyboard */
#define USB_PRODUCT_LOGITECH_M4848 0x0301 /* M4848 mouse */
diff --git a/sys/dev/usb/usbdevs_data.h b/sys/dev/usb/usbdevs_data.h
index 98bbbc4..cf21c2b 100644
--- a/sys/dev/usb/usbdevs_data.h
+++ b/sys/dev/usb/usbdevs_data.h
@@ -4,7 +4,7 @@
* THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* generated from:
- * NetBSD: usbdevs,v 1.58 1999/11/10 15:55:51 matt Exp
+ * NetBSD: usbdevs,v 1.59 1999/11/10 19:46:40 augustss Exp
*/
/*
@@ -94,6 +94,12 @@ struct usb_knowndev usb_knowndevs[] = {
"Andromeda hub",
},
{
+ USB_VENDOR_CATC, USB_PRODUCT_CATC_CHIEF,
+ 0,
+ "Computer Access Technology Corp.",
+ "USB Chief Bus & Protocol Analyzer",
+ },
+ {
USB_VENDOR_GRAVIS, USB_PRODUCT_GRAVIS_GAMEPADPRO,
0,
"Advanced Gravis Computer Tech. Ltd.",
@@ -418,6 +424,12 @@ struct usb_knowndev usb_knowndevs[] = {
"Scorpion-980N keyboard",
},
{
+ USB_VENDOR_ELSA, USB_PRODUCT_ELSA_MODEM1,
+ 0,
+ "ELSA Gmbh",
+ "ELSA Modem Board",
+ },
+ {
USB_VENDOR_LOGITECH, USB_PRODUCT_LOGITECH_M2452,
0,
"Logitech Inc.",
@@ -904,6 +916,12 @@ struct usb_knowndev usb_knowndevs[] = {
NULL,
},
{
+ USB_VENDOR_ELSA, 0,
+ USB_KNOWNDEV_NOPROD,
+ "ELSA Gmbh",
+ NULL,
+ },
+ {
USB_VENDOR_EIZONANAO, 0,
USB_KNOWNDEV_NOPROD,
"EIZO Nanao",
diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c
index 72207f9..c7aa594 100644
--- a/sys/dev/usb/usbdi.c
+++ b/sys/dev/usb/usbdi.c
@@ -1,4 +1,4 @@
-/* $NetBSD: usbdi.c,v 1.37 1999/09/11 08:19:27 augustss Exp $ */
+/* $NetBSD: usbdi.c,v 1.47 1999/10/13 23:46:10 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -46,10 +46,16 @@
#elif defined(__FreeBSD__)
#include <sys/module.h>
#include <sys/bus.h>
+#include <sys/conf.h>
+#include "usb_if.h"
+#if defined(DIAGNOSTIC) && defined(__i386__)
+#include <machine/cpu.h>
+#endif
#endif
#include <sys/malloc.h>
#include <sys/proc.h>
+#include <machine/bus.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
@@ -60,7 +66,7 @@
#if defined(__FreeBSD__)
#include "usb_if.h"
#endif
-
+
#ifdef USB_DEBUG
#define DPRINTF(x) if (usbdebug) logprintf x
#define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x
@@ -71,22 +77,47 @@ extern int usbdebug;
#endif
static usbd_status usbd_ar_pipe __P((usbd_pipe_handle pipe));
-void usbd_do_request_async_cb
- __P((usbd_request_handle, usbd_private_handle, usbd_status));
-void usbd_start_next __P((usbd_pipe_handle pipe));
+static void usbd_do_request_async_cb
+ __P((usbd_xfer_handle, usbd_private_handle, usbd_status));
+static void usbd_start_next __P((usbd_pipe_handle pipe));
+
+static SIMPLEQ_HEAD(, usbd_xfer) usbd_free_requests =
+ SIMPLEQ_HEAD_INITIALIZER(usbd_free_requests);
+
+static int usbd_nbuses = 0;
-static SIMPLEQ_HEAD(, usbd_request) usbd_free_requests
- = SIMPLEQ_HEAD_INITIALIZER(usbd_free_requests);
+void
+usbd_init()
+{
+ usbd_nbuses++;
+}
-static __inline int usbd_reqh_isread __P((usbd_request_handle reqh));
+void
+usbd_finish()
+{
+ usbd_xfer_handle xfer;
+
+ if (--usbd_nbuses == 0) {
+ /* Last controller is gone, free all requests. */
+ for (;;) {
+ xfer = SIMPLEQ_FIRST(&usbd_free_requests);
+ if (xfer == NULL)
+ break;
+ SIMPLEQ_REMOVE_HEAD(&usbd_free_requests, xfer, next);
+ free(xfer, M_USB);
+ }
+ }
+}
+
+static __inline int usbd_xfer_isread __P((usbd_xfer_handle xfer));
static __inline int
-usbd_reqh_isread(reqh)
- usbd_request_handle reqh;
+usbd_xfer_isread(xfer)
+ usbd_xfer_handle xfer;
{
- if (reqh->rqflags & URQ_REQUEST)
- return (reqh->request.bmRequestType & UT_READ);
+ if (xfer->rqflags & URQ_REQUEST)
+ return (xfer->request.bmRequestType & UT_READ);
else
- return (reqh->pipe->endpoint->edesc->bEndpointAddress &
+ return (xfer->pipe->endpoint->edesc->bEndpointAddress &
UE_DIR_IN);
}
@@ -97,13 +128,13 @@ void
usbd_dump_queue(pipe)
usbd_pipe_handle pipe;
{
- usbd_request_handle reqh;
+ usbd_xfer_handle xfer;
printf("usbd_dump_queue: pipe=%p\n", pipe);
- for (reqh = SIMPLEQ_FIRST(&pipe->queue);
- reqh;
- reqh = SIMPLEQ_NEXT(reqh, next)) {
- printf(" reqh=%p\n", reqh);
+ for (xfer = SIMPLEQ_FIRST(&pipe->queue);
+ xfer;
+ xfer = SIMPLEQ_NEXT(xfer, next)) {
+ printf(" xfer=%p\n", xfer);
}
}
#endif
@@ -117,7 +148,7 @@ usbd_open_pipe(iface, address, flags, pipe)
{
usbd_pipe_handle p;
struct usbd_endpoint *ep;
- usbd_status r;
+ usbd_status err;
int i;
for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
@@ -130,9 +161,9 @@ usbd_open_pipe(iface, address, flags, pipe)
if ((flags & USBD_EXCLUSIVE_USE) &&
ep->refcnt != 0)
return (USBD_IN_USE);
- r = usbd_setup_pipe(iface->device, iface, ep, &p);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_setup_pipe(iface->device, iface, ep, &p);
+ if (err)
+ return (err);
LIST_INSERT_HEAD(&iface->pipes, p, next);
*pipe = p;
return (USBD_NORMAL_COMPLETION);
@@ -149,35 +180,35 @@ usbd_open_pipe_intr(iface, address, flags, pipe, priv, buffer, length, cb)
u_int32_t length;
usbd_callback cb;
{
- usbd_status r;
- usbd_request_handle reqh;
+ usbd_status err;
+ usbd_xfer_handle xfer;
usbd_pipe_handle ipipe;
- r = usbd_open_pipe(iface, address, USBD_EXCLUSIVE_USE, &ipipe);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- reqh = usbd_alloc_request(iface->device);
- if (reqh == 0) {
- r = USBD_NOMEM;
+ err = usbd_open_pipe(iface, address, USBD_EXCLUSIVE_USE, &ipipe);
+ if (err)
+ return (err);
+ xfer = usbd_alloc_request(iface->device);
+ if (xfer == NULL) {
+ err = USBD_NOMEM;
goto bad1;
}
- usbd_setup_request(reqh, ipipe, priv, buffer, length, flags,
+ usbd_setup_request(xfer, ipipe, priv, buffer, length, flags,
USBD_NO_TIMEOUT, cb);
- ipipe->intrreqh = reqh;
+ ipipe->intrxfer = xfer;
ipipe->repeat = 1;
- r = usbd_transfer(reqh);
+ err = usbd_transfer(xfer);
*pipe = ipipe;
- if (r != USBD_IN_PROGRESS)
+ if (err != USBD_IN_PROGRESS)
goto bad2;
return (USBD_NORMAL_COMPLETION);
bad2:
- ipipe->intrreqh = 0;
+ ipipe->intrxfer = NULL;
ipipe->repeat = 0;
- usbd_free_request(reqh);
+ usbd_free_request(xfer);
bad1:
usbd_close_pipe(ipipe);
- return r;
+ return (err);
}
usbd_status
@@ -185,7 +216,7 @@ usbd_close_pipe(pipe)
usbd_pipe_handle pipe;
{
#ifdef DIAGNOSTIC
- if (pipe == 0) {
+ if (pipe == NULL) {
printf("usbd_close_pipe: pipe==NULL\n");
return (USBD_NORMAL_COMPLETION);
}
@@ -198,175 +229,185 @@ usbd_close_pipe(pipe)
LIST_REMOVE(pipe, next);
pipe->endpoint->refcnt--;
pipe->methods->close(pipe);
- if (pipe->intrreqh)
- usbd_free_request(pipe->intrreqh);
+ if (pipe->intrxfer != NULL)
+ usbd_free_request(pipe->intrxfer);
free(pipe, M_USB);
return (USBD_NORMAL_COMPLETION);
}
usbd_status
-usbd_transfer(reqh)
- usbd_request_handle reqh;
+usbd_transfer(xfer)
+ usbd_xfer_handle xfer;
{
- usbd_pipe_handle pipe = reqh->pipe;
- usbd_status r;
+ usbd_pipe_handle pipe = xfer->pipe;
+ usb_dma_t *dmap = &xfer->dmabuf;
+ usbd_status err;
u_int size;
int s;
- DPRINTFN(5,("usbd_transfer: reqh=%p, flags=%d, pipe=%p, running=%d\n",
- reqh, reqh->flags, pipe, pipe->running));
+ DPRINTFN(5,("usbd_transfer: xfer=%p, flags=%d, pipe=%p, running=%d\n",
+ xfer, xfer->flags, pipe, pipe->running));
#ifdef USB_DEBUG
if (usbdebug > 5)
usbd_dump_queue(pipe);
#endif
- reqh->done = 0;
+ xfer->done = 0;
- size = reqh->length;
- /* If there is no buffer, allocate one and copy data. */
- if (!(reqh->rqflags & URQ_DEV_DMABUF) && size != 0) {
- usb_dma_t *dmap = &reqh->dmabuf;
+ size = xfer->length;
+ /* If there is no buffer, allocate one. */
+ if (!(xfer->rqflags & URQ_DEV_DMABUF) && size != 0) {
struct usbd_bus *bus = pipe->device->bus;
#ifdef DIAGNOSTIC
- if (reqh->rqflags & URQ_AUTO_DMABUF)
+ if (xfer->rqflags & URQ_AUTO_DMABUF)
printf("usbd_transfer: has old buffer!\n");
#endif
- r = bus->methods->allocm(bus, dmap, size);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- reqh->rqflags |= URQ_AUTO_DMABUF;
-
- /* finally copy data if going out */
- if (!usbd_reqh_isread(reqh))
- memcpy(KERNADDR(dmap), reqh->buffer, size);
+ err = bus->methods->allocm(bus, dmap, size);
+ if (err)
+ return (err);
+ xfer->rqflags |= URQ_AUTO_DMABUF;
}
- r = pipe->methods->transfer(reqh);
+ /* Copy data if going out. */
+ if (!(xfer->flags & USBD_NO_COPY) && size != 0 &&
+ !usbd_xfer_isread(xfer))
+ memcpy(KERNADDR(dmap), xfer->buffer, size);
+
+ err = pipe->methods->transfer(xfer);
- if (r != USBD_IN_PROGRESS && r != USBD_NORMAL_COMPLETION) {
+ if (err != USBD_IN_PROGRESS && err) {
/* The transfer has not been queued, so free buffer. */
- if (reqh->rqflags & URQ_AUTO_DMABUF) {
+ if (xfer->rqflags & URQ_AUTO_DMABUF) {
struct usbd_bus *bus = pipe->device->bus;
- bus->methods->freem(bus, &reqh->dmabuf);
- reqh->rqflags &= ~URQ_AUTO_DMABUF;
+ bus->methods->freem(bus, &xfer->dmabuf);
+ xfer->rqflags &= ~URQ_AUTO_DMABUF;
}
}
- if (!(reqh->flags & USBD_SYNCHRONOUS))
- return (r);
+ if (!(xfer->flags & USBD_SYNCHRONOUS))
+ return (err);
/* Sync transfer, wait for completion. */
- if (r != USBD_IN_PROGRESS)
- return (r);
+ if (err != USBD_IN_PROGRESS)
+ return (err);
s = splusb();
- if (!reqh->done) {
+ if (!xfer->done) {
if (pipe->device->bus->use_polling)
panic("usbd_transfer: not done\n");
- tsleep(reqh, PRIBIO, "usbsyn", 0);
+ tsleep(xfer, PRIBIO, "usbsyn", 0);
}
splx(s);
- return (reqh->status);
+ return (xfer->status);
}
/* Like usbd_transfer(), but waits for completion. */
usbd_status
-usbd_sync_transfer(reqh)
- usbd_request_handle reqh;
+usbd_sync_transfer(xfer)
+ usbd_xfer_handle xfer;
{
- reqh->flags |= USBD_SYNCHRONOUS;
- return (usbd_transfer(reqh));
+ xfer->flags |= USBD_SYNCHRONOUS;
+ return (usbd_transfer(xfer));
}
void *
-usbd_alloc_buffer(reqh, size)
- usbd_request_handle reqh;
+usbd_alloc_buffer(xfer, size)
+ usbd_xfer_handle xfer;
u_int32_t size;
{
- struct usbd_bus *bus = reqh->device->bus;
- usbd_status r;
+ struct usbd_bus *bus = xfer->device->bus;
+ usbd_status err;
- r = bus->methods->allocm(bus, &reqh->dmabuf, size);
- if (r != USBD_NORMAL_COMPLETION)
+ err = bus->methods->allocm(bus, &xfer->dmabuf, size);
+ if (err)
return (0);
- reqh->rqflags |= URQ_DEV_DMABUF;
- return (KERNADDR(&reqh->dmabuf));
+ xfer->rqflags |= URQ_DEV_DMABUF;
+ return (KERNADDR(&xfer->dmabuf));
}
void
-usbd_free_buffer(reqh)
- usbd_request_handle reqh;
+usbd_free_buffer(xfer)
+ usbd_xfer_handle xfer;
{
#ifdef DIAGNOSTIC
- if (!(reqh->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))) {
+ if (!(xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))) {
printf("usbd_free_buffer: no buffer\n");
return;
}
#endif
- reqh->rqflags &= ~(URQ_DEV_DMABUF | URQ_AUTO_DMABUF);
- reqh->device->bus->methods->freem(reqh->device->bus, &reqh->dmabuf);
+ xfer->rqflags &= ~(URQ_DEV_DMABUF | URQ_AUTO_DMABUF);
+ xfer->device->bus->methods->freem(xfer->device->bus, &xfer->dmabuf);
}
-usbd_request_handle
+void *
+usbd_get_buffer(xfer)
+ usbd_xfer_handle xfer;
+{
+ if (!(xfer->rqflags & URQ_DEV_DMABUF))
+ return (0);
+ return (KERNADDR(&xfer->dmabuf));
+}
+
+usbd_xfer_handle
usbd_alloc_request(dev)
usbd_device_handle dev;
{
- usbd_request_handle reqh;
+ usbd_xfer_handle xfer;
- reqh = SIMPLEQ_FIRST(&usbd_free_requests);
- if (reqh)
- SIMPLEQ_REMOVE_HEAD(&usbd_free_requests, reqh, next);
+ xfer = SIMPLEQ_FIRST(&usbd_free_requests);
+ if (xfer != NULL)
+ SIMPLEQ_REMOVE_HEAD(&usbd_free_requests, xfer, next);
else
- reqh = malloc(sizeof(*reqh), M_USB, M_NOWAIT);
- if (!reqh)
+ xfer = malloc(sizeof(*xfer), M_USB, M_NOWAIT);
+ if (xfer == NULL)
return (0);
- memset(reqh, 0, sizeof *reqh);
- reqh->device = dev;
- DPRINTFN(5,("usbd_alloc_request() = %p\n", reqh));
- return (reqh);
+ memset(xfer, 0, sizeof *xfer);
+ xfer->device = dev;
+ DPRINTFN(5,("usbd_alloc_request() = %p\n", xfer));
+ return (xfer);
}
usbd_status
-usbd_free_request(reqh)
- usbd_request_handle reqh;
+usbd_free_request(xfer)
+ usbd_xfer_handle xfer;
{
- DPRINTFN(5,("usbd_free_request: %p\n", reqh));
- if (reqh->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
- usbd_free_buffer(reqh);
- SIMPLEQ_INSERT_HEAD(&usbd_free_requests, reqh, next);
+ DPRINTFN(5,("usbd_free_request: %p\n", xfer));
+ if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
+ usbd_free_buffer(xfer);
+ SIMPLEQ_INSERT_HEAD(&usbd_free_requests, xfer, next);
return (USBD_NORMAL_COMPLETION);
}
void
-usbd_setup_request(reqh, pipe, priv, buffer, length, flags, timeout, callback)
- usbd_request_handle reqh;
+usbd_setup_request(xfer, pipe, priv, buffer, length, flags, timeout, callback)
+ usbd_xfer_handle xfer;
usbd_pipe_handle pipe;
usbd_private_handle priv;
void *buffer;
u_int32_t length;
u_int16_t flags;
u_int32_t timeout;
- void (*callback) __P((usbd_request_handle,
+ void (*callback) __P((usbd_xfer_handle,
usbd_private_handle,
usbd_status));
{
- reqh->pipe = pipe;
- reqh->priv = priv;
- reqh->buffer = buffer;
- reqh->length = length;
- reqh->actlen = 0;
- reqh->flags = flags;
- reqh->timeout = timeout;
- reqh->status = USBD_NOT_STARTED;
- reqh->callback = callback;
- reqh->rqflags &= ~URQ_REQUEST;
- reqh->nframes = 0;
+ xfer->pipe = pipe;
+ xfer->priv = priv;
+ xfer->buffer = buffer;
+ xfer->length = length;
+ xfer->actlen = 0;
+ xfer->flags = flags;
+ xfer->timeout = timeout;
+ xfer->status = USBD_NOT_STARTED;
+ xfer->callback = callback;
+ xfer->rqflags &= ~URQ_REQUEST;
+ xfer->nframes = 0;
}
void
-usbd_setup_default_request(reqh, dev, priv, timeout, req, buffer,
+usbd_setup_default_request(xfer, dev, priv, timeout, req, buffer,
length, flags, callback)
- usbd_request_handle reqh;
+ usbd_xfer_handle xfer;
usbd_device_handle dev;
usbd_private_handle priv;
u_int32_t timeout;
@@ -374,63 +415,64 @@ usbd_setup_default_request(reqh, dev, priv, timeout, req, buffer,
void *buffer;
u_int32_t length;
u_int16_t flags;
- void (*callback) __P((usbd_request_handle,
+ void (*callback) __P((usbd_xfer_handle,
usbd_private_handle,
usbd_status));
{
- reqh->pipe = dev->default_pipe;
- reqh->priv = priv;
- reqh->buffer = buffer;
- reqh->length = length;
- reqh->actlen = 0;
- reqh->flags = flags;
- reqh->timeout = timeout;
- reqh->status = USBD_NOT_STARTED;
- reqh->callback = callback;
- reqh->request = *req;
- reqh->rqflags |= URQ_REQUEST;
- reqh->nframes = 0;
+ xfer->pipe = dev->default_pipe;
+ xfer->priv = priv;
+ xfer->buffer = buffer;
+ xfer->length = length;
+ xfer->actlen = 0;
+ xfer->flags = flags;
+ xfer->timeout = timeout;
+ xfer->status = USBD_NOT_STARTED;
+ xfer->callback = callback;
+ xfer->request = *req;
+ xfer->rqflags |= URQ_REQUEST;
+ xfer->nframes = 0;
}
void
-usbd_setup_isoc_request(reqh, pipe, priv, frlengths, nframes, callback)
- usbd_request_handle reqh;
+usbd_setup_isoc_request(xfer, pipe, priv, frlengths, nframes, flags, callback)
+ usbd_xfer_handle xfer;
usbd_pipe_handle pipe;
usbd_private_handle priv;
u_int16_t *frlengths;
u_int32_t nframes;
+ u_int16_t flags;
usbd_callback callback;
{
- reqh->pipe = pipe;
- reqh->priv = priv;
- reqh->buffer = 0;
- reqh->length = 0;
- reqh->actlen = 0;
- reqh->flags = 0;
- reqh->timeout = USBD_NO_TIMEOUT;
- reqh->status = USBD_NOT_STARTED;
- reqh->callback = callback;
- reqh->rqflags &= ~URQ_REQUEST;
- reqh->frlengths = frlengths;
- reqh->nframes = nframes;
+ xfer->pipe = pipe;
+ xfer->priv = priv;
+ xfer->buffer = 0;
+ xfer->length = 0;
+ xfer->actlen = 0;
+ xfer->flags = flags;
+ xfer->timeout = USBD_NO_TIMEOUT;
+ xfer->status = USBD_NOT_STARTED;
+ xfer->callback = callback;
+ xfer->rqflags &= ~URQ_REQUEST;
+ xfer->frlengths = frlengths;
+ xfer->nframes = nframes;
}
void
-usbd_get_request_status(reqh, priv, buffer, count, status)
- usbd_request_handle reqh;
+usbd_get_request_status(xfer, priv, buffer, count, status)
+ usbd_xfer_handle xfer;
usbd_private_handle *priv;
void **buffer;
u_int32_t *count;
usbd_status *status;
{
- if (priv)
- *priv = reqh->priv;
- if (buffer)
- *buffer = reqh->buffer;
- if (count)
- *count = reqh->actlen;
- if (status)
- *status = reqh->status;
+ if (priv != NULL)
+ *priv = xfer->priv;
+ if (buffer != NULL)
+ *buffer = xfer->buffer;
+ if (count != NULL)
+ *count = xfer->actlen;
+ if (status != NULL)
+ *status = xfer->status;
}
usb_config_descriptor_t *
@@ -468,19 +510,19 @@ usbd_status
usbd_abort_pipe(pipe)
usbd_pipe_handle pipe;
{
- usbd_status r;
+ usbd_status err;
int s;
#ifdef DIAGNOSTIC
- if (pipe == 0) {
+ if (pipe == NULL) {
printf("usbd_close_pipe: pipe==NULL\n");
return (USBD_NORMAL_COMPLETION);
}
#endif
s = splusb();
- r = usbd_ar_pipe(pipe);
+ err = usbd_ar_pipe(pipe);
splx(s);
- return (r);
+ return (err);
}
usbd_status
@@ -489,7 +531,7 @@ usbd_clear_endpoint_stall(pipe)
{
usbd_device_handle dev = pipe->device;
usb_device_request_t req;
- usbd_status r;
+ usbd_status err;
DPRINTFN(8, ("usbd_clear_endpoint_stall\n"));
@@ -504,15 +546,15 @@ usbd_clear_endpoint_stall(pipe)
USETW(req.wValue, UF_ENDPOINT_HALT);
USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
USETW(req.wLength, 0);
- r = usbd_do_request(dev, &req, 0);
+ err = usbd_do_request(dev, &req, 0);
#if 0
XXX should we do this?
- if (r == USBD_NORMAL_COMPLETION) {
+ if (!err) {
pipe->state = USBD_PIPE_ACTIVE;
/* XXX activate pipe */
}
#endif
- return (r);
+ return (err);
}
usbd_status
@@ -521,7 +563,7 @@ usbd_clear_endpoint_stall_async(pipe)
{
usbd_device_handle dev = pipe->device;
usb_device_request_t req;
- usbd_status r;
+ usbd_status err;
pipe->methods->cleartoggle(pipe);
@@ -530,8 +572,8 @@ usbd_clear_endpoint_stall_async(pipe)
USETW(req.wValue, UF_ENDPOINT_HALT);
USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
USETW(req.wLength, 0);
- r = usbd_do_request_async(dev, &req, 0);
- return (r);
+ err = usbd_do_request_async(dev, &req, 0);
+ return (err);
}
usbd_status
@@ -548,7 +590,7 @@ usbd_interface_count(dev, count)
usbd_device_handle dev;
u_int8_t *count;
{
- if (!dev->cdesc)
+ if (dev->cdesc == NULL)
return (USBD_NOT_CONFIGURED);
*count = dev->cdesc->bNumInterface;
return (USBD_NORMAL_COMPLETION);
@@ -569,7 +611,7 @@ usbd_device2interface_handle(dev, ifaceno, iface)
u_int8_t ifaceno;
usbd_interface_handle *iface;
{
- if (!dev->cdesc)
+ if (dev->cdesc == NULL)
return (USBD_NOT_CONFIGURED);
if (ifaceno >= dev->cdesc->bNumInterface)
return (USBD_INVAL);
@@ -591,7 +633,7 @@ usbd_set_interface(iface, altidx)
int altidx;
{
usb_device_request_t req;
- usbd_status r;
+ usbd_status err;
if (LIST_FIRST(&iface->pipes) != 0)
return (USBD_IN_USE);
@@ -601,16 +643,16 @@ usbd_set_interface(iface, altidx)
iface->endpoints = 0;
iface->idesc = 0;
- r = usbd_fill_iface_data(iface->device, iface->index, altidx);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_fill_iface_data(iface->device, iface->index, altidx);
+ if (err)
+ return (err);
req.bmRequestType = UT_WRITE_INTERFACE;
req.bRequest = UR_SET_INTERFACE;
USETW(req.wValue, iface->idesc->bAlternateSetting);
USETW(req.wIndex, iface->idesc->bInterfaceNumber);
USETW(req.wLength, 0);
- return usbd_do_request(iface->device, &req, 0);
+ return (usbd_do_request(iface->device, &req, 0));
}
int
@@ -652,7 +694,7 @@ usbd_get_interface(iface, aiface)
USETW(req.wValue, 0);
USETW(req.wIndex, iface->idesc->bInterfaceNumber);
USETW(req.wLength, 1);
- return usbd_do_request(iface->device, &req, aiface);
+ return (usbd_do_request(iface->device, &req, aiface));
}
/*** Internal routines ***/
@@ -662,143 +704,167 @@ static usbd_status
usbd_ar_pipe(pipe)
usbd_pipe_handle pipe;
{
- usbd_request_handle reqh;
+ usbd_xfer_handle xfer;
+
+ SPLUSBCHECK;
DPRINTFN(2,("usbd_ar_pipe: pipe=%p\n", pipe));
#ifdef USB_DEBUG
if (usbdebug > 5)
usbd_dump_queue(pipe);
#endif
- while ((reqh = SIMPLEQ_FIRST(&pipe->queue))) {
- DPRINTFN(2,("usbd_ar_pipe: pipe=%p reqh=%p (methods=%p)\n",
- pipe, reqh, pipe->methods));
+ pipe->repeat = 0;
+ while ((xfer = SIMPLEQ_FIRST(&pipe->queue)) != NULL) {
+ DPRINTFN(2,("usbd_ar_pipe: pipe=%p xfer=%p (methods=%p)\n",
+ pipe, xfer, pipe->methods));
/* Make the HC abort it (and invoke the callback). */
- pipe->methods->abort(reqh);
+ pipe->methods->abort(xfer);
/* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */
}
return (USBD_NORMAL_COMPLETION);
}
+/* Called at splusb() */
void
-usb_transfer_complete(reqh)
- usbd_request_handle reqh;
+usb_transfer_complete(xfer)
+ usbd_xfer_handle xfer;
{
- usbd_pipe_handle pipe = reqh->pipe;
+ usbd_pipe_handle pipe = xfer->pipe;
+ usb_dma_t *dmap = &xfer->dmabuf;
+ int repeat = pipe->repeat;
int polling;
- DPRINTFN(5, ("usb_transfer_complete: pipe=%p reqh=%p actlen=%d\n",
- pipe, reqh, reqh->actlen));
+ SPLUSBCHECK;
+
+ DPRINTFN(5, ("usb_transfer_complete: pipe=%p xfer=%p status=%d "
+ "actlen=%d\n", pipe, xfer, xfer->status, xfer->actlen));
#ifdef DIAGNOSTIC
- if (!pipe) {
- printf("usbd_transfer_cb: pipe==0, reqh=%p\n", reqh);
+ if (pipe == NULL) {
+ printf("usbd_transfer_cb: pipe==0, xfer=%p\n", xfer);
return;
}
#endif
-
polling = pipe->device->bus->use_polling;
/* XXXX */
if (polling)
pipe->running = 0;
- /* if we allocated the buffer in usbd_transfer() we free it here. */
- if (reqh->rqflags & URQ_AUTO_DMABUF) {
- usb_dma_t *dmap = &reqh->dmabuf;
+ if (!(xfer->flags & USBD_NO_COPY) && xfer->actlen != 0 &&
+ usbd_xfer_isread(xfer)) {
+#ifdef DIAGNOSTIC
+ if (xfer->actlen > xfer->length) {
+ printf("usb_transfer_complete: actlen > len %d > %d\n",
+ xfer->actlen, xfer->length);
+ xfer->actlen = xfer->length;
+ }
+#endif
+ memcpy(xfer->buffer, KERNADDR(dmap), xfer->actlen);
+ }
- if (usbd_reqh_isread(reqh))
- memcpy(reqh->buffer, KERNADDR(dmap), reqh->actlen);
- if (!pipe->repeat) {
+ /* if we allocated the buffer in usbd_transfer() we free it here. */
+ if (xfer->rqflags & URQ_AUTO_DMABUF) {
+ if (!repeat) {
struct usbd_bus *bus = pipe->device->bus;
bus->methods->freem(bus, dmap);
- reqh->rqflags &= ~URQ_AUTO_DMABUF;
+ xfer->rqflags &= ~URQ_AUTO_DMABUF;
}
}
- if (pipe->methods->done)
- pipe->methods->done(reqh);
-
- /* Remove request from queue. */
- if ( reqh == SIMPLEQ_FIRST(&pipe->queue) )
- SIMPLEQ_REMOVE_HEAD(&pipe->queue, reqh, next);
- else
- DPRINTF(("XXX duplicated call to usb_transfer_complete\n"));
+ if (pipe->methods->done != NULL)
+ pipe->methods->done(xfer);
+ if (!repeat) {
+ /* Remove request from queue. */
+#ifdef DIAGNOSTIC
+ if (xfer != SIMPLEQ_FIRST(&pipe->queue))
+ printf("usb_transfer_complete: bad dequeue %p != %p\n",
+ xfer, SIMPLEQ_FIRST(&pipe->queue));
+#endif
+ SIMPLEQ_REMOVE_HEAD(&pipe->queue, xfer, next);
+ }
/* Count completed transfers. */
++pipe->device->bus->stats.requests
[pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE];
- reqh->done = 1;
- if (reqh->status == USBD_NORMAL_COMPLETION &&
- reqh->actlen < reqh->length &&
- !(reqh->flags & USBD_SHORT_XFER_OK)) {
- DPRINTFN(-1, ("usbd_transfer_cb: short xfer %d<%d (bytes)\n",
- reqh->actlen, reqh->length));
- reqh->status = USBD_SHORT_XFER;
+ xfer->done = 1;
+ if (xfer->status == USBD_NORMAL_COMPLETION &&
+ xfer->actlen < xfer->length &&
+ !(xfer->flags & USBD_SHORT_XFER_OK)) {
+ DPRINTFN(-1, ("usbd_transfer_cb: short transfer %d<%d\n",
+ xfer->actlen, xfer->length));
+ xfer->status = USBD_SHORT_XFER;
}
- if (reqh->callback)
- reqh->callback(reqh, reqh->priv, reqh->status);
+ if (xfer->callback)
+ xfer->callback(xfer, xfer->priv, xfer->status);
- if ((reqh->flags & USBD_SYNCHRONOUS) && !polling)
- wakeup(reqh);
+ if ((xfer->flags & USBD_SYNCHRONOUS) && !polling)
+ wakeup(xfer);
- if (!pipe->repeat &&
- reqh->status != USBD_CANCELLED && reqh->status != USBD_TIMEOUT)
- usbd_start_next(pipe);
+ if (!repeat) {
+ /* XXX should we stop the queue on all errors? */
+ if (xfer->status == USBD_CANCELLED ||
+ xfer->status == USBD_TIMEOUT)
+ pipe->running = 0;
+ else
+ usbd_start_next(pipe);
+ }
}
usbd_status
-usb_insert_transfer(reqh)
- usbd_request_handle reqh;
+usb_insert_transfer(xfer)
+ usbd_xfer_handle xfer;
{
- usbd_pipe_handle pipe = reqh->pipe;
- usbd_status r;
+ usbd_pipe_handle pipe = xfer->pipe;
+ usbd_status err;
int s;
- DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d\n", pipe,
- pipe->running));
+ DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d timeout=%d\n",
+ pipe, pipe->running, xfer->timeout));
s = splusb();
- SIMPLEQ_INSERT_TAIL(&pipe->queue, reqh, next);
+ SIMPLEQ_INSERT_TAIL(&pipe->queue, xfer, next);
if (pipe->running)
- r = USBD_IN_PROGRESS;
+ err = USBD_IN_PROGRESS;
else {
pipe->running = 1;
- r = USBD_NORMAL_COMPLETION;
+ err = USBD_NORMAL_COMPLETION;
}
splx(s);
- return (r);
+ return (err);
}
+/* Called at splusb() */
void
usbd_start_next(pipe)
usbd_pipe_handle pipe;
{
- usbd_request_handle reqh;
- usbd_status r;
+ usbd_xfer_handle xfer;
+ usbd_status err;
+
+ SPLUSBCHECK;
- DPRINTFN(10, ("usbd_start_next: pipe=%p\n", pipe));
-
#ifdef DIAGNOSTIC
- if (!pipe) {
- printf("usbd_start_next: pipe == 0\n");
+ if (pipe == NULL) {
+ printf("usbd_start_next: pipe == NULL\n");
return;
}
- if (!pipe->methods || !pipe->methods->start) {
- printf("usbd_start_next: no start method\n");
+ if (pipe->methods == NULL || pipe->methods->start == NULL) {
+ printf("usbd_start_next: pipe=%p no start method\n", pipe);
return;
}
#endif
/* Get next request in queue. */
- reqh = SIMPLEQ_FIRST(&pipe->queue);
- DPRINTFN(5, ("usbd_start_next: pipe=%p start reqh=%p\n", pipe, reqh));
- if (!reqh)
+ xfer = SIMPLEQ_FIRST(&pipe->queue);
+ DPRINTFN(5, ("usbd_start_next: pipe=%p, xfer=%p\n", pipe, xfer));
+ if (xfer == NULL) {
pipe->running = 0;
- else {
- r = pipe->methods->start(reqh);
- if (r != USBD_IN_PROGRESS) {
- printf("usbd_start_next: error=%d\n", r);
+ } else {
+ err = pipe->methods->start(xfer);
+ if (err != USBD_IN_PROGRESS) {
+ printf("usbd_start_next: error=%d\n", err);
pipe->running = 0;
/* XXX do what? */
}
@@ -822,35 +888,39 @@ usbd_do_request_flags(dev, req, data, flags, actlen)
u_int16_t flags;
int *actlen;
{
- usbd_request_handle reqh;
- usbd_status r;
+ usbd_xfer_handle xfer;
+ usbd_status err;
#ifdef DIAGNOSTIC
- if (!curproc) {
+#if defined(__i386__)
+ KASSERT(intr_nesting_level == 0,
+ ("ohci_abort_req in interrupt context"));
+#endif
+ if (dev->bus->intr_context) {
printf("usbd_do_request: not in process context\n");
return (USBD_INVAL);
}
#endif
- reqh = usbd_alloc_request(dev);
- if (reqh == 0)
+ xfer = usbd_alloc_request(dev);
+ if (xfer == NULL)
return (USBD_NOMEM);
- usbd_setup_default_request(reqh, dev, 0, USBD_DEFAULT_TIMEOUT, req,
+ usbd_setup_default_request(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req,
data, UGETW(req->wLength), flags, 0);
- r = usbd_sync_transfer(reqh);
+ err = usbd_sync_transfer(xfer);
#if defined(USB_DEBUG) || defined(DIAGNOSTIC)
- if (reqh->actlen > reqh->length)
+ if (xfer->actlen > xfer->length)
DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
"%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
- dev->address, reqh->request.bmRequestType,
- reqh->request.bRequest, UGETW(reqh->request.wValue),
- UGETW(reqh->request.wIndex),
- UGETW(reqh->request.wLength),
- reqh->length, reqh->actlen));
+ dev->address, xfer->request.bmRequestType,
+ xfer->request.bRequest, UGETW(xfer->request.wValue),
+ UGETW(xfer->request.wIndex),
+ UGETW(xfer->request.wLength),
+ xfer->length, xfer->actlen));
#endif
- if (actlen)
- *actlen = reqh->actlen;
- if (r == USBD_STALLED) {
+ if (actlen != NULL)
+ *actlen = xfer->actlen;
+ if (err == USBD_STALLED) {
/*
* The control endpoint has stalled. Control endpoints
* should not halt, but some may do so anyway so clear
@@ -859,18 +929,18 @@ usbd_do_request_flags(dev, req, data, flags, actlen)
usb_device_request_t treq;
usb_status_t status;
u_int16_t s;
- usbd_status nr;
+ usbd_status nerr;
treq.bmRequestType = UT_READ_ENDPOINT;
treq.bRequest = UR_GET_STATUS;
USETW(treq.wValue, 0);
USETW(treq.wIndex, 0);
USETW(treq.wLength, sizeof(usb_status_t));
- usbd_setup_default_request(reqh, dev, 0, USBD_DEFAULT_TIMEOUT,
+ usbd_setup_default_request(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
&treq, &status,sizeof(usb_status_t),
0, 0);
- nr = usbd_sync_transfer(reqh);
- if (nr != USBD_NORMAL_COMPLETION)
+ nerr = usbd_sync_transfer(xfer);
+ if (nerr)
goto bad;
s = UGETW(status.wStatus);
DPRINTF(("usbd_do_request: status = 0x%04x\n", s));
@@ -881,36 +951,36 @@ usbd_do_request_flags(dev, req, data, flags, actlen)
USETW(treq.wValue, UF_ENDPOINT_HALT);
USETW(treq.wIndex, 0);
USETW(treq.wLength, 0);
- usbd_setup_default_request(reqh, dev, 0, USBD_DEFAULT_TIMEOUT,
+ usbd_setup_default_request(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
&treq, &status, 0, 0, 0);
- nr = usbd_sync_transfer(reqh);
- if (nr != USBD_NORMAL_COMPLETION)
+ nerr = usbd_sync_transfer(xfer);
+ if (nerr)
goto bad;
}
bad:
- usbd_free_request(reqh);
- return (r);
+ usbd_free_request(xfer);
+ return (err);
}
void
-usbd_do_request_async_cb(reqh, priv, status)
- usbd_request_handle reqh;
+usbd_do_request_async_cb(xfer, priv, status)
+ usbd_xfer_handle xfer;
usbd_private_handle priv;
usbd_status status;
{
#if defined(USB_DEBUG) || defined(DIAGNOSTIC)
- if (reqh->actlen > reqh->length)
+ if (xfer->actlen > xfer->length)
DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
"%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
- reqh->pipe->device->address,
- reqh->request.bmRequestType,
- reqh->request.bRequest, UGETW(reqh->request.wValue),
- UGETW(reqh->request.wIndex),
- UGETW(reqh->request.wLength),
- reqh->length, reqh->actlen));
+ xfer->pipe->device->address,
+ xfer->request.bmRequestType,
+ xfer->request.bRequest, UGETW(xfer->request.wValue),
+ UGETW(xfer->request.wIndex),
+ UGETW(xfer->request.wLength),
+ xfer->length, xfer->actlen));
#endif
- usbd_free_request(reqh);
+ usbd_free_request(xfer);
}
/*
@@ -923,19 +993,18 @@ usbd_do_request_async(dev, req, data)
usb_device_request_t *req;
void *data;
{
- usbd_request_handle reqh;
- usbd_status r;
+ usbd_xfer_handle xfer;
+ usbd_status err;
- reqh = usbd_alloc_request(dev);
- if (reqh == 0)
+ xfer = usbd_alloc_request(dev);
+ if (xfer == NULL)
return (USBD_NOMEM);
- usbd_setup_default_request(reqh, dev, 0, USBD_DEFAULT_TIMEOUT, req, data,
- UGETW(req->wLength), 0,
- usbd_do_request_async_cb);
- r = usbd_transfer(reqh);
- if (r != USBD_IN_PROGRESS) {
- usbd_free_request(reqh);
- return (r);
+ usbd_setup_default_request(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req,
+ data, UGETW(req->wLength), 0, usbd_do_request_async_cb);
+ err = usbd_transfer(xfer);
+ if (err != USBD_IN_PROGRESS) {
+ usbd_free_request(xfer);
+ return (err);
}
return (USBD_NORMAL_COMPLETION);
}
@@ -964,7 +1033,10 @@ usbd_set_polling(iface, on)
usbd_interface_handle iface;
int on;
{
- iface->device->bus->use_polling = on;
+ if (on)
+ iface->device->bus->use_polling++;
+ else
+ iface->device->bus->use_polling--;
}
@@ -989,7 +1061,8 @@ int
usbd_driver_load(module_t mod, int what, void *arg)
{
/* XXX should implement something like a function that removes all generic devices */
-
- return 0; /* nothing to do by us */
+
+ return (0);
}
+
#endif
diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h
index 7fb4469..fef131d 100644
--- a/sys/dev/usb/usbdi.h
+++ b/sys/dev/usb/usbdi.h
@@ -1,4 +1,4 @@
-/* $NetBSD: usbdi.h,v 1.28 1999/09/11 08:19:27 augustss Exp $ */
+/* $NetBSD: usbdi.h,v 1.31 1999/10/13 08:10:58 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -42,11 +42,11 @@ typedef struct usbd_bus *usbd_bus_handle;
typedef struct usbd_device *usbd_device_handle;
typedef struct usbd_interface *usbd_interface_handle;
typedef struct usbd_pipe *usbd_pipe_handle;
-typedef struct usbd_request *usbd_request_handle;
+typedef struct usbd_xfer *usbd_xfer_handle;
typedef void *usbd_private_handle;
-typedef enum { /* keep in sync with usbd_status_msgs */
- USBD_NORMAL_COMPLETION = 0, /* must be 0 */
+typedef enum { /* keep in sync with usbd_status_msgs */
+ USBD_NORMAL_COMPLETION = 0, /* must be 0 */
USBD_IN_PROGRESS,
/* errors */
USBD_PENDING_REQUESTS,
@@ -72,15 +72,16 @@ typedef enum { /* keep in sync with usbd_status_msgs */
typedef int usbd_lock_token;
-typedef void (*usbd_callback) __P((usbd_request_handle, usbd_private_handle,
+typedef void (*usbd_callback) __P((usbd_xfer_handle, usbd_private_handle,
usbd_status));
/* Open flags */
#define USBD_EXCLUSIVE_USE 0x01
/* Request flags */
+#define USBD_NO_COPY 0x01 /* do not copy data to DMA buffer */
+#define USBD_SYNCHRONOUS 0x02 /* wait for completion */
/* in usb.h #define USBD_SHORT_XFER_OK 0x04*/ /* allow short reads */
-#define USBD_SYNCHRONOUS 0x08 /* wait for completion */
#define USBD_NO_TIMEOUT 0
#define USBD_DEFAULT_TIMEOUT 5000 /* ms = 5 s */
@@ -93,25 +94,25 @@ usbd_status usbd_open_pipe
__P((usbd_interface_handle iface, u_int8_t address,
u_int8_t flags, usbd_pipe_handle *pipe));
usbd_status usbd_close_pipe __P((usbd_pipe_handle pipe));
-usbd_status usbd_transfer __P((usbd_request_handle req));
-usbd_request_handle usbd_alloc_request __P((usbd_device_handle));
-usbd_status usbd_free_request __P((usbd_request_handle reqh));
+usbd_status usbd_transfer __P((usbd_xfer_handle req));
+usbd_xfer_handle usbd_alloc_request __P((usbd_device_handle));
+usbd_status usbd_free_request __P((usbd_xfer_handle xfer));
void usbd_setup_request
- __P((usbd_request_handle reqh, usbd_pipe_handle pipe,
+ __P((usbd_xfer_handle xfer, usbd_pipe_handle pipe,
usbd_private_handle priv, void *buffer,
u_int32_t length, u_int16_t flags, u_int32_t timeout,
usbd_callback));
void usbd_setup_default_request
- __P((usbd_request_handle reqh, usbd_device_handle dev,
+ __P((usbd_xfer_handle xfer, usbd_device_handle dev,
usbd_private_handle priv, u_int32_t timeout,
usb_device_request_t *req, void *buffer,
u_int32_t length, u_int16_t flags, usbd_callback));
void usbd_setup_isoc_request
- __P((usbd_request_handle reqh, usbd_pipe_handle pipe,
+ __P((usbd_xfer_handle xfer, usbd_pipe_handle pipe,
usbd_private_handle priv, u_int16_t *frlengths,
- u_int32_t nframes, usbd_callback));
+ u_int32_t nframes, u_int16_t flags, usbd_callback));
void usbd_get_request_status
- __P((usbd_request_handle reqh, usbd_private_handle *priv,
+ __P((usbd_xfer_handle xfer, usbd_private_handle *priv,
void **buffer, u_int32_t *count, usbd_status *status));
usb_endpoint_descriptor_t *usbd_interface2endpoint_descriptor
__P((usbd_interface_handle iface, u_int8_t address));
@@ -128,9 +129,10 @@ usbd_status usbd_device2interface_handle
__P((usbd_device_handle dev, u_int8_t ifaceno, usbd_interface_handle *iface));
usbd_device_handle usbd_pipe2device_handle __P((usbd_pipe_handle));
-void *usbd_alloc_buffer __P((usbd_request_handle req, u_int32_t size));
-void usbd_free_buffer __P((usbd_request_handle req));
-usbd_status usbd_sync_transfer __P((usbd_request_handle req));
+void *usbd_alloc_buffer __P((usbd_xfer_handle req, u_int32_t size));
+void usbd_free_buffer __P((usbd_xfer_handle req));
+void *usbd_get_buffer __P((usbd_xfer_handle xfer));
+usbd_status usbd_sync_transfer __P((usbd_xfer_handle req));
usbd_status usbd_open_pipe_intr
__P((usbd_interface_handle iface, u_int8_t address,
u_int8_t flags, usbd_pipe_handle *pipe,
@@ -166,6 +168,10 @@ usb_endpoint_descriptor_t *usbd_find_edesc
void usbd_dopoll __P((usbd_interface_handle));
void usbd_set_polling __P((usbd_interface_handle iface, int on));
+const char *usbd_errstr __P((usbd_status err));
+
+void usbd_add_event __P((int, usbd_device_handle));
+
/* NetBSD attachment information */
/* Attach data */
@@ -229,8 +235,6 @@ void usbd_devinfo __P((usbd_device_handle, int, char *));
struct usbd_quirks *usbd_get_quirks __P((usbd_device_handle));
usb_endpoint_descriptor_t *usbd_get_endpoint_descriptor
__P((usbd_interface_handle iface, u_int8_t address));
-const char *usbd_errstr __P((usbd_status));
-
#if defined(__FreeBSD__)
int usbd_driver_load __P((module_t mod, int what, void *arg));
diff --git a/sys/dev/usb/usbdi_util.c b/sys/dev/usb/usbdi_util.c
index 69fa222..ab54b13 100644
--- a/sys/dev/usb/usbdi_util.c
+++ b/sys/dev/usb/usbdi_util.c
@@ -1,4 +1,4 @@
-/* $NetBSD: usbdi_util.c,v 1.21 1999/09/09 12:26:48 augustss Exp $ */
+/* $NetBSD: usbdi_util.c,v 1.22 1999/10/13 08:10:59 augustss Exp $ */
/* $FreeBSD$ */
/*
@@ -87,13 +87,13 @@ usbd_get_config_desc(dev, conf, d)
int conf;
usb_config_descriptor_t *d;
{
- usbd_status r;
+ usbd_status err;
DPRINTFN(3,("usbd_get_config_desc: conf=%d\n", conf));
- r = usbd_get_desc(dev, UDESC_CONFIG, conf,
+ err = usbd_get_desc(dev, UDESC_CONFIG, conf,
USB_CONFIG_DESCRIPTOR_SIZE, d);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ if (err)
+ return (err);
if (d->bDescriptorType != UDESC_CONFIG) {
DPRINTFN(-1,("usbd_get_config_desc: conf %d, bad desc %d\n",
conf, d->bDescriptorType));
@@ -253,17 +253,15 @@ usbd_set_protocol(iface, report)
usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface);
usbd_device_handle dev;
usb_device_request_t req;
- usbd_status r;
+ usbd_status err;
DPRINTFN(4, ("usbd_set_protocol: iface=%p, report=%d, endpt=%d\n",
iface, report, id->bInterfaceNumber));
- if (!id)
+ if (id == NULL)
return (USBD_IOERROR);
- r = usbd_interface2device_handle(iface, &dev);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- if (!id)
- return (USBD_INVAL);
+ err = usbd_interface2device_handle(iface, &dev);
+ if (err)
+ return (err);
req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
req.bRequest = UR_SET_PROTOCOL;
USETW(req.wValue, report);
@@ -283,16 +281,14 @@ usbd_set_report(iface, type, id, data, len)
usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
usbd_device_handle dev;
usb_device_request_t req;
- usbd_status r;
+ usbd_status err;
DPRINTFN(4, ("usbd_set_report: len=%d\n", len));
- if (!ifd)
+ if (ifd == NULL)
return (USBD_IOERROR);
- r = usbd_interface2device_handle(iface, &dev);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- if (!ifd)
- return (USBD_INVAL);
+ err = usbd_interface2device_handle(iface, &dev);
+ if (err)
+ return (err);
req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
req.bRequest = UR_SET_REPORT;
USETW2(req.wValue, type, id);
@@ -312,16 +308,14 @@ usbd_set_report_async(iface, type, id, data, len)
usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
usbd_device_handle dev;
usb_device_request_t req;
- usbd_status r;
+ usbd_status err;
DPRINTFN(4, ("usbd_set_report_async: len=%d\n", len));
- if (!ifd)
+ if (ifd == NULL)
return (USBD_IOERROR);
- r = usbd_interface2device_handle(iface, &dev);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- if (!ifd)
- return (USBD_INVAL);
+ err = usbd_interface2device_handle(iface, &dev);
+ if (err)
+ return (err);
req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
req.bRequest = UR_SET_REPORT;
USETW2(req.wValue, type, id);
@@ -341,16 +335,14 @@ usbd_get_report(iface, type, id, data, len)
usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
usbd_device_handle dev;
usb_device_request_t req;
- usbd_status r;
+ usbd_status err;
DPRINTFN(4, ("usbd_set_report: len=%d\n", len));
- if (!id)
+ if (id == NULL)
return (USBD_IOERROR);
- r = usbd_interface2device_handle(iface, &dev);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- if (!ifd)
- return (USBD_INVAL);
+ err = usbd_interface2device_handle(iface, &dev);
+ if (err)
+ return (err);
req.bmRequestType = UT_READ_CLASS_INTERFACE;
req.bRequest = UR_GET_REPORT;
USETW2(req.wValue, type, id);
@@ -368,16 +360,14 @@ usbd_set_idle(iface, duration, id)
usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface);
usbd_device_handle dev;
usb_device_request_t req;
- usbd_status r;
+ usbd_status err;
DPRINTFN(4, ("usbd_set_idle: %d %d\n", duration, id));
- if (!ifd)
+ if (ifd == NULL)
return (USBD_IOERROR);
- r = usbd_interface2device_handle(iface, &dev);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
- if (!ifd)
- return (USBD_INVAL);
+ err = usbd_interface2device_handle(iface, &dev);
+ if (err)
+ return (err);
req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
req.bRequest = UR_SET_IDLE;
USETW2(req.wValue, duration, id);
@@ -413,12 +403,12 @@ usbd_get_hid_descriptor(ifc)
usb_config_descriptor_t *cdesc;
usb_hid_descriptor_t *hd;
char *p, *end;
- usbd_status r;
+ usbd_status err;
- if (!idesc)
+ if (idesc == NULL)
return (0);
- r = usbd_interface2device_handle(ifc, &dev);
- if (r != USBD_NORMAL_COMPLETION)
+ err = usbd_interface2device_handle(ifc, &dev);
+ if (err)
return (0);
cdesc = usbd_get_config_descriptor(dev);
@@ -450,27 +440,27 @@ usbd_alloc_report_desc(ifc, descp, sizep, mem)
usb_interface_descriptor_t *id;
usb_hid_descriptor_t *hid;
usbd_device_handle dev;
- usbd_status r;
+ usbd_status err;
- r = usbd_interface2device_handle(ifc, &dev);
- if (r != USBD_NORMAL_COMPLETION)
- return (r);
+ err = usbd_interface2device_handle(ifc, &dev);
+ if (err)
+ return (err);
id = usbd_get_interface_descriptor(ifc);
- if (!id)
+ if (id == NULL)
return (USBD_INVAL);
hid = usbd_get_hid_descriptor(ifc);
- if (!hid)
+ if (hid == NULL)
return (USBD_IOERROR);
*sizep = UGETW(hid->descrs[0].wDescriptorLength);
*descp = malloc(*sizep, mem, M_NOWAIT);
- if (!*descp)
+ if (*descp == NULL)
return (USBD_NOMEM);
/* XXX should not use 0 Report ID */
- r = usbd_get_report_descriptor(dev, id->bInterfaceNumber, 0,
+ err = usbd_get_report_descriptor(dev, id->bInterfaceNumber, 0,
*sizep, *descp);
- if (r != USBD_NORMAL_COMPLETION) {
+ if (err) {
free(*descp, mem);
- return (r);
+ return (err);
}
return (USBD_NORMAL_COMPLETION);
}
@@ -490,20 +480,20 @@ usbd_get_config(dev, conf)
return (usbd_do_request(dev, &req, conf));
}
-static void usbd_bulk_transfer_cb __P((usbd_request_handle reqh,
+static void usbd_bulk_transfer_cb __P((usbd_xfer_handle xfer,
usbd_private_handle priv, usbd_status status));
static void
-usbd_bulk_transfer_cb(reqh, priv, status)
- usbd_request_handle reqh;
+usbd_bulk_transfer_cb(xfer, priv, status)
+ usbd_xfer_handle xfer;
usbd_private_handle priv;
usbd_status status;
{
- wakeup(reqh);
+ wakeup(xfer);
}
usbd_status
-usbd_bulk_transfer(reqh, pipe, flags, timeout, buf, size, lbl)
- usbd_request_handle reqh;
+usbd_bulk_transfer(xfer, pipe, flags, timeout, buf, size, lbl)
+ usbd_xfer_handle xfer;
usbd_pipe_handle pipe;
u_int16_t flags;
u_int32_t timeout;
@@ -511,32 +501,32 @@ usbd_bulk_transfer(reqh, pipe, flags, timeout, buf, size, lbl)
u_int32_t *size;
char *lbl;
{
- usbd_status r;
+ usbd_status err;
int s, error;
- usbd_setup_request(reqh, pipe, 0, buf, *size,
+ usbd_setup_request(xfer, pipe, 0, buf, *size,
flags, timeout, usbd_bulk_transfer_cb);
DPRINTFN(1, ("usbd_bulk_transfer: start transfer %d bytes\n", *size));
s = splusb(); /* don't want callback until tsleep() */
- r = usbd_transfer(reqh);
- if (r != USBD_IN_PROGRESS) {
+ err = usbd_transfer(xfer);
+ if (err != USBD_IN_PROGRESS) {
splx(s);
- return (r);
+ return (err);
}
- error = tsleep((caddr_t)reqh, PZERO | PCATCH, lbl, 0);
+ error = tsleep((caddr_t)xfer, PZERO | PCATCH, lbl, 0);
splx(s);
if (error) {
DPRINTF(("usbd_bulk_transfer: tsleep=%d\n", error));
usbd_abort_pipe(pipe);
return (USBD_INTERRUPTED);
}
- usbd_get_request_status(reqh, 0, 0, size, &r);
+ usbd_get_request_status(xfer, 0, 0, size, &err);
DPRINTFN(1,("usbd_bulk_transfer: transferred %d\n", *size));
- if (r != USBD_NORMAL_COMPLETION) {
- DPRINTF(("usbd_bulk_transfer: error=%d\n", r));
+ if (err) {
+ DPRINTF(("usbd_bulk_transfer: error=%d\n", err));
usbd_clear_endpoint_stall(pipe);
}
- return (r);
+ return (err);
}
void
diff --git a/sys/dev/usb/usbdi_util.h b/sys/dev/usb/usbdi_util.h
index 17d6d5b..115bd9b 100644
--- a/sys/dev/usb/usbdi_util.h
+++ b/sys/dev/usb/usbdi_util.h
@@ -90,7 +90,7 @@ usbd_status usbd_set_config_index
__P((usbd_device_handle dev, int index, int msg));
usbd_status usbd_bulk_transfer
- __P((usbd_request_handle reqh, usbd_pipe_handle pipe, u_int16_t flags,
+ __P((usbd_xfer_handle xfer, usbd_pipe_handle pipe, u_int16_t flags,
u_int32_t timeout, void *buf, u_int32_t *size, char *lbl));
void usb_detach_wait __P((device_ptr_t));
diff --git a/sys/dev/usb/usbdivar.h b/sys/dev/usb/usbdivar.h
index d2a1544..46cd1be 100644
--- a/sys/dev/usb/usbdivar.h
+++ b/sys/dev/usb/usbdivar.h
@@ -1,5 +1,5 @@
-/* $NetBSD: usbdivar.h,v 1.30 1999/09/11 08:19:27 augustss Exp $ */
-/* $FreeBSD$ */
+/* $NetBSD: usbdivar.h,v 1.39 1999/11/10 04:19:59 mycroft Exp $ */
+/* $FreeBSD$ */
/*
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -41,7 +41,7 @@
/* From usb_mem.h */
DECLARE_USB_DMA_T;
-struct usbd_request;
+struct usbd_xfer;
struct usbd_pipe;
struct usbd_endpoint {
@@ -58,12 +58,12 @@ struct usbd_bus_methods {
};
struct usbd_pipe_methods {
- usbd_status (*transfer)__P((usbd_request_handle reqh));
- usbd_status (*start)__P((usbd_request_handle reqh));
- void (*abort)__P((usbd_request_handle reqh));
+ usbd_status (*transfer)__P((usbd_xfer_handle xfer));
+ usbd_status (*start)__P((usbd_xfer_handle xfer));
+ void (*abort)__P((usbd_xfer_handle xfer));
void (*close)__P((usbd_pipe_handle pipe));
void (*cleartoggle)__P((usbd_pipe_handle pipe));
- void (*done)__P((usbd_request_handle reqh));
+ void (*done)__P((usbd_xfer_handle xfer));
};
struct usbd_port {
@@ -99,6 +99,11 @@ struct usbd_bus {
char use_polling;
struct usb_softc *usbctl;
struct usb_device_stats stats;
+ int intr_context;
+ u_int no_intrs;
+#if defined(__NetBSD__) || defined(__OpenBSD__)
+ bus_dma_tag_t dmatag; /* DMA tag */
+#endif
};
struct usbd_device {
@@ -112,6 +117,7 @@ struct usbd_device {
int config;
int langid; /* language to use for strings */
#define USBD_NOLANG (-1)
+ usb_event_cookie_t cookie; /* unique connection id */
struct usbd_port *powersrc;
struct usbd_endpoint def_ep; /* for pipe 0 */
usb_endpoint_descriptor_t def_ep_desc; /* for pipe 0 */
@@ -139,17 +145,17 @@ struct usbd_pipe {
struct usbd_endpoint *endpoint;
int refcnt;
char running;
- SIMPLEQ_HEAD(, usbd_request) queue;
+ SIMPLEQ_HEAD(, usbd_xfer) queue;
LIST_ENTRY(usbd_pipe) next;
- usbd_request_handle intrreqh; /* used for repeating requests */
+ usbd_xfer_handle intrxfer; /* used for repeating requests */
char repeat;
/* Filled by HC driver. */
struct usbd_pipe_methods *methods;
};
-struct usbd_request {
+struct usbd_xfer {
struct usbd_pipe *pipe;
void *priv;
void *buffer;
@@ -177,7 +183,7 @@ struct usbd_request {
#define URQ_AUTO_DMABUF 0x10
#define URQ_DEV_DMABUF 0x20
- SIMPLEQ_ENTRY(usbd_request) next;
+ SIMPLEQ_ENTRY(usbd_xfer) next;
void *hcpriv; /* private use by the HC driver */
int hcprivint; /* ditto */
@@ -187,6 +193,9 @@ struct usbd_request {
#endif
};
+void usbd_init __P((void));
+void usbd_finish __P((void));
+
/* Routines from usb_subr.c */
int usbctlprint __P((void *, const char *));
void usb_delay_ms __P((usbd_bus_handle, u_int));
@@ -208,13 +217,26 @@ usbd_status usbd_fill_iface_data __P((usbd_device_handle dev,
int i, int a));
void usb_free_device __P((usbd_device_handle));
-usbd_status usb_insert_transfer __P((usbd_request_handle reqh));
-void usb_transfer_complete __P((usbd_request_handle reqh));
+usbd_status usb_insert_transfer __P((usbd_xfer_handle xfer));
+void usb_transfer_complete __P((usbd_xfer_handle xfer));
+void usb_disconnect_port __P((struct usbd_port *up, device_ptr_t));
/* Routines from usb.c */
int usb_bus_count __P((void));
void usb_needs_explore __P((usbd_bus_handle));
+#ifdef DIAGNOSTIC
+#define SPLUSBCHECK \
+ do { int _s = splusb(), _su = splusb(); \
+ extern int cold; \
+ if (!cold && _s != _su) printf("SPLUSBCHECK failed 0x%x!=0x%x, %s:%d\n", \
+ _s, _su, __FILE__, __LINE__); \
+ splx(_s); \
+ } while (0)
+#else
+#define SPLUSBCHECK
+#endif
+
/* Locator stuff. */
#if defined(__NetBSD__)
diff --git a/sys/dev/usb/usbhid.h b/sys/dev/usb/usbhid.h
index 5858b42..32b91e5 100644
--- a/sys/dev/usb/usbhid.h
+++ b/sys/dev/usb/usbhid.h
@@ -1,4 +1,4 @@
-/* $NetBSD: usbhid.h,v 1.5 1999/05/13 23:29:11 augustss Exp $ */
+/* $NetBSD: usbhid.h,v 1.4 1999/04/22 01:57:01 augustss Exp $ */
/* $FreeBSD$ */
/*
OpenPOWER on IntegriCloud