diff options
| author | skrll <skrll@NetBSD.org> | 2016-04-23 10:15:27 +0000 |
|---|---|---|
| committer | skrll <skrll@NetBSD.org> | 2016-04-23 10:15:27 +0000 |
| commit | 71112a2e15f9bf53afce3c1dba49efee488f907e (patch) | |
| tree | bb8969a62e25f8d246da06e3baf5e17264941596 /sys/dev | |
| parent | ea543e244a8a4befd86336dd6e2b4dba44e6ed86 (diff) | |
Merge nick-nhusb
- API / infrastructure changes to support memory management changes.
- Memory management improvements and bug fixes.
- HCDs should now be MP safe
- conversion to KERNHIST based debug
- FS/LS isoc support on ehci(4).
- conversion to kmem(9)
- Some USB 3 support - mostly from Takahiro HAYASHI (t-hash).
- interrupt transfers now get proper DMA operations
- general bug fixes
- kern/48308
- uhub status notification improvements
- umass(4) probe fix (applied to HEAD already)
- ohci(4) short transfer fix
Diffstat (limited to 'sys/dev')
186 files changed, 17727 insertions, 15878 deletions
diff --git a/sys/dev/audio.c b/sys/dev/audio.c index de3348c47f0..9d2f9e91106 100644 --- a/sys/dev/audio.c +++ b/sys/dev/audio.c @@ -1,4 +1,4 @@ -/* $NetBSD: audio.c,v 1.266 2014/11/18 01:50:12 jmcneill Exp $ */ +/* $NetBSD: audio.c,v 1.267 2016/04/23 10:15:31 skrll Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -99,9 +99,9 @@ * LONG TERM SLEEPS MUST NOT OCCUR WITH THIS LOCK HELD. * * - sc_intr_lock, provided by the underlying driver. This may be either a - * spinlock (at IPL_SCHED or IPL_VM) or an adaptive lock (IPL_NONE), - * returned in the first parameter to hw_if->get_locks(). It is known as - * the "interrupt lock". + * spinlock (at IPL_SCHED or IPL_VM) or an adaptive lock (IPL_NONE or + * IPL_SOFT*), returned in the first parameter to hw_if->get_locks(). It + * is known as the "interrupt lock". * * It provides atomic access to the device's hardware state, and to audio * channel data that may be accessed by the hardware driver's ISR. @@ -155,7 +155,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.266 2014/11/18 01:50:12 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.267 2016/04/23 10:15:31 skrll Exp $"); #include "audio.h" #if NAUDIO > 0 diff --git a/sys/dev/cardbus/ehci_cardbus.c b/sys/dev/cardbus/ehci_cardbus.c index d3b97db6a26..667be2a8f62 100644 --- a/sys/dev/cardbus/ehci_cardbus.c +++ b/sys/dev/cardbus/ehci_cardbus.c @@ -1,4 +1,4 @@ -/* $NetBSD: ehci_cardbus.c,v 1.32 2014/09/21 15:07:19 christos Exp $ */ +/* $NetBSD: ehci_cardbus.c,v 1.33 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ehci_cardbus.c,v 1.32 2014/09/21 15:07:19 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ehci_cardbus.c,v 1.33 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -91,9 +91,9 @@ ehci_cardbus_match(device_t parent, cfdata_t match, void *aux) if (PCI_CLASS(ca->ca_class) == PCI_CLASS_SERIALBUS && PCI_SUBCLASS(ca->ca_class) == PCI_SUBCLASS_SERIALBUS_USB && PCI_INTERFACE(ca->ca_class) == PCI_INTERFACE_EHCI) - return (1); + return 1; - return (0); + return 0; } static bool @@ -128,13 +128,12 @@ ehci_cardbus_attach(device_t parent, device_t self, void *aux) cardbus_function_tag_t cf = ct->ct_cf; pcireg_t csr; char devinfo[256]; - usbd_status r; u_int ncomp; const char *devname = device_xname(self); struct usb_cardbus *up; sc->sc.sc_dev = self; - sc->sc.sc_bus.hci_private = sc; + sc->sc.sc_bus.ub_hcpriv = sc; pci_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof(devinfo)); printf(": %s (rev. 0x%02x)\n", devinfo, @@ -150,7 +149,7 @@ ehci_cardbus_attach(device_t parent, device_t self, void *aux) sc->sc_cc = cc; sc->sc_cf = cf; sc->sc_ct = ct; - sc->sc.sc_bus.dmatag = ca->ca_dmat; + sc->sc.sc_bus.ub_dmatag = ca->ca_dmat; /* Enable the device. */ csr = Cardbus_conf_read(ct, ca->ca_tag, PCI_COMMAND_STATUS_REG); @@ -190,9 +189,9 @@ ehci_cardbus_attach(device_t parent, device_t self, void *aux) } sc->sc.sc_ncomp = ncomp; - r = ehci_init(&sc->sc); - if (r != USBD_NORMAL_COMPLETION) { - printf("%s: init failed, error=%d\n", devname, r); + int err = ehci_init(&sc->sc); + if (err) { + printf("%s: init failed, error=%d\n", devname, err); /* Avoid spurious interrupts. */ Cardbus_intr_disestablish(ct, sc->sc_ih); @@ -218,7 +217,7 @@ ehci_cardbus_detach(device_t self, int flags) rv = ehci_detach(&sc->sc, flags); if (rv) - return (rv); + return rv; if (sc->sc_ih != NULL) { Cardbus_intr_disestablish(ct, sc->sc_ih); sc->sc_ih = NULL; @@ -228,7 +227,7 @@ ehci_cardbus_detach(device_t self, int flags) sc->sc.ioh, sc->sc.sc_size); sc->sc.sc_size = 0; } - return (0); + return 0; } void diff --git a/sys/dev/cardbus/ohci_cardbus.c b/sys/dev/cardbus/ohci_cardbus.c index d0dfa7e8ef1..0af54e7025e 100644 --- a/sys/dev/cardbus/ohci_cardbus.c +++ b/sys/dev/cardbus/ohci_cardbus.c @@ -1,4 +1,4 @@ -/* $NetBSD: ohci_cardbus.c,v 1.40 2014/09/21 15:07:19 christos Exp $ */ +/* $NetBSD: ohci_cardbus.c,v 1.41 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ohci_cardbus.c,v 1.40 2014/09/21 15:07:19 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ohci_cardbus.c,v 1.41 2016/04/23 10:15:31 skrll Exp $"); #include "ehci_cardbus.h" @@ -93,9 +93,9 @@ ohci_cardbus_match(device_t parent, cfdata_t match, void *aux) if (PCI_CLASS(ca->ca_class) == PCI_CLASS_SERIALBUS && PCI_SUBCLASS(ca->ca_class) == PCI_SUBCLASS_SERIALBUS_USB && PCI_INTERFACE(ca->ca_class) == PCI_INTERFACE_OHCI) - return (1); + return 1; - return (0); + return 0; } void @@ -108,11 +108,10 @@ ohci_cardbus_attach(device_t parent, device_t self, void *aux) cardbus_function_tag_t cf = ct->ct_cf; pcireg_t csr; char devinfo[256]; - usbd_status r; const char *devname = device_xname(self); sc->sc.sc_dev = self; - sc->sc.sc_bus.hci_private = sc; + sc->sc.sc_bus.ub_hcpriv = sc; pci_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof(devinfo)); printf(": %s (rev. 0x%02x)\n", devinfo, @@ -128,7 +127,7 @@ ohci_cardbus_attach(device_t parent, device_t self, void *aux) sc->sc_cc = cc; sc->sc_cf = cf; sc->sc_ct = ct; - sc->sc.sc_bus.dmatag = ca->ca_dmat; + sc->sc.sc_bus.ub_dmatag = ca->ca_dmat; /* Enable the device. */ csr = Cardbus_conf_read(ct, ca->ca_tag, @@ -152,9 +151,9 @@ ohci_cardbus_attach(device_t parent, device_t self, void *aux) pci_findvendor(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor), sc->sc.sc_id_vendor); - r = ohci_init(&sc->sc); - if (r != USBD_NORMAL_COMPLETION) { - printf("%s: init failed, error=%d\n", devname, r); + int err = ohci_init(&sc->sc); + if (err) { + printf("%s: init failed, error=%d\n", devname, err); /* Avoid spurious interrupts. */ Cardbus_intr_disestablish(ct, sc->sc_ih); @@ -184,7 +183,7 @@ ohci_cardbus_detach(device_t self, int flags) rv = ohci_detach(&sc->sc, flags); if (rv) - return (rv); + return rv; if (sc->sc_ih != NULL) { Cardbus_intr_disestablish(ct, sc->sc_ih); sc->sc_ih = NULL; @@ -197,5 +196,5 @@ ohci_cardbus_detach(device_t self, int flags) #if NEHCI_CARDBUS > 0 usb_cardbus_rem(&sc->sc_cardbus); #endif - return (0); + return 0; } diff --git a/sys/dev/cardbus/uhci_cardbus.c b/sys/dev/cardbus/uhci_cardbus.c index 79a01193f50..cf87b33f031 100644 --- a/sys/dev/cardbus/uhci_cardbus.c +++ b/sys/dev/cardbus/uhci_cardbus.c @@ -1,4 +1,4 @@ -/* $NetBSD: uhci_cardbus.c,v 1.21 2014/09/21 15:07:19 christos Exp $ */ +/* $NetBSD: uhci_cardbus.c,v 1.22 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 1998-2005 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uhci_cardbus.c,v 1.21 2014/09/21 15:07:19 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uhci_cardbus.c,v 1.22 2016/04/23 10:15:31 skrll Exp $"); #include "ehci_cardbus.h" @@ -82,9 +82,9 @@ uhci_cardbus_match(device_t parent, cfdata_t match, void *aux) if (PCI_CLASS(ca->ca_class) == PCI_CLASS_SERIALBUS && PCI_SUBCLASS(ca->ca_class) == PCI_SUBCLASS_SERIALBUS_USB && PCI_INTERFACE(ca->ca_class) == PCI_INTERFACE_UHCI) - return (1); + return 1; - return (0); + return 0; } static void @@ -100,10 +100,9 @@ uhci_cardbus_attach(device_t parent, device_t self, pcireg_t csr; const char *devname = device_xname(self); char devinfo[256]; - usbd_status r; sc->sc.sc_dev = self; - sc->sc.sc_bus.hci_private = sc; + sc->sc.sc_bus.ub_hcpriv = sc; pci_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof(devinfo)); printf(": %s (rev. 0x%02x)\n", devinfo, PCI_REVISION(ca->ca_class)); @@ -119,7 +118,7 @@ uhci_cardbus_attach(device_t parent, device_t self, sc->sc_cf = cf; sc->sc_ct = ct; sc->sc_tag = tag; - sc->sc.sc_bus.dmatag = ca->ca_dmat; + sc->sc.sc_bus.ub_dmatag = ca->ca_dmat; /* Enable the device. */ csr = Cardbus_conf_read(ct, tag, PCI_COMMAND_STATUS_REG); @@ -141,16 +140,16 @@ uhci_cardbus_attach(device_t parent, device_t self, switch(Cardbus_conf_read(ct, tag, PCI_USBREV) & PCI_USBREV_MASK) { case PCI_USBREV_PRE_1_0: - sc->sc.sc_bus.usbrev = USBREV_PRE_1_0; + sc->sc.sc_bus.ub_revision = USBREV_PRE_1_0; break; case PCI_USBREV_1_0: - sc->sc.sc_bus.usbrev = USBREV_1_0; + sc->sc.sc_bus.ub_revision = USBREV_1_0; break; case PCI_USBREV_1_1: - sc->sc.sc_bus.usbrev = USBREV_1_1; + sc->sc.sc_bus.ub_revision = USBREV_1_1; break; default: - sc->sc.sc_bus.usbrev = USBREV_UNKNOWN; + sc->sc.sc_bus.ub_revision = USBREV_UNKNOWN; break; } @@ -159,9 +158,9 @@ uhci_cardbus_attach(device_t parent, device_t self, pci_findvendor(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor), sc->sc.sc_id_vendor); - r = uhci_init(&sc->sc); - if (r != USBD_NORMAL_COMPLETION) { - printf("%s: init failed, error=%d\n", devname, r); + int err = uhci_init(&sc->sc); + if (err) { + printf("%s: init failed, error=%d\n", devname, err); /* Avoid spurious interrupts. */ Cardbus_intr_disestablish(ct, sc->sc_ih); @@ -187,7 +186,7 @@ uhci_cardbus_detach(device_t self, int flags) rv = uhci_detach(&sc->sc, flags); if (rv) - return (rv); + return rv; if (sc->sc_ih != NULL) { Cardbus_intr_disestablish(ct, sc->sc_ih); sc->sc_ih = NULL; @@ -200,5 +199,5 @@ uhci_cardbus_detach(device_t self, int flags) #if NEHCI_CARDBUS > 0 usb_cardbus_rem(&sc->sc_cardbus); #endif - return (0); + return 0; } diff --git a/sys/dev/ic/sl811hs.c b/sys/dev/ic/sl811hs.c index 12f2de58129..2074eeb5025 100644 --- a/sys/dev/ic/sl811hs.c +++ b/sys/dev/ic/sl811hs.c @@ -1,4 +1,4 @@ -/* $NetBSD: sl811hs.c,v 1.47 2013/10/17 21:24:24 christos Exp $ */ +/* $NetBSD: sl811hs.c,v 1.48 2016/04/23 10:15:31 skrll Exp $ */ /* * Not (c) 2007 Matthew Orgass @@ -64,11 +64,11 @@ * could keep track of known values of all buffer space? * combined print/log function for errors * - * use_polling support is untested and may not work + * ub_usepolling support is untested and may not work */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.47 2013/10/17 21:24:24 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.48 2016/04/23 10:15:31 skrll Exp $"); #include "opt_slhci.h" @@ -78,7 +78,7 @@ __KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.47 2013/10/17 21:24:24 christos Exp $" #include <sys/kernel.h> #include <sys/proc.h> #include <sys/device.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/queue.h> #include <sys/gcq.h> #include <sys/intr.h> @@ -90,7 +90,7 @@ __KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.47 2013/10/17 21:24:24 christos Exp $" #include <dev/usb/usbdivar.h> #include <dev/usb/usb_mem.h> #include <dev/usb/usbdevs.h> -#include <dev/usb/usbroothub_subr.h> +#include <dev/usb/usbroothub.h> #include <dev/ic/sl811hsreg.h> #include <dev/ic/sl811hsvar.h> @@ -252,9 +252,6 @@ static const struct timeval overflow_warn_rate = SLHCI_OVERFLOW_WARNING_RATE; #endif const int slhci_wait_time = SLHCI_WAIT_TIME; -/* Root hub intr endpoint */ -#define ROOT_INTR_ENDPT 1 - #ifndef SLHCI_MAX_RETRIES #define SLHCI_MAX_RETRIES 3 #endif @@ -295,18 +292,24 @@ struct slhci_pipe { uint8_t ptype; /* Pipe type */ }; +#define SLHCI_BUS2SC(bus) ((bus)->ub_hcpriv) +#define SLHCI_PIPE2SC(pipe) SLHCI_BUS2SC((pipe)->up_dev->ud_bus) +#define SLHCI_XFER2SC(xfer) SLHCI_BUS2SC((xfer)->ux_bus) + +#define SLHCI_PIPE2SPIPE(pipe) ((struct slhci_pipe *)(pipe)) + #ifdef SLHCI_PROFILE_TRANSFER #if defined(__mips__) /* * MIPS cycle counter does not directly count cpu cycles but is a different * fraction of cpu cycles depending on the cpu. */ -typedef u_int32_t cc_type; +typedef uint32_t cc_type; #define CC_TYPE_FMT "%u" #define slhci_cc_set(x) __asm volatile ("mfc0 %[cc], $9\n\tnop\n\tnop\n\tnop" \ : [cc] "=r"(x)) #elif defined(__i386__) -typedef u_int64_t cc_type; +typedef uint64_t cc_type; #define CC_TYPE_FMT "%llu" #define slhci_cc_set(x) __asm volatile ("rdtsc" : "=A"(x)) #else @@ -423,9 +426,7 @@ slhci_dump_cc_times(int n) { typedef usbd_status (*LockCallFunc)(struct slhci_softc *, struct slhci_pipe *, struct usbd_xfer *); -usbd_status slhci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t); -void slhci_freem(struct usbd_bus *, usb_dma_t *); -struct usbd_xfer * slhci_allocx(struct usbd_bus *); +struct usbd_xfer * slhci_allocx(struct usbd_bus *, unsigned int); void slhci_freex(struct usbd_bus *, struct usbd_xfer *); static void slhci_get_lock(struct usbd_bus *, kmutex_t **); @@ -434,6 +435,9 @@ usbd_status slhci_start(struct usbd_xfer *); usbd_status slhci_root_start(struct usbd_xfer *); usbd_status slhci_open(struct usbd_pipe *); +static int slhci_roothub_ctrl(struct usbd_bus *, usb_device_request_t *, + void *, int); + /* * slhci_supported_rev, slhci_preinit, slhci_attach, slhci_detach, * slhci_activate @@ -680,33 +684,31 @@ DDOLOGBUF(uint8_t *buf, unsigned int length) #endif const struct usbd_bus_methods slhci_bus_methods = { - .open_pipe = slhci_open, - .soft_intr = slhci_void, - .do_poll = slhci_poll, - .allocm = slhci_allocm, - .freem = slhci_freem, - .allocx = slhci_allocx, - .freex = slhci_freex, - .get_lock = slhci_get_lock, - NULL, /* new_device */ + .ubm_open = slhci_open, + .ubm_softint= slhci_void, + .ubm_dopoll = slhci_poll, + .ubm_allocx = slhci_allocx, + .ubm_freex = slhci_freex, + .ubm_getlock = slhci_get_lock, + .ubm_rhctrl = slhci_roothub_ctrl, }; const struct usbd_pipe_methods slhci_pipe_methods = { - .transfer = slhci_transfer, - .start = slhci_start, - .abort = slhci_abort, - .close = slhci_close, - .cleartoggle = slhci_clear_toggle, - .done = slhci_done, + .upm_transfer = slhci_transfer, + .upm_start = slhci_start, + .upm_abort = slhci_abort, + .upm_close = slhci_close, + .upm_cleartoggle = slhci_clear_toggle, + .upm_done = slhci_done, }; const struct usbd_pipe_methods slhci_root_methods = { - .transfer = slhci_transfer, - .start = slhci_root_start, - .abort = slhci_abort, - .close = (void (*)(struct usbd_pipe *))slhci_void, /* XXX safe? */ - .cleartoggle = slhci_clear_toggle, - .done = slhci_done, + .upm_transfer = slhci_transfer, + .upm_start = slhci_root_start, + .upm_abort = slhci_abort, + .upm_close = (void (*)(struct usbd_pipe *))slhci_void, /* XXX safe? */ + .upm_cleartoggle = slhci_clear_toggle, + .upm_done = slhci_done, }; /* Queue inlines */ @@ -761,61 +763,12 @@ enter_all_pipes(struct slhci_transfers *t, struct slhci_pipe *spipe) /* Start out of lock functions. */ -struct slhci_mem { - usb_dma_block_t block; - uint8_t data[]; -}; - -/* - * The SL811HS does not do DMA as a host controller, but NetBSD's USB interface - * assumes DMA is used. So we fake the DMA block. - */ -usbd_status -slhci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size) -{ - struct slhci_mem *mem; - - mem = malloc(sizeof(struct slhci_mem) + size, M_USB, M_NOWAIT|M_ZERO); - - DLOG(D_MEM, "allocm %p", mem, 0,0,0); - - if (mem == NULL) - return USBD_NOMEM; - - dma->block = &mem->block; - dma->block->kaddr = mem->data; - - /* dma->offs = 0; */ - dma->block->nsegs = 1; - dma->block->size = size; - dma->block->align = size; - dma->block->flags |= USB_DMA_FULLBLOCK; - -#ifdef SLHCI_MEM_ACCOUNTING - slhci_mem_use(bus, 1); -#endif - - return USBD_NORMAL_COMPLETION; -} - -void -slhci_freem(struct usbd_bus *bus, usb_dma_t *dma) -{ - DLOG(D_MEM, "freem %p", dma->block, 0,0,0); - -#ifdef SLHCI_MEM_ACCOUNTING - slhci_mem_use(bus, -1); -#endif - - free(dma->block, M_USB); -} - struct usbd_xfer * -slhci_allocx(struct usbd_bus *bus) +slhci_allocx(struct usbd_bus *bus, unsigned int nframes) { struct usbd_xfer *xfer; - xfer = malloc(sizeof(*xfer), M_USB, M_NOWAIT|M_ZERO); + xfer = kmem_zalloc(sizeof(*xfer), KM_SLEEP); DLOG(D_MEM, "allocx %p", xfer, 0,0,0); @@ -824,7 +777,7 @@ slhci_allocx(struct usbd_bus *bus) #endif #ifdef DIAGNOSTIC if (xfer != NULL) - xfer->busy_free = XFER_BUSY; + xfer->ux_state = XFER_BUSY; #endif return xfer; } @@ -832,31 +785,31 @@ slhci_allocx(struct usbd_bus *bus) void slhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) { - DLOG(D_MEM, "freex xfer %p spipe %p", xfer, xfer->pipe,0,0); + DLOG(D_MEM, "freex xfer %p spipe %p", xfer, xfer->ux_pipe,0,0); #ifdef SLHCI_MEM_ACCOUNTING slhci_mem_use(bus, -1); #endif #ifdef DIAGNOSTIC - if (xfer->busy_free != XFER_BUSY) { - struct slhci_softc *sc = bus->hci_private; + if (xfer->ux_state != XFER_BUSY) { + struct slhci_softc *sc = SLHCI_BUS2SC(bus); printf("%s: slhci_freex: xfer=%p not busy, %#08x halted\n", - SC_NAME(sc), xfer, xfer->busy_free); + SC_NAME(sc), xfer, xfer->ux_state); DDOLOG("%s: slhci_freex: xfer=%p not busy, %#08x halted\n", - SC_NAME(sc), xfer, xfer->busy_free, 0); + SC_NAME(sc), xfer, xfer->ux_state, 0); slhci_lock_call(sc, &slhci_halt, NULL, NULL); return; } - xfer->busy_free = XFER_FREE; + xfer->ux_state = XFER_FREE; #endif - free(xfer, M_USB); + kmem_free(xfer, sizeof(*xfer)); } static void slhci_get_lock(struct usbd_bus *bus, kmutex_t **lock) { - struct slhci_softc *sc = bus->hci_private; + struct slhci_softc *sc = SLHCI_BUS2SC(bus); *lock = &sc->sc_lock; } @@ -864,11 +817,11 @@ slhci_get_lock(struct usbd_bus *bus, kmutex_t **lock) usbd_status slhci_transfer(struct usbd_xfer *xfer) { - struct slhci_softc *sc = xfer->pipe->device->bus->hci_private; + struct slhci_softc *sc = SLHCI_XFER2SC(xfer); usbd_status error; DLOG(D_TRACE, "%s transfer xfer %p spipe %p ", - pnames(SLHCI_XFER_TYPE(xfer)), xfer, xfer->pipe,0); + pnames(SLHCI_XFER_TYPE(xfer)), xfer, xfer->ux_pipe,0); /* Insert last in queue */ mutex_enter(&sc->sc_lock); @@ -889,7 +842,7 @@ slhci_transfer(struct usbd_xfer *xfer) /* * Start will take the lock. */ - error = xfer->pipe->methods->start(SIMPLEQ_FIRST(&xfer->pipe->queue)); + error = xfer->ux_pipe->up_methods->upm_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); return error; } @@ -898,11 +851,11 @@ slhci_transfer(struct usbd_xfer *xfer) usbd_status slhci_start(struct usbd_xfer *xfer) { - struct slhci_softc *sc = xfer->pipe->device->bus->hci_private; - struct usbd_pipe *pipe = xfer->pipe; - struct slhci_pipe *spipe = (struct slhci_pipe *)pipe; + struct slhci_softc *sc = SLHCI_XFER2SC(xfer); + struct usbd_pipe *pipe = xfer->ux_pipe; + struct slhci_pipe *spipe = SLHCI_PIPE2SPIPE(pipe); struct slhci_transfers *t = &sc->sc_transfers; -; usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc; + usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc; unsigned int max_packet; mutex_enter(&sc->sc_lock); @@ -910,44 +863,44 @@ slhci_start(struct usbd_xfer *xfer) max_packet = UGETW(ed->wMaxPacketSize); DLOG(D_TRACE, "%s start xfer %p spipe %p length %d", - pnames(spipe->ptype), xfer, spipe, xfer->length); + pnames(spipe->ptype), xfer, spipe, xfer->ux_length); /* root transfers use slhci_root_start */ KASSERT(spipe->xfer == NULL); /* not SLASSERT */ - xfer->actlen = 0; - xfer->status = USBD_IN_PROGRESS; + xfer->ux_actlen = 0; + xfer->ux_status = USBD_IN_PROGRESS; spipe->xfer = xfer; spipe->nerrs = 0; spipe->frame = t->frame; spipe->control = SL11_EPCTRL_ARM_ENABLE; - spipe->tregs[DEV] = pipe->device->address; + spipe->tregs[DEV] = pipe->up_dev->ud_addr; spipe->tregs[PID] = spipe->newpid = UE_GET_ADDR(ed->bEndpointAddress) | (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN ? SL11_PID_IN : SL11_PID_OUT); - spipe->newlen[0] = xfer->length % max_packet; - spipe->newlen[1] = min(xfer->length, max_packet); + spipe->newlen[0] = xfer->ux_length % max_packet; + spipe->newlen[1] = min(xfer->ux_length, max_packet); if (spipe->ptype == PT_BULK || spipe->ptype == PT_INTR) { if (spipe->pflags & PF_TOGGLE) spipe->control |= SL11_EPCTRL_DATATOGGLE; spipe->tregs[LEN] = spipe->newlen[1]; if (spipe->tregs[LEN]) - spipe->buffer = KERNADDR(&xfer->dmabuf, 0); + spipe->buffer = xfer->ux_buf; else spipe->buffer = NULL; spipe->lastframe = t->frame; #if defined(DEBUG) || defined(SLHCI_DEBUG) if (__predict_false(spipe->ptype == PT_INTR && - xfer->length > spipe->tregs[LEN])) { + xfer->ux_length > spipe->tregs[LEN])) { printf("%s: Long INTR transfer not supported!\n", SC_NAME(sc)); DDOLOG("%s: Long INTR transfer not supported!\n", SC_NAME(sc), 0,0,0); - xfer->status = USBD_INVAL; + xfer->ux_status = USBD_INVAL; } #endif } else { @@ -957,18 +910,18 @@ slhci_start(struct usbd_xfer *xfer) /* SETUP contains IN/OUT bits also */ spipe->tregs[PID] |= SL11_PID_SETUP; spipe->tregs[LEN] = 8; - spipe->buffer = (uint8_t *)&xfer->request; + spipe->buffer = (uint8_t *)&xfer->ux_request; DLOGBUF(D_XFER, spipe->buffer, spipe->tregs[LEN]); spipe->ptype = PT_CTRL_SETUP; spipe->newpid &= ~SL11_PID_BITS; - if (xfer->length == 0 || (xfer->request.bmRequestType & + if (xfer->ux_length == 0 || (xfer->ux_request.bmRequestType & UT_READ)) spipe->newpid |= SL11_PID_IN; else spipe->newpid |= SL11_PID_OUT; } - if (xfer->flags & USBD_FORCE_SHORT_XFER && spipe->tregs[LEN] == + if (xfer->ux_flags & USBD_FORCE_SHORT_XFER && spipe->tregs[LEN] == max_packet && (spipe->newpid & SL11_PID_BITS) == SL11_PID_OUT) spipe->wantshort = 1; else @@ -984,7 +937,7 @@ slhci_start(struct usbd_xfer *xfer) */ if (spipe->pflags & PF_LS) { /* - * Setting PREAMBLE for directly connnected LS devices will + * Setting PREAMBLE for directly connected LS devices will * lock up the chip. */ if (spipe->pflags & PF_PREAMBLE) @@ -997,9 +950,9 @@ slhci_start(struct usbd_xfer *xfer) spipe->newbustime[1] = SLHCI_LS_CONST + SLHCI_LS_DATA_TIME(spipe->newlen[1]); } else - xfer->status = USBD_INVAL; + xfer->ux_status = USBD_INVAL; } else { - UL_SLASSERT(pipe->device->speed == USB_SPEED_FULL, sc, + UL_SLASSERT(pipe->up_dev->ud_speed == USB_SPEED_FULL, sc, spipe, xfer, return USBD_IN_PROGRESS); if (max_packet <= SL11_MAX_PACKET_SIZE) { spipe->bustime = SLHCI_FS_CONST + @@ -1009,7 +962,7 @@ slhci_start(struct usbd_xfer *xfer) spipe->newbustime[1] = SLHCI_FS_CONST + SLHCI_FS_DATA_TIME(spipe->newlen[1]); } else - xfer->status = USBD_INVAL; + xfer->ux_status = USBD_INVAL; } /* @@ -1033,8 +986,8 @@ slhci_root_start(struct usbd_xfer *xfer) struct slhci_softc *sc; struct slhci_pipe *spipe; - spipe = (struct slhci_pipe *)xfer->pipe; - sc = xfer->pipe->device->bus->hci_private; + spipe = SLHCI_PIPE2SPIPE(xfer->ux_pipe); + sc = SLHCI_XFER2SC(xfer); return slhci_lock_call(sc, &slhci_root, spipe, xfer); } @@ -1046,17 +999,17 @@ slhci_open(struct usbd_pipe *pipe) struct slhci_softc *sc; struct slhci_pipe *spipe; usb_endpoint_descriptor_t *ed; - struct slhci_transfers *t; unsigned int max_packet, pmaxpkt; + uint8_t rhaddr; - dev = pipe->device; - sc = dev->bus->hci_private; - spipe = (struct slhci_pipe *)pipe; - ed = pipe->endpoint->edesc; - t = &sc->sc_transfers; + dev = pipe->up_dev; + sc = SLHCI_PIPE2SC(pipe); + spipe = SLHCI_PIPE2SPIPE(pipe); + ed = pipe->up_endpoint->ue_edesc; + rhaddr = dev->ud_bus->ub_rhaddr; DLOG(D_TRACE, "slhci_open(addr=%d,ep=%d,rootaddr=%d)", - dev->address, ed->bEndpointAddress, t->rootaddr, 0); + dev->ud_addr, ed->bEndpointAddress, rhaddr, 0); spipe->pflags = 0; spipe->frame = 0; @@ -1076,9 +1029,9 @@ slhci_open(struct usbd_pipe *pipe) max_packet = UGETW(ed->wMaxPacketSize); - if (dev->speed == USB_SPEED_LOW) { + if (dev->ud_speed == USB_SPEED_LOW) { spipe->pflags |= PF_LS; - if (dev->myhub->address != t->rootaddr) { + if (dev->ud_myhub->ud_addr != rhaddr) { spipe->pflags |= PF_PREAMBLE; if (!slhci_try_lsvh) return slhci_lock_call(sc, &slhci_lsvh_warn, @@ -1094,15 +1047,17 @@ slhci_open(struct usbd_pipe *pipe) return USBD_INVAL; } - if (dev->address == t->rootaddr) { + if (dev->ud_addr == rhaddr) { switch (ed->bEndpointAddress) { case USB_CONTROL_ENDPOINT: spipe->ptype = PT_ROOT_CTRL; - pipe->interval = 0; + pipe->up_interval = 0; + pipe->up_methods = &roothub_ctrl_methods; break; - case UE_DIR_IN | ROOT_INTR_ENDPT: + case UE_DIR_IN | USBROOTHUB_INTR_ENDPT: spipe->ptype = PT_ROOT_INTR; - pipe->interval = 1; + pipe->up_interval = 1; + pipe->up_methods = &slhci_root_methods; break; default: printf("%s: Invalid root endpoint!\n", SC_NAME(sc)); @@ -1110,32 +1065,31 @@ slhci_open(struct usbd_pipe *pipe) 0,0,0); return USBD_INVAL; } - pipe->methods = __UNCONST(&slhci_root_methods); return USBD_NORMAL_COMPLETION; } else { switch (ed->bmAttributes & UE_XFERTYPE) { case UE_CONTROL: spipe->ptype = PT_CTRL_SETUP; - pipe->interval = 0; + pipe->up_interval = 0; break; case UE_INTERRUPT: spipe->ptype = PT_INTR; - if (pipe->interval == USBD_DEFAULT_INTERVAL) - pipe->interval = ed->bInterval; + if (pipe->up_interval == USBD_DEFAULT_INTERVAL) + pipe->up_interval = ed->bInterval; break; case UE_ISOCHRONOUS: return slhci_lock_call(sc, &slhci_isoc_warn, spipe, NULL); case UE_BULK: spipe->ptype = PT_BULK; - pipe->interval = 0; + pipe->up_interval = 0; break; } DLOG(D_MSG, "open pipe %s interval %d", pnames(spipe->ptype), - pipe->interval, 0,0); + pipe->up_interval, 0,0); - pipe->methods = __UNCONST(&slhci_pipe_methods); + pipe->up_methods = __UNCONST(&slhci_pipe_methods); return slhci_lock_call(sc, &slhci_open_pipe, spipe, NULL); } @@ -1144,7 +1098,7 @@ slhci_open(struct usbd_pipe *pipe) int slhci_supported_rev(uint8_t rev) { - return (rev >= SLTYPE_SL811HS_R12 && rev <= SLTYPE_SL811HS_R15); + return rev >= SLTYPE_SL811HS_R12 && rev <= SLTYPE_SL811HS_R15; } /* @@ -1217,7 +1171,7 @@ slhci_attach(struct slhci_softc *sc) /* * It is not safe to call the soft interrupt directly as - * usb_schedsoftintr does in the use_polling case (due to locking). + * usb_schedsoftintr does in the ub_usepolling case (due to locking). */ sc->sc_cb_softintr = softint_establish(SOFTINT_NET, slhci_callback_entry, sc); @@ -1260,9 +1214,10 @@ slhci_attach(struct slhci_softc *sc) #endif "\n", SC_NAME(sc)); #endif - sc->sc_bus.usbrev = USBREV_1_1; - sc->sc_bus.methods = __UNCONST(&slhci_bus_methods); - sc->sc_bus.pipe_size = sizeof(struct slhci_pipe); + sc->sc_bus.ub_revision = USBREV_1_1; + sc->sc_bus.ub_methods = __UNCONST(&slhci_bus_methods); + sc->sc_bus.ub_pipesize = sizeof(struct slhci_pipe); + sc->sc_bus.ub_usedma = false; if (!sc->sc_enable_power) t->flags |= F_REALPOWER; @@ -1340,12 +1295,12 @@ slhci_abort(struct usbd_xfer *xfer) struct slhci_softc *sc; struct slhci_pipe *spipe; - spipe = (struct slhci_pipe *)xfer->pipe; + spipe = SLHCI_PIPE2SPIPE(xfer->ux_pipe); if (spipe == NULL) goto callback; - sc = spipe->pipe.device->bus->hci_private; + sc = SLHCI_XFER2SC(xfer); KASSERT(mutex_owned(&sc->sc_lock)); @@ -1355,7 +1310,7 @@ slhci_abort(struct usbd_xfer *xfer) slhci_lock_call(sc, &slhci_do_abort, spipe, xfer); callback: - xfer->status = USBD_CANCELLED; + xfer->ux_status = USBD_CANCELLED; /* Abort happens at IPL_USB. */ usb_transfer_complete(xfer); } @@ -1366,8 +1321,8 @@ slhci_close(struct usbd_pipe *pipe) struct slhci_softc *sc; struct slhci_pipe *spipe; - sc = pipe->device->bus->hci_private; - spipe = (struct slhci_pipe *)pipe; + sc = SLHCI_PIPE2SC(pipe); + spipe = SLHCI_PIPE2SPIPE(pipe); DLOG(D_TRACE, "%s close spipe %p spipe->xfer %p", pnames(spipe->ptype), spipe, spipe->xfer, 0); @@ -1380,7 +1335,7 @@ slhci_clear_toggle(struct usbd_pipe *pipe) { struct slhci_pipe *spipe; - spipe = (struct slhci_pipe *)pipe; + spipe = SLHCI_PIPE2SPIPE(pipe); DLOG(D_TRACE, "%s toggle spipe %p", pnames(spipe->ptype), spipe,0,0); @@ -1390,7 +1345,7 @@ slhci_clear_toggle(struct usbd_pipe *pipe) #ifdef DIAGNOSTIC if (spipe->xfer != NULL) { struct slhci_softc *sc = (struct slhci_softc - *)pipe->device->bus; + *)pipe->up_dev->ud_bus; printf("%s: Clear toggle on transfer in progress! halted\n", SC_NAME(sc)); @@ -1406,7 +1361,7 @@ slhci_poll(struct usbd_bus *bus) /* XXX necessary? */ { struct slhci_softc *sc; - sc = bus->hci_private; + sc = SLHCI_BUS2SC(bus); DLOG(D_TRACE, "slhci_poll", 0,0,0,0); @@ -1428,7 +1383,7 @@ slhci_void(void *v) {} void slhci_mem_use(struct usbd_bus *bus, int val) { - struct slhci_softc *sc = bus->hci_private; + struct slhci_softc *sc = SLHCI_BUS2SC(bus); int s; mutex_enter(&sc->sc_intr_lock); @@ -1524,14 +1479,14 @@ slhci_do_callback(struct slhci_softc *sc, struct usbd_xfer *xfer) mutex_exit(&sc->sc_intr_lock); mutex_enter(&sc->sc_lock); - repeat = xfer->pipe->repeat; + repeat = xfer->ux_pipe->up_repeat; usb_transfer_complete(xfer); mutex_exit(&sc->sc_lock); mutex_enter(&sc->sc_intr_lock); stop_cc_time(&t_callback); - if (repeat && !sc->sc_bus.use_polling) + if (repeat && !sc->sc_bus.ub_usepolling) slhci_do_repeat(sc, xfer); } @@ -1566,7 +1521,7 @@ waitcheck: slhci_waitintr(sc, slhci_wait_time); /* - * The direct call is needed in the use_polling and disabled cases + * The direct call is needed in the ub_usepolling and disabled cases * since the soft interrupt is not available. In the disabled case, * this code can be reached from the usb detach, after the reaping of * the soft interrupt. That test could be !F_ACTIVE, but there is no @@ -1574,7 +1529,7 @@ waitcheck: * cases. */ if ((t->flags & F_ROOTINTR) || !gcq_empty(&t->q[Q_CALLBACKS])) { - if (__predict_false(sc->sc_bus.use_polling || + if (__predict_false(sc->sc_bus.ub_usepolling || t->flags & F_DISABLED)) slhci_callback(sc); else @@ -1746,7 +1701,7 @@ slhci_waitintr(struct slhci_softc *sc, int wait_time) KASSERT(mutex_owned(&sc->sc_intr_lock)); - if (__predict_false(sc->sc_bus.use_polling)) + if (__predict_false(sc->sc_bus.ub_usepolling)) wait_time = 12000; while (t->pend <= wait_time) { @@ -1854,7 +1809,7 @@ slhci_dointr(struct slhci_softc *sc) while (__predict_true(GOT_FIRST_TO(tosp, t)) && __predict_false(tosp->to_frame <= t->frame)) { - tosp->xfer->status = USBD_TIMEOUT; + tosp->xfer->ux_status = USBD_TIMEOUT; slhci_do_abort(sc, tosp, tosp->xfer); enter_callback(t, tosp); } @@ -2040,12 +1995,12 @@ slhci_abdone(struct slhci_softc *sc, int ab) DLOG(D_XFER, "cont %d len %d", cont, spipe->tregs[LEN], 0,0); if (__predict_false(cont > spipe->tregs[LEN])) { - DDOLOG("cont > len! cont %d len %d xfer->length %d " - "spipe %p", cont, spipe->tregs[LEN], xfer->length, + DDOLOG("cont > len! cont %d len %d xfer->ux_length %d " + "spipe %p", cont, spipe->tregs[LEN], xfer->ux_length, spipe); - printf("%s: cont > len! cont %d len %d xfer->length " + printf("%s: cont > len! cont %d len %d xfer->ux_length " "%d", SC_NAME(sc), cont, spipe->tregs[LEN], - xfer->length); + xfer->ux_length); slhci_halt(sc, spipe, xfer); return; } else { @@ -2072,20 +2027,20 @@ slhci_abdone(struct slhci_softc *sc, int ab) "halted\n", SC_NAME(sc), 0,0,0); slhci_halt(sc, spipe, xfer); return; - } else if (__predict_false(sc->sc_bus.use_polling)) { + } else if (__predict_false(sc->sc_bus.ub_usepolling)) { if (status == SL11_EPSTAT_STALL) - xfer->status = USBD_STALLED; + xfer->ux_status = USBD_STALLED; else if (status == SL11_EPSTAT_TIMEOUT) - xfer->status = USBD_TIMEOUT; + xfer->ux_status = USBD_TIMEOUT; else if (status == SL11_EPSTAT_NAK) - xfer->status = USBD_TIMEOUT; /*XXX*/ + xfer->ux_status = USBD_TIMEOUT; /*XXX*/ else - xfer->status = USBD_IOERROR; + xfer->ux_status = USBD_IOERROR; head = Q_CALLBACKS; } else if (status == SL11_EPSTAT_NAK) { - if (spipe->pipe.interval) { + if (spipe->pipe.up_interval) { spipe->lastframe = spipe->frame = - t->frame + spipe->pipe.interval; + t->frame + spipe->pipe.up_interval; slhci_queue_timed(sc, spipe); goto queued; } @@ -2093,14 +2048,14 @@ slhci_abdone(struct slhci_softc *sc, int ab) } else if (++spipe->nerrs > SLHCI_MAX_RETRIES || status == SL11_EPSTAT_STALL) { if (status == SL11_EPSTAT_STALL) - xfer->status = USBD_STALLED; + xfer->ux_status = USBD_STALLED; else if (status == SL11_EPSTAT_TIMEOUT) - xfer->status = USBD_TIMEOUT; + xfer->ux_status = USBD_TIMEOUT; else - xfer->status = USBD_IOERROR; + xfer->ux_status = USBD_IOERROR; DLOG(D_ERR, "Max retries reached! status %#x " - "xfer->status %#x", status, xfer->status, 0,0); + "xfer->ux_status %#x", status, xfer->ux_status, 0,0); DLOGFLAG8(D_ERR, "STATUS=", status, "STALL", "NAK", "Overflow", "Setup", "Data Toggle", "Timeout", "Error", "ACK"); @@ -2122,12 +2077,12 @@ slhci_abdone(struct slhci_softc *sc, int ab) } else if (spipe->ptype == PT_CTRL_SETUP) { spipe->tregs[PID] = spipe->newpid; - if (xfer->length) { + if (xfer->ux_length) { LK_SLASSERT(spipe->newlen[1] != 0, sc, spipe, xfer, return); spipe->tregs[LEN] = spipe->newlen[1]; spipe->bustime = spipe->newbustime[1]; - spipe->buffer = KERNADDR(&xfer->dmabuf, 0); + spipe->buffer = xfer->ux_buf; spipe->ptype = PT_CTRL_DATA; } else { status_setup: @@ -2152,20 +2107,20 @@ status_setup: } else if (spipe->ptype == PT_CTRL_STATUS) { head = Q_CALLBACKS; } else { /* bulk, intr, control data */ - xfer->actlen += actlen; + xfer->ux_actlen += actlen; spipe->control ^= SL11_EPCTRL_DATATOGGLE; - if (actlen == spipe->tregs[LEN] && (xfer->length > - xfer->actlen || spipe->wantshort)) { + if (actlen == spipe->tregs[LEN] && (xfer->ux_length > + xfer->ux_actlen || spipe->wantshort)) { spipe->buffer += actlen; - LK_SLASSERT(xfer->length >= xfer->actlen, sc, + LK_SLASSERT(xfer->ux_length >= xfer->ux_actlen, sc, spipe, xfer, return); - if (xfer->length - xfer->actlen < actlen) { + if (xfer->ux_length - xfer->ux_actlen < actlen) { spipe->wantshort = 0; spipe->tregs[LEN] = spipe->newlen[0]; spipe->bustime = spipe->newbustime[0]; - LK_SLASSERT(xfer->actlen + - spipe->tregs[LEN] == xfer->length, sc, + LK_SLASSERT(xfer->ux_actlen + + spipe->tregs[LEN] == xfer->ux_length, sc, spipe, xfer, return); } head = Q_CB; @@ -2175,14 +2130,14 @@ status_setup: } else { if (spipe->ptype == PT_INTR) { spipe->lastframe += - spipe->pipe.interval; + spipe->pipe.up_interval; /* * If ack, we try to keep the * interrupt rate by using lastframe * instead of the current frame. */ spipe->frame = spipe->lastframe + - spipe->pipe.interval; + spipe->pipe.up_interval; } /* @@ -2203,16 +2158,16 @@ status_setup: if (head == Q_CALLBACKS) { gcq_remove(&spipe->to); - if (xfer->status == USBD_IN_PROGRESS) { - LK_SLASSERT(xfer->actlen <= xfer->length, sc, + if (xfer->ux_status == USBD_IN_PROGRESS) { + LK_SLASSERT(xfer->ux_actlen <= xfer->ux_length, sc, spipe, xfer, return); - xfer->status = USBD_NORMAL_COMPLETION; + xfer->ux_status = USBD_NORMAL_COMPLETION; #if 0 /* usb_transfer_complete will do this */ - if (xfer->length == xfer->actlen || xfer->flags & + if (xfer->ux_length == xfer->ux_actlen || xfer->ux_flags & USBD_SHORT_XFER_OK) - xfer->status = USBD_NORMAL_COMPLETION; + xfer->ux_status = USBD_NORMAL_COMPLETION; else - xfer->status = USBD_SHORT_XFER; + xfer->ux_status = USBD_SHORT_XFER; #endif } } @@ -2392,10 +2347,10 @@ slhci_callback(struct slhci_softc *sc) if (t->rootintr != NULL) { u_char *p; - p = KERNADDR(&t->rootintr->dmabuf, 0); + p = t->rootintr->ux_buf; p[0] = 2; - t->rootintr->actlen = 1; - t->rootintr->status = USBD_NORMAL_COMPLETION; + t->rootintr->ux_actlen = 1; + t->rootintr->ux_status = USBD_NORMAL_COMPLETION; xfer = t->rootintr; goto do_callback; } @@ -2409,7 +2364,7 @@ slhci_callback(struct slhci_softc *sc) LK_SLASSERT(xfer != NULL, sc, spipe, NULL, return); spipe->xfer = NULL; DLOG(D_XFER, "xfer callback length %d actlen %d spipe %x " - "type %s", xfer->length, xfer->actlen, spipe, + "type %s", xfer->ux_length, xfer->ux_actlen, spipe, pnames(spipe->ptype)); do_callback: slhci_do_callback(sc, xfer); @@ -2428,15 +2383,15 @@ slhci_enter_xfer(struct slhci_softc *sc, struct slhci_pipe *spipe) if (__predict_false(t->flags & F_DISABLED) || __predict_false(spipe->pflags & PF_GONE)) { DLOG(D_MSG, "slhci_enter_xfer: DISABLED or GONE", 0,0,0,0); - spipe->xfer->status = USBD_CANCELLED; + spipe->xfer->ux_status = USBD_CANCELLED; } - if (spipe->xfer->status == USBD_IN_PROGRESS) { - if (spipe->xfer->timeout) { - spipe->to_frame = t->frame + spipe->xfer->timeout; + if (spipe->xfer->ux_status == USBD_IN_PROGRESS) { + if (spipe->xfer->ux_timeout) { + spipe->to_frame = t->frame + spipe->xfer->ux_timeout; slhci_xfer_timer(sc, spipe); } - if (spipe->pipe.interval) + if (spipe->pipe.up_interval) slhci_queue_timed(sc, spipe); else enter_q(t, spipe, Q_CB); @@ -2492,18 +2447,18 @@ slhci_do_repeat(struct slhci_softc *sc, struct usbd_xfer *xfer) struct slhci_pipe *spipe; t = &sc->sc_transfers; - spipe = (struct slhci_pipe *)xfer->pipe; + spipe = SLHCI_PIPE2SPIPE(xfer->ux_pipe); if (xfer == t->rootintr) return; DLOG(D_TRACE, "REPEAT: xfer %p actlen %d frame %u now %u", - xfer, xfer->actlen, spipe->frame, sc->sc_transfers.frame); + xfer, xfer->ux_actlen, spipe->frame, sc->sc_transfers.frame); - xfer->actlen = 0; + xfer->ux_actlen = 0; spipe->xfer = xfer; if (spipe->tregs[LEN]) - KASSERT(spipe->buffer == KERNADDR(&xfer->dmabuf, 0)); + KASSERT(spipe->buffer == xfer->ux_buf); slhci_queue_timed(sc, spipe); slhci_dotransfer(sc); } @@ -2545,7 +2500,7 @@ slhci_pollxfer(struct slhci_softc *sc, struct usbd_xfer *xfer) slhci_dotransfer(sc); do { slhci_dointr(sc); - } while (xfer->status == USBD_IN_PROGRESS); + } while (xfer->ux_status == USBD_IN_PROGRESS); slhci_do_callback(sc, xfer); } #endif @@ -2607,7 +2562,7 @@ slhci_open_pipe(struct slhci_softc *sc, struct slhci_pipe *spipe, struct if (t->flags & F_DISABLED) return USBD_CANCELLED; - else if (pipe->interval && !slhci_reserve_bustime(sc, spipe, 1)) + else if (pipe->up_interval && !slhci_reserve_bustime(sc, spipe, 1)) return USBD_PENDING_REQUESTS; else { enter_all_pipes(t, spipe); @@ -2623,7 +2578,7 @@ slhci_close_pipe(struct slhci_softc *sc, struct slhci_pipe *spipe, struct pipe = &spipe->pipe; - if (pipe->interval && spipe->ptype != PT_ROOT_INTR) + if (pipe->up_interval && spipe->ptype != PT_ROOT_INTR) slhci_reserve_bustime(sc, spipe, 0); gcq_remove(&spipe->ap); return USBD_NORMAL_COMPLETION; @@ -2658,9 +2613,9 @@ slhci_do_abort(struct slhci_softc *sc, struct slhci_pipe *spipe, struct } } - if (xfer->status != USBD_TIMEOUT) { + if (xfer->ux_status != USBD_TIMEOUT) { spipe->xfer = NULL; - spipe->pipe.repeat = 0; /* XXX timeout? */ + spipe->pipe.up_repeat = 0; /* XXX timeout? */ } } @@ -2672,8 +2627,8 @@ slhci_do_abort(struct slhci_softc *sc, struct slhci_pipe *spipe, struct * Will cancel the xfer correctly even when not on a list. */ static usbd_status -slhci_halt(struct slhci_softc *sc, struct slhci_pipe *spipe, struct usbd_xfer - *xfer) +slhci_halt(struct slhci_softc *sc, struct slhci_pipe *spipe, + struct usbd_xfer *xfer) { struct slhci_transfers *t; @@ -2692,7 +2647,7 @@ slhci_halt(struct slhci_softc *sc, struct slhci_pipe *spipe, struct usbd_xfer if (spipe != NULL && xfer != NULL && spipe->xfer == xfer && !gcq_onlist(&spipe->xq) && t->spipe[A] != spipe && t->spipe[B] != spipe) { - xfer->status = USBD_CANCELLED; + xfer->ux_status = USBD_CANCELLED; enter_callback(t, spipe); } @@ -2773,10 +2728,10 @@ slhci_drain(struct slhci_softc *sc) */ FOREACH_AP(q, t, spipe) { spipe->pflags |= PF_GONE; - spipe->pipe.repeat = 0; - spipe->pipe.aborting = 1; + spipe->pipe.up_repeat = 0; + spipe->pipe.up_aborting = 1; if (spipe->xfer != NULL) - spipe->xfer->status = USBD_CANCELLED; + spipe->xfer->ux_status = USBD_CANCELLED; } gcq_remove_all(&t->to); @@ -2793,7 +2748,7 @@ slhci_drain(struct slhci_softc *sc) * by spec. uhub does this delay * * Started from root hub set feature reset, which does step one. - * use_polling will call slhci_reset directly, otherwise the callout goes + * ub_usepolling will call slhci_reset directly, otherwise the callout goes * through slhci_reset_entry. */ void @@ -2896,7 +2851,7 @@ slhci_reset(struct slhci_softc *sc) t->flags |= F_CRESET|F_ROOTINTR; FOREACH_AP(q, t, spipe) { spipe->pflags &= ~PF_GONE; - spipe->pipe.aborting = 0; + spipe->pipe.up_aborting = 0; } DLOG(D_MSG, "RESET done flags %#x", t->flags, 0,0,0); } @@ -2912,7 +2867,7 @@ slhci_reserve_bustime(struct slhci_softc *sc, struct slhci_pipe *spipe, int KASSERT(mutex_owned(&sc->sc_intr_lock)); t = &sc->sc_transfers; - max_packet = UGETW(spipe->pipe.endpoint->edesc->wMaxPacketSize); + max_packet = UGETW(spipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize); if (spipe->pflags & PF_LS) bustime = SLHCI_LS_CONST + SLHCI_LS_DATA_TIME(max_packet); @@ -2982,69 +2937,16 @@ slhci_insert(struct slhci_softc *sc) /* * Data structures and routines to emulate the root hub. */ -static const usb_device_descriptor_t slhci_devd = { - USB_DEVICE_DESCRIPTOR_SIZE, - UDESC_DEVICE, /* type */ - {0x01, 0x01}, /* USB version */ - UDCLASS_HUB, /* class */ - UDSUBCLASS_HUB, /* subclass */ - 0, /* protocol */ - 64, /* max packet */ - {USB_VENDOR_SCANLOGIC & 0xff, /* vendor ID (low) */ - USB_VENDOR_SCANLOGIC >> 8 }, /* vendor ID (high) */ - {0} /* ? */, /* product ID */ - {0}, /* device */ - 1, /* index to manufacturer */ - 2, /* index to product */ - 0, /* index to serial number */ - 1 /* number of configurations */ -}; - -static const struct slhci_confd_t { - const usb_config_descriptor_t confd; - const usb_interface_descriptor_t ifcd; - const usb_endpoint_descriptor_t endpd; -} UPACKED slhci_confd = { - { /* Configuration */ - USB_CONFIG_DESCRIPTOR_SIZE, - UDESC_CONFIG, - {USB_CONFIG_DESCRIPTOR_SIZE + - USB_INTERFACE_DESCRIPTOR_SIZE + - USB_ENDPOINT_DESCRIPTOR_SIZE}, - 1, /* number of interfaces */ - 1, /* configuration value */ - 0, /* index to configuration */ - UC_SELF_POWERED, /* attributes */ - 0 /* max current, filled in later */ - }, { /* Interface */ - USB_INTERFACE_DESCRIPTOR_SIZE, - UDESC_INTERFACE, - 0, /* interface number */ - 0, /* alternate setting */ - 1, /* number of endpoint */ - UICLASS_HUB, /* class */ - UISUBCLASS_HUB, /* subclass */ - 0, /* protocol */ - 0 /* index to interface */ - }, { /* Endpoint */ - USB_ENDPOINT_DESCRIPTOR_SIZE, - UDESC_ENDPOINT, - UE_DIR_IN | ROOT_INTR_ENDPT, /* endpoint address */ - UE_INTERRUPT, /* attributes */ - {240, 0}, /* max packet size */ - 255 /* interval */ - } -}; static const usb_hub_descriptor_t slhci_hubd = { - USB_HUB_DESCRIPTOR_SIZE, - UDESC_HUB, - 1, /* number of ports */ - {UHD_PWR_INDIVIDUAL | UHD_OC_NONE, 0}, /* hub characteristics */ - 50, /* 5:power on to power good, units of 2ms */ - 0, /* 6:maximum current, filled in later */ - { 0x00 }, /* port is removable */ - { 0x00 } /* port power control mask */ + .bDescLength = USB_HUB_DESCRIPTOR_SIZE, + .bDescriptorType = UDESC_HUB, + .bNbrPorts = 1, + .wHubCharacteristics = USETWD(UHD_PWR_INDIVIDUAL | UHD_OC_NONE), + .bPwrOn2PwrGood = 50, + .bHubContrCurrent = 0, + .DeviceRemovable = { 0x00 }, + .PortPowerCtrlMask = { 0x00 } }; static usbd_status @@ -3113,7 +3015,7 @@ slhci_set_feature(struct slhci_softc *sc, unsigned int what) slhci_write(sc, SL11_CTRL, SL11_CTRL_RESETENGINE); /* usb spec says delay >= 10ms, app note 50ms */ start_cc_time(&t_delay, 50000); - if (sc->sc_bus.use_polling) { + if (sc->sc_bus.ub_usepolling) { DELAY(50000); slhci_reset(sc); } else { @@ -3193,17 +3095,12 @@ slhci_get_status(struct slhci_softc *sc, usb_port_status_t *ps) } static usbd_status -slhci_root(struct slhci_softc *sc, struct slhci_pipe *spipe, struct usbd_xfer - *xfer) +slhci_root(struct slhci_softc *sc, struct slhci_pipe *spipe, + struct usbd_xfer *xfer) { struct slhci_transfers *t; - usb_device_request_t *req; - unsigned int len, value, index, actlen, type; - uint8_t *buf; - usbd_status error; t = &sc->sc_transfers; - buf = NULL; LK_SLASSERT(spipe != NULL && xfer != NULL, sc, spipe, xfer, return USBD_CANCELLED); @@ -3211,18 +3108,25 @@ slhci_root(struct slhci_softc *sc, struct slhci_pipe *spipe, struct usbd_xfer DLOG(D_TRACE, "%s start", pnames(SLHCI_XFER_TYPE(xfer)), 0,0,0); KASSERT(mutex_owned(&sc->sc_intr_lock)); - if (spipe->ptype == PT_ROOT_INTR) { - LK_SLASSERT(t->rootintr == NULL, sc, spipe, xfer, return - USBD_CANCELLED); - t->rootintr = xfer; - if (t->flags & F_CHANGE) - t->flags |= F_ROOTINTR; - return USBD_IN_PROGRESS; - } + KASSERT(spipe->ptype == PT_ROOT_INTR); + LK_SLASSERT(t->rootintr == NULL, sc, spipe, xfer, return + USBD_CANCELLED); + t->rootintr = xfer; + if (t->flags & F_CHANGE) + t->flags |= F_ROOTINTR; + return USBD_IN_PROGRESS; +} - error = USBD_IOERROR; /* XXX should be STALL */ - actlen = 0; - req = &xfer->request; +static int +slhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, + void *buf, int buflen) +{ + struct slhci_softc *sc = SLHCI_BUS2SC(bus); + struct slhci_transfers *t = &sc->sc_transfers; + usbd_status error = USBD_IOERROR; /* XXX should be STALL */ + uint16_t len, value, index; + uint8_t type; + int actlen = 0; len = UGETW(req->wLength); value = UGETW(req->wValue); @@ -3230,9 +3134,6 @@ slhci_root(struct slhci_softc *sc, struct slhci_pipe *spipe, struct usbd_xfer type = req->bmRequestType; - if (len) - buf = KERNADDR(&xfer->dmabuf, 0); - SLHCI_DEXEC(D_TRACE, slhci_log_req_hub(req)); /* @@ -3292,24 +3193,7 @@ slhci_root(struct slhci_softc *sc, struct slhci_pipe *spipe, struct usbd_xfer "ENDPOINT_HALT or DEVICE_REMOTE_WAKEUP " "not supported", 0,0,0,0); break; - case UR_SET_ADDRESS: - if (type == UT_WRITE_DEVICE) { - DLOG(D_ROOT, "Set Address %#.4x", value, 0,0,0); - if (value < USB_MAX_DEVICES) { - t->rootaddr = value; - error = USBD_NORMAL_COMPLETION; - } - } - break; - case UR_SET_CONFIG: - if (type == UT_WRITE_DEVICE) { - DLOG(D_ROOT, "Set Config %#.4x", value, 0,0,0); - if (value == 0 || value == 1) { - t->rootconf = value; - error = USBD_NORMAL_COMPLETION; - } - } - break; + /* Read Requests */ case UR_GET_STATUS: if (type == UT_READ_CLASS_OTHER) { @@ -3332,57 +3216,29 @@ slhci_root(struct slhci_softc *sc, struct slhci_pipe *spipe, struct usbd_xfer } else DLOG(D_ROOT, "Get Hub Status bad len %#.4x", len, 0,0,0); - } else if (type == UT_READ_DEVICE) { - if (len >= 2) { - USETW(((usb_status_t *)buf)->wStatus, UDS_SELF_POWERED); - actlen = 2; - error = USBD_NORMAL_COMPLETION; - } - } else if (type == (UT_READ_INTERFACE|UT_READ_ENDPOINT)) { - if (len >= 2) { - USETW(((usb_status_t *)buf)->wStatus, 0); - actlen = 2; - error = USBD_NORMAL_COMPLETION; - } - } - break; - case UR_GET_CONFIG: - if (type == UT_READ_DEVICE) { - DLOG(D_ROOT, "Get Config", 0,0,0,0); - if (len > 0) { - *buf = t->rootconf; - actlen = 1; - error = USBD_NORMAL_COMPLETION; - } - } - break; - case UR_GET_INTERFACE: - if (type == UT_READ_INTERFACE) { - if (len > 0) { - *buf = 0; - actlen = 1; - error = USBD_NORMAL_COMPLETION; - } } break; case UR_GET_DESCRIPTOR: if (type == UT_READ_DEVICE) { /* value is type (&0xff00) and index (0xff) */ if (value == (UDESC_DEVICE<<8)) { - actlen = min(len, sizeof(slhci_devd)); - memcpy(buf, &slhci_devd, actlen); + usb_device_descriptor_t devd; + + actlen = min(buflen, sizeof(devd)); + memcpy(&devd, buf, actlen); + USETW(devd.idVendor, USB_VENDOR_SCANLOGIC); + memcpy(buf, &devd, actlen); error = USBD_NORMAL_COMPLETION; } else if (value == (UDESC_CONFIG<<8)) { - actlen = min(len, sizeof(slhci_confd)); - memcpy(buf, &slhci_confd, actlen); - if (actlen > offsetof(usb_config_descriptor_t, - bMaxPower)) - ((usb_config_descriptor_t *) - buf)->bMaxPower = t->max_current; - /* 2 mA units */ + struct usb_roothub_descriptors confd; + + actlen = min(buflen, sizeof(confd)); + memcpy(&confd, buf, actlen); + + /* 2 mA units */ + confd.urh_confd.bMaxPower = t->max_current; + memcpy(buf, &confd, actlen); error = USBD_NORMAL_COMPLETION; - } else if (value == (UDESC_STRING<<8)) { - /* language table XXX */ } else if (value == ((UDESC_STRING<<8)|1)) { /* Vendor */ actlen = usb_makestrdesc((usb_string_descriptor_t *) @@ -3399,29 +3255,28 @@ slhci_root(struct slhci_softc *sc, struct slhci_pipe *spipe, struct usbd_xfer } else if (type == UT_READ_CLASS_DEVICE) { /* Descriptor number is 0 */ if (value == (UDESC_HUB<<8)) { - actlen = min(len, sizeof(slhci_hubd)); - memcpy(buf, &slhci_hubd, actlen); - if (actlen > offsetof(usb_config_descriptor_t, - bMaxPower)) - ((usb_hub_descriptor_t *) - buf)->bHubContrCurrent = 500 - - t->max_current; + usb_hub_descriptor_t hubd; + + actlen = min(buflen, sizeof(hubd)); + memcpy(&hubd, buf, actlen); + hubd.bHubContrCurrent = + 500 - t->max_current; + memcpy(buf, &hubd, actlen); error = USBD_NORMAL_COMPLETION; } else DDOLOG("Unknown Get Hub Descriptor %#.4x", value, 0,0,0); } break; + default: + /* default from usbroothub */ + return buflen; } if (error == USBD_NORMAL_COMPLETION) - xfer->actlen = actlen; - xfer->status = error; - KASSERT(spipe->xfer == NULL); - spipe->xfer = xfer; - enter_callback(t, spipe); + return actlen; - return USBD_IN_PROGRESS; + return -1; } /* End in lock functions. Start debug functions. */ @@ -3432,13 +3287,13 @@ slhci_log_buffer(struct usbd_xfer *xfer) { u_char *buf; - if(xfer->length > 0 && - UE_GET_DIR(xfer->pipe->endpoint->edesc->bEndpointAddress) == + if(xfer->ux_length > 0 && + UE_GET_DIR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN) { - buf = KERNADDR(&xfer->dmabuf, 0); - DDOLOGBUF(buf, xfer->actlen); - DDOLOG("len %d actlen %d short %d", xfer->length, - xfer->actlen, xfer->length - xfer->actlen, 0); + buf = xfer->ux_buf; + DDOLOGBUF(buf, xfer->ux_actlen); + DDOLOG("len %d actlen %d short %d", xfer->ux_length, + xfer->ux_actlen, xfer->ux_length - xfer->ux_actlen, 0); } } @@ -3587,10 +3442,10 @@ void slhci_log_xfer(struct usbd_xfer *xfer) { DDOLOG("xfer: length=%u, actlen=%u, flags=%#x, timeout=%u,", - xfer->length, xfer->actlen, xfer->flags, xfer->timeout); - if (xfer->dmabuf.block) - DDOLOG("buffer=%p", KERNADDR(&xfer->dmabuf, 0), 0,0,0); - slhci_log_req_hub(&xfer->request); + xfer->ux_length, xfer->ux_actlen, xfer->ux_flags, xfer->ux_timeout); + if (xfer->ux_dmabuf.block) + DDOLOG("buffer=%p", xfer->ux_buf, 0,0,0); + slhci_log_req_hub(&xfer->ux_request); } void @@ -3633,7 +3488,7 @@ slhci_log_sc(void) DDOLOG("frame=%d rootintr=%p", t->frame, t->rootintr, 0,0); - DDOLOG("use_polling=%d", ssc->sc_bus.use_polling, 0, 0, 0); + DDOLOG("ub_usepolling=%d", ssc->sc_bus.ub_usepolling, 0, 0, 0); } void diff --git a/sys/dev/ic/sl811hsvar.h b/sys/dev/ic/sl811hsvar.h index 2ca4e5bdfbc..9a5b0e21d3c 100644 --- a/sys/dev/ic/sl811hsvar.h +++ b/sys/dev/ic/sl811hsvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: sl811hsvar.h,v 1.11 2013/10/02 22:55:04 skrll Exp $ */ +/* $NetBSD: sl811hsvar.h,v 1.12 2016/04/23 10:15:31 skrll Exp $ */ /* * Not (c) 2007 Matthew Orgass @@ -36,8 +36,6 @@ struct slhci_transfers { int16_t len[2]; /* length of transfer or -1 if none */ uint8_t current_tregs[2][4]; /* ab, ADR, LEN, PID, DEV */ uint8_t copyin[2]; /* copyin ADR, LEN */ - uint8_t rootaddr; /* device address of root hub */ - uint8_t rootconf; /* root configuration */ uint8_t max_current; /* max current / 2 */ uint8_t sltype; /* revision */ }; diff --git a/sys/dev/isa/slhci_isa.c b/sys/dev/isa/slhci_isa.c index 00a2ab7991b..8816107f7e9 100644 --- a/sys/dev/isa/slhci_isa.c +++ b/sys/dev/isa/slhci_isa.c @@ -1,4 +1,4 @@ -/* $NetBSD: slhci_isa.c,v 1.12 2011/03/08 04:58:21 kiyohara Exp $ */ +/* $NetBSD: slhci_isa.c,v 1.13 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 2001 Kiyoshi Ikehara. All rights reserved. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: slhci_isa.c,v 1.12 2011/03/08 04:58:21 kiyohara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: slhci_isa.c,v 1.13 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -98,7 +98,7 @@ slhci_isa_attach(device_t parent, device_t self, void *aux) bus_space_handle_t ioh; sc->sc_dev = self; - sc->sc_bus.hci_private = sc; + sc->sc_bus.ub_hcpriv = sc; printf("\n"); /* XXX still needed? */ diff --git a/sys/dev/marvell/ehci_mv.c b/sys/dev/marvell/ehci_mv.c index 9a4008a1efe..801eb87ccfa 100644 --- a/sys/dev/marvell/ehci_mv.c +++ b/sys/dev/marvell/ehci_mv.c @@ -1,4 +1,4 @@ -/* $NetBSD: ehci_mv.c,v 1.5 2014/03/15 13:33:48 kiyohara Exp $ */ +/* $NetBSD: ehci_mv.c,v 1.6 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 2008 KIYOHARA Takashi * All rights reserved. @@ -26,7 +26,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ehci_mv.c,v 1.5 2014/03/15 13:33:48 kiyohara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ehci_mv.c,v 1.6 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -198,13 +198,12 @@ mvusb_attach(device_t parent, device_t self, void *aux) { struct mvusb_softc *sc = device_private(self); struct marvell_attach_args *mva = aux; - usbd_status r; aprint_normal(": Marvell USB 2.0 Interface\n"); aprint_naive("\n"); sc->sc.sc_dev = self; - sc->sc.sc_bus.hci_private = sc; + sc->sc.sc_bus.ub_hcpriv = sc; sc->sc_model = mva->mva_model; sc->sc_rev = mva->mva_revision; @@ -226,7 +225,7 @@ mvusb_attach(device_t parent, device_t self, void *aux) return; } sc->sc.iot = sc->sc_iot; - sc->sc.sc_bus.dmatag = mva->mva_dmat; + sc->sc.sc_bus.ub_dmatag = mva->mva_dmat; /* Disable interrupts, so we don't get any spurious ones. */ sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); @@ -235,7 +234,7 @@ mvusb_attach(device_t parent, device_t self, void *aux) marvell_intr_establish(mva->mva_irq, IPL_USB, ehci_intr, sc); - sc->sc.sc_bus.usbrev = USBREV_2_0; + sc->sc.sc_bus.ub_revision = USBREV_2_0; /* Figure out vendor for root hub descriptor. */ sc->sc.sc_id_vendor = 0x0000; /* XXXXX */ strcpy(sc->sc.sc_vendor, "Marvell"); @@ -243,9 +242,9 @@ mvusb_attach(device_t parent, device_t self, void *aux) sc->sc.sc_vendor_init = mvusb_vendor_init; sc->sc.sc_vendor_port_status = mvusb_vendor_port_status; - r = ehci_init(&sc->sc); - if (r != USBD_NORMAL_COMPLETION) { - aprint_error_dev(self, "init failed, error=%d\n", r); + int err = ehci_init(&sc->sc); + if (err) { + aprint_error_dev(self, "init failed, error=%d\n", err); return; } @@ -316,7 +315,7 @@ mvusb_init(struct mvusb_softc *sc, enum marvell_tags *tags) /* bits[8:9] - (DISCON_THRESHOLD ) */ /* * Orion1-A0/A1/B0=11, Orion2-A0=10, - * Orion1-B1 and Orion2-B0 later=00 + * Orion1-B1 and Orion2-B0 later=00 */ reg &= ~(3 << 8); if (sc->sc_model == MARVELL_ORION_1_88F5181 && sc->sc_rev <= 2) diff --git a/sys/dev/pci/ehci_pci.c b/sys/dev/pci/ehci_pci.c index c814eb2c6f4..bd616e7eea1 100644 --- a/sys/dev/pci/ehci_pci.c +++ b/sys/dev/pci/ehci_pci.c @@ -1,4 +1,4 @@ -/* $NetBSD: ehci_pci.c,v 1.62 2015/08/31 10:41:22 skrll Exp $ */ +/* $NetBSD: ehci_pci.c,v 1.63 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 2001, 2002 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ehci_pci.c,v 1.62 2015/08/31 10:41:22 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ehci_pci.c,v 1.63 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -119,14 +119,13 @@ ehci_pci_attach(device_t parent, device_t self, void *aux) char const *intrstr; pci_intr_handle_t ih; pcireg_t csr; - usbd_status r; int ncomp; struct usb_pci *up; int quirk; char intrbuf[PCI_INTRSTR_LEN]; sc->sc.sc_dev = self; - sc->sc.sc_bus.hci_private = sc; + sc->sc.sc_bus.ub_hcpriv = sc; pci_aprint_devinfo(pa, "USB controller"); @@ -144,7 +143,7 @@ ehci_pci_attach(device_t parent, device_t self, void *aux) sc->sc_pc = pc; sc->sc_tag = tag; - sc->sc.sc_bus.dmatag = pa->pa_dmat; + sc->sc.sc_bus.ub_dmatag = pa->pa_dmat; /* Disable interrupts, so we don't get any spurious ones. */ sc->sc.sc_offs = EREAD1(&sc->sc, EHCI_CAPLENGTH); @@ -191,14 +190,14 @@ ehci_pci_attach(device_t parent, device_t self, void *aux) case PCI_USBREV_PRE_1_0: case PCI_USBREV_1_0: case PCI_USBREV_1_1: - sc->sc.sc_bus.usbrev = USBREV_UNKNOWN; + sc->sc.sc_bus.ub_revision = USBREV_UNKNOWN; aprint_verbose_dev(self, "pre-2.0 USB rev\n"); goto fail; case PCI_USBREV_2_0: - sc->sc.sc_bus.usbrev = USBREV_2_0; + sc->sc.sc_bus.ub_revision = USBREV_2_0; break; default: - sc->sc.sc_bus.usbrev = USBREV_UNKNOWN; + sc->sc.sc_bus.ub_revision = USBREV_UNKNOWN; break; } @@ -239,9 +238,9 @@ ehci_pci_attach(device_t parent, device_t self, void *aux) ehci_get_ownership(&sc->sc, pc, tag); - r = ehci_init(&sc->sc); - if (r != USBD_NORMAL_COMPLETION) { - aprint_error_dev(self, "init failed, error=%d\n", r); + int err = ehci_init(&sc->sc); + if (err) { + aprint_error_dev(self, "init failed, error=%d\n", err); goto fail; } @@ -463,7 +462,7 @@ static int ehci_apply_amd_quirks(struct ehci_pci_softc *sc) { pcireg_t value; - + aprint_normal_dev(sc->sc.sc_dev, "applying AMD SB600/SB700 USB freeze workaround\n"); value = pci_conf_read(sc->sc_pc, sc->sc_tag, EHCI_SBx00_WORKAROUND_REG); diff --git a/sys/dev/pci/ohci_pci.c b/sys/dev/pci/ohci_pci.c index 09126575b3d..48c25cf6df3 100644 --- a/sys/dev/pci/ohci_pci.c +++ b/sys/dev/pci/ohci_pci.c @@ -1,4 +1,4 @@ -/* $NetBSD: ohci_pci.c,v 1.54 2015/08/19 06:16:18 skrll Exp $ */ +/* $NetBSD: ohci_pci.c,v 1.55 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ohci_pci.c,v 1.54 2015/08/19 06:16:18 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ohci_pci.c,v 1.55 2016/04/23 10:15:31 skrll Exp $"); #include "ehci.h" @@ -89,11 +89,10 @@ ohci_pci_attach(device_t parent, device_t self, void *aux) char const *intrstr; pci_intr_handle_t ih; pcireg_t csr; - usbd_status r; char intrbuf[PCI_INTRSTR_LEN]; sc->sc.sc_dev = self; - sc->sc.sc_bus.hci_private = sc; + sc->sc.sc_bus.ub_hcpriv = sc; if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_NS && PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_NS_USB) { @@ -126,7 +125,7 @@ ohci_pci_attach(device_t parent, device_t self, void *aux) sc->sc_pc = pc; sc->sc_tag = tag; - sc->sc.sc_bus.dmatag = pa->pa_dmat; + sc->sc.sc_bus.ub_dmatag = pa->pa_dmat; /* Enable the device. */ pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, @@ -156,9 +155,9 @@ ohci_pci_attach(device_t parent, device_t self, void *aux) sc->sc.sc_id_vendor = PCI_VENDOR(pa->pa_id); pci_findvendor(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor), sc->sc.sc_id_vendor); - r = ohci_init(&sc->sc); - if (r != USBD_NORMAL_COMPLETION) { - aprint_error_dev(self, "init failed, error=%d\n", r); + int err = ohci_init(&sc->sc); + if (err) { + aprint_error_dev(self, "init failed, error=%d\n", err); goto fail; } diff --git a/sys/dev/pci/uhci_pci.c b/sys/dev/pci/uhci_pci.c index e42c72b9073..c5a0ffc51a4 100644 --- a/sys/dev/pci/uhci_pci.c +++ b/sys/dev/pci/uhci_pci.c @@ -1,4 +1,4 @@ -/* $NetBSD: uhci_pci.c,v 1.59 2015/08/19 06:16:18 skrll Exp $ */ +/* $NetBSD: uhci_pci.c,v 1.60 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uhci_pci.c,v 1.59 2015/08/19 06:16:18 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uhci_pci.c,v 1.60 2016/04/23 10:15:31 skrll Exp $"); #include "ehci.h" @@ -78,9 +78,9 @@ uhci_pci_match(device_t parent, cfdata_t match, void *aux) if (PCI_CLASS(pa->pa_class) == PCI_CLASS_SERIALBUS && PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_SERIALBUS_USB && PCI_INTERFACE(pa->pa_class) == PCI_INTERFACE_UHCI) - return (1); + return 1; - return (0); + return 0; } static void @@ -93,12 +93,11 @@ uhci_pci_attach(device_t parent, device_t self, void *aux) char const *intrstr; pci_intr_handle_t ih; pcireg_t csr; - usbd_status r; int s; char intrbuf[PCI_INTRSTR_LEN]; sc->sc.sc_dev = self; - sc->sc.sc_bus.hci_private = sc; + sc->sc.sc_bus.ub_hcpriv = sc; pci_aprint_devinfo(pa, NULL); @@ -119,7 +118,7 @@ uhci_pci_attach(device_t parent, device_t self, void *aux) sc->sc_pc = pc; sc->sc_tag = tag; - sc->sc.sc_bus.dmatag = pa->pa_dmat; + sc->sc.sc_bus.ub_dmatag = pa->pa_dmat; /* Enable the device. */ csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); @@ -156,16 +155,16 @@ uhci_pci_attach(device_t parent, device_t self, void *aux) switch(pci_conf_read(pc, tag, PCI_USBREV) & PCI_USBREV_MASK) { case PCI_USBREV_PRE_1_0: - sc->sc.sc_bus.usbrev = USBREV_PRE_1_0; + sc->sc.sc_bus.ub_revision = USBREV_PRE_1_0; break; case PCI_USBREV_1_0: - sc->sc.sc_bus.usbrev = USBREV_1_0; + sc->sc.sc_bus.ub_revision = USBREV_1_0; break; case PCI_USBREV_1_1: - sc->sc.sc_bus.usbrev = USBREV_1_1; + sc->sc.sc_bus.ub_revision = USBREV_1_1; break; default: - sc->sc.sc_bus.usbrev = USBREV_UNKNOWN; + sc->sc.sc_bus.ub_revision = USBREV_UNKNOWN; break; } @@ -173,9 +172,9 @@ uhci_pci_attach(device_t parent, device_t self, void *aux) sc->sc.sc_id_vendor = PCI_VENDOR(pa->pa_id); pci_findvendor(sc->sc.sc_vendor, sizeof(sc->sc.sc_vendor), sc->sc.sc_id_vendor); - r = uhci_init(&sc->sc); - if (r != USBD_NORMAL_COMPLETION) { - aprint_error_dev(self, "init failed, error=%d\n", r); + int err = uhci_init(&sc->sc); + if (err) { + aprint_error_dev(self, "init failed, error=%d\n", err); return; } sc->sc_initialized = SC_INIT_UHCI; @@ -202,7 +201,7 @@ uhci_pci_detach(device_t self, int flags) if (sc->sc_initialized & SC_INIT_UHCI) { rv = uhci_detach(&sc->sc, flags); if (rv) - return (rv); + return rv; } if (sc->sc_initialized & SC_INIT_PMF) @@ -224,7 +223,7 @@ uhci_pci_detach(device_t self, int flags) #if NEHCI > 0 usb_pci_rem(&sc->sc_pci); #endif - return (0); + return 0; } static bool diff --git a/sys/dev/pci/xhci_pci.c b/sys/dev/pci/xhci_pci.c index 89fdabf6ae3..c8ec7c3d7e5 100644 --- a/sys/dev/pci/xhci_pci.c +++ b/sys/dev/pci/xhci_pci.c @@ -1,4 +1,5 @@ -/* $NetBSD: xhci_pci.c,v 1.4 2014/09/21 14:30:22 christos Exp $ */ +/* $NetBSD: xhci_pci.c,v 1.5 2016/04/23 10:15:31 skrll Exp $ */ +/* OpenBSD: xhci_pci.c,v 1.4 2014/07/12 17:38:51 yuo Exp */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -31,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: xhci_pci.c,v 1.4 2014/09/21 14:30:22 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xhci_pci.c,v 1.5 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -43,6 +44,7 @@ __KERNEL_RCSID(0, "$NetBSD: xhci_pci.c,v 1.4 2014/09/21 14:30:22 christos Exp $" #include <sys/bus.h> #include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> #include <dev/usb/usb.h> #include <dev/usb/usbdi.h> @@ -52,13 +54,38 @@ __KERNEL_RCSID(0, "$NetBSD: xhci_pci.c,v 1.4 2014/09/21 14:30:22 christos Exp $" #include <dev/usb/xhcireg.h> #include <dev/usb/xhcivar.h> +struct xhci_pci_quirk { + pci_vendor_id_t vendor; + pci_product_id_t product; + int quirks; +}; + +static const struct xhci_pci_quirk xhci_pci_quirks[] = { + { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_CORE4G_M_XHCI, + XHCI_QUIRK_FORCE_INTR }, +}; + struct xhci_pci_softc { struct xhci_softc sc_xhci; pci_chipset_tag_t sc_pc; pcitag_t sc_tag; + void *sc_ih; + pci_intr_handle_t *sc_pihp; }; static int +xhci_pci_has_quirk(pci_vendor_id_t vendor, pci_product_id_t product) +{ + int i; + + for (i = 0; i < __arraycount(xhci_pci_quirks); i++) + if (vendor == xhci_pci_quirks[i].vendor && + product == xhci_pci_quirks[i].product) + return xhci_pci_quirks[i].quirks; + return 0; +} + +static int xhci_pci_match(device_t parent, cfdata_t match, void *aux) { struct pci_attach_args *pa = (struct pci_attach_args *) aux; @@ -71,6 +98,42 @@ xhci_pci_match(device_t parent, cfdata_t match, void *aux) return 0; } +static int +xhci_pci_port_route(struct xhci_pci_softc *psc) +{ + struct xhci_softc * const sc = &psc->sc_xhci; + + pcireg_t val; + + /* + * Check USB3 Port Routing Mask register that indicates the ports + * can be changed from OS, and turn on by USB3 Port SS Enable register. + */ + val = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_USB3PRM); + aprint_debug_dev(sc->sc_dev, + "USB3PRM / USB3.0 configurable ports: 0x%08x\n", val); + + pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_USB3_PSSEN, val); + val = pci_conf_read(psc->sc_pc, psc->sc_tag,PCI_XHCI_INTEL_USB3_PSSEN); + aprint_debug_dev(sc->sc_dev, + "USB3_PSSEN / Enabled USB3.0 ports under xHCI: 0x%08x\n", val); + + /* + * Check USB2 Port Routing Mask register that indicates the USB2.0 + * ports to be controlled by xHCI HC, and switch them to xHCI HC. + */ + val = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_USB2PRM); + aprint_debug_dev(sc->sc_dev, + "XUSB2PRM / USB2.0 ports can switch from EHCI to xHCI:" + "0x%08x\n", val); + pci_conf_write(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_XUSB2PR, val); + val = pci_conf_read(psc->sc_pc, psc->sc_tag, PCI_XHCI_INTEL_XUSB2PR); + aprint_debug_dev(sc->sc_dev, + "XUSB2PR / USB2.0 ports under xHCI: 0x%08x\n", val); + + return 0; +} + static void xhci_pci_attach(device_t parent, device_t self, void *aux) { @@ -80,22 +143,24 @@ xhci_pci_attach(device_t parent, device_t self, void *aux) const pci_chipset_tag_t pc = pa->pa_pc; const pcitag_t tag = pa->pa_tag; char const *intrstr; - pci_intr_handle_t ih; pcireg_t csr, memtype; int err; - //const char *vendor; uint32_t hccparams; char intrbuf[PCI_INTRSTR_LEN]; sc->sc_dev = self; - sc->sc_bus.hci_private = sc; + sc->sc_bus.ub_hcpriv = sc; pci_aprint_devinfo(pa, "USB Controller"); + /* Check for quirks */ + sc->sc_quirks = xhci_pci_has_quirk(PCI_VENDOR(pa->pa_id), + PCI_PRODUCT(pa->pa_id)); + /* check if memory space access is enabled */ csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); #ifdef DEBUG - printf("csr: %08x\n", csr); + printf("%s: csr: %08x\n", __func__, csr); #endif if ((csr & PCI_COMMAND_MEM_ENABLE) == 0) { aprint_error_dev(self, "memory access is disabled\n"); @@ -117,35 +182,32 @@ xhci_pci_attach(device_t parent, device_t self, void *aux) default: aprint_error_dev(self, "BAR not 64 or 32-bit MMIO\n"); return; - break; } psc->sc_pc = pc; psc->sc_tag = tag; - hccparams = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 0x10); + hccparams = bus_space_read_4(sc->sc_iot, sc->sc_ioh, XHCI_HCCPARAMS); - if (pci_dma64_available(pa) && ((hccparams&1)==1)) - sc->sc_bus.dmatag = pa->pa_dmat64; + if (pci_dma64_available(pa) && (XHCI_HCC_AC64(hccparams) != 0)) + sc->sc_bus.ub_dmatag = pa->pa_dmat64; else - sc->sc_bus.dmatag = pa->pa_dmat; + sc->sc_bus.ub_dmatag = pa->pa_dmat; /* Enable the device. */ pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr | PCI_COMMAND_MASTER_ENABLE); - /* Map and establish the interrupt. */ - if (pci_intr_map(pa, &ih)) { - aprint_error_dev(self, "couldn't map interrupt\n"); + /* Allocate and establish the interrupt. */ + if (pci_intr_alloc(pa, &psc->sc_pihp, NULL, 0)) { + aprint_error_dev(self, "can't allocate handler\n"); goto fail; } - - /* - * Allocate IRQ - */ - intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf)); - sc->sc_ih = pci_intr_establish(pc, ih, IPL_USB, xhci_intr, sc); - if (sc->sc_ih == NULL) { + intrstr = pci_intr_string(pc, psc->sc_pihp[0], intrbuf, + sizeof(intrbuf)); + psc->sc_ih = pci_intr_establish(pc, psc->sc_pihp[0], IPL_USB, + xhci_intr, sc); + if (psc->sc_ih == NULL) { aprint_error_dev(self, "couldn't establish interrupt"); if (intrstr != NULL) aprint_error(" at %s", intrstr); @@ -154,12 +216,19 @@ xhci_pci_attach(device_t parent, device_t self, void *aux) } aprint_normal_dev(self, "interrupting at %s\n", intrstr); -#if 0 /* Figure out vendor for root hub descriptor. */ sc->sc_id_vendor = PCI_VENDOR(pa->pa_id); pci_findvendor(sc->sc_vendor, sizeof(sc->sc_vendor), sc->sc_id_vendor); -#endif + + /* Intel chipset requires SuperSpeed enable and USB2 port routing */ + switch (PCI_VENDOR(pa->pa_id)) { + case PCI_VENDOR_INTEL: + sc->sc_quirks |= XHCI_QUIRK_INTEL; + break; + default: + break; + } err = xhci_init(sc); if (err) { @@ -167,6 +236,9 @@ xhci_pci_attach(device_t parent, device_t self, void *aux) goto fail; } + if ((sc->sc_quirks & XHCI_QUIRK_INTEL) != 0) + xhci_pci_port_route(psc); + if (!pmf_device_register1(self, xhci_suspend, xhci_resume, xhci_shutdown)) aprint_error_dev(self, "couldn't establish power handler\n"); @@ -176,9 +248,9 @@ xhci_pci_attach(device_t parent, device_t self, void *aux) return; fail: - if (sc->sc_ih) { - pci_intr_disestablish(psc->sc_pc, sc->sc_ih); - sc->sc_ih = NULL; + if (psc->sc_ih) { + pci_intr_release(psc->sc_pc, psc->sc_pihp, 1); + psc->sc_ih = NULL; } if (sc->sc_ios) { bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); @@ -210,9 +282,9 @@ xhci_pci_detach(device_t self, int flags) #endif } - if (sc->sc_ih != NULL) { - pci_intr_disestablish(psc->sc_pc, sc->sc_ih); - sc->sc_ih = NULL; + if (psc->sc_ih != NULL) { + pci_intr_release(psc->sc_pc, psc->sc_pihp, 1); + psc->sc_ih = NULL; } if (sc->sc_ios) { bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_ios); diff --git a/sys/dev/pcmcia/slhci_pcmcia.c b/sys/dev/pcmcia/slhci_pcmcia.c index d40a7c4bd6c..1e04a1bf24e 100644 --- a/sys/dev/pcmcia/slhci_pcmcia.c +++ b/sys/dev/pcmcia/slhci_pcmcia.c @@ -1,4 +1,4 @@ -/* $NetBSD: slhci_pcmcia.c,v 1.9 2011/11/27 14:36:20 rmind Exp $ */ +/* $NetBSD: slhci_pcmcia.c,v 1.10 2016/04/23 10:15:31 skrll Exp $ */ /* * Not (c) 2007 Matthew Orgass * This file is public domain, meaning anyone can make any use of part or all @@ -11,7 +11,7 @@ /* Glue for RATOC USB HOST CF+ Card (SL811HS chip) */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: slhci_pcmcia.c,v 1.9 2011/11/27 14:36:20 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: slhci_pcmcia.c,v 1.10 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -89,7 +89,7 @@ slhci_pcmcia_attach(device_t parent, device_t self, void *aux) struct pcmcia_function *pf = pa->pf; psc->sc_slhci.sc_dev = self; - psc->sc_slhci.sc_bus.hci_private = &psc->sc_slhci; + psc->sc_slhci.sc_bus.ub_hcpriv = &psc->sc_slhci; psc->sc_pf = pf; psc->sc_flags = 0; diff --git a/sys/dev/usb/TODO.usbmp b/sys/dev/usb/TODO.usbmp index 4ec01ed6ac2..b9d7395bc6c 100644 --- a/sys/dev/usb/TODO.usbmp +++ b/sys/dev/usb/TODO.usbmp @@ -1,4 +1,4 @@ -$NetBSD: TODO.usbmp,v 1.9 2015/03/07 20:20:55 mrg Exp $ +$NetBSD: TODO.usbmp,v 1.10 2016/04/23 10:15:31 skrll Exp $ the majority of the USB MP device interface is documented in usbdivar.h. @@ -9,6 +9,15 @@ flesh out most of usbdi(9). usb_event_thread() startup should use something to sync companions +KERNEL_LOCK + - auvitek.c + - auvitek_dtv.c + - emdtv.c + - emdtv_dtv.c + - ubt.c + - uhub.c + - usscanner.c + usb_detach_{waitold,wakeup} to usb_detach_{wait,broadcast} conversion: - drivers: if_aue.c @@ -53,9 +62,34 @@ convert uhidev users to MPSAFE: uyurex(4) - sysmon -- hm? +splusb drivers: + - auvitek_dtv.c + - auvitek_video.c + - emdtv_dtv.c + - if_athn_usb.c + - if_aue.c + - if_axe.c + - if_axen.c + - if_cdce.c + - if_cue.c + - if_kue.c + - if_otus.c + - if_rum.c + - if_run.c + - if_smsc.c + - if_udav.c + - if_upl.c + - if_ural.c + - if_url.c + - if_urndis.c + - if_urtw.c + - if_urtwn.c + - if_zyd.c + - ubt.c + - ucycom.c + - udsir.c wakeup/tsleep drivers: - - if_athn_usb.c - if_otus.c - if_run.c - if_upgt.c diff --git a/sys/dev/usb/aubtfwl.c b/sys/dev/usb/aubtfwl.c index dc214677b80..d8d7ebbf63d 100644 --- a/sys/dev/usb/aubtfwl.c +++ b/sys/dev/usb/aubtfwl.c @@ -1,4 +1,4 @@ -/* $NetBSD: aubtfwl.c,v 1.5 2013/05/09 12:44:31 aymeric Exp $ */ +/* $NetBSD: aubtfwl.c,v 1.6 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 2011 Jonathan A. Kollasch @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: aubtfwl.c,v 1.5 2013/05/09 12:44:31 aymeric Exp $"); +__KERNEL_RCSID(0, "$NetBSD: aubtfwl.c,v 1.6 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <dev/usb/usb.h> @@ -47,7 +47,7 @@ static int aubtfwl_detach(device_t, int); static void aubtfwl_attach_hook(device_t); struct aubtfwl_softc { - usbd_device_handle sc_udev; + struct usbd_device *sc_udev; int sc_flags; #define AUBT_IS_AR3012 1 }; @@ -67,11 +67,11 @@ aubtfwl_match(device_t parent, cfdata_t match, void *aux) { const struct usb_attach_arg * const uaa = aux; - if (usb_lookup(ar3k_devs, uaa->vendor, uaa->product)) + if (usb_lookup(ar3k_devs, uaa->uaa_vendor, uaa->uaa_product)) return UMATCH_VENDOR_PRODUCT; - if (usb_lookup(ar3k12_devs, uaa->vendor, uaa->product)) { - return (UGETW(uaa->device->ddesc.bcdDevice) > 1)? + if (usb_lookup(ar3k12_devs, uaa->uaa_vendor, uaa->uaa_product)) { + return (UGETW(uaa->uaa_device->ud_ddesc.bcdDevice) > 1)? UMATCH_NONE : UMATCH_VENDOR_PRODUCT; } @@ -85,10 +85,10 @@ aubtfwl_attach(device_t parent, device_t self, void *aux) struct aubtfwl_softc * const sc = device_private(self); aprint_naive("\n"); aprint_normal("\n"); - sc->sc_udev = uaa->device; + sc->sc_udev = uaa->uaa_device; sc->sc_flags = 0; - if (usb_lookup(ar3k12_devs, uaa->vendor, uaa->product)) + if (usb_lookup(ar3k12_devs, uaa->uaa_vendor, uaa->uaa_product)) sc->sc_flags |= AUBT_IS_AR3012; config_mountroot(self, aubtfwl_attach_hook); @@ -108,9 +108,9 @@ aubtfwl_detach(device_t self, int flags) static int aubtfwl_firmware_load(device_t self, const char *name) { struct aubtfwl_softc * const sc = device_private(self); - usbd_interface_handle iface; - usbd_pipe_handle pipe; - usbd_xfer_handle xfer; + struct usbd_interface *iface; + struct usbd_pipe *pipe; + struct usbd_xfer *xfer; void *buf; usb_device_request_t req; int error = 0; @@ -119,7 +119,7 @@ aubtfwl_firmware_load(device_t self, const char *name) { size_t fwo = 0; uint32_t n; - memset(&req, 0, sizeof req); + memset(&req, 0, sizeof(req)); error = firmware_open("ubt", name, &fwh); if (error != 0) { @@ -149,19 +149,13 @@ aubtfwl_firmware_load(device_t self, const char *name) { goto out_firmware; } - xfer = usbd_alloc_xfer(sc->sc_udev); - if (xfer == NULL) { - aprint_error_dev(self, "failed to alloc xfer\n"); - error = 1; + error = usbd_create_xfer(pipe, AR3K_FIRMWARE_CHUNK_SIZE, 0, 0, &xfer); + if (error) { + aprint_verbose_dev(self, "cannot create xfer(%d)\n", + error); goto out_pipe; } - - buf = usbd_alloc_buffer(xfer, AR3K_FIRMWARE_CHUNK_SIZE); - if (buf == NULL) { - aprint_error_dev(self, "failed to alloc buffer\n"); - error = 1; - goto out_xfer; - } + buf = usbd_get_buffer(xfer); error = firmware_read(fwh, fwo, buf, AR3K_FIRMWARE_HEADER_SIZE); if (error != 0) { @@ -190,9 +184,8 @@ aubtfwl_firmware_load(device_t self, const char *name) { if (error != 0) { break; } - error = usbd_bulk_transfer(xfer, pipe, - USBD_NO_COPY, USBD_DEFAULT_TIMEOUT, - buf, &n, device_xname(self)); + error = usbd_bulk_transfer(xfer, pipe, 0, USBD_DEFAULT_TIMEOUT, + buf, &n); if (error != USBD_NORMAL_COMPLETION) { aprint_error_dev(self, "xfer failed, %s\n", usbd_errstr(error)); @@ -205,7 +198,7 @@ aubtfwl_firmware_load(device_t self, const char *name) { aprint_verbose_dev(self, "firmware load complete\n"); out_xfer: - usbd_free_xfer(xfer); + usbd_destroy_xfer(xfer); out_pipe: usbd_close_pipe(pipe); out_firmware: @@ -219,13 +212,13 @@ aubtfwl_get_state(struct aubtfwl_softc *sc, uint8_t *state) { usb_device_request_t req; int error = 0; - memset(&req, 0, sizeof req); + memset(&req, 0, sizeof(req)); req.bRequest = AR3K_GET_STATE; req.bmRequestType = UT_READ_VENDOR_DEVICE; USETW(req.wValue, 0); USETW(req.wIndex, 0); - USETW(req.wLength, sizeof *state); + USETW(req.wLength, sizeof(*state)); error = usbd_do_request(sc->sc_udev, &req, state); @@ -237,13 +230,13 @@ aubtfwl_get_version(struct aubtfwl_softc *sc, struct ar3k_version *ver) { usb_device_request_t req; int error = 0; - memset(&req, 0, sizeof req); + memset(&req, 0, sizeof(req)); req.bRequest = AR3K_GET_VERSION; req.bmRequestType = UT_READ_VENDOR_DEVICE; USETW(req.wValue, 0); USETW(req.wIndex, 0); - USETW(req.wLength, sizeof *ver); + USETW(req.wLength, sizeof(*ver)); error = usbd_do_request(sc->sc_udev, &req, ver); @@ -262,7 +255,7 @@ aubtfwl_send_command(struct aubtfwl_softc *sc, uByte cmd) { usb_device_request_t req; int error = 0; - memset(&req, 0, sizeof req); + memset(&req, 0, sizeof(req)); req.bRequest = cmd; req.bmRequestType = UT_WRITE_VENDOR_DEVICE; @@ -299,7 +292,7 @@ aubtfwl_attach_hook(device_t self) aprint_verbose_dev(self, "state is 0x%02x\n", state); if (!(state & AR3K_STATE_IS_PATCHED)) { - snprintf(firmware_name, sizeof firmware_name, + snprintf(firmware_name, sizeof(firmware_name), "ar3k/AthrBT_0x%08x.dfu", ver.rom); error = aubtfwl_firmware_load(self, firmware_name); @@ -319,7 +312,7 @@ aubtfwl_attach_hook(device_t self) break; } - snprintf(firmware_name, sizeof firmware_name, + snprintf(firmware_name, sizeof(firmware_name), "ar3k/ramps_0x%08x_%d.dfu", ver.rom, clock); aubtfwl_firmware_load(self, firmware_name); diff --git a/sys/dev/usb/auvitek.c b/sys/dev/usb/auvitek.c index 5262bbfc1cd..5de04fcdead 100644 --- a/sys/dev/usb/auvitek.c +++ b/sys/dev/usb/auvitek.c @@ -1,4 +1,4 @@ -/* $NetBSD: auvitek.c,v 1.9 2014/08/09 13:33:43 jmcneill Exp $ */ +/* $NetBSD: auvitek.c,v 1.10 2016/04/23 10:15:31 skrll Exp $ */ /*- * Copyright (c) 2010 Jared D. McNeill <jmcneill@invisible.ca> @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: auvitek.c,v 1.9 2014/08/09 13:33:43 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: auvitek.c,v 1.10 2016/04/23 10:15:31 skrll Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -79,8 +79,8 @@ auvitek_match(device_t parent, cfdata_t match, void *opaque) unsigned int i; for (i = 0; i < __arraycount(auvitek_devices); i++) { - if (auvitek_devices[i].vendor == uaa->vendor && - auvitek_devices[i].product == uaa->product) + if (auvitek_devices[i].vendor == uaa->uaa_vendor && + auvitek_devices[i].product == uaa->uaa_product) return UMATCH_VENDOR_PRODUCT; } @@ -92,7 +92,7 @@ auvitek_attach(device_t parent, device_t self, void *opaque) { struct auvitek_softc *sc = device_private(self); struct usb_attach_arg *uaa = opaque; - usbd_device_handle dev = uaa->device; + struct usbd_device *dev = uaa->uaa_device; usb_endpoint_descriptor_t *ed; usbd_status err; unsigned int i; @@ -103,11 +103,11 @@ auvitek_attach(device_t parent, device_t self, void *opaque) sc->sc_dev = self; sc->sc_udev = dev; - sc->sc_uport = uaa->port; + sc->sc_uport = uaa->uaa_port; for (i = 0; i < __arraycount(auvitek_devices); i++) { - if (auvitek_devices[i].vendor == uaa->vendor && - auvitek_devices[i].product == uaa->product) + if (auvitek_devices[i].vendor == uaa->uaa_vendor && + auvitek_devices[i].product == uaa->uaa_product) break; } KASSERT(i != __arraycount(auvitek_devices)); @@ -219,24 +219,6 @@ auvitek_attach(device_t parent, device_t self, void *opaque) return; } - for (i = 0; i < AUVITEK_NBULK_XFERS; i++) { - sc->sc_ab.ab_bx[i].bx_sc = sc; - sc->sc_ab.ab_bx[i].bx_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_ab.ab_bx[i].bx_xfer == NULL) { - aprint_error_dev(self, "couldn't allocate xfer\n"); - sc->sc_dying = 1; - return; - } - sc->sc_ab.ab_bx[i].bx_buffer = usbd_alloc_buffer( - sc->sc_ab.ab_bx[i].bx_xfer, AUVITEK_BULK_BUFLEN); - if (sc->sc_ab.ab_bx[i].bx_buffer == NULL) { - aprint_error_dev(self, - "couldn't allocate xfer buffer\n"); - sc->sc_dying = 1; - return; - } - } - aprint_debug_dev(self, "bulk endpoint 0x%02x size %d\n", sc->sc_ab.ab_endpt, AUVITEK_BULK_BUFLEN); @@ -278,7 +260,6 @@ static int auvitek_detach(device_t self, int flags) { struct auvitek_softc *sc = device_private(self); - unsigned int i; sc->sc_dying = 1; @@ -297,11 +278,6 @@ auvitek_detach(device_t self, int flags) mutex_destroy(&sc->sc_subdev_lock); - for (i = 0; i < AUVITEK_NBULK_XFERS; i++) { - if (sc->sc_ab.ab_bx[i].bx_xfer) - usbd_free_xfer(sc->sc_ab.ab_bx[i].bx_xfer); - } - return 0; } diff --git a/sys/dev/usb/auvitek_audio.c b/sys/dev/usb/auvitek_audio.c index 5c84f9c6d8b..1cb18ef68e8 100644 --- a/sys/dev/usb/auvitek_audio.c +++ b/sys/dev/usb/auvitek_audio.c @@ -1,4 +1,4 @@ -/* $NetBSD: auvitek_audio.c,v 1.1 2010/12/27 15:42:11 jmcneill Exp $ */ +/* $NetBSD: auvitek_audio.c,v 1.2 2016/04/23 10:15:31 skrll Exp $ */ /*- * Copyright (c) 2010 Jared D. McNeill <jmcneill@invisible.ca> @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: auvitek_audio.c,v 1.1 2010/12/27 15:42:11 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: auvitek_audio.c,v 1.2 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -57,48 +57,48 @@ int auvitek_audio_attach(struct auvitek_softc *sc) { struct usbif_attach_arg uiaa; - usbd_device_handle udev = sc->sc_udev; - usb_device_descriptor_t *dd = &udev->ddesc; - usbd_interface_handle *ifaces; + struct usbd_device *udev = sc->sc_udev; + usb_device_descriptor_t *dd = &udev->ud_ddesc; + struct usbd_interface **ifaces; int ilocs[USBIFIFCF_NLOCS], nifaces, i; - nifaces = udev->cdesc->bNumInterface; + nifaces = udev->ud_cdesc->bNumInterface; ifaces = kmem_zalloc(nifaces * sizeof(*ifaces), KM_SLEEP); if (ifaces == NULL) { aprint_error_dev(sc->sc_dev, "audio attach: no memory\n"); return ENOMEM; } for (i = 0; i < nifaces; i++) { - ifaces[i] = &udev->ifaces[i]; + ifaces[i] = &udev->ud_ifaces[i]; } - uiaa.device = udev; - uiaa.port = sc->sc_uport; - uiaa.vendor = UGETW(dd->idVendor); - uiaa.product = UGETW(dd->idProduct); - uiaa.release = UGETW(dd->bcdDevice); - uiaa.configno = udev->cdesc->bConfigurationValue; - uiaa.ifaces = ifaces; - uiaa.nifaces = nifaces; - ilocs[USBIFIFCF_PORT] = uiaa.port; - ilocs[USBIFIFCF_VENDOR] = uiaa.vendor; - ilocs[USBIFIFCF_PRODUCT] = uiaa.product; - ilocs[USBIFIFCF_RELEASE] = uiaa.release; - ilocs[USBIFIFCF_CONFIGURATION] = uiaa.configno; + uiaa.uiaa_device = udev; + uiaa.uiaa_port = sc->sc_uport; + uiaa.uiaa_vendor = UGETW(dd->idVendor); + uiaa.uiaa_product = UGETW(dd->idProduct); + uiaa.uiaa_release = UGETW(dd->bcdDevice); + uiaa.uiaa_configno = udev->ud_cdesc->bConfigurationValue; + uiaa.uiaa_ifaces = ifaces; + uiaa.uiaa_nifaces = nifaces; + ilocs[USBIFIFCF_PORT] = uiaa.uiaa_port; + ilocs[USBIFIFCF_VENDOR] = uiaa.uiaa_vendor; + ilocs[USBIFIFCF_PRODUCT] = uiaa.uiaa_product; + ilocs[USBIFIFCF_RELEASE] = uiaa.uiaa_release; + ilocs[USBIFIFCF_CONFIGURATION] = uiaa.uiaa_configno; for (i = 0; i < nifaces; i++) { if (!ifaces[i]) continue; - uiaa.class = ifaces[i]->idesc->bInterfaceClass; - uiaa.subclass = ifaces[i]->idesc->bInterfaceSubClass; - if (uiaa.class != UICLASS_AUDIO) + uiaa.uiaa_class = ifaces[i]->ui_idesc->bInterfaceClass; + uiaa.uiaa_subclass = ifaces[i]->ui_idesc->bInterfaceSubClass; + if (uiaa.uiaa_class != UICLASS_AUDIO) continue; - if (uiaa.subclass != UISUBCLASS_AUDIOCONTROL) + if (uiaa.uiaa_subclass != UISUBCLASS_AUDIOCONTROL) continue; - uiaa.iface = ifaces[i]; - uiaa.proto = ifaces[i]->idesc->bInterfaceProtocol; - uiaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber; - ilocs[USBIFIFCF_INTERFACE] = uiaa.ifaceno; + uiaa.uiaa_iface = ifaces[i]; + uiaa.uiaa_proto = ifaces[i]->ui_idesc->bInterfaceProtocol; + uiaa.uiaa_ifaceno = ifaces[i]->ui_idesc->bInterfaceNumber; + ilocs[USBIFIFCF_INTERFACE] = uiaa.uiaa_ifaceno; sc->sc_audiodev = config_found_sm_loc(sc->sc_dev, "usbifif", ilocs, &uiaa, auvitek_ifprint, config_stdsubmatch); if (sc->sc_audiodev) @@ -131,14 +131,14 @@ auvitek_audio_childdet(struct auvitek_softc *sc, device_t child) static int auvitek_ifprint(void *opaque, const char *pnp) { - struct usbif_attach_arg *uaa = opaque; + struct usbif_attach_arg *uiaa = opaque; if (pnp) return QUIET; - aprint_normal(" port %d", uaa->port); - aprint_normal(" configuration %d", uaa->configno); - aprint_normal(" interface %d", uaa->ifaceno); + aprint_normal(" port %d", uiaa->uiaa_port); + aprint_normal(" configuration %d", uiaa->uiaa_configno); + aprint_normal(" interface %d", uiaa->uiaa_ifaceno); return UNCONF; } diff --git a/sys/dev/usb/auvitek_dtv.c b/sys/dev/usb/auvitek_dtv.c index 28818d1d079..6cfa95909a1 100644 --- a/sys/dev/usb/auvitek_dtv.c +++ b/sys/dev/usb/auvitek_dtv.c @@ -1,4 +1,4 @@ -/* $NetBSD: auvitek_dtv.c,v 1.6 2013/01/22 12:40:42 jmcneill Exp $ */ +/* $NetBSD: auvitek_dtv.c,v 1.7 2016/04/23 10:15:31 skrll Exp $ */ /*- * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: auvitek_dtv.c,v 1.6 2013/01/22 12:40:42 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: auvitek_dtv.c,v 1.7 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -66,13 +66,13 @@ static int auvitek_dtv_start_transfer(void *, static int auvitek_dtv_stop_transfer(void *); static int auvitek_dtv_init_pipes(struct auvitek_softc *); +static int auvitek_dtv_abort_pipes(struct auvitek_softc *); static int auvitek_dtv_close_pipes(struct auvitek_softc *); static int auvitek_dtv_bulk_start(struct auvitek_softc *); static int auvitek_dtv_bulk_start1(struct auvitek_bulk_xfer *); -static void auvitek_dtv_bulk_cb(usbd_xfer_handle, - usbd_private_handle, - usbd_status); +static void auvitek_dtv_bulk_cb(struct usbd_xfer *, void *, + usbd_status); static const struct dtv_hw_if auvitek_dtv_if = { .get_devinfo = auvitek_dtv_get_devinfo, @@ -92,7 +92,7 @@ auvitek_dtv_attach(struct auvitek_softc *sc) auvitek_dtv_rescan(sc, NULL, NULL); - return (sc->sc_dtvdev != NULL); + return sc->sc_dtvdev != NULL; } int @@ -153,7 +153,26 @@ auvitek_dtv_open(void *priv, int flags) if (sc->sc_xc5k == NULL) return ENXIO; - return auvitek_dtv_init_pipes(sc); + int err = auvitek_dtv_init_pipes(sc); + if (err) + return err; + + for (size_t i = 0; i < AUVITEK_NBULK_XFERS; i++) { + sc->sc_ab.ab_bx[i].bx_sc = sc; + err = usbd_create_xfer(sc->sc_ab.ab_pipe, + AUVITEK_BULK_BUFLEN, 0, 0, &sc->sc_ab.ab_bx[i].bx_xfer); + if (err) { + aprint_error_dev(sc->sc_dev, + "couldn't allocate xfer\n"); + sc->sc_dying = 1; + return err; + } + sc->sc_ab.ab_bx[i].bx_buffer = usbd_get_buffer( + sc->sc_ab.ab_bx[i].bx_xfer); + } + + + return 0; } static void @@ -162,6 +181,13 @@ auvitek_dtv_close(void *priv) struct auvitek_softc *sc = priv; auvitek_dtv_stop_transfer(sc); + auvitek_dtv_abort_pipes(sc); + + for (size_t i = 0; i < AUVITEK_NBULK_XFERS; i++) { + if (sc->sc_ab.ab_bx[i].bx_xfer) + usbd_destroy_xfer(sc->sc_ab.ab_bx[i].bx_xfer); + } + auvitek_dtv_close_pipes(sc); sc->sc_dtvsubmitcb = NULL; @@ -272,11 +298,22 @@ auvitek_dtv_init_pipes(struct auvitek_softc *sc) } static int -auvitek_dtv_close_pipes(struct auvitek_softc *sc) +auvitek_dtv_abort_pipes(struct auvitek_softc *sc) { if (sc->sc_ab.ab_pipe != NULL) { KERNEL_LOCK(1, curlwp); usbd_abort_pipe(sc->sc_ab.ab_pipe); + KERNEL_UNLOCK_ONE(curlwp); + } + + return 0; +} + +static int +auvitek_dtv_close_pipes(struct auvitek_softc *sc) +{ + if (sc->sc_ab.ab_pipe != NULL) { + KERNEL_LOCK(1, curlwp); usbd_close_pipe(sc->sc_ab.ab_pipe); KERNEL_UNLOCK_ONE(curlwp); sc->sc_ab.ab_pipe = NULL; @@ -286,7 +323,7 @@ auvitek_dtv_close_pipes(struct auvitek_softc *sc) } static void -auvitek_dtv_bulk_cb(usbd_xfer_handle xfer, usbd_private_handle priv, +auvitek_dtv_bulk_cb(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct auvitek_bulk_xfer *bx = priv; @@ -345,13 +382,10 @@ static int auvitek_dtv_bulk_start1(struct auvitek_bulk_xfer *bx) { struct auvitek_softc *sc = bx->bx_sc; - struct auvitek_bulk *ab = &sc->sc_ab; - int err; + usbd_status err; - usbd_setup_xfer(bx->bx_xfer, ab->ab_pipe, bx, - bx->bx_buffer, AUVITEK_BULK_BUFLEN, - //USBD_SHORT_XFER_OK|USBD_NO_COPY, USBD_NO_TIMEOUT, - USBD_NO_COPY, 100, + usbd_setup_xfer(bx->bx_xfer, bx, bx->bx_buffer, AUVITEK_BULK_BUFLEN, + 0 /* USBD_SHORT_XFER_OK */, 100 /* USBD_NO_TIMEOUT */, auvitek_dtv_bulk_cb); KERNEL_LOCK(1, curlwp); diff --git a/sys/dev/usb/auvitek_video.c b/sys/dev/usb/auvitek_video.c index 500fd998fb8..4dbc771d51f 100644 --- a/sys/dev/usb/auvitek_video.c +++ b/sys/dev/usb/auvitek_video.c @@ -1,4 +1,4 @@ -/* $NetBSD: auvitek_video.c,v 1.6 2011/10/02 19:15:40 jmcneill Exp $ */ +/* $NetBSD: auvitek_video.c,v 1.7 2016/04/23 10:15:31 skrll Exp $ */ /*- * Copyright (c) 2010 Jared D. McNeill <jmcneill@invisible.ca> @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: auvitek_video.c,v 1.6 2011/10/02 19:15:40 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: auvitek_video.c,v 1.7 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -93,8 +93,7 @@ static int auvitek_start_xfer(struct auvitek_softc *); static int auvitek_stop_xfer(struct auvitek_softc *); static int auvitek_isoc_start(struct auvitek_softc *); static int auvitek_isoc_start1(struct auvitek_isoc *); -static void auvitek_isoc_intr(usbd_xfer_handle, - usbd_private_handle, +static void auvitek_isoc_intr(struct usbd_xfer *, void *, usbd_status); static int auvitek_isoc_process(struct auvitek_softc *, uint8_t *, uint32_t); @@ -131,7 +130,7 @@ int auvitek_video_attach(struct auvitek_softc *sc) { snprintf(sc->sc_businfo, sizeof(sc->sc_businfo), "usb:%08x", - sc->sc_udev->cookie.cookie); + sc->sc_udev->ud_cookie.cookie); auvitek_video_rescan(sc, NULL, NULL); @@ -585,20 +584,15 @@ auvitek_start_xfer(struct auvitek_softc *sc) for (i = 0; i < AUVITEK_NISOC_XFERS; i++) { struct auvitek_isoc *isoc = &ax->ax_i[i]; - isoc->i_xfer = usbd_alloc_xfer(sc->sc_udev); - if (isoc->i_xfer == NULL) { + int error = usbd_create_xfer(ax->ax_pipe, + nframes * uframe_len, 0, ax->ax_nframes, &isoc->i_xfer); + if (error) { aprint_error_dev(sc->sc_dev, - "couldn't allocate usb xfer\n"); - return ENOMEM; + "couldn't create usb xfer\n"); + return error; } - isoc->i_buf = usbd_alloc_buffer(isoc->i_xfer, - nframes * uframe_len); - if (isoc->i_buf == NULL) { - aprint_error_dev(sc->sc_dev, - "couldn't allocate usb xfer buffer\n"); - return ENOMEM; - } + isoc->i_buf = usbd_get_buffer(isoc->i_xfer); } return auvitek_isoc_start(sc); @@ -613,15 +607,11 @@ auvitek_stop_xfer(struct auvitek_softc *sc) if (ax->ax_pipe != NULL) { usbd_abort_pipe(ax->ax_pipe); - usbd_close_pipe(ax->ax_pipe); - ax->ax_pipe = NULL; } - for (i = 0; i < AUVITEK_NISOC_XFERS; i++) { struct auvitek_isoc *isoc = &ax->ax_i[i]; if (isoc->i_xfer != NULL) { - usbd_free_buffer(isoc->i_xfer); - usbd_free_xfer(isoc->i_xfer); + usbd_destroy_xfer(isoc->i_xfer); isoc->i_xfer = NULL; } if (isoc->i_frlengths != NULL) { @@ -630,6 +620,10 @@ auvitek_stop_xfer(struct auvitek_softc *sc) isoc->i_frlengths = NULL; } } + if (ax->ax_pipe != NULL) { + usbd_close_pipe(ax->ax_pipe); + ax->ax_pipe = NULL; + } usbd_delay_ms(sc->sc_udev, 1000); err = usbd_set_interface(sc->sc_isoc_iface, 0); @@ -676,11 +670,10 @@ auvitek_isoc_start1(struct auvitek_isoc *isoc) isoc->i_frlengths[i] = ax->ax_uframe_len; usbd_setup_isoc_xfer(isoc->i_xfer, - ax->ax_pipe, isoc, isoc->i_frlengths, ax->ax_nframes, - USBD_NO_COPY | USBD_SHORT_XFER_OK, + USBD_SHORT_XFER_OK, auvitek_isoc_intr); err = usbd_transfer(isoc->i_xfer); @@ -694,7 +687,7 @@ auvitek_isoc_start1(struct auvitek_isoc *isoc) } static void -auvitek_isoc_intr(usbd_xfer_handle xfer, usbd_private_handle priv, +auvitek_isoc_intr(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct auvitek_isoc *isoc = priv; diff --git a/sys/dev/usb/auvitekvar.h b/sys/dev/usb/auvitekvar.h index a943ceea2f6..55da9b266c2 100644 --- a/sys/dev/usb/auvitekvar.h +++ b/sys/dev/usb/auvitekvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: auvitekvar.h,v 1.8 2014/08/09 13:33:43 jmcneill Exp $ */ +/* $NetBSD: auvitekvar.h,v 1.9 2016/04/23 10:15:31 skrll Exp $ */ /*- * Copyright (c) 2010 Jared D. McNeill <jmcneill@invisible.ca> @@ -58,7 +58,7 @@ enum auvitek_board { struct auvitek_isoc { struct auvitek_xfer *i_ax; - usbd_xfer_handle i_xfer; + struct usbd_xfer *i_xfer; uint8_t *i_buf; uint16_t *i_frlengths; }; @@ -74,7 +74,7 @@ struct auvitek_xfer { struct auvitek_softc *ax_sc; int ax_endpt; uint16_t ax_maxpktlen; - usbd_pipe_handle ax_pipe; + struct usbd_pipe * ax_pipe; struct auvitek_isoc ax_i[AUVITEK_NISOC_XFERS]; uint32_t ax_nframes; uint32_t ax_uframe_len; @@ -85,14 +85,14 @@ struct auvitek_xfer { struct auvitek_bulk_xfer { struct auvitek_softc *bx_sc; - usbd_xfer_handle bx_xfer; + struct usbd_xfer *bx_xfer; uint8_t *bx_buffer; }; struct auvitek_bulk { struct auvitek_softc *ab_sc; int ab_endpt; - usbd_pipe_handle ab_pipe; + struct usbd_pipe *ab_pipe; struct auvitek_bulk_xfer ab_bx[AUVITEK_NBULK_XFERS]; bool ab_running; }; @@ -103,10 +103,10 @@ struct auvitek_softc { struct i2c_controller sc_i2c; kmutex_t sc_i2c_lock; - usbd_device_handle sc_udev; + struct usbd_device *sc_udev; int sc_uport; - usbd_interface_handle sc_isoc_iface; - usbd_interface_handle sc_bulk_iface; + struct usbd_interface *sc_isoc_iface; + struct usbd_interface *sc_bulk_iface; char sc_running; char sc_dying; diff --git a/sys/dev/usb/ehci.c b/sys/dev/usb/ehci.c index 2baa1bf7048..31dcf308c04 100644 --- a/sys/dev/usb/ehci.c +++ b/sys/dev/usb/ehci.c @@ -1,4 +1,4 @@ -/* $NetBSD: ehci.c,v 1.248 2016/03/13 07:01:43 skrll Exp $ */ +/* $NetBSD: ehci.c,v 1.249 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 2004-2012 The NetBSD Foundation, Inc. @@ -53,7 +53,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.248 2016/03/13 07:01:43 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.249 2016/04/23 10:15:31 skrll Exp $"); #include "ohci.h" #include "uhci.h" @@ -84,10 +84,10 @@ __KERNEL_RCSID(0, "$NetBSD: ehci.c,v 1.248 2016/03/13 07:01:43 skrll Exp $"); #include <dev/usb/usbhist.h> #include <dev/usb/usb_mem.h> #include <dev/usb/usb_quirks.h> -#include <dev/usb/usbroothub_subr.h> #include <dev/usb/ehcireg.h> #include <dev/usb/ehcivar.h> +#include <dev/usb/usbroothub.h> #ifdef USB_DEBUG @@ -126,121 +126,150 @@ fail: #endif /* EHCI_DEBUG */ #endif /* USB_DEBUG */ +#define DPRINTF(FMT,A,B,C,D) USBHIST_LOG(ehcidebug,FMT,A,B,C,D) +#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(ehcidebug,N,FMT,A,B,C,D) +#define EHCIHIST_FUNC() USBHIST_FUNC() +#define EHCIHIST_CALLED() USBHIST_CALLED(ehcidebug) + struct ehci_pipe { struct usbd_pipe pipe; int nexttoggle; ehci_soft_qh_t *sqh; union { - ehci_soft_qtd_t *qtd; - /* ehci_soft_itd_t *itd; */ - } tail; - union { /* Control pipe */ struct { usb_dma_t reqdma; - } ctl; + } ctrl; /* Interrupt pipe */ struct { u_int length; } intr; - /* Bulk pipe */ - struct { - u_int length; - } bulk; /* Iso pipe */ struct { u_int next_frame; u_int cur_xfers; } isoc; - } u; + }; }; -Static usbd_status ehci_open(usbd_pipe_handle); +typedef TAILQ_HEAD(ex_completeq, ehci_xfer) ex_completeq_t; + +Static usbd_status ehci_open(struct usbd_pipe *); Static void ehci_poll(struct usbd_bus *); Static void ehci_softintr(void *); Static int ehci_intr1(ehci_softc_t *); -Static void ehci_waitintr(ehci_softc_t *, usbd_xfer_handle); -Static void ehci_check_intr(ehci_softc_t *, struct ehci_xfer *); -Static void ehci_check_qh_intr(ehci_softc_t *, struct ehci_xfer *); -Static void ehci_check_itd_intr(ehci_softc_t *, struct ehci_xfer *); -Static void ehci_idone(struct ehci_xfer *); +Static void ehci_waitintr(ehci_softc_t *, struct usbd_xfer *); +Static void ehci_check_qh_intr(ehci_softc_t *, struct ehci_xfer *, + ex_completeq_t *); +Static void ehci_check_itd_intr(ehci_softc_t *, struct ehci_xfer *, + ex_completeq_t *); +Static void ehci_check_sitd_intr(ehci_softc_t *, struct ehci_xfer *, + ex_completeq_t *); +Static void ehci_idone(struct ehci_xfer *, ex_completeq_t *); Static void ehci_timeout(void *); Static void ehci_timeout_task(void *); Static void ehci_intrlist_timeout(void *); Static void ehci_doorbell(void *); Static void ehci_pcd(void *); -Static usbd_status ehci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t); -Static void ehci_freem(struct usbd_bus *, usb_dma_t *); +Static struct usbd_xfer * + ehci_allocx(struct usbd_bus *, unsigned int); +Static void ehci_freex(struct usbd_bus *, struct usbd_xfer *); -Static usbd_xfer_handle ehci_allocx(struct usbd_bus *); -Static void ehci_freex(struct usbd_bus *, usbd_xfer_handle); Static void ehci_get_lock(struct usbd_bus *, kmutex_t **); - -Static usbd_status ehci_root_ctrl_transfer(usbd_xfer_handle); -Static usbd_status ehci_root_ctrl_start(usbd_xfer_handle); -Static void ehci_root_ctrl_abort(usbd_xfer_handle); -Static void ehci_root_ctrl_close(usbd_pipe_handle); -Static void ehci_root_ctrl_done(usbd_xfer_handle); - -Static usbd_status ehci_root_intr_transfer(usbd_xfer_handle); -Static usbd_status ehci_root_intr_start(usbd_xfer_handle); -Static void ehci_root_intr_abort(usbd_xfer_handle); -Static void ehci_root_intr_close(usbd_pipe_handle); -Static void ehci_root_intr_done(usbd_xfer_handle); - -Static usbd_status ehci_device_ctrl_transfer(usbd_xfer_handle); -Static usbd_status ehci_device_ctrl_start(usbd_xfer_handle); -Static void ehci_device_ctrl_abort(usbd_xfer_handle); -Static void ehci_device_ctrl_close(usbd_pipe_handle); -Static void ehci_device_ctrl_done(usbd_xfer_handle); - -Static usbd_status ehci_device_bulk_transfer(usbd_xfer_handle); -Static usbd_status ehci_device_bulk_start(usbd_xfer_handle); -Static void ehci_device_bulk_abort(usbd_xfer_handle); -Static void ehci_device_bulk_close(usbd_pipe_handle); -Static void ehci_device_bulk_done(usbd_xfer_handle); - -Static usbd_status ehci_device_intr_transfer(usbd_xfer_handle); -Static usbd_status ehci_device_intr_start(usbd_xfer_handle); -Static void ehci_device_intr_abort(usbd_xfer_handle); -Static void ehci_device_intr_close(usbd_pipe_handle); -Static void ehci_device_intr_done(usbd_xfer_handle); - -Static usbd_status ehci_device_isoc_transfer(usbd_xfer_handle); -Static usbd_status ehci_device_isoc_start(usbd_xfer_handle); -Static void ehci_device_isoc_abort(usbd_xfer_handle); -Static void ehci_device_isoc_close(usbd_pipe_handle); -Static void ehci_device_isoc_done(usbd_xfer_handle); - -Static void ehci_device_clear_toggle(usbd_pipe_handle pipe); -Static void ehci_noop(usbd_pipe_handle pipe); +Static int ehci_roothub_ctrl(struct usbd_bus *, + usb_device_request_t *, void *, int); + +Static usbd_status ehci_root_intr_transfer(struct usbd_xfer *); +Static usbd_status ehci_root_intr_start(struct usbd_xfer *); +Static void ehci_root_intr_abort(struct usbd_xfer *); +Static void ehci_root_intr_close(struct usbd_pipe *); +Static void ehci_root_intr_done(struct usbd_xfer *); + +Static int ehci_device_ctrl_init(struct usbd_xfer *); +Static void ehci_device_ctrl_fini(struct usbd_xfer *); +Static usbd_status ehci_device_ctrl_transfer(struct usbd_xfer *); +Static usbd_status ehci_device_ctrl_start(struct usbd_xfer *); +Static void ehci_device_ctrl_abort(struct usbd_xfer *); +Static void ehci_device_ctrl_close(struct usbd_pipe *); +Static void ehci_device_ctrl_done(struct usbd_xfer *); + +Static int ehci_device_bulk_init(struct usbd_xfer *); +Static void ehci_device_bulk_fini(struct usbd_xfer *); +Static usbd_status ehci_device_bulk_transfer(struct usbd_xfer *); +Static usbd_status ehci_device_bulk_start(struct usbd_xfer *); +Static void ehci_device_bulk_abort(struct usbd_xfer *); +Static void ehci_device_bulk_close(struct usbd_pipe *); +Static void ehci_device_bulk_done(struct usbd_xfer *); + +Static int ehci_device_intr_init(struct usbd_xfer *); +Static void ehci_device_intr_fini(struct usbd_xfer *); +Static usbd_status ehci_device_intr_transfer(struct usbd_xfer *); +Static usbd_status ehci_device_intr_start(struct usbd_xfer *); +Static void ehci_device_intr_abort(struct usbd_xfer *); +Static void ehci_device_intr_close(struct usbd_pipe *); +Static void ehci_device_intr_done(struct usbd_xfer *); + +Static int ehci_device_isoc_init(struct usbd_xfer *); +Static void ehci_device_isoc_fini(struct usbd_xfer *); +Static usbd_status ehci_device_isoc_transfer(struct usbd_xfer *); +Static void ehci_device_isoc_abort(struct usbd_xfer *); +Static void ehci_device_isoc_close(struct usbd_pipe *); +Static void ehci_device_isoc_done(struct usbd_xfer *); + +Static int ehci_device_fs_isoc_init(struct usbd_xfer *); +Static void ehci_device_fs_isoc_fini(struct usbd_xfer *); +Static usbd_status ehci_device_fs_isoc_transfer(struct usbd_xfer *); +Static void ehci_device_fs_isoc_abort(struct usbd_xfer *); +Static void ehci_device_fs_isoc_close(struct usbd_pipe *); +Static void ehci_device_fs_isoc_done(struct usbd_xfer *); + +Static void ehci_device_clear_toggle(struct usbd_pipe *); +Static void ehci_noop(struct usbd_pipe *); Static void ehci_disown(ehci_softc_t *, int, int); -Static ehci_soft_qh_t *ehci_alloc_sqh(ehci_softc_t *); +Static ehci_soft_qh_t * ehci_alloc_sqh(ehci_softc_t *); Static void ehci_free_sqh(ehci_softc_t *, ehci_soft_qh_t *); -Static ehci_soft_qtd_t *ehci_alloc_sqtd(ehci_softc_t *); +Static ehci_soft_qtd_t *ehci_alloc_sqtd(ehci_softc_t *); Static void ehci_free_sqtd(ehci_softc_t *, ehci_soft_qtd_t *); -Static usbd_status ehci_alloc_sqtd_chain(struct ehci_pipe *, - ehci_softc_t *, int, int, usbd_xfer_handle, - ehci_soft_qtd_t **, ehci_soft_qtd_t **); -Static void ehci_free_sqtd_chain(ehci_softc_t *, ehci_soft_qtd_t *, - ehci_soft_qtd_t *); +Static int ehci_alloc_sqtd_chain(ehci_softc_t *, + struct usbd_xfer *, int, int, ehci_soft_qtd_t **); +Static void ehci_free_sqtds(ehci_softc_t *, struct ehci_xfer *); + +Static void ehci_reset_sqtd_chain(ehci_softc_t *, struct usbd_xfer *, + int, int, int *, ehci_soft_qtd_t **); +Static void ehci_append_sqtd(ehci_soft_qtd_t *, ehci_soft_qtd_t *); + +Static ehci_soft_itd_t *ehci_alloc_itd(ehci_softc_t *); +Static ehci_soft_sitd_t * + ehci_alloc_sitd(ehci_softc_t *); -Static ehci_soft_itd_t *ehci_alloc_itd(ehci_softc_t *sc); -Static void ehci_free_itd(ehci_softc_t *sc, ehci_soft_itd_t *itd); -Static void ehci_rem_free_itd_chain(ehci_softc_t *sc, - struct ehci_xfer *exfer); -Static void ehci_abort_isoc_xfer(usbd_xfer_handle xfer, - usbd_status status); +Static void ehci_remove_itd_chain(ehci_softc_t *, ehci_soft_itd_t *); +Static void ehci_remove_sitd_chain(ehci_softc_t *, ehci_soft_sitd_t *); +Static void ehci_free_itd_chain(ehci_softc_t *, ehci_soft_itd_t *); +Static void ehci_free_sitd_chain(ehci_softc_t *, ehci_soft_sitd_t *); + +static inline void +ehci_free_itd_locked(ehci_softc_t *sc, ehci_soft_itd_t *itd) +{ + + LIST_INSERT_HEAD(&sc->sc_freeitds, itd, free_list); +} + +static inline void +ehci_free_sitd_locked(ehci_softc_t *sc, ehci_soft_sitd_t *sitd) +{ + + LIST_INSERT_HEAD(&sc->sc_freesitds, sitd, free_list); +} -Static usbd_status ehci_device_request(usbd_xfer_handle xfer); +Static void ehci_abort_isoc_xfer(struct usbd_xfer *, usbd_status); Static usbd_status ehci_device_setintr(ehci_softc_t *, ehci_soft_qh_t *, - int ival); + int); Static void ehci_add_qh(ehci_softc_t *, ehci_soft_qh_t *, ehci_soft_qh_t *); @@ -249,8 +278,8 @@ Static void ehci_rem_qh(ehci_softc_t *, ehci_soft_qh_t *, Static void ehci_set_qh_qtd(ehci_soft_qh_t *, ehci_soft_qtd_t *); Static void ehci_sync_hc(ehci_softc_t *); -Static void ehci_close_pipe(usbd_pipe_handle, ehci_soft_qh_t *); -Static void ehci_abort_xfer(usbd_xfer_handle, usbd_status); +Static void ehci_close_pipe(struct usbd_pipe *, ehci_soft_qh_t *); +Static void ehci_abort_xfer(struct usbd_xfer *, usbd_status); #ifdef EHCI_DEBUG Static ehci_softc_t *theehci; @@ -263,88 +292,98 @@ Static void ehci_dump_sqtds(ehci_soft_qtd_t *); Static void ehci_dump_sqtd(ehci_soft_qtd_t *); Static void ehci_dump_qtd(ehci_qtd_t *); Static void ehci_dump_sqh(ehci_soft_qh_t *); -Static void ehci_dump_sitd(struct ehci_soft_itd *itd); +Static void ehci_dump_sitd(struct ehci_soft_itd *); +Static void ehci_dump_itds(ehci_soft_itd_t *); Static void ehci_dump_itd(struct ehci_soft_itd *); Static void ehci_dump_exfer(struct ehci_xfer *); #endif #define EHCI_NULL htole32(EHCI_LINK_TERMINATE) -#define EHCI_INTR_ENDPT 1 +static inline void +ehci_add_intr_list(ehci_softc_t *sc, struct ehci_xfer *ex) +{ -#define ehci_add_intr_list(sc, ex) \ - TAILQ_INSERT_TAIL(&(sc)->sc_intrhead, (ex), inext); -#define ehci_del_intr_list(sc, ex) \ - do { \ - TAILQ_REMOVE(&sc->sc_intrhead, (ex), inext); \ - (ex)->inext.tqe_prev = NULL; \ - } while (0) -#define ehci_active_intr_list(ex) ((ex)->inext.tqe_prev != NULL) + TAILQ_INSERT_TAIL(&sc->sc_intrhead, ex, ex_next); +} -Static const struct usbd_bus_methods ehci_bus_methods = { - .open_pipe = ehci_open, - .soft_intr = ehci_softintr, - .do_poll = ehci_poll, - .allocm = ehci_allocm, - .freem = ehci_freem, - .allocx = ehci_allocx, - .freex = ehci_freex, - .get_lock = ehci_get_lock, - .new_device = NULL, -}; +static inline void +ehci_del_intr_list(ehci_softc_t *sc, struct ehci_xfer *ex) +{ + + TAILQ_REMOVE(&sc->sc_intrhead, ex, ex_next); +} -Static const struct usbd_pipe_methods ehci_root_ctrl_methods = { - .transfer = ehci_root_ctrl_transfer, - .start = ehci_root_ctrl_start, - .abort = ehci_root_ctrl_abort, - .close = ehci_root_ctrl_close, - .cleartoggle = ehci_noop, - .done = ehci_root_ctrl_done, +Static const struct usbd_bus_methods ehci_bus_methods = { + .ubm_open = ehci_open, + .ubm_softint = ehci_softintr, + .ubm_dopoll = ehci_poll, + .ubm_allocx = ehci_allocx, + .ubm_freex = ehci_freex, + .ubm_getlock = ehci_get_lock, + .ubm_rhctrl = ehci_roothub_ctrl, }; Static const struct usbd_pipe_methods ehci_root_intr_methods = { - .transfer = ehci_root_intr_transfer, - .start = ehci_root_intr_start, - .abort = ehci_root_intr_abort, - .close = ehci_root_intr_close, - .cleartoggle = ehci_noop, - .done = ehci_root_intr_done, + .upm_transfer = ehci_root_intr_transfer, + .upm_start = ehci_root_intr_start, + .upm_abort = ehci_root_intr_abort, + .upm_close = ehci_root_intr_close, + .upm_cleartoggle = ehci_noop, + .upm_done = ehci_root_intr_done, }; Static const struct usbd_pipe_methods ehci_device_ctrl_methods = { - .transfer = ehci_device_ctrl_transfer, - .start = ehci_device_ctrl_start, - .abort = ehci_device_ctrl_abort, - .close = ehci_device_ctrl_close, - .cleartoggle = ehci_noop, - .done = ehci_device_ctrl_done, + .upm_init = ehci_device_ctrl_init, + .upm_fini = ehci_device_ctrl_fini, + .upm_transfer = ehci_device_ctrl_transfer, + .upm_start = ehci_device_ctrl_start, + .upm_abort = ehci_device_ctrl_abort, + .upm_close = ehci_device_ctrl_close, + .upm_cleartoggle = ehci_noop, + .upm_done = ehci_device_ctrl_done, }; Static const struct usbd_pipe_methods ehci_device_intr_methods = { - .transfer = ehci_device_intr_transfer, - .start = ehci_device_intr_start, - .abort = ehci_device_intr_abort, - .close = ehci_device_intr_close, - .cleartoggle = ehci_device_clear_toggle, - .done = ehci_device_intr_done, + .upm_init = ehci_device_intr_init, + .upm_fini = ehci_device_intr_fini, + .upm_transfer = ehci_device_intr_transfer, + .upm_start = ehci_device_intr_start, + .upm_abort = ehci_device_intr_abort, + .upm_close = ehci_device_intr_close, + .upm_cleartoggle = ehci_device_clear_toggle, + .upm_done = ehci_device_intr_done, }; Static const struct usbd_pipe_methods ehci_device_bulk_methods = { - .transfer = ehci_device_bulk_transfer, - .start = ehci_device_bulk_start, - .abort = ehci_device_bulk_abort, - .close = ehci_device_bulk_close, - .cleartoggle = ehci_device_clear_toggle, - .done = ehci_device_bulk_done, + .upm_init = ehci_device_bulk_init, + .upm_fini = ehci_device_bulk_fini, + .upm_transfer = ehci_device_bulk_transfer, + .upm_start = ehci_device_bulk_start, + .upm_abort = ehci_device_bulk_abort, + .upm_close = ehci_device_bulk_close, + .upm_cleartoggle = ehci_device_clear_toggle, + .upm_done = ehci_device_bulk_done, }; Static const struct usbd_pipe_methods ehci_device_isoc_methods = { - .transfer = ehci_device_isoc_transfer, - .start = ehci_device_isoc_start, - .abort = ehci_device_isoc_abort, - .close = ehci_device_isoc_close, - .cleartoggle = ehci_noop, - .done = ehci_device_isoc_done, + .upm_init = ehci_device_isoc_init, + .upm_fini = ehci_device_isoc_fini, + .upm_transfer = ehci_device_isoc_transfer, + .upm_abort = ehci_device_isoc_abort, + .upm_close = ehci_device_isoc_close, + .upm_cleartoggle = ehci_noop, + .upm_done = ehci_device_isoc_done, +}; + +Static const struct usbd_pipe_methods ehci_device_fs_isoc_methods = { + .upm_init = ehci_device_fs_isoc_init, + .upm_fini = ehci_device_fs_isoc_fini, + .upm_transfer = ehci_device_fs_isoc_transfer, + .upm_abort = ehci_device_fs_isoc_abort, + .upm_close = ehci_device_fs_isoc_close, + .upm_cleartoggle = ehci_noop, + .upm_done = ehci_device_fs_isoc_done, }; static const uint8_t revbits[EHCI_MAX_POLLRATE] = { @@ -358,16 +397,16 @@ static const uint8_t revbits[EHCI_MAX_POLLRATE] = { 0x07,0x47,0x27,0x67,0x17,0x57,0x37,0x77,0x0f,0x4f,0x2f,0x6f,0x1f,0x5f,0x3f,0x7f, }; -usbd_status +int ehci_init(ehci_softc_t *sc) { - u_int32_t vers, sparams, cparams, hcr; + uint32_t vers, sparams, cparams, hcr; u_int i; usbd_status err; ehci_soft_qh_t *sqh; u_int ncomp; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); #ifdef EHCI_DEBUG theehci = sc; #endif @@ -391,10 +430,10 @@ ehci_init(ehci_softc_t *sc) vers = EREAD2(sc, EHCI_HCIVERSION); aprint_verbose("%s: EHCI version %x.%x\n", device_xname(sc->sc_dev), - vers >> 8, vers & 0xff); + vers >> 8, vers & 0xff); sparams = EREAD4(sc, EHCI_HCSPARAMS); - USBHIST_LOG(ehcidebug, "sparams=%#x", sparams, 0, 0, 0); + DPRINTF("sparams=%#x", sparams, 0, 0, 0); sc->sc_npcomp = EHCI_HCS_N_PCC(sparams); ncomp = EHCI_HCS_N_CC(sparams); if (ncomp != sc->sc_ncomp) { @@ -418,22 +457,28 @@ ehci_init(ehci_softc_t *sc) aprint_normal("\n"); } sc->sc_noport = EHCI_HCS_N_PORTS(sparams); - cparams = EREAD4(sc, EHCI_HCCPARAMS); - USBHIST_LOG(ehcidebug, "cparams=%#x", cparams, 0, 0, 0); sc->sc_hasppc = EHCI_HCS_PPC(sparams); + cparams = EREAD4(sc, EHCI_HCCPARAMS); + DPRINTF("cparams=%#x", cparams, 0, 0, 0); + if (EHCI_HCC_64BIT(cparams)) { /* MUST clear segment register if 64 bit capable. */ EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0); } - sc->sc_bus.usbrev = USBREV_2_0; + if (cparams & EHCI_HCC_IST_FULLFRAME) { + sc->sc_istthreshold = 0; + } else { + sc->sc_istthreshold = EHCI_HCC_GET_IST_THRESHOLD(cparams); + } - usb_setup_reserve(sc->sc_dev, &sc->sc_dma_reserve, sc->sc_bus.dmatag, - USB_MEM_RESERVE); + sc->sc_bus.ub_revision = USBREV_2_0; + sc->sc_bus.ub_usedma = true; + sc->sc_bus.ub_dmaflags = USBMALLOC_MULTISEG; /* Reset the controller */ - USBHIST_LOG(ehcidebug, "resetting", 0, 0, 0, 0); + DPRINTF("resetting", 0, 0, 0, 0); EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */ usb_delay_ms(&sc->sc_bus, 1); EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET); @@ -445,7 +490,7 @@ ehci_init(ehci_softc_t *sc) } if (hcr) { aprint_error("%s: reset timeout\n", device_xname(sc->sc_dev)); - return (USBD_IOERROR); + return EIO; } if (sc->sc_vendor_init) sc->sc_vendor_init(sc); @@ -458,13 +503,13 @@ ehci_init(ehci_softc_t *sc) case 0: sc->sc_flsize = 1024; break; case 1: sc->sc_flsize = 512; break; case 2: sc->sc_flsize = 256; break; - case 3: return (USBD_IOERROR); + case 3: return EIO; } err = usb_allocmem(&sc->sc_bus, sc->sc_flsize * sizeof(ehci_link_t), EHCI_FLALIGN_ALIGN, &sc->sc_fldma); if (err) - return (err); - USBHIST_LOG(ehcidebug, "flsize=%d", sc->sc_flsize, 0, 0, 0); + return err; + DPRINTF("flsize=%d", sc->sc_flsize, 0, 0, 0); sc->sc_flist = KERNADDR(&sc->sc_fldma, 0); for (i = 0; i < sc->sc_flsize; i++) { @@ -478,11 +523,12 @@ ehci_init(ehci_softc_t *sc) if (sc->sc_softitds == NULL) return ENOMEM; LIST_INIT(&sc->sc_freeitds); + LIST_INIT(&sc->sc_freesitds); TAILQ_INIT(&sc->sc_intrhead); /* Set up the bus struct. */ - sc->sc_bus.methods = &ehci_bus_methods; - sc->sc_bus.pipe_size = sizeof(struct ehci_pipe); + sc->sc_bus.ub_methods = &ehci_bus_methods; + sc->sc_bus.ub_pipesize= sizeof(struct ehci_pipe); sc->sc_eintrs = EHCI_NORMAL_INTRS; @@ -493,7 +539,7 @@ ehci_init(ehci_softc_t *sc) for (i = 0; i < EHCI_INTRQHS; i++) { sqh = ehci_alloc_sqh(sc); if (sqh == NULL) { - err = USBD_NOMEM; + err = ENOMEM; goto bad1; } sc->sc_islots[i].sqh = sqh; @@ -536,7 +582,7 @@ ehci_init(ehci_softc_t *sc) /* Allocate dummy QH that starts the async list. */ sqh = ehci_alloc_sqh(sc); if (sqh == NULL) { - err = USBD_NOMEM; + err = ENOMEM; goto bad1; } /* Fill the QH */ @@ -554,9 +600,9 @@ ehci_init(ehci_softc_t *sc) usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); #ifdef EHCI_DEBUG - USBHIST_LOGN(ehcidebug, 5, "--- dump start ---", 0, 0, 0, 0); + DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); ehci_dump_sqh(sqh); - USBHIST_LOGN(ehcidebug, 5, "--- dump end ---", 0, 0, 0, 0); + DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); #endif /* Point to async list */ @@ -584,14 +630,14 @@ ehci_init(ehci_softc_t *sc) } if (hcr) { aprint_error("%s: run timeout\n", device_xname(sc->sc_dev)); - return (USBD_IOERROR); + return EIO; } /* Enable interrupts */ - USBHIST_LOG(ehcidebug, "enabling interupts", 0, 0, 0, 0); + DPRINTF("enabling interupts", 0, 0, 0, 0); EOWRITE4(sc, EHCI_USBINTR, sc->sc_eintrs); - return (USBD_NORMAL_COMPLETION); + return 0; #if 0 bad2: @@ -599,7 +645,7 @@ ehci_init(ehci_softc_t *sc) #endif bad1: usb_freemem(&sc->sc_bus, &sc->sc_fldma); - return (err); + return err; } int @@ -608,7 +654,7 @@ ehci_intr(void *v) ehci_softc_t *sc = v; int ret = 0; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); if (sc == NULL) return 0; @@ -619,15 +665,12 @@ ehci_intr(void *v) goto done; /* If we get an interrupt while polling, then just ignore it. */ - if (sc->sc_bus.use_polling) { - u_int32_t intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS)); + if (sc->sc_bus.ub_usepolling) { + uint32_t intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS)); if (intrs) EOWRITE4(sc, EHCI_USBSTS, intrs); /* Acknowledge */ -#ifdef DIAGNOSTIC - USBHIST_LOGN(ehcidebug, 16, - "ignored interrupt while polling", 0, 0, 0, 0); -#endif + DPRINTFN(16, "ignored interrupt while polling", 0, 0, 0, 0); goto done; } @@ -641,34 +684,33 @@ done: Static int ehci_intr1(ehci_softc_t *sc) { - u_int32_t intrs, eintrs; + uint32_t intrs, eintrs; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); /* In case the interrupt occurs before initialization has completed. */ if (sc == NULL) { #ifdef DIAGNOSTIC printf("ehci_intr1: sc == NULL\n"); #endif - return (0); + return 0; } KASSERT(mutex_owned(&sc->sc_intr_lock)); intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS)); if (!intrs) - return (0); + return 0; eintrs = intrs & sc->sc_eintrs; - USBHIST_LOG(ehcidebug, "sc=%p intrs=%#x(%#x) eintrs=%#x", - sc, intrs, EOREAD4(sc, EHCI_USBSTS), eintrs); + DPRINTF("sc=%p intrs=%#x(%#x) eintrs=%#x", sc, intrs, + EOREAD4(sc, EHCI_USBSTS), eintrs); if (!eintrs) - return (0); + return 0; EOWRITE4(sc, EHCI_USBSTS, intrs); /* Acknowledge */ - sc->sc_bus.no_intrs++; if (eintrs & EHCI_STS_IAA) { - USBHIST_LOG(ehcidebug, "door bell", 0, 0, 0, 0); + DPRINTF("door bell", 0, 0, 0, 0); kpreempt_disable(); KASSERT(sc->sc_doorbell_si != NULL); softint_schedule(sc->sc_doorbell_si); @@ -676,7 +718,7 @@ ehci_intr1(ehci_softc_t *sc) eintrs &= ~EHCI_STS_IAA; } if (eintrs & (EHCI_STS_INT | EHCI_STS_ERRINT)) { - USBHIST_LOG(ehcidebug, "INT=%d ERRINT=%d", + DPRINTF("INT=%d ERRINT=%d", eintrs & EHCI_STS_INT ? 1 : 0, eintrs & EHCI_STS_ERRINT ? 1 : 0, 0, 0); usb_schedsoftintr(&sc->sc_bus); @@ -703,7 +745,7 @@ ehci_intr1(ehci_softc_t *sc) device_xname(sc->sc_dev), eintrs); } - return (1); + return 1; } Static void @@ -720,11 +762,11 @@ Static void ehci_pcd(void *addr) { ehci_softc_t *sc = addr; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; u_char *p; int i, m; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); mutex_enter(&sc->sc_lock); xfer = sc->sc_intrxfer; @@ -734,19 +776,18 @@ ehci_pcd(void *addr) goto done; } - p = KERNADDR(&xfer->dmabuf, 0); - m = min(sc->sc_noport, xfer->length * 8 - 1); - memset(p, 0, xfer->length); + p = xfer->ux_buf; + m = min(sc->sc_noport, xfer->ux_length * 8 - 1); + memset(p, 0, xfer->ux_length); for (i = 1; i <= m; i++) { /* Pick out CHANGE bits from the status reg. */ if (EOREAD4(sc, EHCI_PORTSC(i)) & EHCI_PS_CLEAR) p[i/8] |= 1 << (i%8); if (i % 8 == 7) - USBHIST_LOG(ehcidebug, "change(%d)=0x%02x", i / 8, - p[i/8], 0, 0); + DPRINTF("change(%d)=0x%02x", i / 8, p[i/8], 0, 0); } - xfer->actlen = xfer->length; - xfer->status = USBD_NORMAL_COMPLETION; + xfer->ux_actlen = xfer->ux_length; + xfer->ux_status = USBD_NORMAL_COMPLETION; usb_transfer_complete(xfer); @@ -758,12 +799,15 @@ Static void ehci_softintr(void *v) { struct usbd_bus *bus = v; - ehci_softc_t *sc = bus->hci_private; + ehci_softc_t *sc = EHCI_BUS2SC(bus); struct ehci_xfer *ex, *nextex; - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + + ex_completeq_t cq; + TAILQ_INIT(&cq); /* * The only explanation I can think of for why EHCI is as brain dead @@ -771,9 +815,38 @@ ehci_softintr(void *v) * An interrupt just tells us that something is done, we have no * clue what, so we need to scan through all active transfers. :-( */ - for (ex = TAILQ_FIRST(&sc->sc_intrhead); ex; ex = nextex) { - nextex = TAILQ_NEXT(ex, inext); - ehci_check_intr(sc, ex); + + /* + * ehci_idone will remove transfer from sc->sc_intrhead if it's + * complete and add to our cq list + * + */ + TAILQ_FOREACH_SAFE(ex, &sc->sc_intrhead, ex_next, nextex) { + switch (ex->ex_type) { + case EX_CTRL: + case EX_BULK: + case EX_INTR: + ehci_check_qh_intr(sc, ex, &cq); + break; + case EX_ISOC: + ehci_check_itd_intr(sc, ex, &cq); + break; + case EX_FS_ISOC: + ehci_check_sitd_intr(sc, ex, &cq); + break; + default: + KASSERT(false); + } + + } + + /* + * We abuse ex_next for the interrupt and complete lists and + * interrupt transfers will get re-added here so use + * the _SAFE version of TAILQ_FOREACH. + */ + TAILQ_FOREACH_SAFE(ex, &cq, ex_next, nextex) { + usb_transfer_complete(&ex->ex_xfer); } /* Schedule a callout to catch any dropped transactions. */ @@ -788,48 +861,26 @@ ehci_softintr(void *v) } } -/* Check for an interrupt. */ Static void -ehci_check_intr(ehci_softc_t *sc, struct ehci_xfer *ex) +ehci_check_qh_intr(ehci_softc_t *sc, struct ehci_xfer *ex, ex_completeq_t *cq) { - int attr; + ehci_soft_qtd_t *sqtd, *fsqtd, *lsqtd; + uint32_t status; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); - USBHIST_LOG(ehcidebug, "ex = %p", ex, 0, 0, 0); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); - attr = ex->xfer.pipe->endpoint->edesc->bmAttributes; - if (UE_GET_XFERTYPE(attr) == UE_ISOCHRONOUS) - ehci_check_itd_intr(sc, ex); - else - ehci_check_qh_intr(sc, ex); - - return; -} - -Static void -ehci_check_qh_intr(ehci_softc_t *sc, struct ehci_xfer *ex) -{ - ehci_soft_qtd_t *sqtd, *lsqtd; - __uint32_t status; - - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); - - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); - - if (ex->sqtdstart == NULL) { - printf("ehci_check_qh_intr: not valid sqtd\n"); - return; + if (ex->ex_type == EX_CTRL) { + fsqtd = ex->ex_setup; + lsqtd = ex->ex_status; + } else { + fsqtd = ex->ex_sqtdstart; + lsqtd = ex->ex_sqtdend; } + KASSERTMSG(fsqtd != NULL && lsqtd != NULL, + "xfer %p xt %d fsqtd %p lsqtd %p", ex, ex->ex_type, fsqtd, lsqtd); - lsqtd = ex->sqtdend; -#ifdef DIAGNOSTIC - if (lsqtd == NULL) { - printf("ehci_check_qh_intr: lsqtd==0\n"); - return; - } -#endif /* * If the last TD is still active we need to check whether there * is an error somewhere in the middle, or whether there was a @@ -844,8 +895,10 @@ ehci_check_qh_intr(ehci_softc_t *sc, struct ehci_xfer *ex) lsqtd->offs + offsetof(ehci_qtd_t, qtd_status), sizeof(lsqtd->qtd.qtd_status), BUS_DMASYNC_PREREAD); if (status & EHCI_QTD_ACTIVE) { - USBHIST_LOGN(ehcidebug, 10, "active ex=%p", ex, 0, 0, 0); - for (sqtd = ex->sqtdstart; sqtd != lsqtd; sqtd=sqtd->nextqtd) { + DPRINTFN(10, "active ex=%p", ex, 0, 0, 0); + + /* last qTD has already been checked */ + for (sqtd = fsqtd; sqtd != lsqtd; sqtd = sqtd->nextqtd) { usb_syncmem(&sqtd->dma, sqtd->offs + offsetof(ehci_qtd_t, qtd_status), sizeof(sqtd->qtd.qtd_status), @@ -862,11 +915,6 @@ ehci_check_qh_intr(ehci_softc_t *sc, struct ehci_xfer *ex) goto done; /* Handle short packets */ if (EHCI_QTD_GET_BYTES(status) != 0) { - usbd_pipe_handle pipe = ex->xfer.pipe; - usb_endpoint_descriptor_t *ed = - pipe->endpoint->edesc; - uint8_t xt = UE_GET_XFERTYPE(ed->bmAttributes); - /* * If we get here for a control transfer then * we need to let the hardware complete the @@ -875,61 +923,52 @@ ehci_check_qh_intr(ehci_softc_t *sc, struct ehci_xfer *ex) * * Otherwise, we're done. */ - if (xt == UE_CONTROL) { + if (ex->ex_type == EX_CTRL) { break; } goto done; } } - USBHIST_LOGN(ehcidebug, 10, "ex=%p std=%p still active", - ex, ex->sqtdstart, 0, 0); + DPRINTFN(10, "ex=%p std=%p still active", ex, ex->ex_sqtdstart, + 0, 0); #ifdef EHCI_DEBUG - USBHIST_LOGN(ehcidebug, 5, "--- still active start ---", 0, 0, 0, 0); - ehci_dump_sqtds(ex->sqtdstart); - USBHIST_LOGN(ehcidebug, 5, "--- still active end ---", 0, 0, 0, 0); + DPRINTFN(5, "--- still active start ---", 0, 0, 0, 0); + ehci_dump_sqtds(ex->ex_sqtdstart); + DPRINTFN(5, "--- still active end ---", 0, 0, 0, 0); #endif - return; } done: - USBHIST_LOGN(ehcidebug, 10, "ex=%p done", ex, 0, 0, 0); - callout_stop(&ex->xfer.timeout_handle); - ehci_idone(ex); + DPRINTFN(10, "ex=%p done", ex, 0, 0, 0); + callout_stop(&ex->ex_xfer.ux_callout); + ehci_idone(ex, cq); } Static void -ehci_check_itd_intr(ehci_softc_t *sc, struct ehci_xfer *ex) +ehci_check_itd_intr(ehci_softc_t *sc, struct ehci_xfer *ex, ex_completeq_t *cq) { ehci_soft_itd_t *itd; int i; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); KASSERT(mutex_owned(&sc->sc_lock)); - if (&ex->xfer != SIMPLEQ_FIRST(&ex->xfer.pipe->queue)) + if (&ex->ex_xfer != SIMPLEQ_FIRST(&ex->ex_xfer.ux_pipe->up_queue)) return; - if (ex->itdstart == NULL) { - printf("ehci_check_itd_intr: not valid itd\n"); - return; - } + KASSERTMSG(ex->ex_itdstart != NULL && ex->ex_itdend != NULL, + "xfer %p fitd %p litd %p", ex, ex->ex_itdstart, ex->ex_itdend); - itd = ex->itdend; -#ifdef DIAGNOSTIC - if (itd == NULL) { - printf("ehci_check_itd_intr: itdend == 0\n"); - return; - } -#endif + itd = ex->ex_itdend; /* * check no active transfers in last itd, meaning we're finished */ usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_ctl), - sizeof(itd->itd.itd_ctl), BUS_DMASYNC_POSTWRITE | - BUS_DMASYNC_POSTREAD); + sizeof(itd->itd.itd_ctl), + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); for (i = 0; i < EHCI_ITD_NUFRAMES; i++) { if (le32toh(itd->itd.itd_ctl[i]) & EHCI_ITD_ACTIVE) @@ -940,80 +979,126 @@ ehci_check_itd_intr(ehci_softc_t *sc, struct ehci_xfer *ex) goto done; /* All 8 descriptors inactive, it's done */ } - USBHIST_LOGN(ehcidebug, 10, "ex %p itd %p still active", ex, - ex->itdstart, 0, 0); + usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_ctl), + sizeof(itd->itd.itd_ctl), BUS_DMASYNC_PREREAD); + + DPRINTFN(10, "ex %p itd %p still active", ex, ex->ex_itdstart, 0, 0); return; done: - USBHIST_LOG(ehcidebug, "ex %p done", ex, 0, 0, 0); - callout_stop(&ex->xfer.timeout_handle); - ehci_idone(ex); + DPRINTF("ex %p done", ex, 0, 0, 0); + callout_stop(&ex->ex_xfer.ux_callout); + ehci_idone(ex, cq); } -Static void -ehci_idone(struct ehci_xfer *ex) +void +ehci_check_sitd_intr(ehci_softc_t *sc, struct ehci_xfer *ex, ex_completeq_t *cq) { - usbd_xfer_handle xfer = &ex->xfer; - struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe; - struct ehci_softc *sc = xfer->pipe->device->bus->hci_private; - ehci_soft_qtd_t *sqtd, *lsqtd; - u_int32_t status = 0, nstatus = 0; - int actlen; + ehci_soft_sitd_t *sitd; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + KASSERT(mutex_owned(&sc->sc_lock)); - USBHIST_LOG(ehcidebug, "ex=%p", ex, 0, 0, 0); + if (&ex->ex_xfer != SIMPLEQ_FIRST(&ex->ex_xfer.ux_pipe->up_queue)) + return; -#ifdef DIAGNOSTIC - if (ex->isdone) { - printf("ehci_idone: ex=%p is done!\n", ex); -#ifdef EHCI_DEBUG - ehci_dump_exfer(ex); -#endif + KASSERTMSG(ex->ex_sitdstart != NULL && ex->ex_sitdend != NULL, + "xfer %p fsitd %p lsitd %p", ex, ex->ex_sitdstart, ex->ex_sitdend); + + sitd = ex->ex_sitdend; + + /* + * check no active transfers in last sitd, meaning we're finished + */ + + usb_syncmem(&sitd->dma, sitd->offs + offsetof(ehci_sitd_t, sitd_trans), + sizeof(sitd->sitd.sitd_trans), + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); + + bool active = ((le32toh(sitd->sitd.sitd_trans) & EHCI_SITD_ACTIVE) != 0); + + usb_syncmem(&sitd->dma, sitd->offs + offsetof(ehci_sitd_t, sitd_trans), + sizeof(sitd->sitd.sitd_trans), BUS_DMASYNC_PREREAD); + + if (active) return; - } - ex->isdone = 1; -#endif - if (xfer->status == USBD_CANCELLED || - xfer->status == USBD_TIMEOUT) { - USBHIST_LOG(ehcidebug, "aborted xfer=%p", xfer, 0, 0, 0); + DPRINTFN(10, "ex=%p done", ex, 0, 0, 0); + callout_stop(&(ex->ex_xfer.ux_callout)); + ehci_idone(ex, cq); +} + + +Static void +ehci_idone(struct ehci_xfer *ex, ex_completeq_t *cq) +{ + struct usbd_xfer *xfer = &ex->ex_xfer; + struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); + struct ehci_softc *sc = EHCI_XFER2SC(xfer); + ehci_soft_qtd_t *sqtd, *fsqtd, *lsqtd; + uint32_t status = 0, nstatus = 0; + int actlen = 0; + + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + + DPRINTF("ex=%p", ex, 0, 0, 0); + + if (xfer->ux_status == USBD_CANCELLED || + xfer->ux_status == USBD_TIMEOUT) { + DPRINTF("aborted xfer=%p", xfer, 0, 0, 0); return; } - USBHIST_LOG(ehcidebug, "xfer=%p, pipe=%p ready", xfer, epipe, 0, 0); +#ifdef DIAGNOSTIC #ifdef EHCI_DEBUG - ehci_dump_sqtds(ex->sqtdstart); + if (ex->ex_isdone) { + DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); + ehci_dump_exfer(ex); + DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); + } #endif + KASSERTMSG(!ex->ex_isdone, "xfer %p type %d status %d", xfer, + ex->ex_type, xfer->ux_status); + ex->ex_isdone = true; +#endif + + DPRINTF("xfer=%p, pipe=%p ready", xfer, epipe, 0, 0); /* The transfer is done, compute actual length and status. */ + if (ex->ex_type == EX_ISOC) { + /* HS isoc transfer */ - if (UE_GET_XFERTYPE(xfer->pipe->endpoint->edesc->bmAttributes) - == UE_ISOCHRONOUS) { - /* Isoc transfer */ struct ehci_soft_itd *itd; int i, nframes, len, uframes; nframes = 0; - actlen = 0; - i = xfer->pipe->endpoint->edesc->bInterval; +#ifdef EHCI_DEBUG + DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); + ehci_dump_itds(ex->ex_itdstart); + DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); +#endif + + i = xfer->ux_pipe->up_endpoint->ue_edesc->bInterval; uframes = min(1 << (i - 1), USB_UFRAMES_PER_FRAME); - for (itd = ex->itdstart; itd != NULL; itd = itd->xfer_next) { - usb_syncmem(&itd->dma,itd->offs + offsetof(ehci_itd_t,itd_ctl), - sizeof(itd->itd.itd_ctl), BUS_DMASYNC_POSTWRITE | - BUS_DMASYNC_POSTREAD); + for (itd = ex->ex_itdstart; itd != NULL; itd = itd->xfer_next) { + usb_syncmem(&itd->dma, + itd->offs + offsetof(ehci_itd_t,itd_ctl), + sizeof(itd->itd.itd_ctl), + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); for (i = 0; i < EHCI_ITD_NUFRAMES; i += uframes) { - /* XXX - driver didn't fill in the frame full + /* + * XXX - driver didn't fill in the frame full * of uframes. This leads to scheduling * inefficiencies, but working around * this doubles complexity of tracking * an xfer. */ - if (nframes >= xfer->nframes) + if (nframes >= xfer->ux_nframes) break; status = le32toh(itd->itd.itd_ctl[i]); @@ -1021,28 +1106,95 @@ ehci_idone(struct ehci_xfer *ex) if (EHCI_ITD_GET_STATUS(status) != 0) len = 0; /*No valid data on error*/ - xfer->frlengths[nframes++] = len; + xfer->ux_frlengths[nframes++] = len; actlen += len; } + usb_syncmem(&itd->dma, + itd->offs + offsetof(ehci_itd_t,itd_ctl), + sizeof(itd->itd.itd_ctl), BUS_DMASYNC_PREREAD); - if (nframes >= xfer->nframes) + if (nframes >= xfer->ux_nframes) + break; + } + + xfer->ux_actlen = actlen; + xfer->ux_status = USBD_NORMAL_COMPLETION; + goto end; + } else if (ex->ex_type == EX_FS_ISOC) { + /* FS isoc transfer */ + struct ehci_soft_sitd *sitd; + int nframes, len; + + nframes = 0; + + for (sitd = ex->ex_sitdstart; sitd != NULL; + sitd = sitd->xfer_next) { + usb_syncmem(&sitd->dma, + sitd->offs + offsetof(ehci_sitd_t, sitd_trans), + sizeof(sitd->sitd.sitd_trans), + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); + + /* + * XXX - driver didn't fill in the frame full + * of uframes. This leads to scheduling + * inefficiencies, but working around + * this doubles complexity of tracking + * an xfer. + */ + if (nframes >= xfer->ux_nframes) + break; + + status = le32toh(sitd->sitd.sitd_trans); + usb_syncmem(&sitd->dma, + sitd->offs + offsetof(ehci_sitd_t, sitd_trans), + sizeof(sitd->sitd.sitd_trans), BUS_DMASYNC_PREREAD); + + len = EHCI_SITD_GET_LEN(status); + if (status & (EHCI_SITD_ERR|EHCI_SITD_BUFERR| + EHCI_SITD_BABBLE|EHCI_SITD_XACTERR|EHCI_SITD_MISS)) { + /* No valid data on error */ + len = xfer->ux_frlengths[nframes]; + } + + /* + * frlengths[i]: # of bytes to send + * len: # of bytes host didn't send + */ + xfer->ux_frlengths[nframes] -= len; + /* frlengths[i]: # of bytes host sent */ + actlen += xfer->ux_frlengths[nframes++]; + + if (nframes >= xfer->ux_nframes) break; } - xfer->actlen = actlen; - xfer->status = USBD_NORMAL_COMPLETION; + xfer->ux_actlen = actlen; + xfer->ux_status = USBD_NORMAL_COMPLETION; goto end; } + KASSERT(ex->ex_type == EX_CTRL || ex->ex_type == EX_INTR || + ex->ex_type == EX_BULK); /* Continue processing xfers using queue heads */ + if (ex->ex_type == EX_CTRL) { + fsqtd = ex->ex_setup; + lsqtd = ex->ex_status; + } else { + fsqtd = ex->ex_sqtdstart; + lsqtd = ex->ex_sqtdend; + } +#ifdef EHCI_DEBUG + DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); + ehci_dump_sqtds(fsqtd); + DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); +#endif - lsqtd = ex->sqtdend; - actlen = 0; - for (sqtd = ex->sqtdstart; sqtd != lsqtd->nextqtd; - sqtd = sqtd->nextqtd) { + for (sqtd = fsqtd; sqtd != lsqtd->nextqtd; sqtd = sqtd->nextqtd) { usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); nstatus = le32toh(sqtd->qtd.qtd_status); + usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd), + BUS_DMASYNC_PREREAD); if (nstatus & EHCI_QTD_ACTIVE) break; @@ -1051,7 +1203,6 @@ ehci_idone(struct ehci_xfer *ex) actlen += sqtd->len - EHCI_QTD_GET_BYTES(status); } - /* * If there are left over TDs we need to update the toggle. * The default pipe doesn't need it since control transfers @@ -1060,44 +1211,44 @@ ehci_idone(struct ehci_xfer *ex) * packets within the qTD. */ if ((sqtd != lsqtd->nextqtd || EHCI_QTD_GET_BYTES(status)) && - xfer->pipe->device->default_pipe != xfer->pipe) { - USBHIST_LOG(ehcidebug, - "toggle update status=0x%08x nstatus=0x%08x", + xfer->ux_pipe->up_dev->ud_pipe0 != xfer->ux_pipe) { + DPRINTF("toggle update status=0x%08x nstatus=0x%08x", status, nstatus, 0, 0); #if 0 ehci_dump_sqh(epipe->sqh); - ehci_dump_sqtds(ex->sqtdstart); + ehci_dump_sqtds(ex->ex_sqtdstart); #endif epipe->nexttoggle = EHCI_QTD_GET_TOGGLE(nstatus); } - USBHIST_LOG(ehcidebug, "len=%d actlen=%d status=0x%08x", xfer->length, - actlen, status, 0); - xfer->actlen = actlen; + DPRINTF("len=%d actlen=%d status=0x%08x", xfer->ux_length, actlen, + status, 0); + xfer->ux_actlen = actlen; if (status & EHCI_QTD_HALTED) { #ifdef EHCI_DEBUG - USBHIST_LOG(ehcidebug, "halted addr=%d endpt=0x%02x", - xfer->pipe->device->address, - xfer->pipe->endpoint->edesc->bEndpointAddress, 0, 0); - USBHIST_LOG(ehcidebug, "cerr=%d pid=%d stat=%#x", + DPRINTF("halted addr=%d endpt=0x%02x", + xfer->ux_pipe->up_dev->ud_addr, + xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress, + 0, 0); + DPRINTF("cerr=%d pid=%d", EHCI_QTD_GET_CERR(status), EHCI_QTD_GET_PID(status), - status, 0); - USBHIST_LOG(ehcidebug, - "active =%d halted=%d buferr=%d babble=%d", + 0, 0); + DPRINTF("active =%d halted=%d buferr=%d babble=%d", status & EHCI_QTD_ACTIVE ? 1 : 0, status & EHCI_QTD_HALTED ? 1 : 0, status & EHCI_QTD_BUFERR ? 1 : 0, status & EHCI_QTD_BABBLE ? 1 : 0); - USBHIST_LOG(ehcidebug, - "xacterr=%d missed=%d split =%d ping =%d", + DPRINTF("xacterr=%d missed=%d split =%d ping =%d", status & EHCI_QTD_XACTERR ? 1 : 0, status & EHCI_QTD_MISSEDMICRO ? 1 : 0, status & EHCI_QTD_SPLITXSTATE ? 1 : 0, status & EHCI_QTD_PINGSTATE ? 1 : 0); + DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); ehci_dump_sqh(epipe->sqh); - ehci_dump_sqtds(ex->sqtdstart); + ehci_dump_sqtds(ex->ex_sqtdstart); + DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); #endif /* low&full speed has an extra error flag */ if (EHCI_QH_GET_EPS(epipe->sqh->qh.qh_endp) != @@ -1106,9 +1257,9 @@ ehci_idone(struct ehci_xfer *ex) else status &= EHCI_QTD_STATERRS; if (status == 0) /* no other errors means a stall */ { - xfer->status = USBD_STALLED; + xfer->ux_status = USBD_STALLED; } else { - xfer->status = USBD_IOERROR; /* more info XXX */ + xfer->ux_status = USBD_IOERROR; /* more info XXX */ } /* XXX need to reset TT on missed microframe */ if (status & EHCI_QTD_MISSEDMICRO) { @@ -1117,15 +1268,15 @@ ehci_idone(struct ehci_xfer *ex) device_xname(sc->sc_dev)); } } else { - xfer->status = USBD_NORMAL_COMPLETION; + xfer->ux_status = USBD_NORMAL_COMPLETION; } end: - /* XXX transfer_complete memcpys out transfer data (for in endpoints) - * during this call, before methods->done is called: dma sync required - * beforehand? */ - usb_transfer_complete(xfer); - USBHIST_LOG(ehcidebug, "ex=%p done", ex, 0, 0, 0); + + ehci_del_intr_list(sc, ex); + TAILQ_INSERT_TAIL(cq, ex, ex_next); + + DPRINTF("ex=%p done", ex, 0, 0, 0); } /* @@ -1134,56 +1285,55 @@ ehci_idone(struct ehci_xfer *ex) * too long. */ Static void -ehci_waitintr(ehci_softc_t *sc, usbd_xfer_handle xfer) +ehci_waitintr(ehci_softc_t *sc, struct usbd_xfer *xfer) { int timo; - u_int32_t intrs; + uint32_t intrs; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - xfer->status = USBD_IN_PROGRESS; - for (timo = xfer->timeout; timo >= 0; timo--) { + xfer->ux_status = USBD_IN_PROGRESS; + for (timo = xfer->ux_timeout; timo >= 0; timo--) { usb_delay_ms(&sc->sc_bus, 1); if (sc->sc_dying) break; intrs = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS)) & sc->sc_eintrs; - USBHIST_LOG(ehcidebug, "0x%04x", intrs, 0, 0, 0); + DPRINTF("0x%04x", intrs, 0, 0, 0); #ifdef EHCI_DEBUG - if (ehcidebug > 15) + if (ehcidebug >= 15) ehci_dump_regs(sc); #endif if (intrs) { mutex_spin_enter(&sc->sc_intr_lock); ehci_intr1(sc); mutex_spin_exit(&sc->sc_intr_lock); - if (xfer->status != USBD_IN_PROGRESS) + if (xfer->ux_status != USBD_IN_PROGRESS) return; } } /* Timeout */ - USBHIST_LOG(ehcidebug, "timeout", 0, 0, 0, 0); - xfer->status = USBD_TIMEOUT; + DPRINTF("timeout", 0, 0, 0, 0); + xfer->ux_status = USBD_TIMEOUT; mutex_enter(&sc->sc_lock); usb_transfer_complete(xfer); mutex_exit(&sc->sc_lock); - /* XXX should free TD */ } Static void ehci_poll(struct usbd_bus *bus) { - ehci_softc_t *sc = bus->hci_private; + ehci_softc_t *sc = EHCI_BUS2SC(bus); - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); #ifdef EHCI_DEBUG static int last; int new; new = EHCI_STS_INTRS(EOREAD4(sc, EHCI_USBSTS)); if (new != last) { - USBHIST_LOG(ehcidebug, "intrs=0x%04x", new, 0, 0, 0); + DPRINTF("intrs=0x%04x", new, 0, 0, 0); last = new; } #endif @@ -1209,13 +1359,13 @@ ehci_detach(struct ehci_softc *sc, int flags) { int rv = 0; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); if (sc->sc_child != NULL) rv = config_detach(sc->sc_child, flags); if (rv != 0) - return (rv); + return rv; callout_halt(&sc->sc_tmo_intrlist, NULL); callout_destroy(&sc->sc_tmo_intrlist); @@ -1241,7 +1391,7 @@ ehci_detach(struct ehci_softc *sc, int flags) EOWRITE4(sc, EHCI_CONFIGFLAG, 0); - return (rv); + return rv; } @@ -1276,10 +1426,10 @@ ehci_suspend(device_t dv, const pmf_qual_t *qual) int i; uint32_t cmd, hcr; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); mutex_spin_enter(&sc->sc_intr_lock); - sc->sc_bus.use_polling++; + sc->sc_bus.ub_usepolling++; mutex_spin_exit(&sc->sc_intr_lock); for (i = 1; i <= sc->sc_noport; i++) { @@ -1317,7 +1467,7 @@ ehci_suspend(device_t dv, const pmf_qual_t *qual) printf("%s: config timeout\n", device_xname(dv)); mutex_spin_enter(&sc->sc_intr_lock); - sc->sc_bus.use_polling--; + sc->sc_bus.ub_usepolling--; mutex_spin_exit(&sc->sc_intr_lock); return true; @@ -1330,7 +1480,7 @@ ehci_resume(device_t dv, const pmf_qual_t *qual) int i; uint32_t cmd, hcr; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); /* restore things in case the bios sucks */ EOWRITE4(sc, EHCI_CTRLDSSEGMENT, 0); @@ -1388,100 +1538,65 @@ ehci_shutdown(device_t self, int flags) { ehci_softc_t *sc = device_private(self); - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); EOWRITE4(sc, EHCI_USBCMD, 0); /* Halt controller */ EOWRITE4(sc, EHCI_USBCMD, EHCI_CMD_HCRESET); return true; } -Static usbd_status -ehci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size) -{ - struct ehci_softc *sc = bus->hci_private; - usbd_status err; - - err = usb_allocmem_flags(&sc->sc_bus, size, 0, dma, USBMALLOC_MULTISEG); -#ifdef EHCI_DEBUG - if (err) - printf("ehci_allocm: usb_allocmem_flags()= %s (%d)\n", - usbd_errstr(err), err); -#endif - if (err == USBD_NOMEM) - err = usb_reserve_allocm(&sc->sc_dma_reserve, dma, size); -#ifdef EHCI_DEBUG - if (err) - printf("ehci_allocm: usb_reserve_allocm()= %s (%d)\n", - usbd_errstr(err), err); -#endif - return (err); -} - -Static void -ehci_freem(struct usbd_bus *bus, usb_dma_t *dma) -{ - struct ehci_softc *sc = bus->hci_private; - - if (dma->block->flags & USB_DMA_RESERVE) { - usb_reserve_freem(&sc->sc_dma_reserve, - dma); - return; - } - usb_freemem(&sc->sc_bus, dma); -} - -Static usbd_xfer_handle -ehci_allocx(struct usbd_bus *bus) +Static struct usbd_xfer * +ehci_allocx(struct usbd_bus *bus, unsigned int nframes) { - struct ehci_softc *sc = bus->hci_private; - usbd_xfer_handle xfer; + struct ehci_softc *sc = EHCI_BUS2SC(bus); + struct usbd_xfer *xfer; xfer = pool_cache_get(sc->sc_xferpool, PR_NOWAIT); if (xfer != NULL) { memset(xfer, 0, sizeof(struct ehci_xfer)); #ifdef DIAGNOSTIC - EXFER(xfer)->isdone = 1; - xfer->busy_free = XFER_BUSY; + struct ehci_xfer *ex = EHCI_XFER2EXFER(xfer); + ex->ex_isdone = true; + xfer->ux_state = XFER_BUSY; #endif } - return (xfer); + return xfer; } Static void -ehci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) +ehci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) { - struct ehci_softc *sc = bus->hci_private; + struct ehci_softc *sc = EHCI_BUS2SC(bus); + struct ehci_xfer *ex __diagused = EHCI_XFER2EXFER(xfer); + + KASSERTMSG(xfer->ux_state == XFER_BUSY, "xfer %p state %d\n", xfer, + xfer->ux_state); + KASSERT(ex->ex_isdone); #ifdef DIAGNOSTIC - if (xfer->busy_free != XFER_BUSY) { - printf("ehci_freex: xfer=%p not busy, 0x%08x\n", xfer, - xfer->busy_free); - } - xfer->busy_free = XFER_FREE; - if (!EXFER(xfer)->isdone) { - printf("ehci_freex: !isdone\n"); - } + xfer->ux_state = XFER_FREE; #endif + pool_cache_put(sc->sc_xferpool, xfer); } Static void ehci_get_lock(struct usbd_bus *bus, kmutex_t **lock) { - struct ehci_softc *sc = bus->hci_private; + struct ehci_softc *sc = EHCI_BUS2SC(bus); *lock = &sc->sc_lock; } Static void -ehci_device_clear_toggle(usbd_pipe_handle pipe) +ehci_device_clear_toggle(struct usbd_pipe *pipe) { - struct ehci_pipe *epipe = (struct ehci_pipe *)pipe; + struct ehci_pipe *epipe = EHCI_PIPE2EPIPE(pipe); - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "epipe=%p status=0x%08x", - epipe, epipe->sqh->qh.qh_qtd.qtd_status, 0, 0); + DPRINTF("epipe=%p status=0x%08x", epipe, + epipe->sqh->qh.qh_qtd.qtd_status, 0, 0); #ifdef EHCI_DEBUG if (ehcidebug) usbd_dump_pipe(pipe); @@ -1490,7 +1605,7 @@ ehci_device_clear_toggle(usbd_pipe_handle pipe) } Static void -ehci_noop(usbd_pipe_handle pipe) +ehci_noop(struct usbd_pipe *pipe) { } @@ -1523,25 +1638,22 @@ ehci_dump_regs(ehci_softc_t *sc) { int i; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, - "cmd = 0x%08x sts = 0x%08x ien = 0x%08x", + DPRINTF("cmd = 0x%08x sts = 0x%08x ien = 0x%08x", EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS), EOREAD4(sc, EHCI_USBINTR), 0); - USBHIST_LOG(ehcidebug, - "frindex = 0x%08x ctrdsegm = 0x%08x periodic = 0x%08x " + DPRINTF("frindex = 0x%08x ctrdsegm = 0x%08x periodic = 0x%08x " "async = 0x%08x", EOREAD4(sc, EHCI_FRINDEX), EOREAD4(sc, EHCI_CTRLDSSEGMENT), EOREAD4(sc, EHCI_PERIODICLISTBASE), EOREAD4(sc, EHCI_ASYNCLISTADDR)); for (i = 1; i <= sc->sc_noport; i += 2) { if (i == sc->sc_noport) { - USBHIST_LOG(ehcidebug, - "port %d status = 0x%08x", i, + DPRINTF("port %d status = 0x%08x", i, EOREAD4(sc, EHCI_PORTSC(i)), 0, 0); } else { - USBHIST_LOG(ehcidebug, + DPRINTF( "port %d status = 0x%08x port %d status = 0x%08x", i, EOREAD4(sc, EHCI_PORTSC(i)), i+1, EOREAD4(sc, EHCI_PORTSC(i+1))); @@ -1550,11 +1662,11 @@ ehci_dump_regs(ehci_softc_t *sc) } #define ehci_dump_link(link, type) do { \ - USBHIST_LOG(ehcidebug, " link 0x%08x (T = %d):", \ + DPRINTF(" link 0x%08x (T = %d):", \ link, \ link & EHCI_LINK_TERMINATE ? 1 : 0, 0, 0); \ if (type) { \ - USBHIST_LOG(ehcidebug, \ + DPRINTF( \ " ITD = %d QH = %d SITD = %d FSTN = %d",\ EHCI_LINK_TYPE(link) == EHCI_LINK_ITD ? 1 : 0, \ EHCI_LINK_TYPE(link) == EHCI_LINK_QH ? 1 : 0, \ @@ -1566,7 +1678,7 @@ ehci_dump_regs(ehci_softc_t *sc) Static void ehci_dump_sqtds(ehci_soft_qtd_t *sqtd) { - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); int i; uint32_t stop = 0; @@ -1582,20 +1694,18 @@ ehci_dump_sqtds(ehci_soft_qtd_t *sqtd) sizeof(sqtd->qtd), BUS_DMASYNC_PREREAD); } if (!stop) - USBHIST_LOG(ehcidebug, - "dump aborted, too many TDs", 0, 0, 0, 0); + DPRINTF("dump aborted, too many TDs", 0, 0, 0, 0); } Static void ehci_dump_sqtd(ehci_soft_qtd_t *sqtd) { - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - USBHIST_LOGN(ehcidebug, 10, - "QTD(%p) at 0x%08x:", sqtd, sqtd->physaddr, 0, 0); + DPRINTFN(10, "QTD(%p) at 0x%08x:", sqtd, sqtd->physaddr, 0, 0); ehci_dump_qtd(&sqtd->qtd); usb_syncmem(&sqtd->dma, sqtd->offs, @@ -1605,38 +1715,38 @@ ehci_dump_sqtd(ehci_soft_qtd_t *sqtd) Static void ehci_dump_qtd(ehci_qtd_t *qtd) { - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); uint32_t s = le32toh(qtd->qtd_status); - USBHIST_LOGN(ehcidebug, 10, + DPRINTFN(10, " next = 0x%08x altnext = 0x%08x status = 0x%08x", qtd->qtd_next, qtd->qtd_altnext, s, 0); - USBHIST_LOGN(ehcidebug, 10, + DPRINTFN(10, " toggle = %d ioc = %d bytes = %#x " "c_page = %#x", EHCI_QTD_GET_TOGGLE(s), EHCI_QTD_GET_IOC(s), EHCI_QTD_GET_BYTES(s), EHCI_QTD_GET_C_PAGE(s)); - USBHIST_LOGN(ehcidebug, 10, + DPRINTFN(10, " cerr = %d pid = %d stat = %x", EHCI_QTD_GET_CERR(s), EHCI_QTD_GET_PID(s), EHCI_QTD_GET_STATUS(s), 0); - USBHIST_LOGN(ehcidebug, 10, + DPRINTFN(10, "active =%d halted=%d buferr=%d babble=%d", s & EHCI_QTD_ACTIVE ? 1 : 0, s & EHCI_QTD_HALTED ? 1 : 0, s & EHCI_QTD_BUFERR ? 1 : 0, s & EHCI_QTD_BABBLE ? 1 : 0); - USBHIST_LOGN(ehcidebug, 10, + DPRINTFN(10, "xacterr=%d missed=%d split =%d ping =%d", s & EHCI_QTD_XACTERR ? 1 : 0, s & EHCI_QTD_MISSEDMICRO ? 1 : 0, s & EHCI_QTD_SPLITXSTATE ? 1 : 0, s & EHCI_QTD_PINGSTATE ? 1 : 0); - USBHIST_LOGN(ehcidebug, 10, + DPRINTFN(10, "buffer[0] = %#x buffer[1] = %#x " "buffer[2] = %#x buffer[3] = %#x", le32toh(qtd->qtd_buffer[0]), le32toh(qtd->qtd_buffer[1]), le32toh(qtd->qtd_buffer[2]), le32toh(qtd->qtd_buffer[3])); - USBHIST_LOGN(ehcidebug, 10, + DPRINTFN(10, "buffer[4] = %#x", le32toh(qtd->qtd_buffer[4]), 0, 0, 0); } @@ -1645,50 +1755,64 @@ ehci_dump_sqh(ehci_soft_qh_t *sqh) { ehci_qh_t *qh = &sqh->qh; ehci_link_t link; - u_int32_t endp, endphub; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + uint32_t endp, endphub; + EHCIHIST_FUNC(); EHCIHIST_CALLED(); usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - USBHIST_LOGN(ehcidebug, 10, - "QH(%p) at %#x:", sqh, sqh->physaddr, 0, 0); + DPRINTFN(10, "QH(%p) at %#x:", sqh, sqh->physaddr, 0, 0); link = le32toh(qh->qh_link); ehci_dump_link(link, true); endp = le32toh(qh->qh_endp); - USBHIST_LOGN(ehcidebug, 10, - " endp = %#x", endp, 0, 0, 0); - USBHIST_LOGN(ehcidebug, 10, - " addr = 0x%02x inact = %d endpt = %d eps = %d", + DPRINTFN(10, " endp = %#x", endp, 0, 0, 0); + DPRINTFN(10, " addr = 0x%02x inact = %d endpt = %d eps = %d", EHCI_QH_GET_ADDR(endp), EHCI_QH_GET_INACT(endp), EHCI_QH_GET_ENDPT(endp), EHCI_QH_GET_EPS(endp)); - USBHIST_LOGN(ehcidebug, 10, - " dtc = %d hrecl = %d", + DPRINTFN(10, " dtc = %d hrecl = %d", EHCI_QH_GET_DTC(endp), EHCI_QH_GET_HRECL(endp), 0, 0); - USBHIST_LOGN(ehcidebug, 10, - " ctl = %d nrl = %d mpl = %#x(%d)", + DPRINTFN(10, " ctl = %d nrl = %d mpl = %#x(%d)", EHCI_QH_GET_CTL(endp),EHCI_QH_GET_NRL(endp), EHCI_QH_GET_MPL(endp), EHCI_QH_GET_MPL(endp)); endphub = le32toh(qh->qh_endphub); - USBHIST_LOGN(ehcidebug, 10, - " endphub = %#x", endphub, 0, 0, 0); - USBHIST_LOGN(ehcidebug, 10, - " smask = 0x%02x cmask = 0x%02x", + DPRINTFN(10, " endphub = %#x", endphub, 0, 0, 0); + DPRINTFN(10, " smask = 0x%02x cmask = 0x%02x", EHCI_QH_GET_SMASK(endphub), EHCI_QH_GET_CMASK(endphub), 1, 0); - USBHIST_LOGN(ehcidebug, 10, - " huba = 0x%02x port = %d mult = %d", + DPRINTFN(10, " huba = 0x%02x port = %d mult = %d", EHCI_QH_GET_HUBA(endphub), EHCI_QH_GET_PORT(endphub), EHCI_QH_GET_MULT(endphub), 0); link = le32toh(qh->qh_curqtd); ehci_dump_link(link, false); - USBHIST_LOGN(ehcidebug, 10, "Overlay qTD:", 0, 0, 0, 0); + DPRINTFN(10, "Overlay qTD:", 0, 0, 0, 0); ehci_dump_qtd(&qh->qh_qtd); - usb_syncmem(&sqh->dma, sqh->offs, - sizeof(sqh->qh), BUS_DMASYNC_PREREAD); + usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), + BUS_DMASYNC_PREREAD); +} + +Static void +ehci_dump_itds(ehci_soft_itd_t *itd) +{ + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + int i; + uint32_t stop = 0; + + for (i = 0; itd && i < 20 && !stop; itd = itd->xfer_next, i++) { + ehci_dump_itd(itd); + usb_syncmem(&itd->dma, + itd->offs + offsetof(ehci_itd_t, itd_next), + sizeof(itd->itd), + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); + stop = itd->itd.itd_next & htole32(EHCI_LINK_TERMINATE); + usb_syncmem(&itd->dma, + itd->offs + offsetof(ehci_itd_t, itd_next), + sizeof(itd->itd), BUS_DMASYNC_PREREAD); + } + if (!stop) + DPRINTF("dump aborted, too many TDs", 0, 0, 0, 0); } Static void @@ -1698,133 +1822,145 @@ ehci_dump_itd(struct ehci_soft_itd *itd) ehci_isoc_bufr_ptr_t b, b2, b3; int i; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "ITD: next phys = %#x", itd->itd.itd_next, 0, - 0, 0); + DPRINTF("ITD: next phys = %#x", itd->itd.itd_next, 0, 0, 0); for (i = 0; i < EHCI_ITD_NUFRAMES; i++) { t = le32toh(itd->itd.itd_ctl[i]); - USBHIST_LOG(ehcidebug, "ITDctl %d: stat = %x len = %x", + DPRINTF("ITDctl %d: stat = %x len = %x", i, EHCI_ITD_GET_STATUS(t), EHCI_ITD_GET_LEN(t), 0); - USBHIST_LOG(ehcidebug, " ioc = %x pg = %x offs = %x", + DPRINTF(" ioc = %x pg = %x offs = %x", EHCI_ITD_GET_IOC(t), EHCI_ITD_GET_PG(t), EHCI_ITD_GET_OFFS(t), 0); } - USBHIST_LOG(ehcidebug, "ITDbufr: ", 0, 0, 0, 0); + DPRINTF("ITDbufr: ", 0, 0, 0, 0); for (i = 0; i < EHCI_ITD_NBUFFERS; i++) - USBHIST_LOG(ehcidebug, " %x", + DPRINTF(" %x", EHCI_ITD_GET_BPTR(le32toh(itd->itd.itd_bufr[i])), 0, 0, 0); b = le32toh(itd->itd.itd_bufr[0]); b2 = le32toh(itd->itd.itd_bufr[1]); b3 = le32toh(itd->itd.itd_bufr[2]); - USBHIST_LOG(ehcidebug, " ep = %x daddr = %x dir = %d", + DPRINTF(" ep = %x daddr = %x dir = %d", EHCI_ITD_GET_EP(b), EHCI_ITD_GET_DADDR(b), EHCI_ITD_GET_DIR(b2), 0); - USBHIST_LOG(ehcidebug, " maxpkt = %x multi = %x", + DPRINTF(" maxpkt = %x multi = %x", EHCI_ITD_GET_MAXPKT(b2), EHCI_ITD_GET_MULTI(b3), 0, 0); } Static void ehci_dump_sitd(struct ehci_soft_itd *itd) { - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "SITD %p next = %p prev = %p", - itd, itd->u.frame_list.next, itd->u.frame_list.prev, 0); - USBHIST_LOG(ehcidebug, " xfernext=%p physaddr=%X slot=%d", + DPRINTF("SITD %p next = %p prev = %p", + itd, itd->frame_list.next, itd->frame_list.prev, 0); + DPRINTF(" xfernext=%p physaddr=%X slot=%d", itd->xfer_next, itd->physaddr, itd->slot, 0); } Static void ehci_dump_exfer(struct ehci_xfer *ex) { - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "ex = %p sqtdstart = %p end = %p", - ex, ex->sqtdstart, ex->sqtdend, 0); - USBHIST_LOG(ehcidebug, " itdstart = %p end = %p isdone = %d", - ex->itdstart, ex->itdend, ex->isdone, 0); + DPRINTF("ex = %p type %d isdone", ex, ex->ex_type, + ex->ex_isdone, 0); + + switch (ex->ex_type) { + case EX_CTRL: + DPRINTF(" setup = %p data = %p status = %p", + ex->ex_setup, ex->ex_data, ex->ex_status, 0); + break; + case EX_BULK: + case EX_INTR: + DPRINTF(" qtdstart = %p qtdend = %p", + ex->ex_sqtdstart, ex->ex_sqtdend, 0, 0); + break; + case EX_ISOC: + DPRINTF(" itdstart = %p itdend = %p", + ex->ex_itdstart, ex->ex_itdend, 0, 0); + break; + case EX_FS_ISOC: + DPRINTF(" sitdstart = %p sitdend = %p", + ex->ex_sitdstart, ex->ex_sitdend, 0, 0); + break; + default: + DPRINTF(" unknown type", 0, 0, 0, 0); + } } #endif Static usbd_status -ehci_open(usbd_pipe_handle pipe) +ehci_open(struct usbd_pipe *pipe) { - usbd_device_handle dev = pipe->device; - ehci_softc_t *sc = dev->bus->hci_private; - usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc; - u_int8_t addr = dev->address; - u_int8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes); - struct ehci_pipe *epipe = (struct ehci_pipe *)pipe; + struct usbd_device *dev = pipe->up_dev; + ehci_softc_t *sc = EHCI_PIPE2SC(pipe); + usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc; + uint8_t rhaddr = dev->ud_bus->ub_rhaddr; + uint8_t addr = dev->ud_addr; + uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes); + struct ehci_pipe *epipe = EHCI_PIPE2EPIPE(pipe); ehci_soft_qh_t *sqh; usbd_status err; int ival, speed, naks; int hshubaddr, hshubport; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "pipe=%p, addr=%d, endpt=%d (%d)", - pipe, addr, ed->bEndpointAddress, sc->sc_addr); + DPRINTF("pipe=%p, addr=%d, endpt=%d (%d)", pipe, addr, + ed->bEndpointAddress, rhaddr); - if (dev->myhsport) { + if (dev->ud_myhsport) { /* * When directly attached FS/LS device while doing embedded * transaction translations and we are the hub, set the hub * address to 0 (us). */ if (!(sc->sc_flags & EHCIF_ETTF) - || (dev->myhsport->parent->address != sc->sc_addr)) { - hshubaddr = dev->myhsport->parent->address; + || (dev->ud_myhsport->up_parent->ud_addr != rhaddr)) { + hshubaddr = dev->ud_myhsport->up_parent->ud_addr; } else { hshubaddr = 0; } - hshubport = dev->myhsport->portno; + hshubport = dev->ud_myhsport->up_portno; } else { hshubaddr = 0; hshubport = 0; } if (sc->sc_dying) - return (USBD_IOERROR); + return USBD_IOERROR; /* toggle state needed for bulk endpoints */ - epipe->nexttoggle = pipe->endpoint->datatoggle; + epipe->nexttoggle = pipe->up_endpoint->ue_toggle; - if (addr == sc->sc_addr) { + if (addr == rhaddr) { switch (ed->bEndpointAddress) { case USB_CONTROL_ENDPOINT: - pipe->methods = &ehci_root_ctrl_methods; + pipe->up_methods = &roothub_ctrl_methods; break; - case UE_DIR_IN | EHCI_INTR_ENDPT: - pipe->methods = &ehci_root_intr_methods; + case UE_DIR_IN | USBROOTHUB_INTR_ENDPT: + pipe->up_methods = &ehci_root_intr_methods; break; default: - USBHIST_LOG(ehcidebug, - "bad bEndpointAddress 0x%02x", + DPRINTF("bad bEndpointAddress 0x%02x", ed->bEndpointAddress, 0, 0, 0); - return (USBD_INVAL); + return USBD_INVAL; } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } /* XXX All this stuff is only valid for async. */ - switch (dev->speed) { + switch (dev->ud_speed) { case USB_SPEED_LOW: speed = EHCI_QH_SPEED_LOW; break; case USB_SPEED_FULL: speed = EHCI_QH_SPEED_FULL; break; case USB_SPEED_HIGH: speed = EHCI_QH_SPEED_HIGH; break; - default: panic("ehci_open: bad device speed %d", dev->speed); + default: panic("ehci_open: bad device speed %d", dev->ud_speed); } - if (speed != EHCI_QH_SPEED_HIGH && xfertype == UE_ISOCHRONOUS) { - aprint_error_dev(sc->sc_dev, "error opening low/full speed " - "isoc endpoint.\n"); - aprint_normal_dev(sc->sc_dev, "a low/full speed device is " - "attached to a USB2 hub, and transaction translations are " - "not yet supported.\n"); - aprint_normal_dev(sc->sc_dev, "reattach the device to the " - "root hub instead.\n"); - USBHIST_LOG(ehcidebug, "hshubaddr=%d hshubport=%d", - hshubaddr, hshubport, 0, 0); + if (speed == EHCI_QH_SPEED_LOW && xfertype == UE_ISOCHRONOUS) { + DPRINTF("hshubaddr=%d hshubport=%d", hshubaddr, hshubport, 0, + 0); return USBD_INVAL; } @@ -1840,7 +1976,7 @@ ehci_open(usbd_pipe_handle pipe) if (xfertype != UE_ISOCHRONOUS) { sqh = ehci_alloc_sqh(sc); if (sqh == NULL) - return (USBD_NOMEM); + return USBD_NOMEM; /* qh_link filled when the QH is added */ sqh->qh.qh_endp = htole32( EHCI_QH_SET_ADDR(addr) | @@ -1878,27 +2014,27 @@ ehci_open(usbd_pipe_handle pipe) switch (xfertype) { case UE_CONTROL: err = usb_allocmem(&sc->sc_bus, sizeof(usb_device_request_t), - 0, &epipe->u.ctl.reqdma); + 0, &epipe->ctrl.reqdma); #ifdef EHCI_DEBUG if (err) printf("ehci_open: usb_allocmem()=%d\n", err); #endif if (err) goto bad; - pipe->methods = &ehci_device_ctrl_methods; + pipe->up_methods = &ehci_device_ctrl_methods; mutex_enter(&sc->sc_lock); ehci_add_qh(sc, sqh, sc->sc_async_head); mutex_exit(&sc->sc_lock); break; case UE_BULK: - pipe->methods = &ehci_device_bulk_methods; + pipe->up_methods = &ehci_device_bulk_methods; mutex_enter(&sc->sc_lock); ehci_add_qh(sc, sqh, sc->sc_async_head); mutex_exit(&sc->sc_lock); break; case UE_INTERRUPT: - pipe->methods = &ehci_device_intr_methods; - ival = pipe->interval; + pipe->up_methods = &ehci_device_intr_methods; + ival = pipe->up_interval; if (ival == USBD_DEFAULT_INTERVAL) { if (speed == EHCI_QH_SPEED_HIGH) { if (ed->bInterval > 16) { @@ -1918,7 +2054,11 @@ ehci_open(usbd_pipe_handle pipe) goto bad; break; case UE_ISOCHRONOUS: - pipe->methods = &ehci_device_isoc_methods; + pipe->up_serialise = false; + if (speed == EHCI_QH_SPEED_HIGH) + pipe->up_methods = &ehci_device_isoc_methods; + else + pipe->up_methods = &ehci_device_fs_isoc_methods; if (ed->bInterval == 0 || ed->bInterval > 16) { printf("ehci: opening pipe with invalid bInterval\n"); err = USBD_INVAL; @@ -1929,20 +2069,23 @@ ehci_open(usbd_pipe_handle pipe) err = USBD_INVAL; goto bad; } - epipe->u.isoc.next_frame = 0; - epipe->u.isoc.cur_xfers = 0; + epipe->isoc.next_frame = 0; + epipe->isoc.cur_xfers = 0; break; default: - USBHIST_LOG(ehcidebug, "bad xfer type %d", xfertype, 0, 0, 0); + DPRINTF("bad xfer type %d", xfertype, 0, 0, 0); err = USBD_INVAL; goto bad; } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; bad: - if (sqh != NULL) + if (sqh != NULL) { + mutex_enter(&sc->sc_lock); ehci_free_sqh(sc, sqh); - return (err); + mutex_exit(&sc->sc_lock); + } + return err; } /* @@ -1954,7 +2097,7 @@ ehci_add_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head) KASSERT(mutex_owned(&sc->sc_lock)); - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); usb_syncmem(&head->dma, head->offs + offsetof(ehci_qh_t, qh_link), sizeof(head->qh.qh_link), BUS_DMASYNC_POSTWRITE); @@ -1972,7 +2115,9 @@ ehci_add_qh(ehci_softc_t *sc, ehci_soft_qh_t *sqh, ehci_soft_qh_t *head) sizeof(head->qh.qh_link), BUS_DMASYNC_PREWRITE); #ifdef EHCI_DEBUG + DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); ehci_dump_sqh(sqh); + DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); #endif } @@ -2005,7 +2150,7 @@ Static void ehci_set_qh_qtd(ehci_soft_qh_t *sqh, ehci_soft_qtd_t *sqtd) { int i; - u_int32_t status; + uint32_t status; /* Save toggle bit and ping status. */ usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), @@ -2049,21 +2194,21 @@ ehci_sync_hc(ehci_softc_t *sc) KASSERT(mutex_owned(&sc->sc_lock)); - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); if (sc->sc_dying) { - USBHIST_LOG(ehcidebug, "dying", 0, 0, 0, 0); + DPRINTF("dying", 0, 0, 0, 0); return; } /* ask for doorbell */ EOWRITE4(sc, EHCI_USBCMD, EOREAD4(sc, EHCI_USBCMD) | EHCI_CMD_IAAD); - USBHIST_LOG(ehcidebug, "cmd = 0x%08x sts = 0x%08x", - EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS), 0, 0); + DPRINTF("cmd = 0x%08x sts = 0x%08x", + EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS), 0, 0); error = cv_timedwait(&sc->sc_doorbell, &sc->sc_lock, hz); /* bell wait */ - USBHIST_LOG(ehcidebug, "cmd = 0x%08x sts = 0x%08x", - EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS), 0, 0); + DPRINTF("cmd = 0x%08x sts = 0x%08x ... done", + EOREAD4(sc, EHCI_USBCMD), EOREAD4(sc, EHCI_USBSTS), 0, 0); #ifdef DIAGNOSTIC if (error) printf("ehci_sync_hc: cv_timedwait() = %d\n", error); @@ -2071,332 +2216,171 @@ ehci_sync_hc(ehci_softc_t *sc) } Static void -ehci_rem_free_itd_chain(ehci_softc_t *sc, struct ehci_xfer *exfer) +ehci_remove_itd_chain(ehci_softc_t *sc, struct ehci_soft_itd *itd) { - struct ehci_soft_itd *itd, *prev; - prev = NULL; + KASSERT(mutex_owned(&sc->sc_lock)); - if (exfer->itdstart == NULL || exfer->itdend == NULL) - panic("ehci isoc xfer being freed, but with no itd chain"); + for (; itd != NULL; itd = itd->xfer_next) { + struct ehci_soft_itd *prev = itd->frame_list.prev; - for (itd = exfer->itdstart; itd != NULL; itd = itd->xfer_next) { - prev = itd->u.frame_list.prev; /* Unlink itd from hardware chain, or frame array */ if (prev == NULL) { /* We're at the table head */ - sc->sc_softitds[itd->slot] = itd->u.frame_list.next; + sc->sc_softitds[itd->slot] = itd->frame_list.next; sc->sc_flist[itd->slot] = itd->itd.itd_next; usb_syncmem(&sc->sc_fldma, sizeof(ehci_link_t) * itd->slot, - sizeof(ehci_link_t), + sizeof(ehci_link_t), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - if (itd->u.frame_list.next != NULL) - itd->u.frame_list.next->u.frame_list.prev = NULL; + if (itd->frame_list.next != NULL) + itd->frame_list.next->frame_list.prev = NULL; } else { /* XXX this part is untested... */ prev->itd.itd_next = itd->itd.itd_next; usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_next), - sizeof(itd->itd.itd_next), BUS_DMASYNC_PREWRITE); + sizeof(itd->itd.itd_next), BUS_DMASYNC_PREWRITE); - prev->u.frame_list.next = itd->u.frame_list.next; - if (itd->u.frame_list.next != NULL) - itd->u.frame_list.next->u.frame_list.prev = prev; + prev->frame_list.next = itd->frame_list.next; + if (itd->frame_list.next != NULL) + itd->frame_list.next->frame_list.prev = prev; } } - - prev = NULL; - for (itd = exfer->itdstart; itd != NULL; itd = itd->xfer_next) { - if (prev != NULL) - ehci_free_itd(sc, prev); - prev = itd; - } - if (prev) - ehci_free_itd(sc, prev); - exfer->itdstart = NULL; - exfer->itdend = NULL; } -/***********/ +Static void +ehci_free_itd_chain(ehci_softc_t *sc, struct ehci_soft_itd *itd) +{ + struct ehci_soft_itd *next; -/* - * Data structures and routines to emulate the root hub. - */ -Static usb_device_descriptor_t ehci_devd = { - USB_DEVICE_DESCRIPTOR_SIZE, - UDESC_DEVICE, /* type */ - {0x00, 0x02}, /* USB version */ - UDCLASS_HUB, /* class */ - UDSUBCLASS_HUB, /* subclass */ - UDPROTO_HSHUBSTT, /* protocol */ - 64, /* max packet */ - {0},{0},{0x00,0x01}, /* device id */ - 1,2,0, /* string indicies */ - 1 /* # of configurations */ -}; + mutex_enter(&sc->sc_lock); + next = NULL; + for (; itd != NULL; itd = next) { + next = itd->xfer_next; + ehci_free_itd_locked(sc, itd); + } + mutex_exit(&sc->sc_lock); +} -Static const usb_device_qualifier_t ehci_odevd = { - USB_DEVICE_DESCRIPTOR_SIZE, - UDESC_DEVICE_QUALIFIER, /* type */ - {0x00, 0x02}, /* USB version */ - UDCLASS_HUB, /* class */ - UDSUBCLASS_HUB, /* subclass */ - UDPROTO_FSHUB, /* protocol */ - 64, /* max packet */ - 1, /* # of configurations */ - 0 -}; +Static void +ehci_remove_sitd_chain(ehci_softc_t *sc, struct ehci_soft_sitd *sitd) +{ -Static const usb_config_descriptor_t ehci_confd = { - USB_CONFIG_DESCRIPTOR_SIZE, - UDESC_CONFIG, - {USB_CONFIG_DESCRIPTOR_SIZE + - USB_INTERFACE_DESCRIPTOR_SIZE + - USB_ENDPOINT_DESCRIPTOR_SIZE}, - 1, - 1, - 0, - UC_ATTR_MBO | UC_SELF_POWERED, - 0 /* max power */ -}; + KASSERT(mutex_owned(&sc->sc_lock)); -Static const usb_interface_descriptor_t ehci_ifcd = { - USB_INTERFACE_DESCRIPTOR_SIZE, - UDESC_INTERFACE, - 0, - 0, - 1, - UICLASS_HUB, - UISUBCLASS_HUB, - UIPROTO_HSHUBSTT, - 0 -}; + for (; sitd != NULL; sitd = sitd->xfer_next) { + struct ehci_soft_sitd *prev = sitd->frame_list.prev; -Static const usb_endpoint_descriptor_t ehci_endpd = { - USB_ENDPOINT_DESCRIPTOR_SIZE, - UDESC_ENDPOINT, - UE_DIR_IN | EHCI_INTR_ENDPT, - UE_INTERRUPT, - {8, 0}, /* max packet */ - 12 -}; + /* Unlink sitd from hardware chain, or frame array */ + if (prev == NULL) { /* We're at the table head */ + sc->sc_softsitds[sitd->slot] = sitd->frame_list.next; + sc->sc_flist[sitd->slot] = sitd->sitd.sitd_next; + usb_syncmem(&sc->sc_fldma, + sizeof(ehci_link_t) * sitd->slot, + sizeof(ehci_link_t), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); -Static const usb_hub_descriptor_t ehci_hubd = { - USB_HUB_DESCRIPTOR_SIZE, - UDESC_HUB, - 0, - {0,0}, - 0, - 0, - {""}, - {""}, -}; + if (sitd->frame_list.next != NULL) + sitd->frame_list.next->frame_list.prev = NULL; + } else { + /* XXX this part is untested... */ + prev->sitd.sitd_next = sitd->sitd.sitd_next; + usb_syncmem(&sitd->dma, + sitd->offs + offsetof(ehci_sitd_t, sitd_next), + sizeof(sitd->sitd.sitd_next), BUS_DMASYNC_PREWRITE); + + prev->frame_list.next = sitd->frame_list.next; + if (sitd->frame_list.next != NULL) + sitd->frame_list.next->frame_list.prev = prev; + } + } +} -/* - * Simulate a hardware hub by handling all the necessary requests. - */ -Static usbd_status -ehci_root_ctrl_transfer(usbd_xfer_handle xfer) +Static void +ehci_free_sitd_chain(ehci_softc_t *sc, struct ehci_soft_sitd *sitd) { - ehci_softc_t *sc = xfer->pipe->device->bus->hci_private; - usbd_status err; - /* Insert last in queue. */ mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); + struct ehci_soft_sitd *next = NULL; + for (; sitd != NULL; sitd = next) { + next = sitd->xfer_next; + ehci_free_sitd_locked(sc, sitd); + } mutex_exit(&sc->sc_lock); - if (err) - return (err); - - /* Pipe isn't running, start first */ - return (ehci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); } -Static usbd_status -ehci_root_ctrl_start(usbd_xfer_handle xfer) +/***********/ + +Static int +ehci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, + void *buf, int buflen) { - ehci_softc_t *sc = xfer->pipe->device->bus->hci_private; - usb_device_request_t *req; - void *buf = NULL; - int port, i; - int len, value, index, l, totlen = 0; - usb_port_status_t ps; + ehci_softc_t *sc = EHCI_BUS2SC(bus); usb_hub_descriptor_t hubd; - usbd_status err; - u_int32_t v; + usb_port_status_t ps; + uint16_t len, value, index; + int l, totlen = 0; + int port, i; + uint32_t v; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); if (sc->sc_dying) - return (USBD_IOERROR); - -#ifdef DIAGNOSTIC - if (!(xfer->rqflags & URQ_REQUEST)) - /* XXX panic */ - return (USBD_INVAL); -#endif - req = &xfer->request; + return -1; - USBHIST_LOG(ehcidebug, "type=0x%02x request=%02x", - req->bmRequestType, req->bRequest, 0, 0); + DPRINTF("type=0x%02x request=%02x", req->bmRequestType, req->bRequest, + 0, 0); len = UGETW(req->wLength); value = UGETW(req->wValue); index = UGETW(req->wIndex); - if (len != 0) - buf = KERNADDR(&xfer->dmabuf, 0); - #define C(x,y) ((x) | ((y) << 8)) - switch(C(req->bRequest, req->bmRequestType)) { - case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE): - case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE): - case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT): - /* - * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops - * for the integrated root hub. - */ - break; - case C(UR_GET_CONFIG, UT_READ_DEVICE): - if (len > 0) { - *(u_int8_t *)buf = sc->sc_conf; - totlen = 1; - } - break; + switch (C(req->bRequest, req->bmRequestType)) { case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): - USBHIST_LOG(ehcidebug, "wValue=0x%04x", value, 0, 0, 0); if (len == 0) break; - switch(value >> 8) { - case UDESC_DEVICE: - if ((value & 0xff) != 0) { - err = USBD_IOERROR; - goto ret; - } - totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE); - USETW(ehci_devd.idVendor, sc->sc_id_vendor); - memcpy(buf, &ehci_devd, l); + switch (value) { + case C(0, UDESC_DEVICE): { + usb_device_descriptor_t devd; + totlen = min(buflen, sizeof(devd)); + memcpy(&devd, buf, totlen); + USETW(devd.idVendor, sc->sc_id_vendor); + memcpy(buf, &devd, totlen); break; - /* - * We can't really operate at another speed, but the spec says - * we need this descriptor. - */ - case UDESC_DEVICE_QUALIFIER: - if ((value & 0xff) != 0) { - err = USBD_IOERROR; - goto ret; - } - totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE); - memcpy(buf, &ehci_odevd, l); + + } +#define sd ((usb_string_descriptor_t *)buf) + case C(1, UDESC_STRING): + /* Vendor */ + totlen = usb_makestrdesc(sd, len, sc->sc_vendor); break; - /* - * We can't really operate at another speed, but the spec says - * we need this descriptor. - */ - case UDESC_OTHER_SPEED_CONFIGURATION: - case UDESC_CONFIG: - if ((value & 0xff) != 0) { - err = USBD_IOERROR; - goto ret; - } - totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE); - memcpy(buf, &ehci_confd, l); - ((usb_config_descriptor_t *)buf)->bDescriptorType = - value >> 8; - buf = (char *)buf + l; - len -= l; - l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE); - totlen += l; - memcpy(buf, &ehci_ifcd, l); - buf = (char *)buf + l; - len -= l; - l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE); - totlen += l; - memcpy(buf, &ehci_endpd, l); + case C(2, UDESC_STRING): + /* Product */ + totlen = usb_makestrdesc(sd, len, "EHCI root hub"); break; - case UDESC_STRING: -#define sd ((usb_string_descriptor_t *)buf) - switch (value & 0xff) { - case 0: /* Language table */ - totlen = usb_makelangtbl(sd, len); - break; - case 1: /* Vendor */ - totlen = usb_makestrdesc(sd, len, - sc->sc_vendor); - break; - case 2: /* Product */ - totlen = usb_makestrdesc(sd, len, - "EHCI root hub"); - break; - } #undef sd - break; default: - err = USBD_IOERROR; - goto ret; - } - break; - case C(UR_GET_INTERFACE, UT_READ_INTERFACE): - if (len > 0) { - *(u_int8_t *)buf = 0; - totlen = 1; - } - break; - case C(UR_GET_STATUS, UT_READ_DEVICE): - if (len > 1) { - USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED); - totlen = 2; - } - break; - case C(UR_GET_STATUS, UT_READ_INTERFACE): - case C(UR_GET_STATUS, UT_READ_ENDPOINT): - if (len > 1) { - USETW(((usb_status_t *)buf)->wStatus, 0); - totlen = 2; - } - break; - case C(UR_SET_ADDRESS, UT_WRITE_DEVICE): - if (value >= USB_MAX_DEVICES) { - err = USBD_IOERROR; - goto ret; - } - sc->sc_addr = value; - break; - case C(UR_SET_CONFIG, UT_WRITE_DEVICE): - if (value != 0 && value != 1) { - err = USBD_IOERROR; - goto ret; + /* default from usbroothub */ + return buflen; } - sc->sc_conf = value; - break; - case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE): - break; - case C(UR_SET_FEATURE, UT_WRITE_DEVICE): - case C(UR_SET_FEATURE, UT_WRITE_INTERFACE): - case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT): - err = USBD_IOERROR; - goto ret; - case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE): - break; - case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT): break; + /* Hub requests */ case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE): break; case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): - USBHIST_LOG(ehcidebug, - "UR_CLEAR_PORT_FEATURE port=%d feature=%d", index, value, - 0, 0); + DPRINTF("UR_CLEAR_PORT_FEATURE port=%d feature=%d", index, + value, 0, 0); if (index < 1 || index > sc->sc_noport) { - err = USBD_IOERROR; - goto ret; + return -1; } port = EHCI_PORTSC(index); v = EOREAD4(sc, port); - USBHIST_LOG(ehcidebug, "portsc=0x%08x", v, 0, 0, 0); + DPRINTF("portsc=0x%08x", v, 0, 0, 0); v &= ~EHCI_PS_CLEAR; - switch(value) { + switch (value) { case UHF_PORT_ENABLE: EOWRITE4(sc, port, v &~ EHCI_PS_PE); break; @@ -2420,12 +2404,10 @@ ehci_root_ctrl_start(usbd_xfer_handle xfer) EOWRITE4(sc, port, v &~ EHCI_PS_PP); break; case UHF_PORT_TEST: - USBHIST_LOG(ehcidebug, "clear port test " - "%d", index, 0, 0, 0); + DPRINTF("clear port test %d", index, 0, 0, 0); break; case UHF_PORT_INDICATOR: - USBHIST_LOG(ehcidebug, "clear port ind " - "%d", index, 0, 0, 0); + DPRINTF("clear port ind %d", index, 0, 0, 0); EOWRITE4(sc, port, v &~ EHCI_PS_PIC); break; case UHF_C_PORT_CONNECTION: @@ -2444,8 +2426,7 @@ ehci_root_ctrl_start(usbd_xfer_handle xfer) sc->sc_isreset[index] = 0; break; default: - err = USBD_IOERROR; - goto ret; + return -1; } #if 0 switch(value) { @@ -2463,10 +2444,10 @@ ehci_root_ctrl_start(usbd_xfer_handle xfer) if (len == 0) break; if ((value & 0xff) != 0) { - err = USBD_IOERROR; - goto ret; + return -1; } - hubd = ehci_hubd; + totlen = min(buflen, sizeof(hubd)); + memcpy(&hubd, buf, totlen); hubd.bNbrPorts = sc->sc_noport; v = EOREAD4(sc, EHCI_HCSPARAMS); USETW(hubd.wHubCharacteristics, @@ -2477,30 +2458,26 @@ ehci_root_ctrl_start(usbd_xfer_handle xfer) for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8) hubd.DeviceRemovable[i++] = 0; /* XXX can't find out? */ hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i; - l = min(len, hubd.bDescLength); - totlen = l; - memcpy(buf, &hubd, l); + totlen = min(totlen, hubd.bDescLength); + memcpy(buf, &hubd, totlen); break; case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): if (len != 4) { - err = USBD_IOERROR; - goto ret; + return -1; } memset(buf, 0, len); /* ? XXX */ totlen = len; break; case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): - USBHIST_LOG(ehcidebug, "get port status i=%d", index, 0, 0, 0); + DPRINTF("get port status i=%d", index, 0, 0, 0); if (index < 1 || index > sc->sc_noport) { - err = USBD_IOERROR; - goto ret; + return -1; } if (len != 4) { - err = USBD_IOERROR; - goto ret; + return -1; } v = EOREAD4(sc, EHCI_PORTSC(index)); - USBHIST_LOG(ehcidebug, "port status=0x%04x", v, 0, 0, 0); + DPRINTF("port status=0x%04x", v, 0, 0, 0); i = UPS_HIGH_SPEED; if (sc->sc_flags & EHCIF_ETTF) { @@ -2527,23 +2504,20 @@ ehci_root_ctrl_start(usbd_xfer_handle xfer) if (v & EHCI_PS_OCC) i |= UPS_C_OVERCURRENT_INDICATOR; if (sc->sc_isreset[index]) i |= UPS_C_PORT_RESET; USETW(ps.wPortChange, i); - l = min(len, sizeof ps); - memcpy(buf, &ps, l); - totlen = l; + totlen = min(len, sizeof(ps)); + memcpy(buf, &ps, totlen); break; case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE): - err = USBD_IOERROR; - goto ret; + return -1; 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) { - err = USBD_IOERROR; - goto ret; + return -1; } port = EHCI_PORTSC(index); v = EOREAD4(sc, port); - USBHIST_LOG(ehcidebug, "portsc=0x%08x", v, 0, 0, 0); + DPRINTF("portsc=0x%08x", v, 0, 0, 0); v &= ~EHCI_PS_CLEAR; switch(value) { case UHF_PORT_ENABLE: @@ -2553,7 +2527,7 @@ ehci_root_ctrl_start(usbd_xfer_handle xfer) EOWRITE4(sc, port, v | EHCI_PS_SUSP); break; case UHF_PORT_RESET: - USBHIST_LOG(ehcidebug, "reset port %d", index, 0, 0, 0); + DPRINTF("reset port %d", index, 0, 0, 0); if (EHCI_PS_IS_LOWSPEED(v) && sc->sc_ncomp > 0 && !(sc->sc_flags & EHCIF_ETTF)) { @@ -2570,8 +2544,7 @@ ehci_root_ctrl_start(usbd_xfer_handle xfer) /* Wait for reset to complete. */ usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY); if (sc->sc_dying) { - err = USBD_IOERROR; - goto ret; + return -1; } /* * An embedded transaction translator will automatically @@ -2586,18 +2559,16 @@ ehci_root_ctrl_start(usbd_xfer_handle xfer) usb_delay_ms(&sc->sc_bus, EHCI_PORT_RESET_COMPLETE); if (sc->sc_dying) { - err = USBD_IOERROR; - goto ret; + return -1; } } v = EOREAD4(sc, port); - USBHIST_LOG(ehcidebug, - "ehci after reset, status=0x%08x", v, 0, 0, 0); + DPRINTF("ehci after reset, status=0x%08x", v, 0, 0, 0); if (v & EHCI_PS_PR) { printf("%s: port reset timeout\n", device_xname(sc->sc_dev)); - return (USBD_TIMEOUT); + return USBD_TIMEOUT; } if (!(v & EHCI_PS_PE)) { /* Not a high speed device, give up ownership.*/ @@ -2605,29 +2576,24 @@ ehci_root_ctrl_start(usbd_xfer_handle xfer) break; } sc->sc_isreset[index] = 1; - USBHIST_LOG(ehcidebug, - "ehci port %d reset, status = 0x%08x", index, v, 0, - 0); + DPRINTF("ehci port %d reset, status = 0x%08x", index, + v, 0, 0); break; case UHF_PORT_POWER: - USBHIST_LOG(ehcidebug, - "set port power %d (has PPC = %d)", index, + DPRINTF("set port power %d (has PPC = %d)", index, sc->sc_hasppc, 0, 0); if (sc->sc_hasppc) EOWRITE4(sc, port, v | EHCI_PS_PP); break; case UHF_PORT_TEST: - USBHIST_LOG(ehcidebug, "set port test %d", - index, 0, 0, 0); + DPRINTF("set port test %d", index, 0, 0, 0); break; case UHF_PORT_INDICATOR: - USBHIST_LOG(ehcidebug, "set port ind %d", - index, 0, 0, 0); + DPRINTF("set port ind %d", index, 0, 0, 0); EOWRITE4(sc, port, v | EHCI_PS_PIC); break; default: - err = USBD_IOERROR; - goto ret; + return -1; } break; case C(UR_CLEAR_TT_BUFFER, UT_WRITE_CLASS_OTHER): @@ -2636,28 +2602,26 @@ ehci_root_ctrl_start(usbd_xfer_handle xfer) case C(UR_STOP_TT, UT_WRITE_CLASS_OTHER): break; default: - err = USBD_IOERROR; - goto ret; + /* default from usbroothub */ + DPRINTF("returning %d (usbroothub default)", buflen, 0, 0, 0); + + return buflen; } - xfer->actlen = totlen; - err = USBD_NORMAL_COMPLETION; - ret: - mutex_enter(&sc->sc_lock); - xfer->status = err; - usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); - return (USBD_IN_PROGRESS); + + DPRINTF("returning %d", totlen, 0, 0, 0); + + return totlen; } Static void ehci_disown(ehci_softc_t *sc, int index, int lowspeed) { int port; - u_int32_t v; + uint32_t v; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "index=%d lowspeed=%d", index, lowspeed, 0, 0); + DPRINTF("index=%d lowspeed=%d", index, lowspeed, 0, 0); #ifdef DIAGNOSTIC if (sc->sc_npcomp != 0) { int i = (index-1) / sc->sc_npcomp; @@ -2679,31 +2643,10 @@ ehci_disown(ehci_softc_t *sc, int index, int lowspeed) EOWRITE4(sc, port, v | EHCI_PS_PO); } -/* Abort a root control request. */ -Static void -ehci_root_ctrl_abort(usbd_xfer_handle xfer) -{ - /* Nothing to do, all transfers are synchronous. */ -} - -/* Close the root pipe. */ -Static void -ehci_root_ctrl_close(usbd_pipe_handle pipe) -{ - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); - /* Nothing to do. */ -} - -Static void -ehci_root_ctrl_done(usbd_xfer_handle xfer) -{ - xfer->hcpriv = NULL; -} - Static usbd_status -ehci_root_intr_transfer(usbd_xfer_handle xfer) +ehci_root_intr_transfer(struct usbd_xfer *xfer) { - ehci_softc_t *sc = xfer->pipe->device->bus->hci_private; + ehci_softc_t *sc = EHCI_XFER2SC(xfer); usbd_status err; /* Insert last in queue. */ @@ -2711,50 +2654,49 @@ ehci_root_intr_transfer(usbd_xfer_handle xfer) err = usb_insert_transfer(xfer); mutex_exit(&sc->sc_lock); if (err) - return (err); + return err; /* Pipe isn't running, start first */ - return (ehci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return ehci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } Static usbd_status -ehci_root_intr_start(usbd_xfer_handle xfer) +ehci_root_intr_start(struct usbd_xfer *xfer) { - usbd_pipe_handle pipe = xfer->pipe; - ehci_softc_t *sc = pipe->device->bus->hci_private; + ehci_softc_t *sc = EHCI_XFER2SC(xfer); if (sc->sc_dying) - return (USBD_IOERROR); + return USBD_IOERROR; mutex_enter(&sc->sc_lock); sc->sc_intrxfer = xfer; mutex_exit(&sc->sc_lock); - return (USBD_IN_PROGRESS); + return USBD_IN_PROGRESS; } /* Abort a root interrupt request. */ Static void -ehci_root_intr_abort(usbd_xfer_handle xfer) +ehci_root_intr_abort(struct usbd_xfer *xfer) { - ehci_softc_t *sc = xfer->pipe->device->bus->hci_private; + ehci_softc_t *sc = EHCI_XFER2SC(xfer); KASSERT(mutex_owned(&sc->sc_lock)); - KASSERT(xfer->pipe->intrxfer == xfer); + KASSERT(xfer->ux_pipe->up_intrxfer == xfer); sc->sc_intrxfer = NULL; - xfer->status = USBD_CANCELLED; + xfer->ux_status = USBD_CANCELLED; usb_transfer_complete(xfer); } /* Close the root pipe. */ Static void -ehci_root_intr_close(usbd_pipe_handle pipe) +ehci_root_intr_close(struct usbd_pipe *pipe) { - ehci_softc_t *sc = pipe->device->bus->hci_private; + ehci_softc_t *sc = EHCI_PIPE2SC(pipe); - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); KASSERT(mutex_owned(&sc->sc_lock)); @@ -2762,9 +2704,8 @@ ehci_root_intr_close(usbd_pipe_handle pipe) } Static void -ehci_root_intr_done(usbd_xfer_handle xfer) +ehci_root_intr_done(struct usbd_xfer *xfer) { - xfer->hcpriv = NULL; } /************************/ @@ -2777,10 +2718,13 @@ ehci_alloc_sqh(ehci_softc_t *sc) int i, offs; usb_dma_t dma; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + mutex_enter(&sc->sc_lock); if (sc->sc_freeqhs == NULL) { - USBHIST_LOG(ehcidebug, "allocating chunk", 0, 0, 0, 0); + DPRINTF("allocating chunk", 0, 0, 0, 0); + mutex_exit(&sc->sc_lock); + err = usb_allocmem(&sc->sc_bus, EHCI_SQH_SIZE * EHCI_SQH_CHUNK, EHCI_PAGE_SIZE, &dma); #ifdef EHCI_DEBUG @@ -2788,7 +2732,9 @@ ehci_alloc_sqh(ehci_softc_t *sc) printf("ehci_alloc_sqh: usb_allocmem()=%d\n", err); #endif if (err) - return (NULL); + return NULL; + + mutex_enter(&sc->sc_lock); for (i = 0; i < EHCI_SQH_CHUNK; i++) { offs = i * EHCI_SQH_SIZE; sqh = KERNADDR(&dma, offs); @@ -2801,14 +2747,18 @@ ehci_alloc_sqh(ehci_softc_t *sc) } sqh = sc->sc_freeqhs; sc->sc_freeqhs = sqh->next; + mutex_exit(&sc->sc_lock); + memset(&sqh->qh, 0, sizeof(ehci_qh_t)); sqh->next = NULL; - return (sqh); + return sqh; } Static void ehci_free_sqh(ehci_softc_t *sc, ehci_soft_qh_t *sqh) { + KASSERT(mutex_owned(&sc->sc_lock)); + sqh->next = sc->sc_freeqhs; sc->sc_freeqhs = sqh; } @@ -2821,10 +2771,12 @@ ehci_alloc_sqtd(ehci_softc_t *sc) int i, offs; usb_dma_t dma; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + mutex_enter(&sc->sc_lock); if (sc->sc_freeqtds == NULL) { - USBHIST_LOG(ehcidebug, "allocating chunk", 0, 0, 0, 0); + DPRINTF("allocating chunk", 0, 0, 0, 0); + mutex_exit(&sc->sc_lock); err = usb_allocmem(&sc->sc_bus, EHCI_SQTD_SIZE*EHCI_SQTD_CHUNK, EHCI_PAGE_SIZE, &dma); @@ -2835,6 +2787,7 @@ ehci_alloc_sqtd(ehci_softc_t *sc) if (err) goto done; + mutex_enter(&sc->sc_lock); for (i = 0; i < EHCI_SQTD_CHUNK; i++) { offs = i * EHCI_SQTD_SIZE; sqtd = KERNADDR(&dma, offs); @@ -2849,178 +2802,218 @@ ehci_alloc_sqtd(ehci_softc_t *sc) sqtd = sc->sc_freeqtds; sc->sc_freeqtds = sqtd->nextqtd; + mutex_exit(&sc->sc_lock); + memset(&sqtd->qtd, 0, sizeof(ehci_qtd_t)); sqtd->nextqtd = NULL; sqtd->xfer = NULL; done: - return (sqtd); + return sqtd; } Static void ehci_free_sqtd(ehci_softc_t *sc, ehci_soft_qtd_t *sqtd) { - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); - + mutex_enter(&sc->sc_lock); sqtd->nextqtd = sc->sc_freeqtds; sc->sc_freeqtds = sqtd; + mutex_exit(&sc->sc_lock); } -Static usbd_status -ehci_alloc_sqtd_chain(struct ehci_pipe *epipe, ehci_softc_t *sc, - int alen, int rd, usbd_xfer_handle xfer, - ehci_soft_qtd_t **sp, ehci_soft_qtd_t **ep) +Static int +ehci_alloc_sqtd_chain(ehci_softc_t *sc, struct usbd_xfer *xfer, + int alen, int rd, ehci_soft_qtd_t **sp) +{ + struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); + uint16_t flags = xfer->ux_flags; + + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + + ASSERT_SLEEPABLE(); + KASSERT(sp); + KASSERT(alen != 0 || (!rd && (flags & USBD_FORCE_SHORT_XFER))); + + size_t nsqtd = (!rd && (flags & USBD_FORCE_SHORT_XFER)) ? 1 : 0; + nsqtd += ((alen + EHCI_PAGE_SIZE - 1) / EHCI_PAGE_SIZE); + exfer->ex_sqtds = kmem_zalloc(sizeof(ehci_soft_qtd_t *) * nsqtd, + KM_SLEEP); + exfer->ex_nsqtd = nsqtd; + + DPRINTF("xfer %p len %d nsqtd %d flags %x", xfer, alen, nsqtd, flags); + + for (size_t j = 0; j < exfer->ex_nsqtd;) { + ehci_soft_qtd_t *cur = ehci_alloc_sqtd(sc); + if (cur == NULL) + goto nomem; + exfer->ex_sqtds[j++] = cur; + + cur->xfer = xfer; + cur->len = 0; + + } + + *sp = exfer->ex_sqtds[0]; + DPRINTF("return sqtd=%p", *sp, 0, 0, 0); + + return 0; + + nomem: + ehci_free_sqtds(sc, exfer); + kmem_free(exfer->ex_sqtds, sizeof(ehci_soft_qtd_t *) * nsqtd); + DPRINTF("no memory", 0, 0, 0, 0); + return ENOMEM; +} + +Static void +ehci_free_sqtds(ehci_softc_t *sc, struct ehci_xfer *exfer) +{ + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + DPRINTF("exfer=%p", exfer, 0, 0, 0); + + mutex_enter(&sc->sc_lock); + for (size_t i = 0; i < exfer->ex_nsqtd; i++) { + ehci_soft_qtd_t *sqtd = exfer->ex_sqtds[i]; + + if (sqtd == NULL) + break; + + sqtd->nextqtd = sc->sc_freeqtds; + sc->sc_freeqtds = sqtd; + } + mutex_exit(&sc->sc_lock); +} + +Static void +ehci_append_sqtd(ehci_soft_qtd_t *sqtd, ehci_soft_qtd_t *prev) +{ + if (prev) { + prev->nextqtd = sqtd; + prev->qtd.qtd_next = htole32(sqtd->physaddr); + prev->qtd.qtd_altnext = prev->qtd.qtd_next; + usb_syncmem(&prev->dma, prev->offs, sizeof(prev->qtd), + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); + } +} + +Static void +ehci_reset_sqtd_chain(ehci_softc_t *sc, struct usbd_xfer *xfer, + int length, int isread, int *toggle, ehci_soft_qtd_t **lsqtd) { - ehci_soft_qtd_t *next, *cur; - ehci_physaddr_t nextphys; - u_int32_t qtdstatus; - int len, curlen, mps; - int i, tog; - int pages, pageoffs; - bus_size_t curoffs; - vaddr_t va, va_offs; - usb_dma_t *dma = &xfer->dmabuf; - u_int16_t flags = xfer->flags; - paddr_t a; - - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); - - USBHIST_LOG(ehcidebug, "start len=%d", alen, 0, 0, 0); - - len = alen; - qtdstatus = EHCI_QTD_ACTIVE | - EHCI_QTD_SET_PID(rd ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT) | + struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); + usb_dma_t *dma = &xfer->ux_dmabuf; + uint16_t flags = xfer->ux_flags; + ehci_soft_qtd_t *sqtd, *prev; + int tog = *toggle; + int mps = UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize); + int len = length; + + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + DPRINTF("xfer=%p len %d isread %d toggle %d", xfer, len, isread, tog); + DPRINTF(" VA %p", KERNADDR(&xfer->ux_dmabuf, 0), 0, 0, 0); + + KASSERT(length != 0 || (!isread && (flags & USBD_FORCE_SHORT_XFER))); + + const uint32_t qtdstatus = EHCI_QTD_ACTIVE | + EHCI_QTD_SET_PID(isread ? EHCI_QTD_PID_IN : EHCI_QTD_PID_OUT) | EHCI_QTD_SET_CERR(3) - /* IOC set below */ - /* BYTES set below */ ; - mps = UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize); - tog = epipe->nexttoggle; - qtdstatus |= EHCI_QTD_SET_TOGGLE(tog); - - cur = ehci_alloc_sqtd(sc); - *sp = cur; - if (cur == NULL) - goto nomem; - - usb_syncmem(dma, 0, alen, - rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); - curoffs = 0; - for (;;) { - /* The EHCI hardware can handle at most 5 pages. */ - va_offs = (vaddr_t)KERNADDR(dma, curoffs); - va_offs = EHCI_PAGE_OFFSET(va_offs); - if (len-curoffs < EHCI_QTD_NBUFFERS*EHCI_PAGE_SIZE - va_offs) { - /* we can handle it in this QTD */ - curlen = len - curoffs; - } else { - /* must use multiple TDs, fill as much as possible. */ - curlen = EHCI_QTD_NBUFFERS * EHCI_PAGE_SIZE - va_offs; - /* the length must be a multiple of the max size */ - curlen -= curlen % mps; - USBHIST_LOG(ehcidebug, "multiple QTDs, " - "curlen=%d", curlen, 0, 0, 0); -#ifdef DIAGNOSTIC - if (curlen == 0) - panic("ehci_alloc_sqtd_chain: curlen == 0"); -#endif - } - USBHIST_LOG(ehcidebug, "len=%d curlen=%d curoffs=%zu", - len, curlen, (size_t)curoffs, 0); + sqtd = prev = NULL; + size_t curoffs = 0; + size_t j = 0; + for (; len != 0 && j < exfer->ex_nsqtd; prev = sqtd) { + sqtd = exfer->ex_sqtds[j++]; + DPRINTF("sqtd[%d]=%p prev %p", j, sqtd, prev, 0); /* - * Allocate another transfer if there's more data left, - * or if force last short transfer flag is set and we're - * allocating a multiple of the max packet size. + * The EHCI hardware can handle at most 5 pages and they do + * not have to be contiguous */ + vaddr_t va = (vaddr_t)KERNADDR(dma, curoffs); + vaddr_t va_offs = EHCI_PAGE_OFFSET(va); + size_t curlen = len; + if (curlen >= EHCI_QTD_MAXTRANSFER - va_offs) { + /* must use multiple TDs, fill as much as possible. */ + curlen = EHCI_QTD_MAXTRANSFER - va_offs; - if (curoffs + curlen != len || - ((curlen % mps) == 0 && !rd && curlen != 0 && - (flags & USBD_FORCE_SHORT_XFER))) { - next = ehci_alloc_sqtd(sc); - if (next == NULL) - goto nomem; - nextphys = htole32(next->physaddr); - } else { - next = NULL; - nextphys = EHCI_NULL; + /* the length must be a multiple of the max size */ + curlen -= curlen % mps; } + KASSERT(curlen != 0); + DPRINTF(" len=%d curlen=%d curoffs=%zu", len, curlen, + curoffs, 0); + + /* Fill the qTD */ + sqtd->qtd.qtd_next = sqtd->qtd.qtd_altnext = EHCI_NULL; + sqtd->qtd.qtd_status = htole32( + qtdstatus | + EHCI_QTD_SET_BYTES(curlen) | + EHCI_QTD_SET_TOGGLE(tog)); /* Find number of pages we'll be using, insert dma addresses */ - pages = EHCI_PAGE(curlen + EHCI_PAGE_SIZE -1) >> 12; + size_t pages = EHCI_NPAGES(curlen); KASSERT(pages <= EHCI_QTD_NBUFFERS); - pageoffs = EHCI_PAGE(curoffs); - for (i = 0; i < pages; i++) { - a = DMAADDR(dma, pageoffs + i * EHCI_PAGE_SIZE); - cur->qtd.qtd_buffer[i] = htole32(a & 0xFFFFF000); + size_t pageoffs = EHCI_PAGE(curoffs); + for (size_t i = 0; i < pages; i++) { + paddr_t a = DMAADDR(dma, + pageoffs + i * EHCI_PAGE_SIZE); + sqtd->qtd.qtd_buffer[i] = htole32(EHCI_PAGE(a)); /* Cast up to avoid compiler warnings */ - cur->qtd.qtd_buffer_hi[i] = htole32((uint64_t)a >> 32); + sqtd->qtd.qtd_buffer_hi[i] = htole32((uint64_t)a >> 32); + DPRINTF(" buffer[%d/%d] 0x%08x 0x%08x", i, pages, + le32toh(sqtd->qtd.qtd_buffer_hi[i]), + le32toh(sqtd->qtd.qtd_buffer[i])); } - /* First buffer pointer requires a page offset to start at */ - va = (vaddr_t)KERNADDR(dma, curoffs); - cur->qtd.qtd_buffer[0] |= htole32(EHCI_PAGE_OFFSET(va)); - - cur->nextqtd = next; - cur->qtd.qtd_next = cur->qtd.qtd_altnext = nextphys; - cur->qtd.qtd_status = - htole32(qtdstatus | EHCI_QTD_SET_BYTES(curlen)); - cur->xfer = xfer; - cur->len = curlen; + sqtd->qtd.qtd_buffer[0] |= htole32(va_offs); - USBHIST_LOG(ehcidebug, "cbp=0x%08zx end=0x%08zx", - (size_t)curoffs, (size_t)(curoffs + curlen), 0, 0); - - /* adjust the toggle based on the number of packets in this - qtd */ - if (((curlen + mps - 1) / mps) & 1) { - tog ^= 1; - qtdstatus ^= EHCI_QTD_TOGGLE_MASK; - } - if (next == NULL) - break; - usb_syncmem(&cur->dma, cur->offs, sizeof(cur->qtd), + usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - USBHIST_LOG(ehcidebug, "extend chain", 0, 0, 0, 0); - if (len) - curoffs += curlen; - cur = next; - } - cur->qtd.qtd_status |= htole32(EHCI_QTD_IOC); - usb_syncmem(&cur->dma, cur->offs, sizeof(cur->qtd), - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - *ep = cur; - epipe->nexttoggle = tog; - USBHIST_LOG(ehcidebug, "return sqtd=%p sqtdend=%p", - *sp, *ep, 0, 0); + sqtd->len = curlen; - return (USBD_NORMAL_COMPLETION); + DPRINTF(" va %p pa %p len %d", va, + DMAADDR(&xfer->ux_dmabuf, curoffs), curlen, 0); - nomem: - /* XXX free chain */ - USBHIST_LOG(ehcidebug, "no memory", 0, 0, 0, 0); - return (USBD_NOMEM); -} + ehci_append_sqtd(sqtd, prev); -Static void -ehci_free_sqtd_chain(ehci_softc_t *sc, ehci_soft_qtd_t *sqtd, - ehci_soft_qtd_t *sqtdend) -{ - ehci_soft_qtd_t *p; - int i; + if (((curlen + mps - 1) / mps) & 1) { + tog ^= 1; + } - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + curoffs += curlen; + len -= curlen; + } + KASSERTMSG(len == 0, "xfer %p olen %d len %d mps %d ex_nsqtd %zu j %zu", + xfer, length, len, mps, exfer->ex_nsqtd, j); + + if (!isread && + (flags & USBD_FORCE_SHORT_XFER) && + length % mps == 0) { + /* Force a 0 length transfer at the end. */ + + KASSERTMSG(j < exfer->ex_nsqtd, "j=%zu nsqtd=%zu", j, + exfer->ex_nsqtd); + prev = sqtd; + sqtd = exfer->ex_sqtds[j++]; + memset(&sqtd->qtd, 0, sizeof(sqtd->qtd)); + sqtd->qtd.qtd_next = sqtd->qtd.qtd_altnext = EHCI_NULL; + sqtd->qtd.qtd_status = htole32( + qtdstatus | + EHCI_QTD_SET_BYTES(0) | + EHCI_QTD_SET_TOGGLE(tog)); - USBHIST_LOG(ehcidebug, "sqtd=%p sqtdend=%p", - sqtd, sqtdend, 0, 0); + usb_syncmem(&sqtd->dma, sqtd->offs, sizeof(sqtd->qtd), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - for (i = 0; sqtd != sqtdend; sqtd = p, i++) { - p = sqtd->nextqtd; - ehci_free_sqtd(sc, sqtd); + ehci_append_sqtd(sqtd, prev); + tog ^= 1; } + + *lsqtd = sqtd; + *toggle = tog; } Static ehci_soft_itd_t * @@ -3028,77 +3021,97 @@ ehci_alloc_itd(ehci_softc_t *sc) { struct ehci_soft_itd *itd, *freeitd; usbd_status err; - int i, offs, frindex, previndex; usb_dma_t dma; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); mutex_enter(&sc->sc_lock); - /* Find an itd that wasn't freed this frame or last frame. This can - * discard itds that were freed before frindex wrapped around - * XXX - can this lead to thrashing? Could fix by enabling wrap-around - * interrupt and fiddling with list when that happens */ - frindex = (EOREAD4(sc, EHCI_FRINDEX) + 1) >> 3; - previndex = (frindex != 0) ? frindex - 1 : sc->sc_flsize; - - freeitd = NULL; - LIST_FOREACH(itd, &sc->sc_freeitds, u.free_list) { - if (itd == NULL) - break; - if (itd->slot != frindex && itd->slot != previndex) { - freeitd = itd; - break; - } - } - + freeitd = LIST_FIRST(&sc->sc_freeitds); if (freeitd == NULL) { - USBHIST_LOG(ehcidebug, "allocating chunk", 0, 0, 0, 0); + DPRINTF("allocating chunk", 0, 0, 0, 0); + mutex_exit(&sc->sc_lock); err = usb_allocmem(&sc->sc_bus, EHCI_ITD_SIZE * EHCI_ITD_CHUNK, EHCI_PAGE_SIZE, &dma); if (err) { - USBHIST_LOG(ehcidebug, - "alloc returned %d", err, 0, 0, 0); - mutex_exit(&sc->sc_lock); + DPRINTF("alloc returned %d", err, 0, 0, 0); return NULL; } + mutex_enter(&sc->sc_lock); - for (i = 0; i < EHCI_ITD_CHUNK; i++) { - offs = i * EHCI_ITD_SIZE; + for (int i = 0; i < EHCI_ITD_CHUNK; i++) { + int offs = i * EHCI_ITD_SIZE; itd = KERNADDR(&dma, offs); itd->physaddr = DMAADDR(&dma, offs); itd->dma = dma; itd->offs = offs; - LIST_INSERT_HEAD(&sc->sc_freeitds, itd, u.free_list); + LIST_INSERT_HEAD(&sc->sc_freeitds, itd, free_list); } freeitd = LIST_FIRST(&sc->sc_freeitds); } itd = freeitd; - LIST_REMOVE(itd, u.free_list); + LIST_REMOVE(itd, free_list); + mutex_exit(&sc->sc_lock); memset(&itd->itd, 0, sizeof(ehci_itd_t)); - usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_next), - sizeof(itd->itd.itd_next), BUS_DMASYNC_PREWRITE | - BUS_DMASYNC_PREREAD); - itd->u.frame_list.next = NULL; - itd->u.frame_list.prev = NULL; + itd->frame_list.next = NULL; + itd->frame_list.prev = NULL; itd->xfer_next = NULL; itd->slot = 0; - mutex_exit(&sc->sc_lock); - return itd; } -Static void -ehci_free_itd(ehci_softc_t *sc, ehci_soft_itd_t *itd) +Static ehci_soft_sitd_t * +ehci_alloc_sitd(ehci_softc_t *sc) { + struct ehci_soft_sitd *sitd, *freesitd; + usbd_status err; + int i, offs; + usb_dma_t dma; - KASSERT(mutex_owned(&sc->sc_lock)); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + + mutex_enter(&sc->sc_lock); + freesitd = LIST_FIRST(&sc->sc_freesitds); + if (freesitd == NULL) { + DPRINTF("allocating chunk", 0, 0, 0, 0); + mutex_exit(&sc->sc_lock); + err = usb_allocmem(&sc->sc_bus, EHCI_SITD_SIZE * EHCI_SITD_CHUNK, + EHCI_PAGE_SIZE, &dma); + + if (err) { + DPRINTF("alloc returned %d", err, 0, 0, + 0); + return NULL; + } + + mutex_enter(&sc->sc_lock); + for (i = 0; i < EHCI_SITD_CHUNK; i++) { + offs = i * EHCI_SITD_SIZE; + sitd = KERNADDR(&dma, offs); + sitd->physaddr = DMAADDR(&dma, offs); + sitd->dma = dma; + sitd->offs = offs; + LIST_INSERT_HEAD(&sc->sc_freesitds, sitd, free_list); + } + freesitd = LIST_FIRST(&sc->sc_freesitds); + } + + sitd = freesitd; + LIST_REMOVE(sitd, free_list); + mutex_exit(&sc->sc_lock); + + memset(&sitd->sitd, 0, sizeof(ehci_sitd_t)); - LIST_INSERT_HEAD(&sc->sc_freeitds, itd, u.free_list); + sitd->frame_list.next = NULL; + sitd->frame_list.prev = NULL; + sitd->xfer_next = NULL; + sitd->slot = 0; + + return sitd; } /****************/ @@ -3108,10 +3121,10 @@ ehci_free_itd(ehci_softc_t *sc, ehci_soft_itd_t *itd) * Assumes that there are no pending transactions. */ Static void -ehci_close_pipe(usbd_pipe_handle pipe, ehci_soft_qh_t *head) +ehci_close_pipe(struct usbd_pipe *pipe, ehci_soft_qh_t *head) { - struct ehci_pipe *epipe = (struct ehci_pipe *)pipe; - ehci_softc_t *sc = pipe->device->bus->hci_private; + struct ehci_pipe *epipe = EHCI_PIPE2EPIPE(pipe); + ehci_softc_t *sc = EHCI_PIPE2SC(pipe); ehci_soft_qh_t *sqh = epipe->sqh; KASSERT(mutex_owned(&sc->sc_lock)); @@ -3133,61 +3146,59 @@ ehci_close_pipe(usbd_pipe_handle pipe, ehci_soft_qh_t *head) * XXXMRG this doesn't make sense anymore. */ Static void -ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status) +ehci_abort_xfer(struct usbd_xfer *xfer, usbd_status status) { -#define exfer EXFER(xfer) - struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe; - ehci_softc_t *sc = epipe->pipe.device->bus->hci_private; + struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); + struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); + ehci_softc_t *sc = EHCI_XFER2SC(xfer); ehci_soft_qh_t *sqh = epipe->sqh; - ehci_soft_qtd_t *sqtd; + ehci_soft_qtd_t *sqtd, *fsqtd, *lsqtd; ehci_physaddr_t cur; - u_int32_t qhstatus; + uint32_t qhstatus; int hit; int wake; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "xfer=%p pipe=%p", xfer, epipe, 0, 0); + DPRINTF("xfer=%p pipe=%p", xfer, epipe, 0, 0); KASSERT(mutex_owned(&sc->sc_lock)); + ASSERT_SLEEPABLE(); if (sc->sc_dying) { /* If we're dying, just do the software part. */ - xfer->status = status; /* make software ignore it */ - callout_stop(&xfer->timeout_handle); + xfer->ux_status = status; /* make software ignore it */ + callout_stop(&xfer->ux_callout); usb_transfer_complete(xfer); return; } - if (cpu_intr_p() || cpu_softintr_p()) - panic("ehci_abort_xfer: not in process context"); - /* * If an abort is already in progress then just wait for it to * complete and return. */ - if (xfer->hcflags & UXFER_ABORTING) { - USBHIST_LOG(ehcidebug, "already aborting", 0, 0, 0, 0); + if (xfer->ux_hcflags & UXFER_ABORTING) { + DPRINTF("already aborting", 0, 0, 0, 0); #ifdef DIAGNOSTIC if (status == USBD_TIMEOUT) printf("ehci_abort_xfer: TIMEOUT while aborting\n"); #endif /* Override the status which might be USBD_TIMEOUT. */ - xfer->status = status; - USBHIST_LOG(ehcidebug, "waiting for abort to finish", - 0, 0, 0, 0); - xfer->hcflags |= UXFER_ABORTWAIT; - while (xfer->hcflags & UXFER_ABORTING) - cv_wait(&xfer->hccv, &sc->sc_lock); + xfer->ux_status = status; + DPRINTF("waiting for abort to finish", 0, 0, 0, 0); + xfer->ux_hcflags |= UXFER_ABORTWAIT; + while (xfer->ux_hcflags & UXFER_ABORTING) + cv_wait(&xfer->ux_hccv, &sc->sc_lock); return; } - xfer->hcflags |= UXFER_ABORTING; + xfer->ux_hcflags |= UXFER_ABORTING; /* * Step 1: Make interrupt routine and hardware ignore xfer. */ - xfer->status = status; /* make software ignore it */ - callout_stop(&xfer->timeout_handle); + xfer->ux_status = status; /* make software ignore it */ + callout_stop(&xfer->ux_callout); + ehci_del_intr_list(sc, exfer); usb_syncmem(&sqh->dma, sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status), @@ -3199,7 +3210,15 @@ ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status) sqh->offs + offsetof(ehci_qh_t, qh_qtd.qtd_status), sizeof(sqh->qh.qh_qtd.qtd_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - for (sqtd = exfer->sqtdstart; ; sqtd = sqtd->nextqtd) { + + if (exfer->ex_type == EX_CTRL) { + fsqtd = exfer->ex_setup; + lsqtd = exfer->ex_status; + } else { + fsqtd = exfer->ex_sqtdstart; + lsqtd = exfer->ex_sqtdend; + } + for (sqtd = fsqtd; ; sqtd = sqtd->nextqtd) { usb_syncmem(&sqtd->dma, sqtd->offs + offsetof(ehci_qtd_t, qtd_status), sizeof(sqtd->qtd.qtd_status), @@ -3209,7 +3228,7 @@ ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status) sqtd->offs + offsetof(ehci_qtd_t, qtd_status), sizeof(sqtd->qtd.qtd_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - if (sqtd == exfer->sqtdend) + if (sqtd == lsqtd) break; } @@ -3237,15 +3256,15 @@ ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status) BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); cur = EHCI_LINK_ADDR(le32toh(sqh->qh.qh_curqtd)); hit = 0; - for (sqtd = exfer->sqtdstart; ; sqtd = sqtd->nextqtd) { + for (sqtd = fsqtd; ; sqtd = sqtd->nextqtd) { hit |= cur == sqtd->physaddr; - if (sqtd == exfer->sqtdend) + if (sqtd == lsqtd) break; } sqtd = sqtd->nextqtd; /* Zap curqtd register if hardware pointed inside the xfer. */ if (hit && sqtd != NULL) { - USBHIST_LOG(ehcidebug, "cur=0x%08x", sqtd->physaddr, 0, 0, 0); + DPRINTF("cur=0x%08x", sqtd->physaddr, 0, 0, 0); sqh->qh.qh_curqtd = htole32(sqtd->physaddr); /* unlink qTDs */ usb_syncmem(&sqh->dma, sqh->offs + offsetof(ehci_qh_t, qh_curqtd), @@ -3257,104 +3276,126 @@ ehci_abort_xfer(usbd_xfer_handle xfer, usbd_status status) sizeof(sqh->qh.qh_qtd.qtd_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } else { - USBHIST_LOG(ehcidebug, "no hit", 0, 0, 0, 0); + DPRINTF("no hit", 0, 0, 0, 0); + usb_syncmem(&sqh->dma, + sqh->offs + offsetof(ehci_qh_t, qh_curqtd), + sizeof(sqh->qh.qh_curqtd), + BUS_DMASYNC_PREREAD); } /* * Step 4: Execute callback. */ #ifdef DIAGNOSTIC - exfer->isdone = 1; + exfer->ex_isdone = true; #endif - wake = xfer->hcflags & UXFER_ABORTWAIT; - xfer->hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); + wake = xfer->ux_hcflags & UXFER_ABORTWAIT; + xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); usb_transfer_complete(xfer); if (wake) { - cv_broadcast(&xfer->hccv); + cv_broadcast(&xfer->ux_hccv); } KASSERT(mutex_owned(&sc->sc_lock)); -#undef exfer } Static void -ehci_abort_isoc_xfer(usbd_xfer_handle xfer, usbd_status status) +ehci_abort_isoc_xfer(struct usbd_xfer *xfer, usbd_status status) { ehci_isoc_trans_t trans_status; - struct ehci_pipe *epipe; struct ehci_xfer *exfer; ehci_softc_t *sc; struct ehci_soft_itd *itd; + struct ehci_soft_sitd *sitd; int i, wake; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - epipe = (struct ehci_pipe *) xfer->pipe; - exfer = EXFER(xfer); - sc = epipe->pipe.device->bus->hci_private; + exfer = EHCI_XFER2EXFER(xfer); + sc = EHCI_XFER2SC(xfer); - USBHIST_LOG(ehcidebug, "xfer %p pipe %p", xfer, epipe, 0, 0); + DPRINTF("xfer %p pipe %p", xfer, xfer->ux_pipe, 0, 0); KASSERT(mutex_owned(&sc->sc_lock)); if (sc->sc_dying) { - xfer->status = status; - callout_stop(&xfer->timeout_handle); + xfer->ux_status = status; + callout_stop(&xfer->ux_callout); usb_transfer_complete(xfer); return; } - if (xfer->hcflags & UXFER_ABORTING) { - USBHIST_LOG(ehcidebug, "already aborting", 0, 0, 0, 0); + if (xfer->ux_hcflags & UXFER_ABORTING) { + DPRINTF("already aborting", 0, 0, 0, 0); #ifdef DIAGNOSTIC if (status == USBD_TIMEOUT) printf("ehci_abort_isoc_xfer: TIMEOUT while aborting\n"); #endif - xfer->status = status; - USBHIST_LOG(ehcidebug, - "waiting for abort to finish", 0, 0, 0, 0); - xfer->hcflags |= UXFER_ABORTWAIT; - while (xfer->hcflags & UXFER_ABORTING) - cv_wait(&xfer->hccv, &sc->sc_lock); + xfer->ux_status = status; + DPRINTF("waiting for abort to finish", 0, 0, 0, 0); + xfer->ux_hcflags |= UXFER_ABORTWAIT; + while (xfer->ux_hcflags & UXFER_ABORTING) + cv_wait(&xfer->ux_hccv, &sc->sc_lock); goto done; } - xfer->hcflags |= UXFER_ABORTING; + xfer->ux_hcflags |= UXFER_ABORTING; - xfer->status = status; - callout_stop(&xfer->timeout_handle); + xfer->ux_status = status; + callout_stop(&xfer->ux_callout); + ehci_del_intr_list(sc, exfer); - for (itd = exfer->itdstart; itd != NULL; itd = itd->xfer_next) { - usb_syncmem(&itd->dma, - itd->offs + offsetof(ehci_itd_t, itd_ctl), - sizeof(itd->itd.itd_ctl), - BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); + if (xfer->ux_pipe->up_dev->ud_speed == USB_SPEED_HIGH) { + for (itd = exfer->ex_itdstart; itd != NULL; + itd = itd->xfer_next) { + usb_syncmem(&itd->dma, + itd->offs + offsetof(ehci_itd_t, itd_ctl), + sizeof(itd->itd.itd_ctl), + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); + + for (i = 0; i < 8; i++) { + trans_status = le32toh(itd->itd.itd_ctl[i]); + trans_status &= ~EHCI_ITD_ACTIVE; + itd->itd.itd_ctl[i] = htole32(trans_status); + } - for (i = 0; i < 8; i++) { - trans_status = le32toh(itd->itd.itd_ctl[i]); - trans_status &= ~EHCI_ITD_ACTIVE; - itd->itd.itd_ctl[i] = htole32(trans_status); + usb_syncmem(&itd->dma, + itd->offs + offsetof(ehci_itd_t, itd_ctl), + sizeof(itd->itd.itd_ctl), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } + } else { + for (sitd = exfer->ex_sitdstart; sitd != NULL; + sitd = sitd->xfer_next) { + usb_syncmem(&sitd->dma, + sitd->offs + offsetof(ehci_sitd_t, sitd_buffer), + sizeof(sitd->sitd.sitd_buffer), + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - usb_syncmem(&itd->dma, - itd->offs + offsetof(ehci_itd_t, itd_ctl), - sizeof(itd->itd.itd_ctl), - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + trans_status = le32toh(sitd->sitd.sitd_trans); + trans_status &= ~EHCI_SITD_ACTIVE; + sitd->sitd.sitd_trans = htole32(trans_status); + + usb_syncmem(&sitd->dma, + sitd->offs + offsetof(ehci_sitd_t, sitd_buffer), + sizeof(sitd->sitd.sitd_buffer), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + } } - sc->sc_softwake = 1; - usb_schedsoftintr(&sc->sc_bus); + sc->sc_softwake = 1; + usb_schedsoftintr(&sc->sc_bus); cv_wait(&sc->sc_softwake_cv, &sc->sc_lock); #ifdef DIAGNOSTIC - exfer->isdone = 1; + exfer->ex_isdone = true; #endif - wake = xfer->hcflags & UXFER_ABORTWAIT; - xfer->hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); + wake = xfer->ux_hcflags & UXFER_ABORTWAIT; + xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); usb_transfer_complete(xfer); if (wake) { - cv_broadcast(&xfer->hccv); + cv_broadcast(&xfer->ux_hccv); } done: @@ -3365,41 +3406,42 @@ done: Static void ehci_timeout(void *addr) { - struct ehci_xfer *exfer = addr; - struct ehci_pipe *epipe = (struct ehci_pipe *)exfer->xfer.pipe; - ehci_softc_t *sc = epipe->pipe.device->bus->hci_private; + struct usbd_xfer *xfer = addr; + struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); + struct usbd_pipe *pipe = xfer->ux_pipe; + struct usbd_device *dev = pipe->up_dev; + ehci_softc_t *sc = EHCI_XFER2SC(xfer); - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "exfer %p", exfer, 0, 0, 0); + DPRINTF("exfer %p", exfer, 0, 0, 0); #ifdef EHCI_DEBUG - if (ehcidebug > 1) - usbd_dump_pipe(exfer->xfer.pipe); + if (ehcidebug >= 2) + usbd_dump_pipe(pipe); #endif if (sc->sc_dying) { mutex_enter(&sc->sc_lock); - ehci_abort_xfer(&exfer->xfer, USBD_TIMEOUT); + ehci_abort_xfer(xfer, USBD_TIMEOUT); mutex_exit(&sc->sc_lock); return; } /* Execute the abort in a process context. */ - usb_init_task(&exfer->abort_task, ehci_timeout_task, addr, + usb_init_task(&exfer->ex_aborttask, ehci_timeout_task, xfer, USB_TASKQ_MPSAFE); - usb_add_task(exfer->xfer.pipe->device, &exfer->abort_task, - USB_TASKQ_HC); + usb_add_task(dev, &exfer->ex_aborttask, USB_TASKQ_HC); } Static void ehci_timeout_task(void *addr) { - usbd_xfer_handle xfer = addr; - ehci_softc_t *sc = xfer->pipe->device->bus->hci_private; + struct usbd_xfer *xfer = addr; + ehci_softc_t *sc = EHCI_XFER2SC(xfer); - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "xfer=%p", xfer, 0, 0, 0); + DPRINTF("xfer=%p", xfer, 0, 0, 0); mutex_enter(&sc->sc_lock); ehci_abort_xfer(xfer, USBD_TIMEOUT); @@ -3408,269 +3450,314 @@ ehci_timeout_task(void *addr) /************************/ -Static usbd_status -ehci_device_ctrl_transfer(usbd_xfer_handle xfer) -{ - ehci_softc_t *sc = xfer->pipe->device->bus->hci_private; - usbd_status err; - - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return (err); - - /* Pipe isn't running, start first */ - return (ehci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); -} - -Static usbd_status -ehci_device_ctrl_start(usbd_xfer_handle xfer) +Static int +ehci_device_ctrl_init(struct usbd_xfer *xfer) { - ehci_softc_t *sc = xfer->pipe->device->bus->hci_private; - usbd_status err; - - if (sc->sc_dying) - return (USBD_IOERROR); + struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); + struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + usb_device_request_t *req = &xfer->ux_request; + ehci_soft_qtd_t *setup, *status, *next; + int isread = req->bmRequestType & UT_READ; + int len = xfer->ux_bufsize; + int err; -#ifdef DIAGNOSTIC - if (!(xfer->rqflags & URQ_REQUEST)) { - /* XXX panic */ - printf("ehci_device_ctrl_transfer: not a request\n"); - return (USBD_INVAL); + exfer->ex_type = EX_CTRL; + exfer->ex_status = NULL; + exfer->ex_data = NULL; + exfer->ex_setup = ehci_alloc_sqtd(sc); + if (exfer->ex_setup == NULL) { + err = ENOMEM; + goto bad1; } -#endif - - err = ehci_device_request(xfer); - if (err) { - return (err); + exfer->ex_status = ehci_alloc_sqtd(sc); + if (exfer->ex_status == NULL) { + err = ENOMEM; + goto bad2; } - - if (sc->sc_bus.use_polling) - ehci_waitintr(sc, xfer); - - return (USBD_IN_PROGRESS); -} - -Static void -ehci_device_ctrl_done(usbd_xfer_handle xfer) -{ - struct ehci_xfer *ex = EXFER(xfer); - ehci_softc_t *sc = xfer->pipe->device->bus->hci_private; - struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe; - usb_device_request_t *req = &xfer->request; - int len = UGETW(req->wLength); - int rd = req->bmRequestType & UT_READ; - - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); - - USBHIST_LOG(ehcidebug, "xfer=%p", xfer, 0, 0, 0); - - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); - -#ifdef DIAGNOSTIC - if (!(xfer->rqflags & URQ_REQUEST)) { - panic("ehci_ctrl_done: not a request"); + setup = exfer->ex_setup; + status = exfer->ex_status; + exfer->ex_nsqtd = 0; + next = status; + /* Set up data transaction */ + if (len != 0) { + err = ehci_alloc_sqtd_chain(sc, xfer, len, isread, + &exfer->ex_data); + if (err) + goto bad3; + next = exfer->ex_data; } -#endif - if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) { - ehci_del_intr_list(sc, ex); /* remove from active list */ - ehci_free_sqtd_chain(sc, ex->sqtdstart, NULL); - usb_syncmem(&epipe->u.ctl.reqdma, 0, sizeof *req, - BUS_DMASYNC_POSTWRITE); - if (len) - usb_syncmem(&xfer->dmabuf, 0, len, - rd ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); - } + /* Clear toggle */ + setup->qtd.qtd_status = htole32( + EHCI_QTD_SET_PID(EHCI_QTD_PID_SETUP) | + EHCI_QTD_SET_TOGGLE(0) | + EHCI_QTD_SET_BYTES(sizeof(*req)) + ); + setup->qtd.qtd_buffer[0] = htole32(DMAADDR(&epipe->ctrl.reqdma, 0)); + setup->qtd.qtd_buffer_hi[0] = 0; + setup->qtd.qtd_next = setup->qtd.qtd_altnext = htole32(next->physaddr); + setup->nextqtd = next; + setup->xfer = xfer; + setup->len = sizeof(*req); - USBHIST_LOG(ehcidebug, "length=%d", xfer->actlen, 0, 0, 0); + status->qtd.qtd_status = htole32( + EHCI_QTD_SET_PID(isread ? EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN) | + EHCI_QTD_SET_TOGGLE(1) | + EHCI_QTD_IOC + ); + status->qtd.qtd_buffer[0] = 0; + status->qtd.qtd_buffer_hi[0] = 0; + status->qtd.qtd_next = status->qtd.qtd_altnext = EHCI_NULL; + status->nextqtd = NULL; + status->xfer = xfer; + status->len = 0; + + return 0; +bad3: + ehci_free_sqtd(sc, exfer->ex_status); +bad2: + ehci_free_sqtd(sc, exfer->ex_setup); +bad1: + return err; } -/* Abort a device control request. */ Static void -ehci_device_ctrl_abort(usbd_xfer_handle xfer) +ehci_device_ctrl_fini(struct usbd_xfer *xfer) { - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + struct ehci_xfer *ex = EHCI_XFER2EXFER(xfer); - USBHIST_LOG(ehcidebug, "xfer=%p", xfer, 0, 0, 0); - ehci_abort_xfer(xfer, USBD_CANCELLED); + KASSERT(ex->ex_type == EX_CTRL); + + ehci_free_sqtd(sc, ex->ex_setup); + ehci_free_sqtd(sc, ex->ex_status); + ehci_free_sqtds(sc, ex); + if (ex->ex_nsqtd) + kmem_free(ex->ex_sqtds, + sizeof(ehci_soft_qtd_t *) * ex->ex_nsqtd); } -/* Close a device control pipe. */ -Static void -ehci_device_ctrl_close(usbd_pipe_handle pipe) +Static usbd_status +ehci_device_ctrl_transfer(struct usbd_xfer *xfer) { - ehci_softc_t *sc = pipe->device->bus->hci_private; - /*struct ehci_pipe *epipe = (struct ehci_pipe *)pipe;*/ - - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); - - KASSERT(mutex_owned(&sc->sc_lock)); + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + usbd_status err; - USBHIST_LOG(ehcidebug, "pipe=%p", pipe, 0, 0, 0); + /* Insert last in queue. */ + mutex_enter(&sc->sc_lock); + err = usb_insert_transfer(xfer); + mutex_exit(&sc->sc_lock); + if (err) + return err; - ehci_close_pipe(pipe, sc->sc_async_head); + /* Pipe isn't running, start first */ + return ehci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } Static usbd_status -ehci_device_request(usbd_xfer_handle xfer) +ehci_device_ctrl_start(struct usbd_xfer *xfer) { -#define exfer EXFER(xfer) - struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe; - usb_device_request_t *req = &xfer->request; - usbd_device_handle dev = epipe->pipe.device; - ehci_softc_t *sc = dev->bus->hci_private; - ehci_soft_qtd_t *setup, *stat, *next; + struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); + struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); + usb_device_request_t *req = &xfer->ux_request; + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + ehci_soft_qtd_t *setup, *status, *next; ehci_soft_qh_t *sqh; - int isread; - int len; - usbd_status err; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - isread = req->bmRequestType & UT_READ; - len = UGETW(req->wLength); + KASSERT(xfer->ux_rqflags & URQ_REQUEST); - USBHIST_LOG(ehcidebug, "type=0x%02x, request=0x%02x, " - "wValue=0x%04x, wIndex=0x%04x", - req->bmRequestType, req->bRequest, UGETW(req->wValue), - UGETW(req->wIndex)); - USBHIST_LOG(ehcidebug, "len=%d, addr=%d, endpt=%d", - len, dev->address, - epipe->pipe.endpoint->edesc->bEndpointAddress, 0); + if (sc->sc_dying) + return USBD_IOERROR; - setup = ehci_alloc_sqtd(sc); - if (setup == NULL) { - err = USBD_NOMEM; - goto bad1; - } - stat = ehci_alloc_sqtd(sc); - if (stat == NULL) { - err = USBD_NOMEM; - goto bad2; - } + const int isread = req->bmRequestType & UT_READ; + const int len = UGETW(req->wLength); - mutex_enter(&sc->sc_lock); + DPRINTF("type=0x%02x, request=0x%02x, wValue=0x%04x, wIndex=0x%04x", + req->bmRequestType, req->bRequest, UGETW(req->wValue), + UGETW(req->wIndex)); + DPRINTF("len=%d, addr=%d, endpt=%d", len, epipe->pipe.up_dev->ud_addr, + epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress, 0); sqh = epipe->sqh; - KASSERTMSG(EHCI_QH_GET_ADDR(le32toh(sqh->qh.qh_endp)) == dev->address, - "address QH %d pipe %d\n", - EHCI_QH_GET_ADDR(le32toh(sqh->qh.qh_endp)), dev->address); + KASSERTMSG(EHCI_QH_GET_ADDR(le32toh(sqh->qh.qh_endp)) == epipe->pipe.up_dev->ud_addr, + "address QH %" __PRIuBIT " pipe %d\n", + EHCI_QH_GET_ADDR(le32toh(sqh->qh.qh_endp)), + epipe->pipe.up_dev->ud_addr); KASSERTMSG(EHCI_QH_GET_MPL(le32toh(sqh->qh.qh_endp)) == - UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize), - "MPS QH %d pipe %d\n", + UGETW(epipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize), + "MPS QH %" __PRIuBIT " pipe %d\n", EHCI_QH_GET_MPL(le32toh(sqh->qh.qh_endp)), - UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize)); + UGETW(epipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize)); - /* Set up data transaction */ - if (len != 0) { - ehci_soft_qtd_t *end; + setup = exfer->ex_setup; + status = exfer->ex_status; - /* Start toggle at 1. */ - epipe->nexttoggle = 1; - err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer, - &next, &end); - if (err) - goto bad3; - end->qtd.qtd_status &= htole32(~EHCI_QTD_IOC); - end->nextqtd = stat; - end->qtd.qtd_next = end->qtd.qtd_altnext = - htole32(stat->physaddr); - usb_syncmem(&end->dma, end->offs, sizeof(end->qtd), - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - } else { - next = stat; - } + DPRINTF("setup %p status %p data %p", setup, status, exfer->ex_data, 0); + KASSERTMSG(setup != NULL && status != NULL, + "Failed memory allocation, setup %p status %p", + setup, status); - memcpy(KERNADDR(&epipe->u.ctl.reqdma, 0), req, sizeof *req); - usb_syncmem(&epipe->u.ctl.reqdma, 0, sizeof *req, BUS_DMASYNC_PREWRITE); + memcpy(KERNADDR(&epipe->ctrl.reqdma, 0), req, sizeof(*req)); + usb_syncmem(&epipe->ctrl.reqdma, 0, sizeof(*req), BUS_DMASYNC_PREWRITE); /* Clear toggle */ - setup->qtd.qtd_status = htole32( + setup->qtd.qtd_status &= ~htole32( + EHCI_QTD_STATUS_MASK | + EHCI_QTD_BYTES_MASK | + EHCI_QTD_TOGGLE_MASK | + EHCI_QTD_CERR_MASK + ); + setup->qtd.qtd_status |= htole32( EHCI_QTD_ACTIVE | - EHCI_QTD_SET_PID(EHCI_QTD_PID_SETUP) | EHCI_QTD_SET_CERR(3) | EHCI_QTD_SET_TOGGLE(0) | - EHCI_QTD_SET_BYTES(sizeof *req) + EHCI_QTD_SET_BYTES(sizeof(*req)) ); - setup->qtd.qtd_buffer[0] = htole32(DMAADDR(&epipe->u.ctl.reqdma, 0)); + setup->qtd.qtd_buffer[0] = htole32(DMAADDR(&epipe->ctrl.reqdma, 0)); setup->qtd.qtd_buffer_hi[0] = 0; - setup->nextqtd = next; - setup->qtd.qtd_next = setup->qtd.qtd_altnext = htole32(next->physaddr); - setup->xfer = xfer; - setup->len = sizeof *req; - usb_syncmem(&setup->dma, setup->offs, sizeof(setup->qtd), - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - stat->qtd.qtd_status = htole32( + next = status; + status->qtd.qtd_status &= ~htole32( + EHCI_QTD_STATUS_MASK | + EHCI_QTD_PID_MASK | + EHCI_QTD_BYTES_MASK | + EHCI_QTD_TOGGLE_MASK | + EHCI_QTD_CERR_MASK + ); + status->qtd.qtd_status |= htole32( EHCI_QTD_ACTIVE | EHCI_QTD_SET_PID(isread ? EHCI_QTD_PID_OUT : EHCI_QTD_PID_IN) | EHCI_QTD_SET_CERR(3) | EHCI_QTD_SET_TOGGLE(1) | + EHCI_QTD_SET_BYTES(0) | EHCI_QTD_IOC ); - stat->qtd.qtd_buffer[0] = 0; /* XXX not needed? */ - stat->qtd.qtd_buffer_hi[0] = 0; /* XXX not needed? */ - stat->nextqtd = NULL; - stat->qtd.qtd_next = stat->qtd.qtd_altnext = EHCI_NULL; - stat->xfer = xfer; - stat->len = 0; - usb_syncmem(&stat->dma, stat->offs, sizeof(stat->qtd), + KASSERT(status->qtd.qtd_status & htole32(EHCI_QTD_TOGGLE_MASK)); + + KASSERT(exfer->ex_isdone); +#ifdef DIAGNOSTIC + exfer->ex_isdone = false; +#endif + + /* Set up data transaction */ + if (len != 0) { + ehci_soft_qtd_t *end; + + /* Start toggle at 1. */ + int toggle = 1; + next = exfer->ex_data; + KASSERTMSG(next != NULL, "Failed memory allocation"); + ehci_reset_sqtd_chain(sc, xfer, len, isread, &toggle, &end); + end->nextqtd = status; + end->qtd.qtd_next = end->qtd.qtd_altnext = + htole32(status->physaddr); + + usb_syncmem(&end->dma, end->offs, sizeof(end->qtd), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + + usb_syncmem(&xfer->ux_dmabuf, 0, len, + isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); + } + + setup->nextqtd = next; + setup->qtd.qtd_next = setup->qtd.qtd_altnext = htole32(next->physaddr); + + usb_syncmem(&setup->dma, setup->offs, sizeof(setup->qtd), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + usb_syncmem(&status->dma, status->offs, sizeof(status->qtd), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + + KASSERT(status->qtd.qtd_status & htole32(EHCI_QTD_TOGGLE_MASK)); + #ifdef EHCI_DEBUG - USBHIST_LOGN(ehcidebug, 5, "dump:", 0, 0, 0, 0); + DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); ehci_dump_sqh(sqh); ehci_dump_sqtds(setup); + DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); #endif - exfer->sqtdstart = setup; - exfer->sqtdend = stat; -#ifdef DIAGNOSTIC - if (!exfer->isdone) { - printf("ehci_device_request: not done, exfer=%p\n", exfer); - } - exfer->isdone = 0; -#endif + mutex_enter(&sc->sc_lock); - /* Insert qTD in QH list. */ - ehci_set_qh_qtd(sqh, setup); /* also does usb_syncmem(sqh) */ - if (xfer->timeout && !sc->sc_bus.use_polling) { - callout_reset(&xfer->timeout_handle, mstohz(xfer->timeout), + /* Insert qTD in QH list - also does usb_syncmem(sqh) */ + ehci_set_qh_qtd(sqh, setup); + if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { + callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), ehci_timeout, xfer); } ehci_add_intr_list(sc, exfer); - xfer->status = USBD_IN_PROGRESS; + xfer->ux_status = USBD_IN_PROGRESS; mutex_exit(&sc->sc_lock); +#if 0 #ifdef EHCI_DEBUG - USBHIST_LOGN(ehcidebug, 10, "status=%x, dump:", - EOREAD4(sc, EHCI_USBSTS), 0, 0, 0); + DPRINTFN(10, "status=%x, dump:", EOREAD4(sc, EHCI_USBSTS), 0, 0, 0); // delay(10000); ehci_dump_regs(sc); ehci_dump_sqh(sc->sc_async_head); ehci_dump_sqh(sqh); ehci_dump_sqtds(setup); #endif +#endif - return (USBD_NORMAL_COMPLETION); + if (sc->sc_bus.ub_usepolling) + ehci_waitintr(sc, xfer); - bad3: - mutex_exit(&sc->sc_lock); - ehci_free_sqtd(sc, stat); - bad2: - ehci_free_sqtd(sc, setup); - bad1: - USBHIST_LOG(ehcidebug, "no memory", 0, 0, 0, 0); - mutex_enter(&sc->sc_lock); - xfer->status = err; - usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); - return (err); -#undef exfer + return USBD_IN_PROGRESS; +} + +Static void +ehci_device_ctrl_done(struct usbd_xfer *xfer) +{ + ehci_softc_t *sc __diagused = EHCI_XFER2SC(xfer); + struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); + usb_device_request_t *req = &xfer->ux_request; + int len = UGETW(req->wLength); + int rd = req->bmRequestType & UT_READ; + + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + DPRINTF("xfer=%p", xfer, 0, 0, 0); + + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + KASSERT(xfer->ux_rqflags & URQ_REQUEST); + + usb_syncmem(&epipe->ctrl.reqdma, 0, sizeof(*req), + BUS_DMASYNC_POSTWRITE); + if (len) + usb_syncmem(&xfer->ux_dmabuf, 0, len, + rd ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); + + DPRINTF("length=%d", xfer->ux_actlen, 0, 0, 0); +} + +/* Abort a device control request. */ +Static void +ehci_device_ctrl_abort(struct usbd_xfer *xfer) +{ + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + + DPRINTF("xfer=%p", xfer, 0, 0, 0); + ehci_abort_xfer(xfer, USBD_CANCELLED); +} + +/* Close a device control pipe. */ +Static void +ehci_device_ctrl_close(struct usbd_pipe *pipe) +{ + ehci_softc_t *sc = EHCI_PIPE2SC(pipe); + /*struct ehci_pipe *epipe = EHCI_PIPE2EPIPE(pipe);*/ + + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + + KASSERT(mutex_owned(&sc->sc_lock)); + + DPRINTF("pipe=%p", pipe, 0, 0, 0); + + ehci_close_pipe(pipe, sc->sc_async_head); } /* @@ -3689,17 +3776,49 @@ ehci_intrlist_timeout(void *arg) { ehci_softc_t *sc = arg; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); usb_schedsoftintr(&sc->sc_bus); } /************************/ +Static int +ehci_device_bulk_init(struct usbd_xfer *xfer) +{ + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); + usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc; + int endpt = ed->bEndpointAddress; + int isread = UE_GET_DIR(endpt) == UE_DIR_IN; + int len = xfer->ux_bufsize; + int err = 0; + + exfer->ex_type = EX_BULK; + exfer->ex_nsqtd = 0; + err = ehci_alloc_sqtd_chain(sc, xfer, len, isread, + &exfer->ex_sqtdstart); + + return err; +} + +Static void +ehci_device_bulk_fini(struct usbd_xfer *xfer) +{ + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + struct ehci_xfer *ex = EHCI_XFER2EXFER(xfer); + + KASSERT(ex->ex_type == EX_BULK); + + ehci_free_sqtds(sc, ex); + if (ex->ex_nsqtd) + kmem_free(ex->ex_sqtds, sizeof(ehci_soft_qtd_t *) * ex->ex_nsqtd); +} + Static usbd_status -ehci_device_bulk_transfer(usbd_xfer_handle xfer) +ehci_device_bulk_transfer(struct usbd_xfer *xfer) { - ehci_softc_t *sc = xfer->pipe->device->bus->hci_private; + ehci_softc_t *sc = EHCI_XFER2SC(xfer); usbd_status err; /* Insert last in queue. */ @@ -3707,108 +3826,101 @@ ehci_device_bulk_transfer(usbd_xfer_handle xfer) err = usb_insert_transfer(xfer); mutex_exit(&sc->sc_lock); if (err) - return (err); + return err; /* Pipe isn't running, start first */ - return (ehci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return ehci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } Static usbd_status -ehci_device_bulk_start(usbd_xfer_handle xfer) +ehci_device_bulk_start(struct usbd_xfer *xfer) { -#define exfer EXFER(xfer) - struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe; - usbd_device_handle dev = epipe->pipe.device; - ehci_softc_t *sc = dev->bus->hci_private; - ehci_soft_qtd_t *data, *dataend; + struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); + struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); + ehci_softc_t *sc = EHCI_XFER2SC(xfer); ehci_soft_qh_t *sqh; - usbd_status err; + ehci_soft_qtd_t *end; int len, isread, endpt; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "xfer=%p len=%d flags=%d", - xfer, xfer->length, xfer->flags, 0); + DPRINTF("xfer=%p len=%d flags=%d", xfer, xfer->ux_length, + xfer->ux_flags, 0); if (sc->sc_dying) - return (USBD_IOERROR); + return USBD_IOERROR; + + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); + KASSERT(xfer->ux_length <= xfer->ux_bufsize); + + len = xfer->ux_length; + endpt = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; + isread = UE_GET_DIR(endpt) == UE_DIR_IN; + sqh = epipe->sqh; + KASSERT(exfer->ex_isdone); #ifdef DIAGNOSTIC - if (xfer->rqflags & URQ_REQUEST) - panic("ehci_device_bulk_start: a request"); + exfer->ex_isdone = false; #endif + /* Take lock here to protect nexttoggle */ mutex_enter(&sc->sc_lock); - len = xfer->length; - endpt = epipe->pipe.endpoint->edesc->bEndpointAddress; - isread = UE_GET_DIR(endpt) == UE_DIR_IN; - sqh = epipe->sqh; - - epipe->u.bulk.length = len; + ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end); - err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer, &data, - &dataend); - if (err) { - USBHIST_LOG(ehcidebug, "no memory", 0, 0, 0, 0); - xfer->status = err; - usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); - return (err); - } + exfer->ex_sqtdend = end; + end->qtd.qtd_status |= htole32(EHCI_QTD_IOC); + usb_syncmem(&end->dma, end->offs, sizeof(end->qtd), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); #ifdef EHCI_DEBUG - USBHIST_LOGN(ehcidebug, 5, "data(1):", 0, 0, 0, 0); + DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); ehci_dump_sqh(sqh); - ehci_dump_sqtds(data); + ehci_dump_sqtds(exfer->ex_sqtdstart); + DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); #endif - /* Set up interrupt info. */ - exfer->sqtdstart = data; - exfer->sqtdend = dataend; -#ifdef DIAGNOSTIC - if (!exfer->isdone) { - printf("ehci_device_bulk_start: not done, ex=%p\n", exfer); - } - exfer->isdone = 0; -#endif + usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, + isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); - ehci_set_qh_qtd(sqh, data); /* also does usb_syncmem(sqh) */ - if (xfer->timeout && !sc->sc_bus.use_polling) { - callout_reset(&xfer->timeout_handle, mstohz(xfer->timeout), + /* also does usb_syncmem(sqh) */ + ehci_set_qh_qtd(sqh, exfer->ex_sqtdstart); + if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { + callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), ehci_timeout, xfer); } ehci_add_intr_list(sc, exfer); - xfer->status = USBD_IN_PROGRESS; + xfer->ux_status = USBD_IN_PROGRESS; mutex_exit(&sc->sc_lock); +#if 0 #ifdef EHCI_DEBUG - USBHIST_LOGN(ehcidebug, 5, "data(2)", 0, 0, 0, 0); + DPRINTFN(5, "data(2)", 0, 0, 0, 0); // delay(10000); - USBHIST_LOGN(ehcidebug, 5, "data(3)", 0, 0, 0, 0); + DPRINTFN(5, "data(3)", 0, 0, 0, 0); ehci_dump_regs(sc); #if 0 printf("async_head:\n"); ehci_dump_sqh(sc->sc_async_head); #endif - USBHIST_LOG(ehcidebug, "sqh:", 0, 0, 0, 0); + DPRINTF("sqh:", 0, 0, 0, 0); ehci_dump_sqh(sqh); - ehci_dump_sqtds(data); + ehci_dump_sqtds(exfer->ex_sqtdstart); +#endif #endif - if (sc->sc_bus.use_polling) + if (sc->sc_bus.ub_usepolling) ehci_waitintr(sc, xfer); - return (USBD_IN_PROGRESS); -#undef exfer + return USBD_IN_PROGRESS; } Static void -ehci_device_bulk_abort(usbd_xfer_handle xfer) +ehci_device_bulk_abort(struct usbd_xfer *xfer) { - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "xfer %p", xfer, 0, 0, 0); + DPRINTF("xfer %p", xfer, 0, 0, 0); ehci_abort_xfer(xfer, USBD_CANCELLED); } @@ -3816,44 +3928,38 @@ ehci_device_bulk_abort(usbd_xfer_handle xfer) * Close a device bulk pipe. */ Static void -ehci_device_bulk_close(usbd_pipe_handle pipe) +ehci_device_bulk_close(struct usbd_pipe *pipe) { - ehci_softc_t *sc = pipe->device->bus->hci_private; - struct ehci_pipe *epipe = (struct ehci_pipe *)pipe; + ehci_softc_t *sc = EHCI_PIPE2SC(pipe); + struct ehci_pipe *epipe = EHCI_PIPE2EPIPE(pipe); - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); KASSERT(mutex_owned(&sc->sc_lock)); - USBHIST_LOG(ehcidebug, "pipe=%p", pipe, 0, 0, 0); - pipe->endpoint->datatoggle = epipe->nexttoggle; + DPRINTF("pipe=%p", pipe, 0, 0, 0); + pipe->up_endpoint->ue_toggle = epipe->nexttoggle; ehci_close_pipe(pipe, sc->sc_async_head); } Static void -ehci_device_bulk_done(usbd_xfer_handle xfer) +ehci_device_bulk_done(struct usbd_xfer *xfer) { - struct ehci_xfer *ex = EXFER(xfer); - ehci_softc_t *sc = xfer->pipe->device->bus->hci_private; - struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe; - int endpt = epipe->pipe.endpoint->edesc->bEndpointAddress; + ehci_softc_t *sc __diagused = EHCI_XFER2SC(xfer); + struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); + int endpt = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; int rd = UE_GET_DIR(endpt) == UE_DIR_IN; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "xfer=%p, actlen=%d", - xfer, xfer->actlen, 0, 0); + DPRINTF("xfer=%p, actlen=%d", xfer, xfer->ux_actlen, 0, 0); KASSERT(mutex_owned(&sc->sc_lock)); - if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) { - ehci_del_intr_list(sc, ex); /* remove from active list */ - ehci_free_sqtd_chain(sc, ex->sqtdstart, NULL); - usb_syncmem(&xfer->dmabuf, 0, xfer->length, - rd ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); - } + usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, + rd ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); - USBHIST_LOG(ehcidebug, "length=%d", xfer->actlen, 0, 0, 0); + DPRINTF("length=%d", xfer->ux_actlen, 0, 0, 0); } /************************/ @@ -3880,13 +3986,54 @@ ehci_device_setintr(ehci_softc_t *sc, ehci_soft_qh_t *sqh, int ival) ehci_add_qh(sc, sqh, isp->sqh); mutex_exit(&sc->sc_lock); - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; +} + + +Static int +ehci_device_intr_init(struct usbd_xfer *xfer) +{ + struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc; + int endpt = ed->bEndpointAddress; + int isread = UE_GET_DIR(endpt) == UE_DIR_IN; + int len = xfer->ux_bufsize; + int err; + + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + + DPRINTF("xfer=%p len=%d flags=%d", xfer, xfer->ux_length, + xfer->ux_flags, 0); + + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); + KASSERT(len != 0); + + exfer->ex_type = EX_INTR; + exfer->ex_nsqtd = 0; + err = ehci_alloc_sqtd_chain(sc, xfer, len, isread, + &exfer->ex_sqtdstart); + + return err; +} + +Static void +ehci_device_intr_fini(struct usbd_xfer *xfer) +{ + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + struct ehci_xfer *ex = EHCI_XFER2EXFER(xfer); + + KASSERT(ex->ex_type == EX_INTR); + + ehci_free_sqtds(sc, ex); + if (ex->ex_nsqtd) + kmem_free(ex->ex_sqtds, sizeof(ehci_soft_qtd_t *) * ex->ex_nsqtd); } Static usbd_status -ehci_device_intr_transfer(usbd_xfer_handle xfer) +ehci_device_intr_transfer(struct usbd_xfer *xfer) { - ehci_softc_t *sc = xfer->pipe->device->bus->hci_private; + ehci_softc_t *sc = EHCI_XFER2SC(xfer); usbd_status err; /* Insert last in queue. */ @@ -3894,108 +4041,101 @@ ehci_device_intr_transfer(usbd_xfer_handle xfer) err = usb_insert_transfer(xfer); mutex_exit(&sc->sc_lock); if (err) - return (err); + return err; /* * Pipe isn't running (otherwise err would be USBD_INPROG), * so start it first. */ - return (ehci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return ehci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } Static usbd_status -ehci_device_intr_start(usbd_xfer_handle xfer) +ehci_device_intr_start(struct usbd_xfer *xfer) { -#define exfer EXFER(xfer) - struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe; - usbd_device_handle dev = xfer->pipe->device; - ehci_softc_t *sc = dev->bus->hci_private; - ehci_soft_qtd_t *data, *dataend; + struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); + struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + ehci_soft_qtd_t *end; ehci_soft_qh_t *sqh; - usbd_status err; int len, isread, endpt; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "xfer=%p len=%d flags=%d", - xfer, xfer->length, xfer->flags, 0); + DPRINTF("xfer=%p len=%d flags=%d", xfer, xfer->ux_length, + xfer->ux_flags, 0); if (sc->sc_dying) - return (USBD_IOERROR); + return USBD_IOERROR; + + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); + KASSERT(xfer->ux_length <= xfer->ux_bufsize); + + len = xfer->ux_length; + endpt = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; + isread = UE_GET_DIR(endpt) == UE_DIR_IN; + sqh = epipe->sqh; + KASSERT(exfer->ex_isdone); #ifdef DIAGNOSTIC - if (xfer->rqflags & URQ_REQUEST) - panic("ehci_device_intr_start: a request"); + exfer->ex_isdone = false; #endif + /* Take lock to protect nexttoggle */ mutex_enter(&sc->sc_lock); - len = xfer->length; - endpt = epipe->pipe.endpoint->edesc->bEndpointAddress; - isread = UE_GET_DIR(endpt) == UE_DIR_IN; - sqh = epipe->sqh; - - epipe->u.intr.length = len; + ehci_reset_sqtd_chain(sc, xfer, len, isread, &epipe->nexttoggle, &end); - err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer, &data, - &dataend); - if (err) { - USBHIST_LOG(ehcidebug, "no memory", 0, 0, 0, 0); - xfer->status = err; - usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); - return (err); - } + end->qtd.qtd_status |= htole32(EHCI_QTD_IOC); + usb_syncmem(&end->dma, end->offs, sizeof(end->qtd), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + exfer->ex_sqtdend = end; #ifdef EHCI_DEBUG - USBHIST_LOGN(ehcidebug, 5, "data(1)", 0, 0, 0, 0); + DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); ehci_dump_sqh(sqh); - ehci_dump_sqtds(data); + ehci_dump_sqtds(exfer->ex_sqtdstart); + DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); #endif - /* Set up interrupt info. */ - exfer->sqtdstart = data; - exfer->sqtdend = dataend; -#ifdef DIAGNOSTIC - if (!exfer->isdone) { - printf("ehci_device_intr_start: not done, ex=%p\n", exfer); - } - exfer->isdone = 0; -#endif + usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, + isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); - ehci_set_qh_qtd(sqh, data); /* also does usb_syncmem(sqh) */ - if (xfer->timeout && !sc->sc_bus.use_polling) { - callout_reset(&xfer->timeout_handle, mstohz(xfer->timeout), + /* also does usb_syncmem(sqh) */ + ehci_set_qh_qtd(sqh, exfer->ex_sqtdstart); + if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { + callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), ehci_timeout, xfer); } ehci_add_intr_list(sc, exfer); - xfer->status = USBD_IN_PROGRESS; + xfer->ux_status = USBD_IN_PROGRESS; mutex_exit(&sc->sc_lock); +#if 0 #ifdef EHCI_DEBUG - USBHIST_LOGN(ehcidebug, 5, "data(2)", 0, 0, 0, 0); + DPRINTFN(5, "data(2)", 0, 0, 0, 0); // delay(10000); - USBHIST_LOGN(ehcidebug, 5, "data(3)", 0, 0, 0, 0); + DPRINTFN(5, "data(3)", 0, 0, 0, 0); ehci_dump_regs(sc); - USBHIST_LOGN(ehcidebug, 5, "sqh:", 0, 0, 0, 0); + DPRINTFN(5, "sqh:", 0, 0, 0, 0); ehci_dump_sqh(sqh); - ehci_dump_sqtds(data); + ehci_dump_sqtds(exfer->ex_sqtdstart); +#endif #endif - if (sc->sc_bus.use_polling) + if (sc->sc_bus.ub_usepolling) ehci_waitintr(sc, xfer); - return (USBD_IN_PROGRESS); -#undef exfer + return USBD_IN_PROGRESS; } Static void -ehci_device_intr_abort(usbd_xfer_handle xfer) +ehci_device_intr_abort(struct usbd_xfer *xfer) { - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "xfer=%p", xfer, 0, 0, 0); - KASSERT(xfer->pipe->intrxfer == xfer); + DPRINTF("xfer=%p", xfer, 0, 0, 0); + KASSERT(xfer->ux_pipe->up_intrxfer == xfer); /* * XXX - abort_xfer uses ehci_sync_hc, which syncs via the advance @@ -4006,10 +4146,10 @@ ehci_device_intr_abort(usbd_xfer_handle xfer) } Static void -ehci_device_intr_close(usbd_pipe_handle pipe) +ehci_device_intr_close(struct usbd_pipe *pipe) { - ehci_softc_t *sc = pipe->device->bus->hci_private; - struct ehci_pipe *epipe = (struct ehci_pipe *)pipe; + ehci_softc_t *sc = EHCI_PIPE2SC(pipe); + struct ehci_pipe *epipe = EHCI_PIPE2EPIPE(pipe); struct ehci_soft_islot *isp; KASSERT(mutex_owned(&sc->sc_lock)); @@ -4019,126 +4159,536 @@ ehci_device_intr_close(usbd_pipe_handle pipe) } Static void -ehci_device_intr_done(usbd_xfer_handle xfer) +ehci_device_intr_done(struct usbd_xfer *xfer) { -#define exfer EXFER(xfer) - struct ehci_xfer *ex = EXFER(xfer); - ehci_softc_t *sc = xfer->pipe->device->bus->hci_private; - struct ehci_pipe *epipe = (struct ehci_pipe *)xfer->pipe; - ehci_soft_qtd_t *data, *dataend; - ehci_soft_qh_t *sqh; - usbd_status err; - int len, isread, endpt; + ehci_softc_t *sc __diagused = EHCI_XFER2SC(xfer); + struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); + int isread, endpt; + + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + + DPRINTF("xfer=%p, actlen=%d", xfer, xfer->ux_actlen, + 0, 0); + + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + + endpt = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; + isread = UE_GET_DIR(endpt) == UE_DIR_IN; + usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, + isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); +} + +/************************/ +Static int +ehci_device_fs_isoc_init(struct usbd_xfer *xfer) +{ + struct ehci_pipe *epipe = EHCI_PIPE2EPIPE(xfer->ux_pipe); + struct usbd_device *dev = xfer->ux_pipe->up_dev; + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); + ehci_soft_sitd_t *sitd, *prev, *start, *stop; + int i, k, frames; + u_int huba, dir; + int err; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "xfer=%p, actlen=%d", - xfer, xfer->actlen, 0, 0); + start = NULL; + sitd = NULL; - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + DPRINTF("xfer %p len %d flags %d", xfer, xfer->ux_length, + xfer->ux_flags, 0); - if (xfer->pipe->repeat) { - ehci_free_sqtd_chain(sc, ex->sqtdstart, NULL); + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); + KASSERT(xfer->ux_nframes != 0); + KASSERT(exfer->ex_isdone); - len = epipe->u.intr.length; - xfer->length = len; - endpt = epipe->pipe.endpoint->edesc->bEndpointAddress; - isread = UE_GET_DIR(endpt) == UE_DIR_IN; - usb_syncmem(&xfer->dmabuf, 0, len, - isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); - sqh = epipe->sqh; + exfer->ex_type = EX_FS_ISOC; + /* + * Step 1: Allocate and initialize sitds. + */ + i = epipe->pipe.up_endpoint->ue_edesc->bInterval; + if (i > 16 || i == 0) { + /* Spec page 271 says intervals > 16 are invalid */ + DPRINTF("bInterval %d invalid", i, 0, 0, 0); - err = ehci_alloc_sqtd_chain(epipe, sc, len, isread, xfer, - &data, &dataend); - if (err) { - USBHIST_LOG(ehcidebug, "no memory", 0, 0, 0, 0); - xfer->status = err; - return; + return EINVAL; + } + + frames = xfer->ux_nframes; + for (i = 0, prev = NULL; i < frames; i++, prev = sitd) { + sitd = ehci_alloc_sitd(sc); + if (sitd == NULL) { + err = ENOMEM; + goto fail; + } + + if (prev) + prev->xfer_next = sitd; + else + start = sitd; + + huba = dev->ud_myhsport->up_parent->ud_addr; + +#if 0 + if (sc->sc_flags & EHCIF_FREESCALE) { + // Set hub address to 0 if embedded TT is used. + if (huba == sc->sc_addr) + huba = 0; } +#endif + + k = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; + dir = UE_GET_DIR(k) ? 1 : 0; + sitd->sitd.sitd_endp = + htole32(EHCI_SITD_SET_ENDPT(UE_GET_ADDR(k)) | + EHCI_SITD_SET_DADDR(dev->ud_addr) | + EHCI_SITD_SET_PORT(dev->ud_myhsport->up_portno) | + EHCI_SITD_SET_HUBA(huba) | + EHCI_SITD_SET_DIR(dir)); + + sitd->sitd.sitd_back = htole32(EHCI_LINK_TERMINATE); + } /* End of frame */ + + sitd->sitd.sitd_trans |= htole32(EHCI_SITD_IOC); + + stop = sitd; + stop->xfer_next = NULL; + exfer->ex_sitdstart = start; + exfer->ex_sitdend = stop; - /* Set up interrupt info. */ - exfer->sqtdstart = data; - exfer->sqtdend = dataend; + return 0; + +fail: + mutex_enter(&sc->sc_lock); + ehci_soft_sitd_t *next; + for (sitd = start; sitd; sitd = next) { + next = sitd->xfer_next; + ehci_free_sitd_locked(sc, sitd); + } + mutex_exit(&sc->sc_lock); + + return err; +} + +Static void +ehci_device_fs_isoc_fini(struct usbd_xfer *xfer) +{ + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + struct ehci_xfer *ex = EHCI_XFER2EXFER(xfer); + + KASSERT(ex->ex_type == EX_FS_ISOC); + + ehci_free_sitd_chain(sc, ex->ex_sitdstart); +} + +Static usbd_status +ehci_device_fs_isoc_transfer(struct usbd_xfer *xfer) +{ + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + usbd_status __diagused err; + + mutex_enter(&sc->sc_lock); + err = usb_insert_transfer(xfer); + mutex_exit(&sc->sc_lock); + + KASSERT(err == USBD_NORMAL_COMPLETION); + + struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer);; + struct usbd_device *dev = xfer->ux_pipe->up_dev;; + struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); + ehci_soft_sitd_t *sitd; + usb_dma_t *dma_buf; + int i, j, k, frames; + int offs, total_length; + int frindex; + u_int dir; + + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + + sitd = NULL; + total_length = 0; + + + DPRINTF("xfer %p len %d flags %d", xfer, xfer->ux_length, + xfer->ux_flags, 0); + + if (sc->sc_dying) + return USBD_IOERROR; + + /* + * To avoid complication, don't allow a request right now that'll span + * the entire frame table. To within 4 frames, to allow some leeway + * on either side of where the hc currently is. + */ + if (epipe->pipe.up_endpoint->ue_edesc->bInterval * + xfer->ux_nframes >= sc->sc_flsize - 4) { + printf("ehci: isoc descriptor requested that spans the entire" + "frametable, too many frames\n"); + return USBD_INVAL; + } + + KASSERT(xfer->ux_nframes != 0 && xfer->ux_frlengths); + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); + KASSERT(exfer->ex_isdone); #ifdef DIAGNOSTIC - if (!exfer->isdone) { - USBHIST_LOG(ehcidebug, "marked not done, ex = %p", - exfer, 0, 0, 0); - printf("ehci_device_intr_done: not done, ex=%p\n", - exfer); + exfer->ex_isdone = false; +#endif + + /* + * Step 1: Initialize sitds. + */ + + frames = xfer->ux_nframes; + dma_buf = &xfer->ux_dmabuf; + offs = 0; + + for (sitd = exfer->ex_sitdstart, i = 0; i < frames; + i++, sitd = sitd->xfer_next) { + KASSERT(sitd != NULL); + KASSERT(xfer->ux_frlengths[i] <= 0x3ff); + + sitd->sitd.sitd_trans = htole32(EHCI_SITD_ACTIVE | + EHCI_SITD_SET_LEN(xfer->ux_frlengths[i])); + + /* Set page0 index and offset - TP and T-offset are set below */ + sitd->sitd.sitd_buffer[0] = htole32(DMAADDR(dma_buf, offs)); + + total_length += xfer->ux_frlengths[i]; + offs += xfer->ux_frlengths[i]; + + sitd->sitd.sitd_buffer[1] = + htole32(EHCI_SITD_SET_BPTR(DMAADDR(dma_buf, offs - 1))); + + u_int huba __diagused = dev->ud_myhsport->up_parent->ud_addr; + +#if 0 + if (sc->sc_flags & EHCIF_FREESCALE) { + // Set hub address to 0 if embedded TT is used. + if (huba == sc->sc_addr) + huba = 0; } - exfer->isdone = 0; #endif - ehci_set_qh_qtd(sqh, data); /* also does usb_syncmem(sqh) */ - if (xfer->timeout && !sc->sc_bus.use_polling) { - callout_reset(&xfer->timeout_handle, - mstohz(xfer->timeout), ehci_timeout, xfer); + k = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; + dir = UE_GET_DIR(k) ? 1 : 0; + KASSERT(sitd->sitd.sitd_endp == htole32( + EHCI_SITD_SET_ENDPT(UE_GET_ADDR(k)) | + EHCI_SITD_SET_DADDR(dev->ud_addr) | + EHCI_SITD_SET_PORT(dev->ud_myhsport->up_portno) | + EHCI_SITD_SET_HUBA(huba) | + EHCI_SITD_SET_DIR(dir))); + KASSERT(sitd->sitd.sitd_back == htole32(EHCI_LINK_TERMINATE)); + + uint8_t sa = 0; + uint8_t sb = 0; + u_int temp, tlen; + + if (dir == 0) { /* OUT */ + temp = 0; + tlen = xfer->ux_frlengths[i]; + if (tlen <= 188) { + temp |= 1; /* T-count = 1, TP = ALL */ + tlen = 1; + } else { + tlen += 187; + tlen /= 188; + temp |= tlen; /* T-count = [1..6] */ + temp |= 8; /* TP = Begin */ + } + sitd->sitd.sitd_buffer[1] |= htole32(temp); + + tlen += sa; + + if (tlen >= 8) { + sb = 0; + } else { + sb = (1 << tlen); + } + + sa = (1 << sa); + sa = (sb - sa) & 0x3F; + sb = 0; + } else { + sb = (-(4 << sa)) & 0xFE; + sa = (1 << sa) & 0x3F; + sa = 0x01; + sb = 0xfc; } - xfer->status = USBD_IN_PROGRESS; - } else if (xfer->status != USBD_NOMEM && ehci_active_intr_list(ex)) { - ehci_del_intr_list(sc, ex); /* remove from active list */ - ehci_free_sqtd_chain(sc, ex->sqtdstart, NULL); - endpt = epipe->pipe.endpoint->edesc->bEndpointAddress; - isread = UE_GET_DIR(endpt) == UE_DIR_IN; - usb_syncmem(&xfer->dmabuf, 0, xfer->length, - isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); + sitd->sitd.sitd_sched = htole32( + EHCI_SITD_SET_SMASK(sa) | + EHCI_SITD_SET_CMASK(sb) + ); + + usb_syncmem(&sitd->dma, sitd->offs, sizeof(ehci_sitd_t), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + } /* End of frame */ + + sitd = exfer->ex_sitdend; + sitd->sitd.sitd_trans |= htole32(EHCI_SITD_IOC); + + usb_syncmem(&sitd->dma, sitd->offs + offsetof(ehci_sitd_t, sitd_trans), + sizeof(sitd->sitd.sitd_trans), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + + usb_syncmem(&exfer->ex_xfer.ux_dmabuf, 0, total_length, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + + /* + * Part 2: Transfer descriptors have now been set up, now they must + * be scheduled into the periodic frame list. Erk. Not wanting to + * complicate matters, transfer is denied if the transfer spans + * more than the period frame list. + */ + + mutex_enter(&sc->sc_lock); + + /* Start inserting frames */ + if (epipe->isoc.cur_xfers > 0) { + frindex = epipe->isoc.next_frame; + } else { + frindex = EOREAD4(sc, EHCI_FRINDEX); + frindex = frindex >> 3; /* Erase microframe index */ + frindex += 2; + } + + if (frindex >= sc->sc_flsize) + frindex &= (sc->sc_flsize - 1); + + /* Whats the frame interval? */ + i = epipe->pipe.up_endpoint->ue_edesc->bInterval; + + for (sitd = exfer->ex_sitdstart, j = 0; j < frames; + j++, sitd = sitd->xfer_next) { + KASSERT(sitd); + + usb_syncmem(&sc->sc_fldma, + sizeof(ehci_link_t) * frindex, + sizeof(ehci_link_t), + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); + + sitd->sitd.sitd_next = sc->sc_flist[frindex]; + if (sitd->sitd.sitd_next == 0) + /* + * FIXME: frindex table gets initialized to NULL + * or EHCI_NULL? + */ + sitd->sitd.sitd_next = EHCI_NULL; + + usb_syncmem(&sitd->dma, + sitd->offs + offsetof(ehci_sitd_t, sitd_next), + sizeof(ehci_sitd_t), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + + sc->sc_flist[frindex] = + htole32(EHCI_LINK_SITD | sitd->physaddr); + + usb_syncmem(&sc->sc_fldma, + sizeof(ehci_link_t) * frindex, + sizeof(ehci_link_t), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + + sitd->frame_list.next = sc->sc_softsitds[frindex]; + sc->sc_softsitds[frindex] = sitd; + if (sitd->frame_list.next != NULL) + sitd->frame_list.next->frame_list.prev = sitd; + sitd->slot = frindex; + sitd->frame_list.prev = NULL; + + frindex += i; + if (frindex >= sc->sc_flsize) + frindex -= sc->sc_flsize; } -#undef exfer + + epipe->isoc.cur_xfers++; + epipe->isoc.next_frame = frindex; + + ehci_add_intr_list(sc, exfer); + xfer->ux_status = USBD_IN_PROGRESS; + + mutex_exit(&sc->sc_lock); + + if (sc->sc_bus.ub_usepolling) { + printf("Starting ehci isoc xfer with polling. Bad idea?\n"); + ehci_waitintr(sc, xfer); + } + + return USBD_IN_PROGRESS; +} + +Static void +ehci_device_fs_isoc_abort(struct usbd_xfer *xfer) +{ + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + + DPRINTF("xfer = %p", xfer, 0, 0, 0); + ehci_abort_isoc_xfer(xfer, USBD_CANCELLED); +} + +Static void +ehci_device_fs_isoc_close(struct usbd_pipe *pipe) +{ + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + + DPRINTF("nothing in the pipe to free?", 0, 0, 0, 0); +} + +Static void +ehci_device_fs_isoc_done(struct usbd_xfer *xfer) +{ + struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); + + KASSERT(mutex_owned(&sc->sc_lock)); + + epipe->isoc.cur_xfers--; + ehci_remove_sitd_chain(sc, exfer->ex_itdstart); + + usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); } + /************************/ -Static usbd_status -ehci_device_isoc_transfer(usbd_xfer_handle xfer) + +Static int +ehci_device_isoc_init(struct usbd_xfer *xfer) { - ehci_softc_t *sc = xfer->pipe->device->bus->hci_private; - usbd_status err; + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); + struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); + ehci_soft_itd_t *itd, *prev, *start, *stop; + int i, j, k; + int frames, ufrperframe; + int err; + + EHCIHIST_FUNC(); EHCIHIST_CALLED(); + + start = NULL; + prev = NULL; + itd = NULL; + + KASSERT(xfer->ux_nframes != 0); + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); + KASSERT(exfer->ex_isdone); + + exfer->ex_type = EX_ISOC; + + /* + * Step 1: Allocate and initialize itds, how many do we need? + * One per transfer if interval >= 8 microframes, less if we use + * multiple microframes per frame. + */ + i = epipe->pipe.up_endpoint->ue_edesc->bInterval; + if (i > 16 || i == 0) { + /* Spec page 271 says intervals > 16 are invalid */ + DPRINTF("bInterval %d invalid", i, 0, 0, 0); + return USBD_INVAL; + } + + ufrperframe = max(1, USB_UFRAMES_PER_FRAME / (1 << (i - 1))); + frames = (xfer->ux_nframes + (ufrperframe - 1)) / ufrperframe; + + for (i = 0, prev = NULL; i < frames; i++, prev = itd) { + itd = ehci_alloc_itd(sc); + if (itd == NULL) { + err = ENOMEM; + goto fail; + } + + if (prev != NULL) { + /* Maybe not as it's updated by the scheduling? */ + prev->itd.itd_next = + htole32(itd->physaddr | EHCI_LINK_ITD); + + prev->xfer_next = itd; + } else { + start = itd; + } + + /* + * Other special values + */ + k = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; + itd->itd.itd_bufr[0] = htole32( + EHCI_ITD_SET_EP(UE_GET_ADDR(k)) | + EHCI_ITD_SET_DADDR(epipe->pipe.up_dev->ud_addr)); + + k = (UE_GET_DIR(epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress)) + ? 1 : 0; + j = UGETW(epipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize); + itd->itd.itd_bufr[1] |= htole32( + EHCI_ITD_SET_DIR(k) | + EHCI_ITD_SET_MAXPKT(UE_GET_SIZE(j))); + + /* FIXME: handle invalid trans - should be done in openpipe */ + itd->itd.itd_bufr[2] |= + htole32(EHCI_ITD_SET_MULTI(UE_GET_TRANS(j)+1)); + } /* End of frame */ + + stop = itd; + stop->xfer_next = NULL; + exfer->ex_itdstart = start; + exfer->ex_itdend = stop; + + return 0; +fail: mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); + ehci_soft_itd_t *next; + for (itd = start; itd; itd = next) { + next = itd->xfer_next; + ehci_free_itd_locked(sc, itd); + } mutex_exit(&sc->sc_lock); - if (err && err != USBD_IN_PROGRESS) - return err; - return ehci_device_isoc_start(xfer); + return err; + +} + +Static void +ehci_device_isoc_fini(struct usbd_xfer *xfer) +{ + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + struct ehci_xfer *ex = EHCI_XFER2EXFER(xfer); + + KASSERT(ex->ex_type == EX_ISOC); + + ehci_free_itd_chain(sc, ex->ex_itdstart); } Static usbd_status -ehci_device_isoc_start(usbd_xfer_handle xfer) +ehci_device_isoc_transfer(struct usbd_xfer *xfer) { - struct ehci_pipe *epipe; - ehci_softc_t *sc; - struct ehci_xfer *exfer; - ehci_soft_itd_t *itd, *prev, *start, *stop; + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + usbd_status __diagused err; + + mutex_enter(&sc->sc_lock); + err = usb_insert_transfer(xfer); + mutex_exit(&sc->sc_lock); + + KASSERT(err == USBD_NORMAL_COMPLETION); + + struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); + struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); + ehci_soft_itd_t *itd, *prev; usb_dma_t *dma_buf; - int i, j, k, frames, uframes, ufrperframe; + int i, j; + int frames, uframes, ufrperframe; int trans_count, offs, total_length; int frindex; - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - start = NULL; prev = NULL; itd = NULL; trans_count = 0; total_length = 0; - exfer = (struct ehci_xfer *) xfer; - sc = xfer->pipe->device->bus->hci_private; - epipe = (struct ehci_pipe *)xfer->pipe; - /* - * To allow continuous transfers, above we start all transfers - * immediately. However, we're still going to get usbd_start_next call - * this when another xfer completes. So, check if this is already - * in progress or not - */ - - if (exfer->itdstart != NULL) - return USBD_IN_PROGRESS; - - USBHIST_LOG(ehcidebug, "xfer %p len %d flags %d", - xfer, xfer->length, xfer->flags, 0); + DPRINTF("xfer %p flags %d", xfer, xfer->ux_flags, 0, 0); if (sc->sc_dying) return USBD_IOERROR; @@ -4148,65 +4698,55 @@ ehci_device_isoc_start(usbd_xfer_handle xfer) * the entire frame table. To within 4 frames, to allow some leeway * on either side of where the hc currently is. */ - if ((1 << (epipe->pipe.endpoint->edesc->bInterval)) * - xfer->nframes >= (sc->sc_flsize - 4) * 8) { - USBHIST_LOG(ehcidebug, + if ((1 << (epipe->pipe.up_endpoint->ue_edesc->bInterval)) * + xfer->ux_nframes >= (sc->sc_flsize - 4) * 8) { + DPRINTF( "isoc descriptor spans entire frametable", 0, 0, 0, 0); printf("ehci: isoc descriptor requested that spans the entire frametable, too many frames\n"); return USBD_INVAL; } + KASSERT(xfer->ux_nframes != 0 && xfer->ux_frlengths); + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); + KASSERT(exfer->ex_isdone); #ifdef DIAGNOSTIC - if (xfer->rqflags & URQ_REQUEST) - panic("ehci_device_isoc_start: request"); - - if (!exfer->isdone) { - USBHIST_LOG(ehcidebug, "marked not done, ex = %p", exfer, - 0, 0, 0); - printf("ehci_device_isoc_start: not done, ex = %p\n", exfer); - } - exfer->isdone = 0; + exfer->ex_isdone = false; #endif /* - * Step 1: Allocate and initialize itds, how many do we need? - * One per transfer if interval >= 8 microframes, fewer if we use - * multiple microframes per frame. + * Step 1: Re-Initialize itds */ - i = epipe->pipe.endpoint->edesc->bInterval; + i = epipe->pipe.up_endpoint->ue_edesc->bInterval; if (i > 16 || i == 0) { /* Spec page 271 says intervals > 16 are invalid */ - USBHIST_LOG(ehcidebug, "bInterval %d invalid", i, 0, 0, 0); + DPRINTF("bInterval %d invalid", i, 0, 0, 0); return USBD_INVAL; } ufrperframe = max(1, USB_UFRAMES_PER_FRAME / (1 << (i - 1))); - frames = (xfer->nframes + (ufrperframe - 1)) / ufrperframe; + frames = (xfer->ux_nframes + (ufrperframe - 1)) / ufrperframe; uframes = USB_UFRAMES_PER_FRAME / ufrperframe; if (frames == 0) { - USBHIST_LOG(ehcidebug, "frames == 0", 0, 0, 0, 0); + DPRINTF("frames == 0", 0, 0, 0, 0); return USBD_INVAL; } - dma_buf = &xfer->dmabuf; + dma_buf = &xfer->ux_dmabuf; offs = 0; - for (i = 0; i < frames; i++) { + itd = exfer->ex_itdstart; + for (i = 0; i < frames; i++, itd = itd->xfer_next) { int froffs = offs; - itd = ehci_alloc_itd(sc); if (prev != NULL) { prev->itd.itd_next = htole32(itd->physaddr | EHCI_LINK_ITD); - usb_syncmem(&itd->dma, - itd->offs + offsetof(ehci_itd_t, itd_next), - sizeof(itd->itd.itd_next), BUS_DMASYNC_POSTWRITE); - + usb_syncmem(&prev->dma, + prev->offs + offsetof(ehci_itd_t, itd_next), + sizeof(prev->itd.itd_next), BUS_DMASYNC_POSTWRITE); prev->xfer_next = itd; - } else { - start = itd; } /* @@ -4220,27 +4760,29 @@ ehci_device_isoc_start(usbd_xfer_handle xfer) addr = EHCI_PAGE(addr); addr /= EHCI_PAGE_SIZE; - /* This gets the initial offset into the first page, + /* + * This gets the initial offset into the first page, * looks how far further along the current uframe * offset is. Works out how many pages that is. */ itd->itd.itd_ctl[j] = htole32 ( EHCI_ITD_ACTIVE | - EHCI_ITD_SET_LEN(xfer->frlengths[trans_count]) | + EHCI_ITD_SET_LEN(xfer->ux_frlengths[trans_count]) | EHCI_ITD_SET_PG(addr) | EHCI_ITD_SET_OFFS(EHCI_PAGE_OFFSET(DMAADDR(dma_buf,offs)))); - total_length += xfer->frlengths[trans_count]; - offs += xfer->frlengths[trans_count]; + total_length += xfer->ux_frlengths[trans_count]; + offs += xfer->ux_frlengths[trans_count]; trans_count++; - if (trans_count >= xfer->nframes) { /*Set IOC*/ + if (trans_count >= xfer->ux_nframes) { /*Set IOC*/ itd->itd.itd_ctl[j] |= htole32(EHCI_ITD_IOC); break; } } - /* Step 1.75, set buffer pointers. To simplify matters, all + /* + * Step 1.75, set buffer pointers. To simplify matters, all * pointers are filled out for the next 7 hardware pages in * the dma block, so no need to worry what pages to cover * and what to not. @@ -4252,28 +4794,25 @@ ehci_device_isoc_start(usbd_xfer_handle xfer) * of buffer */ int page_offs = EHCI_PAGE(froffs + (EHCI_PAGE_SIZE * j)); - if (page_offs >= dma_buf->block->size) + if (page_offs >= dma_buf->udma_block->size) break; - unsigned long long page = DMAADDR(dma_buf, page_offs); + uint64_t page = DMAADDR(dma_buf, page_offs); page = EHCI_PAGE(page); - itd->itd.itd_bufr[j] = - htole32(EHCI_ITD_SET_BPTR(page)); - itd->itd.itd_bufr_hi[j] = - htole32(page >> 32); + itd->itd.itd_bufr[j] = htole32(EHCI_ITD_SET_BPTR(page)); + itd->itd.itd_bufr_hi[j] = htole32(page >> 32); } - /* * Other special values */ - k = epipe->pipe.endpoint->edesc->bEndpointAddress; + int k = epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; itd->itd.itd_bufr[0] |= htole32(EHCI_ITD_SET_EP(UE_GET_ADDR(k)) | - EHCI_ITD_SET_DADDR(epipe->pipe.device->address)); + EHCI_ITD_SET_DADDR(epipe->pipe.up_dev->ud_addr)); - k = (UE_GET_DIR(epipe->pipe.endpoint->edesc->bEndpointAddress)) + k = (UE_GET_DIR(epipe->pipe.up_endpoint->ue_edesc->bEndpointAddress)) ? 1 : 0; - j = UGETW(epipe->pipe.endpoint->edesc->wMaxPacketSize); + j = UGETW(epipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize); itd->itd.itd_bufr[1] |= htole32(EHCI_ITD_SET_DIR(k) | EHCI_ITD_SET_MAXPKT(UE_GET_SIZE(j))); @@ -4281,20 +4820,14 @@ ehci_device_isoc_start(usbd_xfer_handle xfer) itd->itd.itd_bufr[2] |= htole32(EHCI_ITD_SET_MULTI(UE_GET_TRANS(j)+1)); - usb_syncmem(&itd->dma, - itd->offs + offsetof(ehci_itd_t, itd_next), - sizeof(ehci_itd_t), + usb_syncmem(&itd->dma, itd->offs, sizeof(ehci_itd_t), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); prev = itd; } /* End of frame */ - stop = itd; - stop->xfer_next = NULL; - exfer->isoc_len = total_length; - - usb_syncmem(&exfer->xfer.dmabuf, 0, total_length, - BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + usb_syncmem(&exfer->ex_xfer.ux_dmabuf, 0, total_length, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); /* * Part 2: Transfer descriptors have now been set up, now they must @@ -4306,8 +4839,8 @@ ehci_device_isoc_start(usbd_xfer_handle xfer) mutex_enter(&sc->sc_lock); /* Start inserting frames */ - if (epipe->u.isoc.cur_xfers > 0) { - frindex = epipe->u.isoc.next_frame; + if (epipe->isoc.cur_xfers > 0) { + frindex = epipe->isoc.next_frame; } else { frindex = EOREAD4(sc, EHCI_FRINDEX); frindex = frindex >> 3; /* Erase microframe index */ @@ -4318,41 +4851,47 @@ ehci_device_isoc_start(usbd_xfer_handle xfer) frindex &= (sc->sc_flsize - 1); /* What's the frame interval? */ - i = (1 << (epipe->pipe.endpoint->edesc->bInterval - 1)); + i = (1 << (epipe->pipe.up_endpoint->ue_edesc->bInterval - 1)); if (i / USB_UFRAMES_PER_FRAME == 0) i = 1; else i /= USB_UFRAMES_PER_FRAME; - itd = start; + itd = exfer->ex_itdstart; for (j = 0; j < frames; j++) { - if (itd == NULL) - panic("ehci: unexpectedly ran out of isoc itds, isoc_start"); + KASSERTMSG(itd != NULL, "frame %d\n", j); + + usb_syncmem(&sc->sc_fldma, + sizeof(ehci_link_t) * frindex, + sizeof(ehci_link_t), + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); itd->itd.itd_next = sc->sc_flist[frindex]; if (itd->itd.itd_next == 0) - /* FIXME: frindex table gets initialized to NULL - * or EHCI_NULL? */ + /* + * FIXME: frindex table gets initialized to NULL + * or EHCI_NULL? + */ itd->itd.itd_next = EHCI_NULL; usb_syncmem(&itd->dma, itd->offs + offsetof(ehci_itd_t, itd_next), - sizeof(itd->itd.itd_next), + sizeof(itd->itd.itd_next), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); sc->sc_flist[frindex] = htole32(EHCI_LINK_ITD | itd->physaddr); usb_syncmem(&sc->sc_fldma, sizeof(ehci_link_t) * frindex, - sizeof(ehci_link_t), + sizeof(ehci_link_t), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - itd->u.frame_list.next = sc->sc_softitds[frindex]; + itd->frame_list.next = sc->sc_softitds[frindex]; sc->sc_softitds[frindex] = itd; - if (itd->u.frame_list.next != NULL) - itd->u.frame_list.next->u.frame_list.prev = itd; + if (itd->frame_list.next != NULL) + itd->frame_list.next->frame_list.prev = itd; itd->slot = frindex; - itd->u.frame_list.prev = NULL; + itd->frame_list.prev = NULL; frindex += i; if (frindex >= sc->sc_flsize) @@ -4361,20 +4900,15 @@ ehci_device_isoc_start(usbd_xfer_handle xfer) itd = itd->xfer_next; } - epipe->u.isoc.cur_xfers++; - epipe->u.isoc.next_frame = frindex; - - exfer->itdstart = start; - exfer->itdend = stop; - exfer->sqtdstart = NULL; - exfer->sqtdend = NULL; + epipe->isoc.cur_xfers++; + epipe->isoc.next_frame = frindex; ehci_add_intr_list(sc, exfer); - xfer->status = USBD_IN_PROGRESS; - xfer->done = 0; + xfer->ux_status = USBD_IN_PROGRESS; + mutex_exit(&sc->sc_lock); - if (sc->sc_bus.use_polling) { + if (sc->sc_bus.ub_usepolling) { printf("Starting ehci isoc xfer with polling. Bad idea?\n"); ehci_waitintr(sc, xfer); } @@ -4383,42 +4917,33 @@ ehci_device_isoc_start(usbd_xfer_handle xfer) } Static void -ehci_device_isoc_abort(usbd_xfer_handle xfer) +ehci_device_isoc_abort(struct usbd_xfer *xfer) { - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "xfer = %p", xfer, 0, 0, 0); + DPRINTF("xfer = %p", xfer, 0, 0, 0); ehci_abort_isoc_xfer(xfer, USBD_CANCELLED); } Static void -ehci_device_isoc_close(usbd_pipe_handle pipe) +ehci_device_isoc_close(struct usbd_pipe *pipe) { - USBHIST_FUNC(); USBHIST_CALLED(ehcidebug); + EHCIHIST_FUNC(); EHCIHIST_CALLED(); - USBHIST_LOG(ehcidebug, "nothing in the pipe to free?", 0, 0, 0, 0); + DPRINTF("nothing in the pipe to free?", 0, 0, 0, 0); } Static void -ehci_device_isoc_done(usbd_xfer_handle xfer) +ehci_device_isoc_done(struct usbd_xfer *xfer) { - struct ehci_xfer *exfer; - ehci_softc_t *sc; - struct ehci_pipe *epipe; - - exfer = EXFER(xfer); - sc = xfer->pipe->device->bus->hci_private; - epipe = (struct ehci_pipe *) xfer->pipe; + struct ehci_xfer *exfer = EHCI_XFER2EXFER(xfer); + ehci_softc_t *sc = EHCI_XFER2SC(xfer); + struct ehci_pipe *epipe = EHCI_XFER2EPIPE(xfer); KASSERT(mutex_owned(&sc->sc_lock)); - epipe->u.isoc.cur_xfers--; - if (xfer->status != USBD_NOMEM && ehci_active_intr_list(exfer)) { - ehci_del_intr_list(sc, exfer); - ehci_rem_free_itd_chain(sc, exfer); - } - - usb_syncmem(&xfer->dmabuf, 0, xfer->length, BUS_DMASYNC_POSTWRITE | - BUS_DMASYNC_POSTREAD); - + epipe->isoc.cur_xfers--; + ehci_remove_itd_chain(sc, exfer->ex_sitdstart); + usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); } diff --git a/sys/dev/usb/ehcireg.h b/sys/dev/usb/ehcireg.h index 913f4782755..6bca149e00f 100644 --- a/sys/dev/usb/ehcireg.h +++ b/sys/dev/usb/ehcireg.h @@ -1,4 +1,4 @@ -/* $NetBSD: ehcireg.h,v 1.36 2015/09/11 06:51:43 skrll Exp $ */ +/* $NetBSD: ehcireg.h,v 1.37 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 2001, 2004 The NetBSD Foundation, Inc. @@ -86,8 +86,10 @@ #define EHCI_HCS_N_PORTS(x) ((x) & 0xf) /* # of ports */ #define EHCI_HCCPARAMS 0x08 /* RO Capability parameters */ -#define EHCI_HCC_EECP(x) (((x) >> 8) & 0xff) /* extended ports caps */ -#define EHCI_HCC_IST(x) (((x) >> 4) & 0xf) /* isoc sched threshold */ +#define EHCI_HCC_EECP(x) (((x) >> 8) & 0xff) /* extended ports caps */ +#define EHCI_HCC_IST_FULLFRAME __BIT(7) +#define EHCI_HCC_IST_THRESHOLD_MASK __BITS(6,4) /* isoc sched threshold */ +#define EHCI_HCC_GET_IST_THRESHOLD(x) __SHIFTOUT((x), EHCI_HCC_IST_THRESHOLD_MASK) #define EHCI_HCC_ASPC(x) ((x) & 0x4) /* async sched park cap */ #define EHCI_HCC_PFLF(x) ((x) & 0x2) /* prog frame list flag */ #define EHCI_HCC_64BIT(x) ((x) & 0x1) /* 64 bit address cap */ @@ -179,12 +181,15 @@ #define EHCI_MAX_PORTS 16 /* only 4 bits available in EHCI_HCS_N_PORTS */ /* No data structure may cross a page boundary. */ -#define EHCI_PAGE_SIZE 0x1000 -#define EHCI_PAGE(x) ((x) &~ 0xfff) -#define EHCI_PAGE_OFFSET(x) ((x) & 0xfff) - -typedef u_int32_t ehci_link_t; -#define EHCI_LINK_TERMINATE 0x00000001 +#define EHCI_PAGE_SHIFT 12 +#define EHCI_PAGE_SIZE (1 << EHCI_PAGE_SHIFT) +#define EHCI_PAGE_MASK (EHCI_PAGE_SIZE - 1) +#define EHCI_PAGE(x) ((x) & ~EHCI_PAGE_MASK) +#define EHCI_PAGE_OFFSET(x) ((x) & EHCI_PAGE_MASK) +#define EHCI_NPAGES(x) (((x) + EHCI_PAGE_MASK) >> EHCI_PAGE_SHIFT) + +typedef uint32_t ehci_link_t; +#define EHCI_LINK_TERMINATE __BIT(0) #define EHCI_LINK_TYPE(x) ((x) & 0x00000006) #define EHCI_LINK_ITD 0x0 #define EHCI_LINK_QH 0x2 @@ -192,10 +197,10 @@ typedef u_int32_t ehci_link_t; #define EHCI_LINK_FSTN 0x6 #define EHCI_LINK_ADDR(x) ((x) &~ 0x1f) -typedef u_int32_t ehci_physaddr_t; +typedef uint32_t ehci_physaddr_t; -typedef u_int32_t ehci_isoc_trans_t; -typedef u_int32_t ehci_isoc_bufr_ptr_t; +typedef uint32_t ehci_isoc_trans_t; +typedef uint32_t ehci_isoc_bufr_ptr_t; /* Isochronous Transfer Descriptor */ #define EHCI_ITD_NUFRAMES USB_UFRAMES_PER_FRAME @@ -203,34 +208,44 @@ typedef u_int32_t ehci_isoc_bufr_ptr_t; typedef struct { volatile ehci_link_t itd_next; volatile ehci_isoc_trans_t itd_ctl[EHCI_ITD_NUFRAMES]; -#define EHCI_ITD_GET_STATUS(x) (((x) >> 28) & 0xf) -#define EHCI_ITD_SET_STATUS(x) (((x) & 0xf) << 28) -#define EHCI_ITD_ACTIVE 0x80000000 -#define EHCI_ITD_BUF_ERR 0x40000000 -#define EHCI_ITD_BABBLE 0x20000000 -#define EHCI_ITD_ERROR 0x10000000 -#define EHCI_ITD_GET_LEN(x) (((x) >> 16) & 0xfff) -#define EHCI_ITD_SET_LEN(x) (((x) & 0xfff) << 16) -#define EHCI_ITD_IOC 0x8000 -#define EHCI_ITD_GET_IOC(x) (((x) >> 15) & 1) -#define EHCI_ITD_SET_IOC(x) (((x) << 15) & EHCI_ITD_IOC) -#define EHCI_ITD_GET_PG(x) (((x) >> 12) & 0x7) -#define EHCI_ITD_SET_PG(x) (((x) & 0x7) << 12) -#define EHCI_ITD_GET_OFFS(x) (((x) >> 0) & 0xfff) -#define EHCI_ITD_SET_OFFS(x) (((x) & 0xfff) << 0) +#define EHCI_ITD_STATUS_MASK __BITS(31,28) +#define EHCI_ITD_GET_STATUS(x) __SHIFTOUT((x), EHCI_ITD_STATUS_MASK) +#define EHCI_ITD_SET_STATUS(x) __SHIFTIN((x), EHCI_ITD_STATUS_MASK) +#define EHCI_ITD_ACTIVE __BIT(31) +#define EHCI_ITD_BUF_ERR __BIT(30) +#define EHCI_ITD_BABBLE __BIT(29) +#define EHCI_ITD_ERROR __BIT(28) +#define EHCI_ITD_LEN_MASK __BITS(27,16) +#define EHCI_ITD_GET_LEN(x) __SHIFTOUT((x), EHCI_ITD_LEN_MASK) +#define EHCI_ITD_SET_LEN(x) __SHIFTIN((x), EHCI_ITD_LEN_MASK) +#define EHCI_ITD_IOC __BIT(15) +#define EHCI_ITD_GET_IOC(x) __SHIFTOUT((x), EHCI_ITD_IOC) +#define EHCI_ITD_SET_IOC(x) __SHIFTIN((x), EHCI_ITD_IOC) +#define EHCI_ITD_PG_MASK __BITS(14,12) +#define EHCI_ITD_GET_PG(x) __SHIFTOUT((x), EHCI_ITD_PG_MASK) +#define EHCI_ITD_SET_PG(x) __SHIFTIN((x), EHCI_ITD_PG_MASK) +#define EHCI_ITD_OFFSET_MASK __BITS(11,0) +#define EHCI_ITD_GET_OFFS(x) __SHIFTOUT((x), EHCI_ITD_OFFSET_MASK) +#define EHCI_ITD_SET_OFFS(x) __SHIFTIN((x), EHCI_ITD_OFFSET_MASK) volatile ehci_isoc_bufr_ptr_t itd_bufr[EHCI_ITD_NBUFFERS]; -#define EHCI_ITD_GET_BPTR(x) ((x) & 0xfffff000) -#define EHCI_ITD_SET_BPTR(x) ((x) & 0xfffff000) -#define EHCI_ITD_GET_EP(x) (((x) >> 8) & 0xf) -#define EHCI_ITD_SET_EP(x) (((x) & 0xf) << 8) -#define EHCI_ITD_GET_DADDR(x) ((x) & 0x7f) -#define EHCI_ITD_SET_DADDR(x) ((x) & 0x7f) -#define EHCI_ITD_GET_DIR(x) (((x) >> 11) & 1) -#define EHCI_ITD_SET_DIR(x) (((x) & 1) << 11) -#define EHCI_ITD_GET_MAXPKT(x) ((x) & 0x7ff) -#define EHCI_ITD_SET_MAXPKT(x) ((x) & 0x7ff) -#define EHCI_ITD_GET_MULTI(x) ((x) & 0x3) -#define EHCI_ITD_SET_MULTI(x) ((x) & 0x3) +#define EHCI_ITD_BPTR_MASK __BITS(31,12) +#define EHCI_ITD_GET_BPTR(x) ((x) & EHCI_ITD_BPTR_MASK) +#define EHCI_ITD_SET_BPTR(x) ((x) & EHCI_ITD_BPTR_MASK) +#define EHCI_ITD_EP_MASK __BITS(11,8) +#define EHCI_ITD_GET_EP(x) __SHIFTOUT((x), EHCI_ITD_EP_MASK) +#define EHCI_ITD_SET_EP(x) __SHIFTIN((x), EHCI_ITD_EP_MASK) +#define EHCI_ITD_DADDR_MASK __BITS(6,0) +#define EHCI_ITD_GET_DADDR(x) __SHIFTOUT((x), EHCI_ITD_DADDR_MASK) +#define EHCI_ITD_SET_DADDR(x) __SHIFTIN((x), EHCI_ITD_DADDR_MASK) +#define EHCI_ITD_DIR_MASK __BIT(11) +#define EHCI_ITD_GET_DIR(x) __SHIFTOUT((x), EHCI_ITD_DIR_MASK) +#define EHCI_ITD_SET_DIR(x) __SHIFTIN((x), EHCI_ITD_DIR_MASK) +#define EHCI_ITD_MAXPKT_MASK __BITS(10,0) +#define EHCI_ITD_GET_MAXPKT(x) __SHIFTOUT((x), EHCI_ITD_MAXPKT_MASK) +#define EHCI_ITD_SET_MAXPKT(x) __SHIFTIN((x), EHCI_ITD_MAXPKT_MASK) +#define EHCI_ITD_MULTI_MASK __BITS(1,0) +#define EHCI_ITD_GET_MULTI(x) __SHIFTOUT((x), EHCI_ITD_MULTI_MASK) +#define EHCI_ITD_SET_MULTI(x) __SHIFTIN((x), EHCI_ITD_MULTI_MASK) volatile ehci_isoc_bufr_ptr_t itd_bufr_hi[EHCI_ITD_NBUFFERS]; } ehci_itd_t; #define EHCI_ITD_ALIGN 32 @@ -238,18 +253,60 @@ typedef struct { /* Split Transaction Isochronous Transfer Descriptor */ typedef struct { volatile ehci_link_t sitd_next; - /* XXX many more */ + volatile uint32_t sitd_endp; +#define EHCI_SITD_DIR_MASK __BIT(31) +#define EHCI_SITD_PORT_MASK __BITS(30,24) +#define EHCI_SITD_HUBA_MASK __BITS(22,16) +#define EHCI_SITD_ENDPT_MASK __BITS(11,8) +#define EHCI_SITD_DADDR_MASK __BITS(6,0) +#define EHCI_SITD_SET_DIR(x) __SHIFTIN((x), EHCI_SITD_DIR_MASK) +#define EHCI_SITD_SET_PORT(x) __SHIFTIN((x), EHCI_SITD_PORT_MASK) +#define EHCI_SITD_SET_HUBA(x) __SHIFTIN((x), EHCI_SITD_HUBA_MASK) +#define EHCI_SITD_SET_ENDPT(x) __SHIFTIN((x), EHCI_SITD_ENDPT_MASK) +#define EHCI_SITD_SET_DADDR(x) __SHIFTIN((x), EHCI_SITD_DADDR_MASK) + volatile uint32_t sitd_sched; +#define EHCI_SITD_SMASK_MASK __BITS(7,0) +#define EHCI_SITD_CMASK_MASK __BITS(15,8) +#define EHCI_SITD_SET_SMASK(x) __SHIFTIN((x), EHCI_SITD_SMASK_MASK) +#define EHCI_SITD_SET_CMASK(x) __SHIFTIN((x), EHCI_SITD_CMASK_MASK) + volatile uint32_t sitd_trans; +#define EHCI_SITD_IOC __BIT(31) +#define EHCI_SITD_P __BIT(30) +#define EHCI_SITD_LENGTH_MASK __BITS(25,16) +#define EHCI_SITD_GET_LEN(x) __SHIFTOUT((x), EHCI_SITD_LENGTH_MASK) +#define EHCI_SITD_SET_LEN(x) __SHIFTIN((x), EHCI_SITD_LENGTH_MASK) +#define EHCI_SITD_STATUS_MASK __BITS(7,0) +#define EHCI_SITD_ACTIVE 0x00000080 +#define EHCI_SITD_ERR 0x00000040 +#define EHCI_SITD_BUFERR 0x00000020 +#define EHCI_SITD_BABBLE 0x00000010 +#define EHCI_SITD_XACTERR 0x00000008 +#define EHCI_SITD_MISS 0x00000004 +#define EHCI_SITD_SPLITXSTATE 0x00000002 + +#define EHCI_SITD_BUFFERS 2 + + volatile uint32_t sitd_buffer[EHCI_SITD_BUFFERS]; +#define EHCI_SITD_SET_BPTR(x) ((x) & 0xfffff000) +#define EHCI_SITD_SET_OFFS(x) ((x) & 0xfff) +#define EHCI_SITD_TP_MASK __BITS(4,3) +#define EHCI_SITD_TCOUNT_MASK __BITS(2,0) + + volatile ehci_link_t sitd_back; + volatile uint32_t sitd_buffer_hi[EHCI_SITD_BUFFERS]; } ehci_sitd_t; #define EHCI_SITD_ALIGN 32 /* Queue Element Transfer Descriptor */ -#define EHCI_QTD_NBUFFERS 5 +#define EHCI_QTD_NBUFFERS 5 +#define EHCI_QTD_MAXTRANSFER (EHCI_QTD_NBUFFERS * EHCI_PAGE_SIZE) typedef struct { volatile ehci_link_t qtd_next; volatile ehci_link_t qtd_altnext; - volatile u_int32_t qtd_status; -#define EHCI_QTD_GET_STATUS(x) (((x) >> 0) & 0xff) -#define EHCI_QTD_SET_STATUS(x) ((x) << 0) + volatile uint32_t qtd_status; +#define EHCI_QTD_STATUS_MASK __BITS(7,0) +#define EHCI_QTD_GET_STATUS(x) __SHIFTOUT((x), EHCI_QTD_STATUS_MASK) +#define EHCI_QTD_SET_STATUS(x) __SHIFTIN((x), EHCI_QTD_STATUS_MASK) #define EHCI_QTD_ACTIVE 0x80 #define EHCI_QTD_HALTED 0x40 #define EHCI_QTD_BUFERR 0x20 @@ -259,22 +316,26 @@ typedef struct { #define EHCI_QTD_SPLITXSTATE 0x02 #define EHCI_QTD_PINGSTATE 0x01 #define EHCI_QTD_STATERRS 0x3c -#define EHCI_QTD_GET_PID(x) (((x) >> 8) & 0x3) -#define EHCI_QTD_SET_PID(x) ((x) << 8) +#define EHCI_QTD_PID_MASK __BITS(9,8) +#define EHCI_QTD_GET_PID(x) __SHIFTOUT((x), EHCI_QTD_PID_MASK) +#define EHCI_QTD_SET_PID(x) __SHIFTIN((x), EHCI_QTD_PID_MASK) #define EHCI_QTD_PID_OUT 0x0 #define EHCI_QTD_PID_IN 0x1 #define EHCI_QTD_PID_SETUP 0x2 -#define EHCI_QTD_GET_CERR(x) (((x) >> 10) & 0x3) -#define EHCI_QTD_SET_CERR(x) ((x) << 10) -#define EHCI_QTD_GET_C_PAGE(x) (((x) >> 12) & 0x7) -#define EHCI_QTD_SET_C_PAGE(x) ((x) << 12) -#define EHCI_QTD_GET_IOC(x) (((x) >> 15) & 0x1) -#define EHCI_QTD_IOC 0x00008000 -#define EHCI_QTD_GET_BYTES(x) (((x) >> 16) & 0x7fff) -#define EHCI_QTD_SET_BYTES(x) ((x) << 16) -#define EHCI_QTD_GET_TOGGLE(x) (((x) >> 31) & 0x1) -#define EHCI_QTD_SET_TOGGLE(x) ((x) << 31) -#define EHCI_QTD_TOGGLE_MASK 0x80000000 +#define EHCI_QTD_CERR_MASK __BITS(11,10) +#define EHCI_QTD_GET_CERR(x) __SHIFTOUT((x), EHCI_QTD_CERR_MASK) +#define EHCI_QTD_SET_CERR(x) __SHIFTIN((x), EHCI_QTD_CERR_MASK) +#define EHCI_QTD_C_PAGE_MASK __BITS(14,12) +#define EHCI_QTD_GET_C_PAGE(x) __SHIFTOUT((x), EHCI_QTD_C_PAGE_MASK) +#define EHCI_QTD_SET_C_PAGE(x) __SHIFTIN((x), EHCI_QTD_C_PAGE_MASK) +#define EHCI_QTD_IOC __BIT(15) +#define EHCI_QTD_GET_IOC(x) __SHIFTOUT((x), EHCI_QTD_IOC) +#define EHCI_QTD_BYTES_MASK __BITS(30,16) +#define EHCI_QTD_GET_BYTES(x) __SHIFTOUT((x), EHCI_QTD_BYTES_MASK) +#define EHCI_QTD_SET_BYTES(x) __SHIFTIN((x), EHCI_QTD_BYTES_MASK) +#define EHCI_QTD_TOGGLE_MASK __BIT(31) +#define EHCI_QTD_GET_TOGGLE(x) __SHIFTOUT((x), EHCI_QTD_TOGGLE_MASK) +#define EHCI_QTD_SET_TOGGLE(x) __SHIFTIN((x), EHCI_QTD_TOGGLE_MASK) volatile ehci_physaddr_t qtd_buffer[EHCI_QTD_NBUFFERS]; volatile ehci_physaddr_t qtd_buffer_hi[EHCI_QTD_NBUFFERS]; } ehci_qtd_t; @@ -283,41 +344,49 @@ typedef struct { /* Queue Head */ typedef struct { volatile ehci_link_t qh_link; - volatile u_int32_t qh_endp; -#define EHCI_QH_GET_ADDR(x) (((x) >> 0) & 0x7f) /* endpoint addr */ -#define EHCI_QH_SET_ADDR(x) (x) -#define EHCI_QH_ADDRMASK 0x0000007f -#define EHCI_QH_GET_INACT(x) (((x) >> 7) & 0x01) /* inactivate on next */ -#define EHCI_QH_INACT 0x00000080 -#define EHCI_QH_GET_ENDPT(x) (((x) >> 8) & 0x0f) /* endpoint no */ -#define EHCI_QH_SET_ENDPT(x) ((x) << 8) -#define EHCI_QH_GET_EPS(x) (((x) >> 12) & 0x03) /* endpoint speed */ -#define EHCI_QH_SET_EPS(x) ((x) << 12) + volatile uint32_t qh_endp; +#define EHCI_QH_ADDR_MASK __BITS(6,0) /* endpoint addr */ +#define EHCI_QH_GET_ADDR(x) __SHIFTOUT((x), EHCI_QH_ADDR_MASK) +#define EHCI_QH_SET_ADDR(x) __SHIFTIN((x), EHCI_QH_ADDR_MASK) +#define EHCI_QH_INACT __BIT(7) /* inactivate on next */ +#define EHCI_QH_GET_INACT(x) __SHIFTOUT((x), EHCI_QH_INACT) +#define EHCI_QH_ENDPT_MASK __BITS(11,8) /* endpoint no */ +#define EHCI_QH_GET_ENDPT(x) __SHIFTOUT((x), EHCI_QH_ENDPT_MASK) +#define EHCI_QH_SET_ENDPT(x) __SHIFTIN((x), EHCI_QH_ENDPT_MASK) +#define EHCI_QH_EPS_MASK __BITS(13,12) /* endpoint speed */ +#define EHCI_QH_GET_EPS(x) __SHIFTOUT((x), EHCI_QH_EPS_MASK) +#define EHCI_QH_SET_EPS(x) __SHIFTIN((x), EHCI_QH_EPS_MASK) #define EHCI_QH_SPEED_FULL 0x0 #define EHCI_QH_SPEED_LOW 0x1 #define EHCI_QH_SPEED_HIGH 0x2 -#define EHCI_QH_GET_DTC(x) (((x) >> 14) & 0x01) /* data toggle control */ -#define EHCI_QH_DTC 0x00004000 -#define EHCI_QH_GET_HRECL(x) (((x) >> 15) & 0x01) /* head of reclamation */ -#define EHCI_QH_HRECL 0x00008000 -#define EHCI_QH_GET_MPL(x) (((x) >> 16) & 0x7ff) /* max packet len */ -#define EHCI_QH_SET_MPL(x) ((x) << 16) -#define EHCI_QH_MPLMASK 0x07ff0000 -#define EHCI_QH_GET_CTL(x) (((x) >> 27) & 0x01) /* control endpoint */ -#define EHCI_QH_CTL 0x08000000 -#define EHCI_QH_GET_NRL(x) (((x) >> 28) & 0x0f) /* NAK reload */ -#define EHCI_QH_SET_NRL(x) ((x) << 28) - volatile u_int32_t qh_endphub; -#define EHCI_QH_GET_SMASK(x) (((x) >> 0) & 0xff) /* intr sched mask */ -#define EHCI_QH_SET_SMASK(x) ((x) << 0) -#define EHCI_QH_GET_CMASK(x) (((x) >> 8) & 0xff) /* split completion mask */ -#define EHCI_QH_SET_CMASK(x) ((x) << 8) -#define EHCI_QH_GET_HUBA(x) (((x) >> 16) & 0x7f) /* hub address */ -#define EHCI_QH_SET_HUBA(x) ((x) << 16) -#define EHCI_QH_GET_PORT(x) (((x) >> 23) & 0x7f) /* hub port */ -#define EHCI_QH_SET_PORT(x) ((x) << 23) -#define EHCI_QH_GET_MULT(x) (((x) >> 30) & 0x03) /* pipe multiplier */ -#define EHCI_QH_SET_MULT(x) ((x) << 30) +#define EHCI_QH_DTC __BIT(14) /* data toggle control */ +#define EHCI_QH_GET_DTC(x) __SHIFTOUT((x), EHCI_QH_DTC) +#define EHCI_QH_HRECL __BIT(15) /* head of reclamation */ +#define EHCI_QH_GET_HRECL(x) __SHIFTOUT((x), EHCI_QH_HRECL) +#define EHCI_QH_MPL_MASK __BITS(26,16) /* max packet len */ +#define EHCI_QH_GET_MPL(x) __SHIFTOUT((x), EHCI_QH_MPL_MASK) +#define EHCI_QH_SET_MPL(x) __SHIFTIN((x), EHCI_QH_MPL_MASK) +#define EHCI_QH_CTL __BIT(27) /* control endpoint */ +#define EHCI_QH_GET_CTL(x) __SHIFTOUT((x), EHCI_QH_CTL) +#define EHCI_QH_NRL_MASK __BITS(31,28) /* NAK reload */ +#define EHCI_QH_GET_NRL(x) __SHIFTOUT((x), EHCI_QH_NRL_MASK) +#define EHCI_QH_SET_NRL(x) __SHIFTIN((x), EHCI_QH_NRL_MASK) + volatile uint32_t qh_endphub; +#define EHCI_QH_SMASK_MASK __BITS(7,0) /* intr sched mask */ +#define EHCI_QH_GET_SMASK(x) __SHIFTOUT((x), EHCI_QH_SMASK_MASK) +#define EHCI_QH_SET_SMASK(x) __SHIFTIN((x), EHCI_QH_SMASK_MASK) +#define EHCI_QH_CMASK_MASK __BITS(15,8) /* split completion mask */ +#define EHCI_QH_GET_CMASK(x) __SHIFTOUT((x), EHCI_QH_CMASK_MASK) +#define EHCI_QH_SET_CMASK(x) __SHIFTIN((x), EHCI_QH_CMASK_MASK) +#define EHCI_QH_HUBA_MASK __BITS(22,16) /* hub address */ +#define EHCI_QH_GET_HUBA(x) __SHIFTOUT((x), EHCI_QH_HUBA_MASK) +#define EHCI_QH_SET_HUBA(x) __SHIFTIN((x), EHCI_QH_HUBA_MASK) +#define EHCI_QH_PORT_MASK __BITS(29,23) /* hub port */ +#define EHCI_QH_GET_PORT(x) __SHIFTOUT((x), EHCI_QH_PORT_MASK) +#define EHCI_QH_SET_PORT(x) __SHIFTIN((x), EHCI_QH_PORT_MASK) +#define EHCI_QH_MULTI_MASK __BITS(31,30) /* pipe multiplier */ +#define EHCI_QH_GET_MULT(x) __SHIFTOUT((x), EHCI_QH_MULTI_MASK) +#define EHCI_QH_SET_MULT(x) __SHIFTIN((x), EHCI_QH_MULTI_MASK) volatile ehci_link_t qh_curqtd; ehci_qtd_t qh_qtd; } ehci_qh_t; diff --git a/sys/dev/usb/ehcivar.h b/sys/dev/usb/ehcivar.h index 426019ad059..3abc6273b4f 100644 --- a/sys/dev/usb/ehcivar.h +++ b/sys/dev/usb/ehcivar.h @@ -1,4 +1,4 @@ -/* $NetBSD: ehcivar.h,v 1.42 2013/02/02 14:15:55 matt Exp $ */ +/* $NetBSD: ehcivar.h,v 1.43 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -36,16 +36,15 @@ typedef struct ehci_soft_qtd { ehci_qtd_t qtd; - struct ehci_soft_qtd *nextqtd; /* mirrors nextqtd in TD */ - ehci_physaddr_t physaddr; - usb_dma_t dma; /* qTD's DMA infos */ - int offs; /* qTD's offset in usb_dma_t */ - usbd_xfer_handle xfer; - LIST_ENTRY(ehci_soft_qtd) hnext; - u_int16_t len; + struct ehci_soft_qtd *nextqtd; /* mirrors nextqtd in TD */ + ehci_physaddr_t physaddr; /* qTD's physical address */ + usb_dma_t dma; /* qTD's DMA infos */ + int offs; /* qTD's offset in usb_dma_t */ + struct usbd_xfer *xfer; /* xfer back pointer */ + uint16_t len; } ehci_soft_qtd_t; #define EHCI_SQTD_ALIGN MAX(EHCI_QTD_ALIGN, CACHE_LINE_SIZE) -#define EHCI_SQTD_SIZE ((sizeof (struct ehci_soft_qtd) + EHCI_SQTD_ALIGN - 1) & -EHCI_SQTD_ALIGN) +#define EHCI_SQTD_SIZE ((sizeof(struct ehci_soft_qtd) + EHCI_SQTD_ALIGN - 1) & -EHCI_SQTD_ALIGN) #define EHCI_SQTD_CHUNK (EHCI_PAGE_SIZE / EHCI_SQTD_SIZE) typedef struct ehci_soft_qh { @@ -53,24 +52,27 @@ typedef struct ehci_soft_qh { struct ehci_soft_qh *next; struct ehci_soft_qtd *sqtd; ehci_physaddr_t physaddr; - usb_dma_t dma; /* QH's DMA infos */ - int offs; /* QH's offset in usb_dma_t */ + usb_dma_t dma; /* QH's DMA infos */ + int offs; /* QH's offset in usb_dma_t */ int islot; } ehci_soft_qh_t; -#define EHCI_SQH_SIZE ((sizeof (struct ehci_soft_qh) + EHCI_QH_ALIGN - 1) / EHCI_QH_ALIGN * EHCI_QH_ALIGN) +#define EHCI_SQH_SIZE ((sizeof(struct ehci_soft_qh) + EHCI_QH_ALIGN - 1) / EHCI_QH_ALIGN * EHCI_QH_ALIGN) #define EHCI_SQH_CHUNK (EHCI_PAGE_SIZE / EHCI_SQH_SIZE) typedef struct ehci_soft_itd { - ehci_itd_t itd; + union { + ehci_itd_t itd; + ehci_sitd_t sitd; + }; union { struct { - /* soft_itds links in a periodic frame*/ + /* soft_itds links in a periodic frame */ struct ehci_soft_itd *next; struct ehci_soft_itd *prev; } frame_list; /* circular list of free itds */ LIST_ENTRY(ehci_soft_itd) free_list; - } u; + }; struct ehci_soft_itd *xfer_next; /* Next soft_itd in xfer */ ehci_physaddr_t physaddr; usb_dma_t dma; @@ -81,18 +83,64 @@ typedef struct ehci_soft_itd { #define EHCI_ITD_SIZE ((sizeof(struct ehci_soft_itd) + EHCI_QH_ALIGN - 1) / EHCI_ITD_ALIGN * EHCI_ITD_ALIGN) #define EHCI_ITD_CHUNK (EHCI_PAGE_SIZE / EHCI_ITD_SIZE) +#define ehci_soft_sitd_t ehci_soft_itd_t +#define ehci_soft_sitd ehci_soft_itd +#define sc_softsitds sc_softitds +#define EHCI_SITD_SIZE ((sizeof(struct ehci_soft_sitd) + EHCI_QH_ALIGN - 1) / EHCI_SITD_ALIGN * EHCI_SITD_ALIGN) +#define EHCI_SITD_CHUNK (EHCI_PAGE_SIZE / EHCI_SITD_SIZE) + struct ehci_xfer { - struct usbd_xfer xfer; - struct usb_task abort_task; - TAILQ_ENTRY(ehci_xfer) inext; /* list of active xfers */ - ehci_soft_qtd_t *sqtdstart; - ehci_soft_qtd_t *sqtdend; - ehci_soft_itd_t *itdstart; - ehci_soft_itd_t *itdend; - u_int isoc_len; - int isdone; /* used only when DIAGNOSTIC is defined */ + struct usbd_xfer ex_xfer; + struct usb_task ex_aborttask; + TAILQ_ENTRY(ehci_xfer) ex_next; /* list of active xfers */ + enum { + EX_NONE, + EX_CTRL, + EX_BULK, + EX_INTR, + EX_ISOC, + EX_FS_ISOC + } ex_type; + /* ctrl/bulk/intr */ + struct { + ehci_soft_qtd_t **ex_sqtds; + size_t ex_nsqtd; + }; + union { + /* ctrl */ + struct { + ehci_soft_qtd_t *ex_setup; + ehci_soft_qtd_t *ex_data; + ehci_soft_qtd_t *ex_status; + }; + /* bulk/intr */ + struct { + ehci_soft_qtd_t *ex_sqtdstart; + ehci_soft_qtd_t *ex_sqtdend; + }; + /* isoc */ + struct { + ehci_soft_itd_t *ex_itdstart; + ehci_soft_itd_t *ex_itdend; + }; + /* split (aka fs) isoc */ + struct { + ehci_soft_sitd_t *ex_sitdstart; + ehci_soft_sitd_t *ex_sitdend; + }; + }; + bool ex_isdone; /* used only when DIAGNOSTIC is defined */ }; -#define EXFER(xfer) ((struct ehci_xfer *)(xfer)) + +#define EHCI_BUS2SC(bus) ((bus)->ub_hcpriv) +#define EHCI_PIPE2SC(pipe) EHCI_BUS2SC((pipe)->up_dev->ud_bus) +#define EHCI_XFER2SC(xfer) EHCI_BUS2SC((xfer)->ux_bus) +#define EHCI_EPIPE2SC(epipe) EHCI_BUS2SC((epipe)->pipe.up_dev->ud_bus) + +#define EHCI_XFER2EXFER(xfer) ((struct ehci_xfer *)(xfer)) + +#define EHCI_XFER2EPIPE(xfer) ((struct ehci_pipe *)((xfer)->ux_pipe)) +#define EHCI_PIPE2EPIPE(pipe) ((struct ehci_pipe *)(pipe)) /* Information about an entry in the interrupt list. */ struct ehci_soft_islot { @@ -132,7 +180,7 @@ typedef struct ehci_softc { char sc_vendor[32]; /* vendor string for root hub */ int sc_id_vendor; /* vendor ID for root hub */ - u_int32_t sc_cmd; /* shadow of cmd reg during suspend */ + uint32_t sc_cmd; /* shadow of cmd reg during suspend */ u_int sc_ncomp; u_int sc_npcomp; @@ -145,7 +193,8 @@ typedef struct ehci_softc { struct ehci_soft_islot sc_islots[EHCI_INTRQHS]; - /* jcmm - an array matching sc_flist, but with software pointers, + /* + * an array matching sc_flist, but with software pointers, * not hardware address pointers */ struct ehci_soft_itd **sc_softitds; @@ -155,17 +204,17 @@ typedef struct ehci_softc { ehci_soft_qh_t *sc_freeqhs; ehci_soft_qtd_t *sc_freeqtds; LIST_HEAD(sc_freeitds, ehci_soft_itd) sc_freeitds; + LIST_HEAD(sc_freesitds, ehci_soft_sitd) sc_freesitds; int sc_noport; - u_int8_t sc_hasppc; /* has Port Power Control */ - u_int8_t sc_addr; /* device address */ - u_int8_t sc_conf; /* device configuration */ - usbd_xfer_handle sc_intrxfer; + uint8_t sc_hasppc; /* has Port Power Control */ + uint8_t sc_istthreshold; /* ISOC Scheduling Threshold (uframes) */ + struct usbd_xfer *sc_intrxfer; char sc_isreset[EHCI_MAX_PORTS]; char sc_softwake; kcondvar_t sc_softwake_cv; - u_int32_t sc_eintrs; + uint32_t sc_eintrs; ehci_soft_qh_t *sc_async_head; pool_cache_t sc_xferpool; /* free xfer pool */ @@ -174,7 +223,6 @@ typedef struct ehci_softc { device_t sc_child; /* /dev/usb# device */ char sc_dying; - struct usb_dma_reserve sc_dma_reserve; void (*sc_vendor_init)(struct ehci_softc *); int (*sc_vendor_port_status)(struct ehci_softc *, uint32_t, int); @@ -193,7 +241,7 @@ typedef struct ehci_softc { #define EOWRITE2(sc, a, x) bus_space_write_2((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x)) #define EOWRITE4(sc, a, x) bus_space_write_4((sc)->iot, (sc)->ioh, (sc)->sc_offs+(a), (x)) -usbd_status ehci_init(ehci_softc_t *); +int ehci_init(ehci_softc_t *); int ehci_intr(void *); int ehci_detach(ehci_softc_t *, int); int ehci_activate(device_t, enum devact); diff --git a/sys/dev/usb/emdtv.c b/sys/dev/usb/emdtv.c index cda585efeef..2114a7b11b7 100644 --- a/sys/dev/usb/emdtv.c +++ b/sys/dev/usb/emdtv.c @@ -1,4 +1,4 @@ -/* $NetBSD: emdtv.c,v 1.10 2015/04/02 06:23:04 skrll Exp $ */ +/* $NetBSD: emdtv.c,v 1.11 2016/04/23 10:15:31 skrll Exp $ */ /*- * Copyright (c) 2008, 2011 Jared D. McNeill <jmcneill@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: emdtv.c,v 1.10 2015/04/02 06:23:04 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: emdtv.c,v 1.11 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -73,7 +73,7 @@ emdtv_match(device_t parent, cfdata_t match, void *opaque) { struct usb_attach_arg *uaa = opaque; - return usb_lookup(emdtv_devices, uaa->vendor, uaa->product) != NULL ? + return usb_lookup(emdtv_devices, uaa->uaa_vendor, uaa->uaa_product) != NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } @@ -82,7 +82,7 @@ emdtv_attach(device_t parent, device_t self, void *opaque) { struct emdtv_softc *sc = device_private(self); struct usb_attach_arg *uaa = opaque; - usbd_device_handle dev = uaa->device; + struct usbd_device *dev = uaa->uaa_device; usbd_status status; char *devinfo; @@ -94,8 +94,8 @@ emdtv_attach(device_t parent, device_t self, void *opaque) sc->sc_dev = self; sc->sc_udev = dev; - sc->sc_vendor = uaa->vendor; - sc->sc_product = uaa->product; + sc->sc_vendor = uaa->uaa_vendor; + sc->sc_product = uaa->uaa_product; emdtv_i2c_attach(sc); diff --git a/sys/dev/usb/emdtv_dtv.c b/sys/dev/usb/emdtv_dtv.c index de8150f51e2..7c184bee332 100644 --- a/sys/dev/usb/emdtv_dtv.c +++ b/sys/dev/usb/emdtv_dtv.c @@ -1,4 +1,4 @@ -/* $NetBSD: emdtv_dtv.c,v 1.11 2015/04/02 06:23:04 skrll Exp $ */ +/* $NetBSD: emdtv_dtv.c,v 1.12 2016/04/23 10:15:31 skrll Exp $ */ /*- * Copyright (c) 2008, 2011 Jared D. McNeill <jmcneill@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: emdtv_dtv.c,v 1.11 2015/04/02 06:23:04 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: emdtv_dtv.c,v 1.12 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -65,7 +65,7 @@ static int emdtv_dtv_tuner_reset(void *); static void emdtv_dtv_isoc_startall(struct emdtv_softc *); static int emdtv_dtv_isoc_start(struct emdtv_softc *, struct emdtv_isoc_xfer *); -static void emdtv_dtv_isoc(usbd_xfer_handle, usbd_private_handle, +static void emdtv_dtv_isoc(struct usbd_xfer *, void *, usbd_status); static const struct dtv_hw_if emdtv_dtv_if = { @@ -103,7 +103,7 @@ emdtv_dtv_attach(struct emdtv_softc *sc) aprint_debug_dev(sc->sc_dev, "calling usbd_open_pipe, ep 0x%02x\n", ed->bEndpointAddress); - status = usbd_open_pipe(sc->sc_iface, + status = usbd_open_pipe(sc->sc_iface, ed->bEndpointAddress, USBD_EXCLUSIVE_USE|USBD_MPSAFE, &sc->sc_isoc_pipe); if (status != USBD_NORMAL_COMPLETION) { @@ -125,6 +125,20 @@ emdtv_dtv_attach(struct emdtv_softc *sc) emdtv_dtv_rescan(sc, NULL, NULL); } +static void +emdtv_dtv_free_xfers(struct emdtv_softc *sc) +{ + + for (size_t i = 0; i < EMDTV_NXFERS; i++) + if (sc->sc_ix[i].ix_xfer) { + usbd_destroy_xfer(sc->sc_ix[i].ix_xfer); + sc->sc_ix[i].ix_xfer = NULL; + sc->sc_ix[i].ix_buf = NULL; + } + + return; +} + void emdtv_dtv_detach(struct emdtv_softc *sc, int flags) { @@ -142,6 +156,7 @@ emdtv_dtv_detach(struct emdtv_softc *sc, int flags) if (sc->sc_isoc_pipe) { usbd_abort_pipe(sc->sc_isoc_pipe); + emdtv_dtv_free_xfers(sc); usbd_close_pipe(sc->sc_isoc_pipe); sc->sc_isoc_pipe = NULL; } @@ -182,6 +197,20 @@ emdtv_dtv_open(void *priv, int flags) if (sc->sc_dying) return ENXIO; + aprint_debug_dev(sc->sc_dev, "allocating isoc xfers (pktsz %d)\n", + sc->sc_isoc_maxpacketsize); + + for (size_t i = 0; i < EMDTV_NXFERS; i++) { + int error = usbd_create_xfer(sc->sc_isoc_pipe, + sc->sc_isoc_buflen, USBD_SHORT_XFER_OK, EMDTV_NFRAMES, + &sc->sc_ix[i].ix_xfer); + if (error) + return error; + sc->sc_ix[i].ix_buf = usbd_get_buffer(sc->sc_ix[i].ix_xfer); + aprint_debug_dev(sc->sc_dev, " ix[%zu] xfer %p buf %p\n", + i, sc->sc_ix[i].ix_xfer, sc->sc_ix[i].ix_buf); + } + switch (sc->sc_board->eb_tuner) { case EMDTV_TUNER_XC3028: if (sc->sc_xc3028 == NULL) { @@ -234,7 +263,9 @@ emdtv_dtv_open(void *priv, int flags) static void emdtv_dtv_close(void *priv) { - return; + struct emdtv_softc *sc = priv; + + emdtv_dtv_free_xfers(sc); } static int @@ -297,7 +328,7 @@ emdtv_dtv_start_transfer(void *priv, void (*cb)(void *, const struct dtv_payload *), void *arg) { struct emdtv_softc *sc = priv; - int i, s; + int s; s = splusb(); @@ -305,19 +336,6 @@ emdtv_dtv_start_transfer(void *priv, sc->sc_dtvsubmitcb = cb; sc->sc_dtvsubmitarg = arg; - aprint_debug_dev(sc->sc_dev, "allocating isoc xfers (pktsz %d)\n", - sc->sc_isoc_maxpacketsize); - - KERNEL_LOCK(1, curlwp); - for (i = 0; i < EMDTV_NXFERS; i++) { - sc->sc_ix[i].ix_xfer = usbd_alloc_xfer(sc->sc_udev); - sc->sc_ix[i].ix_buf = usbd_alloc_buffer(sc->sc_ix[i].ix_xfer, - sc->sc_isoc_buflen); - aprint_debug_dev(sc->sc_dev, " ix[%d] xfer %p buf %p\n", - i, sc->sc_ix[i].ix_xfer, sc->sc_ix[i].ix_buf); - } - KERNEL_UNLOCK_ONE(curlwp); - aprint_debug_dev(sc->sc_dev, "starting isoc transactions\n"); emdtv_dtv_isoc_startall(sc); @@ -330,7 +348,6 @@ static int emdtv_dtv_stop_transfer(void *priv) { struct emdtv_softc *sc = priv; - int i; aprint_debug_dev(sc->sc_dev, "stopping stream\n"); @@ -339,13 +356,6 @@ emdtv_dtv_stop_transfer(void *priv) KERNEL_LOCK(1, curlwp); if (sc->sc_isoc_pipe != NULL) usbd_abort_pipe(sc->sc_isoc_pipe); - - for (i = 0; i < EMDTV_NXFERS; i++) - if (sc->sc_ix[i].ix_xfer) { - usbd_free_xfer(sc->sc_ix[i].ix_xfer); - sc->sc_ix[i].ix_xfer = NULL; - sc->sc_ix[i].ix_buf = NULL; - } KERNEL_UNLOCK_ONE(curlwp); sc->sc_dtvsubmitcb = NULL; @@ -378,11 +388,10 @@ emdtv_dtv_isoc_start(struct emdtv_softc *sc, struct emdtv_isoc_xfer *ix) ix->ix_frlengths[i] = sc->sc_isoc_maxpacketsize; usbd_setup_isoc_xfer(ix->ix_xfer, - sc->sc_isoc_pipe, ix, ix->ix_frlengths, EMDTV_NFRAMES, - USBD_NO_COPY | USBD_SHORT_XFER_OK, + USBD_SHORT_XFER_OK, emdtv_dtv_isoc); KERNEL_LOCK(1, curlwp); @@ -393,13 +402,13 @@ emdtv_dtv_isoc_start(struct emdtv_softc *sc, struct emdtv_isoc_xfer *ix) } static void -emdtv_dtv_isoc(usbd_xfer_handle xfer, usbd_private_handle priv, +emdtv_dtv_isoc(struct usbd_xfer *xfer, void * priv, usbd_status err) { struct emdtv_isoc_xfer *ix = priv; struct emdtv_softc *sc = ix->ix_sc; struct dtv_payload payload; - usbd_pipe_handle isoc = sc->sc_isoc_pipe; + struct usbd_pipe *isoc = sc->sc_isoc_pipe; uint32_t len; uint8_t *buf; int i; diff --git a/sys/dev/usb/emdtv_ir.c b/sys/dev/usb/emdtv_ir.c index e6c671dde6f..016afd57421 100644 --- a/sys/dev/usb/emdtv_ir.c +++ b/sys/dev/usb/emdtv_ir.c @@ -1,4 +1,4 @@ -/* $NetBSD: emdtv_ir.c,v 1.1 2011/07/11 18:02:04 jmcneill Exp $ */ +/* $NetBSD: emdtv_ir.c,v 1.2 2016/04/23 10:15:31 skrll Exp $ */ /*- * Copyright (c) 2008 Jared D. McNeill <jmcneill@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: emdtv_ir.c,v 1.1 2011/07/11 18:02:04 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: emdtv_ir.c,v 1.2 2016/04/23 10:15:31 skrll Exp $"); #include <sys/select.h> #include <sys/param.h> @@ -49,7 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: emdtv_ir.c,v 1.1 2011/07/11 18:02:04 jmcneill Exp $" #include <dev/ir/cirio.h> #include <dev/ir/cirvar.h> -static void emdtv_ir_intr(usbd_xfer_handle, usbd_private_handle, +static void emdtv_ir_intr(struct usbd_xfer *, void *, usbd_status); static void emdtv_ir_worker(struct work *, void *); @@ -125,7 +125,7 @@ emdtv_ir_detach(struct emdtv_softc *sc, int flags) } static void -emdtv_ir_intr(usbd_xfer_handle xfer, usbd_private_handle priv, +emdtv_ir_intr(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct emdtv_softc *sc = priv; diff --git a/sys/dev/usb/emdtvvar.h b/sys/dev/usb/emdtvvar.h index 9ff3af98540..f9dd46d0549 100644 --- a/sys/dev/usb/emdtvvar.h +++ b/sys/dev/usb/emdtvvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: emdtvvar.h,v 1.3 2011/08/09 01:42:24 jmcneill Exp $ */ +/* $NetBSD: emdtvvar.h,v 1.4 2016/04/23 10:15:31 skrll Exp $ */ /*- * Copyright (c) 2008 Jared D. McNeill <jmcneill@invisible.ca> @@ -55,7 +55,7 @@ struct emdtv_softc; struct emdtv_isoc_xfer { struct emdtv_softc *ix_sc; - usbd_xfer_handle ix_xfer; + struct usbd_xfer *ix_xfer; uint8_t *ix_buf; uint16_t ix_frlengths[EMDTV_NFRAMES]; struct emdtv_isoc_xfer *ix_altix; @@ -63,7 +63,7 @@ struct emdtv_isoc_xfer { struct emdtv_softc { device_t sc_dev; - usbd_device_handle sc_udev; + struct usbd_device *sc_udev; device_t sc_cirdev; device_t sc_dtvdev; @@ -80,14 +80,14 @@ struct emdtv_softc { uint8_t sc_eeprom[EMDTV_EEPROM_LEN]; - usbd_interface_handle sc_iface; + struct usbd_interface *sc_iface; - usbd_pipe_handle sc_isoc_pipe; + struct usbd_pipe *sc_isoc_pipe; int sc_isoc_buflen; int sc_isoc_maxpacketsize; struct emdtv_isoc_xfer sc_ix[EMDTV_NXFERS]; - usbd_pipe_handle sc_intr_pipe; + struct usbd_pipe *sc_intr_pipe; uint8_t sc_intr_buf; struct workqueue *sc_ir_wq; struct work sc_ir_work; diff --git a/sys/dev/usb/ezload.c b/sys/dev/usb/ezload.c index f11ebe3dcc0..3ef257463ad 100644 --- a/sys/dev/usb/ezload.c +++ b/sys/dev/usb/ezload.c @@ -1,4 +1,4 @@ -/* $NetBSD: ezload.c,v 1.15 2013/01/05 23:34:16 christos Exp $ */ +/* $NetBSD: ezload.c,v 1.16 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ezload.c,v 1.15 2013/01/05 23:34:16 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ezload.c,v 1.16 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -85,7 +85,7 @@ int ezloaddebug = 0; #endif usbd_status -ezload_reset(usbd_device_handle dev, int reset) +ezload_reset(struct usbd_device *dev, int reset) { usb_device_request_t req; uByte rst; @@ -98,11 +98,11 @@ ezload_reset(usbd_device_handle dev, int reset) USETW(req.wValue, ANCHOR_CPUCS_REG); USETW(req.wIndex, 0); USETW(req.wLength, 1); - return (usbd_do_request(dev, &req, &rst)); + return usbd_do_request(dev, &req, &rst); } usbd_status -ezload_download(usbd_device_handle dev, const struct ezdata *rec) +ezload_download(struct usbd_device *dev, const struct ezdata *rec) { usb_device_request_t req; const struct ezdata *ptr; @@ -115,7 +115,7 @@ ezload_download(usbd_device_handle dev, const struct ezdata *rec) #if 0 if (ptr->address + ptr->length > ANCHOR_MAX_INTERNAL_ADDRESS) - return (USBD_INVAL); + return USBD_INVAL; #endif req.bmRequestType = UT_WRITE_VENDOR_DEVICE; @@ -133,30 +133,30 @@ ezload_download(usbd_device_handle dev, const struct ezdata *rec) err = usbd_do_request(dev, &req, __UNCONST(ptr->data + offs)); if (err) - return (err); + return err; } } - return (0); + return 0; } usbd_status -ezload_downloads_and_reset(usbd_device_handle dev, const struct ezdata **recs) +ezload_downloads_and_reset(struct usbd_device *dev, const struct ezdata **recs) { usbd_status err; /*(void)ezload_reset(dev, 1);*/ err = ezload_reset(dev, 1); if (err) - return (err); + return err; usbd_delay_ms(dev, 250); while (*recs != NULL) { err = ezload_download(dev, *recs++); if (err) - return (err); + return err; } usbd_delay_ms(dev, 250); err = ezload_reset(dev, 0); usbd_delay_ms(dev, 250); - return (err); + return err; } diff --git a/sys/dev/usb/ezload.h b/sys/dev/usb/ezload.h index 999b3a7822c..d0a40b9fb23 100644 --- a/sys/dev/usb/ezload.h +++ b/sys/dev/usb/ezload.h @@ -1,4 +1,4 @@ -/* $NetBSD: ezload.h,v 1.5 2008/04/28 20:23:59 martin Exp $ */ +/* $NetBSD: ezload.h,v 1.6 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -30,11 +30,11 @@ */ struct ezdata { - u_int8_t length; - u_int16_t address; - const u_int8_t *data; + uint8_t length; + uint16_t address; + const uint8_t *data; }; -usbd_status ezload_reset(usbd_device_handle, int); -usbd_status ezload_download(usbd_device_handle, const struct ezdata *); -usbd_status ezload_downloads_and_reset(usbd_device_handle, const struct ezdata **); +usbd_status ezload_reset(struct usbd_device *, int); +usbd_status ezload_download(struct usbd_device *, const struct ezdata *); +usbd_status ezload_downloads_and_reset(struct usbd_device *, const struct ezdata **); diff --git a/sys/dev/usb/files.usb b/sys/dev/usb/files.usb index 206e20369e4..0474c1d8009 100644 --- a/sys/dev/usb/files.usb +++ b/sys/dev/usb/files.usb @@ -1,4 +1,4 @@ -# $NetBSD: files.usb,v 1.137 2015/10/29 00:15:48 mrg Exp $ +# $NetBSD: files.usb,v 1.138 2016/04/23 10:15:31 skrll Exp $ # # Config file and device description for machine-independent USB code. # Included by ports that need it. Ports that use it must provide @@ -105,7 +105,7 @@ file dev/usb/usb_subr.c usb file dev/usb/usb_quirks.c usb define usb_dma: usb -file dev/usb/usb_mem.c usb_dma +file dev/usb/usb_mem.c usb_dma needs-flag define usbverbose: usb file dev/usb/usb_verbose.c usbverbose diff --git a/sys/dev/usb/hid.c b/sys/dev/usb/hid.c index 72856c58488..2c9a2bebdbf 100644 --- a/sys/dev/usb/hid.c +++ b/sys/dev/usb/hid.c @@ -1,4 +1,4 @@ -/* $NetBSD: hid.c,v 1.43 2016/01/23 17:02:25 riastradh Exp $ */ +/* $NetBSD: hid.c,v 1.44 2016/04/23 10:15:31 skrll Exp $ */ /* $FreeBSD: src/sys/dev/usb/hid.c,v 1.11 1999/11/17 22:33:39 n_hibma Exp $ */ /* @@ -32,12 +32,12 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: hid.c,v 1.43 2016/01/23 17:02:25 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: hid.c,v 1.44 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <dev/usb/usb.h> #include <dev/usb/usbhid.h> @@ -91,11 +91,13 @@ hid_start_parse(const void *d, int len, enum hid_kind kind) { struct hid_data *s; - s = malloc(sizeof *s, M_TEMP, M_WAITOK|M_ZERO); + s = kmem_zalloc(sizeof(*s), KM_SLEEP); + if (s == NULL) + return s; s->start = s->p = d; s->end = (const char *)d + len; s->kind = kind; - return (s); + return s; } void @@ -104,10 +106,10 @@ hid_end_parse(struct hid_data *s) while (s->cur.next != NULL) { struct hid_item *hi = s->cur.next->next; - free(s->cur.next, M_TEMP); + kmem_free(s->cur.next, sizeof(*s->cur.next)); s->cur.next = hi; } - free(s, M_TEMP); + kmem_free(s, sizeof(*s)); } int @@ -115,7 +117,7 @@ hid_get_item(struct hid_data *s, struct hid_item *h) { struct hid_item *c = &s->cur; unsigned int bTag, bType, bSize; - u_int32_t oldpos; + uint32_t oldpos; const u_char *data; int32_t dval; const u_char *p; @@ -134,7 +136,7 @@ hid_get_item(struct hid_data *s, struct hid_item *h) c->loc.pos += c->loc.size; h->next = NULL; DPRINTFN(5,("return multi\n")); - return (1); + return 1; } else { c->loc.count = s->multimax; s->multimax = 0; @@ -145,7 +147,7 @@ hid_get_item(struct hid_data *s, struct hid_item *h) for (;;) { p = s->p; if (p >= s->end) - return (0); + return 0; bSize = *p++; if (bSize == 0xfe) { @@ -231,7 +233,7 @@ hid_get_item(struct hid_data *s, struct hid_item *h) s->minset = 0; s->nu = 0; hid_clear_local(c); - return (1); + return 1; } case 9: /* Output */ retkind = hid_output; @@ -243,7 +245,7 @@ hid_get_item(struct hid_data *s, struct hid_item *h) *h = *c; hid_clear_local(c); s->nu = 0; - return (1); + return 1; case 11: /* Feature */ retkind = hid_feature; goto ret; @@ -252,7 +254,7 @@ hid_get_item(struct hid_data *s, struct hid_item *h) c->collevel--; *h = *c; s->nu = 0; - return (1); + return 1; default: printf("Main bTag=%d\n", bTag); break; @@ -292,7 +294,7 @@ hid_get_item(struct hid_data *s, struct hid_item *h) c->loc.count = dval; break; case 10: /* Push */ - hi = malloc(sizeof *hi, M_TEMP, M_WAITOK); + hi = kmem_alloc(sizeof(*hi), KM_SLEEP); *hi = *c; c->next = hi; break; @@ -303,7 +305,7 @@ hid_get_item(struct hid_data *s, struct hid_item *h) oldpos = c->loc.pos; *c = *hi; c->loc.pos = oldpos; - free(hi, M_TEMP); + kmem_free(hi, sizeof(*hi)); break; default: printf("Global bTag=%d\n", bTag); @@ -371,7 +373,7 @@ hid_get_item(struct hid_data *s, struct hid_item *h) } int -hid_report_size(const void *buf, int len, enum hid_kind k, u_int8_t id) +hid_report_size(const void *buf, int len, enum hid_kind k, uint8_t id) { struct hid_data *d; struct hid_item h; @@ -399,12 +401,12 @@ hid_report_size(const void *buf, int len, enum hid_kind k, u_int8_t id) } } hid_end_parse(d); - return ((hi - lo + 7) / 8); + return (hi - lo + 7) / 8; } int -hid_locate(const void *desc, int size, u_int32_t u, u_int8_t id, enum hid_kind k, - struct hid_location *loc, u_int32_t *flags) +hid_locate(const void *desc, int size, uint32_t u, uint8_t id, enum hid_kind k, + struct hid_location *loc, uint32_t *flags) { struct hid_data *d; struct hid_item h; @@ -421,13 +423,13 @@ hid_locate(const void *desc, int size, u_int32_t u, u_int8_t id, enum hid_kind k if (flags != NULL) *flags = h.flags; hid_end_parse(d); - return (1); + return 1; } } hid_end_parse(d); if (loc != NULL) loc->size = 0; - return (0); + return 0; } long @@ -437,11 +439,11 @@ hid_get_data(const u_char *buf, const struct hid_location *loc) u_long data; if (hsize == 0) - return (0); + return 0; data = hid_get_udata(buf, loc); if (data < (1UL << (hsize - 1)) || hsize == sizeof(data) * NBBY) - return (data); + return data; return data - (1UL << hsize); } @@ -454,7 +456,7 @@ hid_get_udata(const u_char *buf, const struct hid_location *loc) u_long data; if (hsize == 0) - return (0); + return 0; data = 0; off = hpos / 8; @@ -468,7 +470,7 @@ hid_get_udata(const u_char *buf, const struct hid_location *loc) data &= (1UL << hsize) - 1; DPRINTFN(10,("hid_get_udata: loc %d/%d = %lu\n", hpos, hsize, data)); - return (data); + return data; } /* @@ -483,7 +485,7 @@ hid_get_udata(const u_char *buf, const struct hid_location *loc) * kind of report is considered. The current HID code that uses this for * matching is actually only looking for input reports, so this works * for now. - * + * * This function could try all report kinds (input, output and feature) * consecutively if necessary, but it may be better to integrate the * libusbhid code which can consider multiple report kinds simultaneously @@ -491,15 +493,15 @@ hid_get_udata(const u_char *buf, const struct hid_location *loc) * Needs some thought. */ int -hid_is_collection(const void *desc, int size, u_int8_t id, u_int32_t usage) +hid_is_collection(const void *desc, int size, uint8_t id, uint32_t usage) { struct hid_data *hd; struct hid_item hi; - u_int32_t coll_usage = ~0; + uint32_t coll_usage = ~0; hd = hid_start_parse(desc, size, hid_input); if (hd == NULL) - return (0); + return 0; DPRINTFN(2,("hid_is_collection: id=%d usage=0x%x\n", id, usage)); while (hid_get_item(hd, &hi)) { @@ -519,10 +521,10 @@ hid_is_collection(const void *desc, int size, u_int8_t id, u_int32_t usage) hi.report_ID == id) { DPRINTFN(2,("hid_is_collection: found\n")); hid_end_parse(hd); - return (1); + return 1; } } DPRINTFN(2,("hid_is_collection: not found\n")); hid_end_parse(hd); - return (0); + return 0; } diff --git a/sys/dev/usb/hid.h b/sys/dev/usb/hid.h index 0225fa7195d..c2ed2344610 100644 --- a/sys/dev/usb/hid.h +++ b/sys/dev/usb/hid.h @@ -1,4 +1,4 @@ -/* $NetBSD: hid.h,v 1.13 2010/05/12 18:44:49 plunky Exp $ */ +/* $NetBSD: hid.h,v 1.14 2016/04/23 10:15:31 skrll Exp $ */ /* $FreeBSD: src/sys/dev/usb/hid.h,v 1.7 1999/11/17 22:33:40 n_hibma Exp $ */ /* @@ -41,9 +41,9 @@ enum hid_kind { }; struct hid_location { - u_int32_t size; - u_int32_t count; - u_int32_t pos; + uint32_t size; + uint32_t count; + uint32_t pos; }; struct hid_item { @@ -71,7 +71,7 @@ struct hid_item { int32_t collection; int collevel; enum hid_kind kind; - u_int32_t flags; + uint32_t flags; /* Location */ struct hid_location loc; /* */ @@ -81,9 +81,9 @@ struct hid_item { struct hid_data *hid_start_parse(const void *, int, enum hid_kind); void hid_end_parse(struct hid_data *); int hid_get_item(struct hid_data *, struct hid_item *); -int hid_report_size(const void *, int, enum hid_kind, u_int8_t); -int hid_locate(const void *, int, u_int32_t, u_int8_t, enum hid_kind, - struct hid_location *, u_int32_t *); +int hid_report_size(const void *, int, enum hid_kind, uint8_t); +int hid_locate(const void *, int, uint32_t, uint8_t, enum hid_kind, + struct hid_location *, uint32_t *); long hid_get_data(const u_char *, const struct hid_location *); u_long hid_get_udata(const u_char *, const struct hid_location *); -int hid_is_collection(const void *, int, u_int8_t, u_int32_t); +int hid_is_collection(const void *, int, uint8_t, uint32_t); diff --git a/sys/dev/usb/if_athn_usb.c b/sys/dev/usb/if_athn_usb.c index 6e4258365f8..eddab689d5d 100644 --- a/sys/dev/usb/if_athn_usb.c +++ b/sys/dev/usb/if_athn_usb.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_athn_usb.c,v 1.8 2015/02/21 10:42:15 nonaka Exp $ */ +/* $NetBSD: if_athn_usb.c,v 1.9 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_athn_usb.c,v 1.12 2013/01/14 09:50:31 jsing Exp $ */ /*- @@ -22,7 +22,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_athn_usb.c,v 1.8 2015/02/21 10:42:15 nonaka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_athn_usb.c,v 1.9 2016/04/23 10:15:31 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_athn_usb.c,v 1.8 2015/02/21 10:42:15 nonaka Exp $ #include <sys/socket.h> #include <sys/sockio.h> #include <sys/systm.h> +#include <sys/kmem.h> #include <sys/bus.h> #include <sys/endian.h> @@ -95,8 +96,9 @@ Static int athn_usb_alloc_rx_list(struct athn_usb_softc *); Static int athn_usb_alloc_tx_cmd(struct athn_usb_softc *); Static int athn_usb_alloc_tx_list(struct athn_usb_softc *); Static void athn_usb_attachhook(device_t); -Static void athn_usb_bcneof(usbd_xfer_handle, usbd_private_handle, +Static void athn_usb_bcneof(struct usbd_xfer *, void *, usbd_status); +Static void athn_usb_abort_pipes(struct athn_usb_softc *); Static void athn_usb_close_pipes(struct athn_usb_softc *); Static int athn_usb_create_hw_node(struct athn_usb_softc *, struct ar_htc_target_sta *); @@ -113,7 +115,7 @@ Static int athn_usb_htc_msg(struct athn_usb_softc *, uint16_t, void *, int); Static int athn_usb_htc_setup(struct athn_usb_softc *); Static int athn_usb_init(struct ifnet *); -Static void athn_usb_intr(usbd_xfer_handle, usbd_private_handle, +Static void athn_usb_intr(struct usbd_xfer *, void *, usbd_status); Static int athn_usb_ioctl(struct ifnet *, u_long, void *); Static int athn_usb_load_firmware(struct athn_usb_softc *); @@ -135,7 +137,7 @@ Static void athn_usb_rx_frame(struct athn_usb_softc *, struct mbuf *); Static void athn_usb_rx_radiotap(struct athn_softc *, struct mbuf *, struct ar_rx_status *); Static void athn_usb_rx_wmi_ctrl(struct athn_usb_softc *, uint8_t *, size_t); -Static void athn_usb_rxeof(usbd_xfer_handle, usbd_private_handle, +Static void athn_usb_rxeof(struct usbd_xfer *, void *, usbd_status); Static void athn_usb_start(struct ifnet *); Static void athn_usb_stop(struct ifnet *); @@ -145,7 +147,7 @@ Static int athn_usb_switch_chan(struct athn_softc *, Static void athn_usb_task(void *); Static int athn_usb_tx(struct athn_softc *, struct mbuf *, struct ieee80211_node *, struct athn_usb_tx_data *); -Static void athn_usb_txeof(usbd_xfer_handle, usbd_private_handle, +Static void athn_usb_txeof(struct usbd_xfer *, void *, usbd_status); Static void athn_usb_updateslot(struct ifnet *); Static void athn_usb_updateslot_cb(struct athn_usb_softc *, void *); @@ -156,7 +158,7 @@ Static void athn_usb_wait_wmi(struct athn_usb_softc *); Static void athn_usb_watchdog(struct ifnet *); Static int athn_usb_wmi_xcmd(struct athn_usb_softc *, uint16_t, void *, int, void *); -Static void athn_usb_wmieof(usbd_xfer_handle, usbd_private_handle, +Static void athn_usb_wmieof(struct usbd_xfer *, void *, usbd_status); Static void athn_usb_write(struct athn_softc *, uint32_t, uint32_t); Static void athn_usb_write_barrier(struct athn_softc *); @@ -230,7 +232,7 @@ athn_usb_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return athn_usb_lookup(uaa->vendor, uaa->product) != NULL ? + return athn_usb_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } @@ -246,7 +248,7 @@ athn_usb_attach(device_t parent, device_t self, void *aux) sc = &usc->usc_sc; uaa = aux; sc->sc_dev = self; - usc->usc_udev = uaa->device; + usc->usc_udev = uaa->uaa_device; aprint_naive("\n"); aprint_normal("\n"); @@ -254,7 +256,7 @@ athn_usb_attach(device_t parent, device_t self, void *aux) DPRINTFN(DBG_FN, sc, "\n"); usc->usc_athn_attached = 0; - usc->usc_flags = athn_usb_lookup(uaa->vendor, uaa->product)->flags; + usc->usc_flags = athn_usb_lookup(uaa->uaa_vendor, uaa->uaa_product)->flags; sc->sc_flags |= ATHN_FLAG_USB; #ifdef notyet /* Check if it is a combo WiFi+Bluetooth (WB193) device. */ @@ -266,6 +268,7 @@ athn_usb_attach(device_t parent, device_t self, void *aux) sc->sc_ops.write = athn_usb_write; sc->sc_ops.write_barrier = athn_usb_write_barrier; + cv_init(&usc->usc_task_cv, "athntsk"); mutex_init(&usc->usc_task_mtx, MUTEX_DEFAULT, IPL_NET); mutex_init(&usc->usc_tx_mtx, MUTEX_DEFAULT, IPL_NONE); @@ -292,12 +295,24 @@ athn_usb_attach(device_t parent, device_t self, void *aux) if (athn_usb_alloc_tx_cmd(usc) != 0) goto fail; + /* Allocate Tx/Rx buffers. */ + error = athn_usb_alloc_rx_list(usc); + if (error != 0) + goto fail; + error = athn_usb_alloc_tx_list(usc); + if (error != 0) + goto fail; + config_mountroot(self, athn_usb_attachhook); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, usc->usc_udev, sc->sc_dev); return; fail: + /* Free Tx/Rx buffers. */ + athn_usb_abort_pipes(usc); + athn_usb_free_tx_list(usc); + athn_usb_free_rx_list(usc); athn_usb_free_tx_cmd(usc); athn_usb_close_pipes(usc); usb_rem_task(usc->usc_udev, &usc->usc_task); @@ -443,8 +458,8 @@ athn_usb_detach(device_t self, int flags) usc->usc_athn_attached = 0; athn_detach(sc); } - /* Abort and close Tx/Rx pipes. */ - athn_usb_close_pipes(usc); + /* Abort Tx/Rx pipes. */ + athn_usb_abort_pipes(usc); splx(s); /* Free Tx/Rx buffers. */ @@ -452,8 +467,12 @@ athn_usb_detach(device_t self, int flags) athn_usb_free_tx_list(usc); athn_usb_free_tx_cmd(usc); + /* Close Tx/Rx pipes. */ + athn_usb_close_pipes(usc); + mutex_destroy(&usc->usc_tx_mtx); mutex_destroy(&usc->usc_task_mtx); + cv_destroy(&usc->usc_task_cv); usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, usc->usc_udev, sc->sc_dev); return 0; @@ -481,7 +500,7 @@ Static int athn_usb_open_pipes(struct athn_usb_softc *usc) { usb_endpoint_descriptor_t *ed; - int isize, error; + int error; DPRINTFN(DBG_FN, usc, "\n"); @@ -507,21 +526,22 @@ athn_usb_open_pipes(struct athn_usb_softc *usc) "could not retrieve Rx intr pipe descriptor\n"); goto fail; } - isize = UGETW(ed->wMaxPacketSize); - if (isize == 0) { + usc->usc_ibufsize = UGETW(ed->wMaxPacketSize); + if (usc->usc_ibufsize == 0) { aprint_error_dev(usc->usc_dev, "invalid Rx intr pipe descriptor\n"); goto fail; } - usc->usc_ibuf = malloc(isize, M_USBDEV, M_NOWAIT); + usc->usc_ibuf = kmem_alloc(usc->usc_ibufsize, KM_SLEEP); if (usc->usc_ibuf == NULL) { aprint_error_dev(usc->usc_dev, "could not allocate Rx intr buffer\n"); goto fail; } + error = usbd_open_pipe_intr(usc->usc_iface, AR_PIPE_RX_INTR, - USBD_SHORT_XFER_OK, &usc->usc_rx_intr_pipe, usc, usc->usc_ibuf, isize, - athn_usb_intr, USBD_DEFAULT_INTERVAL); + USBD_SHORT_XFER_OK, &usc->usc_rx_intr_pipe, usc, usc->usc_ibuf, + usc->usc_ibufsize, athn_usb_intr, USBD_DEFAULT_INTERVAL); if (error != 0) { aprint_error_dev(usc->usc_dev, "could not open Rx intr pipe\n"); @@ -536,24 +556,39 @@ athn_usb_open_pipes(struct athn_usb_softc *usc) } return 0; fail: + athn_usb_abort_pipes(usc); athn_usb_close_pipes(usc); return error; } static inline void -athn_usb_kill_pipe(usbd_pipe_handle *pipeptr) +athn_usb_kill_pipe(struct usbd_pipe **pipeptr) { - usbd_pipe_handle pipe; + struct usbd_pipe *pipe; CTASSERT(sizeof(pipe) == sizeof(void *)); pipe = atomic_swap_ptr(pipeptr, NULL); if (pipe != NULL) { - usbd_abort_pipe(pipe); usbd_close_pipe(pipe); } } Static void +athn_usb_abort_pipes(struct athn_usb_softc *usc) +{ + DPRINTFN(DBG_FN, usc, "\n"); + + if (usc->usc_tx_data_pipe != NULL) + usbd_abort_pipe(usc->usc_tx_data_pipe); + if (usc->usc_rx_data_pipe != NULL) + usbd_abort_pipe(usc->usc_rx_data_pipe); + if (usc->usc_tx_intr_pipe != NULL) + usbd_abort_pipe(usc->usc_tx_intr_pipe); + if (usc->usc_rx_intr_pipe != NULL) + usbd_abort_pipe(usc->usc_rx_intr_pipe); +} + +Static void athn_usb_close_pipes(struct athn_usb_softc *usc) { uint8_t *ibuf; @@ -566,7 +601,7 @@ athn_usb_close_pipes(struct athn_usb_softc *usc) athn_usb_kill_pipe(&usc->usc_rx_intr_pipe); ibuf = atomic_swap_ptr(&usc->usc_ibuf, NULL); if (ibuf != NULL) - free(ibuf, M_USBDEV); + kmem_free(ibuf, usc->usc_ibufsize); } Static int @@ -583,20 +618,14 @@ athn_usb_alloc_rx_list(struct athn_usb_softc *usc) data->sc = usc; /* Backpointer for callbacks. */ - data->xfer = usbd_alloc_xfer(usc->usc_udev); - if (data->xfer == NULL) { + error = usbd_create_xfer(usc->usc_rx_data_pipe, + ATHN_USB_RXBUFSZ, USBD_SHORT_XFER_OK, 0, &data->xfer); + if (error) { aprint_error_dev(usc->usc_dev, "could not allocate xfer\n"); - error = ENOMEM; - break; - } - data->buf = usbd_alloc_buffer(data->xfer, ATHN_USB_RXBUFSZ); - if (data->buf == NULL) { - aprint_error_dev(usc->usc_dev, - "could not allocate xfer buffer\n"); - error = ENOMEM; break; } + data->buf = usbd_get_buffer(data->xfer); } if (error != 0) athn_usb_free_rx_list(usc); @@ -606,7 +635,7 @@ athn_usb_alloc_rx_list(struct athn_usb_softc *usc) Static void athn_usb_free_rx_list(struct athn_usb_softc *usc) { - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; size_t i; DPRINTFN(DBG_FN, usc, "\n"); @@ -616,7 +645,7 @@ athn_usb_free_rx_list(struct athn_usb_softc *usc) CTASSERT(sizeof(xfer) == sizeof(void *)); xfer = atomic_swap_ptr(&usc->usc_rx_data[i].xfer, NULL); if (xfer != NULL) - usbd_free_xfer(xfer); + usbd_destroy_xfer(xfer); } } @@ -636,20 +665,15 @@ athn_usb_alloc_tx_list(struct athn_usb_softc *usc) data->sc = usc; /* Backpointer for callbacks. */ - data->xfer = usbd_alloc_xfer(usc->usc_udev); - if (data->xfer == NULL) { + error = usbd_create_xfer(usc->usc_tx_data_pipe, + ATHN_USB_TXBUFSZ, USBD_SHORT_XFER_OK, 0, &data->xfer); + if (error) { aprint_error_dev(usc->usc_dev, - "could not allocate xfer\n"); - error = ENOMEM; - break; - } - data->buf = usbd_alloc_buffer(data->xfer, ATHN_USB_TXBUFSZ); - if (data->buf == NULL) { - aprint_error_dev(usc->usc_dev, - "could not allocate xfer buffer\n"); - error = ENOMEM; + "could not create xfer on TX pipe\n"); break; } + data->buf = usbd_get_buffer(data->xfer); + /* Append this Tx buffer to our free list. */ TAILQ_INSERT_TAIL(&usc->usc_tx_free_list, data, next); } @@ -662,7 +686,7 @@ athn_usb_alloc_tx_list(struct athn_usb_softc *usc) Static void athn_usb_free_tx_list(struct athn_usb_softc *usc) { - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; size_t i; DPRINTFN(DBG_FN, usc, "\n"); @@ -672,7 +696,7 @@ athn_usb_free_tx_list(struct athn_usb_softc *usc) CTASSERT(sizeof(xfer) == sizeof(void *)); xfer = atomic_swap_ptr(&usc->usc_tx_data[i].xfer, NULL); if (xfer != NULL) - usbd_free_xfer(xfer); + usbd_destroy_xfer(xfer); } } @@ -685,31 +709,28 @@ athn_usb_alloc_tx_cmd(struct athn_usb_softc *usc) data->sc = usc; /* Backpointer for callbacks. */ - data->xfer = usbd_alloc_xfer(usc->usc_udev); - if (data->xfer == NULL) { - aprint_error_dev(usc->usc_dev, "could not allocate xfer\n"); - return ENOMEM; - } - data->buf = usbd_alloc_buffer(data->xfer, ATHN_USB_TXCMDSZ); - if (data->buf == NULL) { + int err = usbd_create_xfer(usc->usc_tx_intr_pipe, ATHN_USB_TXCMDSZ, + 0, 0, &data->xfer); + if (err) { aprint_error_dev(usc->usc_dev, - "could not allocate xfer buffer\n"); - return ENOMEM; + "could not allocate command xfer\n"); + return err; } + return 0; } Static void athn_usb_free_tx_cmd(struct athn_usb_softc *usc) { - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; DPRINTFN(DBG_FN, usc, "\n"); CTASSERT(sizeof(xfer) == sizeof(void *)); xfer = atomic_swap_ptr(&usc->usc_tx_cmd.xfer, NULL); if (xfer != NULL) - usbd_free_xfer(xfer); + usbd_destroy_xfer(xfer); } Static void @@ -782,8 +803,10 @@ athn_usb_wait_async(struct athn_usb_softc *usc) DPRINTFN(DBG_FN, usc, "\n"); /* Wait for all queued asynchronous commands to complete. */ + mutex_spin_enter(&usc->usc_task_mtx); while (usc->usc_cmdq.queued > 0) - tsleep(&usc->usc_cmdq, 0, "cmdq", 0); + cv_wait(&usc->usc_task_cv, &usc->usc_task_mtx); + mutex_spin_exit(&usc->usc_task_mtx); } Static int @@ -903,9 +926,9 @@ athn_usb_htc_msg(struct athn_usb_softc *usc, uint16_t msg_id, void *buf, memcpy(&msg[1], buf, len); - usbd_setup_xfer(data->xfer, usc->usc_tx_intr_pipe, NULL, data->buf, + usbd_setup_xfer(data->xfer, NULL, data->buf, sizeof(*htc) + sizeof(*msg) + len, - USBD_SHORT_XFER_OK | USBD_NO_COPY, ATHN_USB_CMD_TIMEOUT, NULL); + USBD_SHORT_XFER_OK, ATHN_USB_CMD_TIMEOUT, NULL); return usbd_sync_transfer(data->xfer); } @@ -1049,7 +1072,7 @@ athn_usb_wait_cmd(struct athn_usb_softc *usc) } Static void -athn_usb_wmieof(usbd_xfer_handle xfer, usbd_private_handle priv, +athn_usb_wmieof(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct athn_usb_softc *usc = priv; @@ -1089,9 +1112,9 @@ athn_usb_wmi_xcmd(struct athn_usb_softc *usc, uint16_t cmd_id, void *ibuf, memcpy(&wmi[1], ibuf, ilen); - usbd_setup_xfer(data->xfer, usc->usc_tx_intr_pipe, usc, data->buf, + usbd_setup_xfer(data->xfer, usc, data->buf, sizeof(*htc) + sizeof(*wmi) + ilen, - USBD_SHORT_XFER_OK | USBD_NO_COPY, ATHN_USB_CMD_TIMEOUT, + USBD_SHORT_XFER_OK, ATHN_USB_CMD_TIMEOUT, athn_usb_wmieof); s = splusb(); @@ -1746,7 +1769,7 @@ athn_usb_delete_key_cb(struct athn_usb_softc *usc, void *arg) #ifndef IEEE80211_STA_ONLY Static void -athn_usb_bcneof(usbd_xfer_handle xfer, usbd_private_handle priv, +athn_usb_bcneof(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct athn_usb_tx_data *data = priv; @@ -1820,9 +1843,9 @@ athn_usb_swba(struct athn_usb_softc *usc) m_copydata(m, 0, m->m_pkthdr.len, (void *)&bcn[1]); - usbd_setup_xfer(data->xfer, usc->usc_tx_data_pipe, data, data->buf, + usbd_setup_xfer(data->xfer, data, data->buf, sizeof(*hdr) + sizeof(*htc) + sizeof(*bcn) + m->m_pkthdr.len, - USBD_SHORT_XFER_OK | USBD_NO_COPY, ATHN_USB_TX_TIMEOUT, + USBD_SHORT_XFER_OK, ATHN_USB_TX_TIMEOUT, athn_usb_bcneof); m_freem(m); @@ -1890,7 +1913,7 @@ athn_usb_rx_wmi_ctrl(struct athn_usb_softc *usc, uint8_t *buf, size_t len) } Static void -athn_usb_intr(usbd_xfer_handle xfer, usbd_private_handle priv, +athn_usb_intr(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct athn_usb_softc *usc = priv; @@ -2099,7 +2122,7 @@ athn_usb_rx_frame(struct athn_usb_softc *usc, struct mbuf *m) } Static void -athn_usb_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, +athn_usb_rxeof(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct athn_usb_rx_data *data = priv; @@ -2207,14 +2230,13 @@ athn_usb_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, resubmit: /* Setup a new transfer. */ - usbd_setup_xfer(xfer, usc->usc_rx_data_pipe, data, data->buf, - ATHN_USB_RXBUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, athn_usb_rxeof); + usbd_setup_xfer(xfer, data, data->buf, ATHN_USB_RXBUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, athn_usb_rxeof); (void)usbd_transfer(xfer); } Static void -athn_usb_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, +athn_usb_txeof(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct athn_usb_tx_data *data = priv; @@ -2358,9 +2380,8 @@ athn_usb_tx(struct athn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, xferlen = frm - data->buf; s = splnet(); - usbd_setup_xfer(data->xfer, usc->usc_tx_data_pipe, data, data->buf, - xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, ATHN_USB_TX_TIMEOUT, - athn_usb_txeof); + usbd_setup_xfer(data->xfer, data, data->buf, xferlen, + USBD_FORCE_SHORT_XFER, ATHN_USB_TX_TIMEOUT, athn_usb_txeof); error = usbd_transfer(data->xfer); if (__predict_false(error != USBD_IN_PROGRESS && error != 0)) { splx(s); @@ -2576,13 +2597,6 @@ athn_usb_init(struct ifnet *ifp) usc->usc_cmdq.cur = usc->usc_cmdq.next = usc->usc_cmdq.queued = 0; mutex_spin_exit(&usc->usc_task_mtx); - /* Allocate Tx/Rx buffers. */ - error = athn_usb_alloc_rx_list(usc); - if (error != 0) - goto fail; - error = athn_usb_alloc_tx_list(usc); - if (error != 0) - goto fail; /* Steal one buffer for beacons. */ mutex_enter(&usc->usc_tx_mtx); usc->usc_tx_bcn = TAILQ_FIRST(&usc->usc_tx_free_list); @@ -2689,8 +2703,8 @@ athn_usb_init(struct ifnet *ifp) for (i = 0; i < ATHN_USB_RX_LIST_COUNT; i++) { data = &usc->usc_rx_data[i]; - usbd_setup_xfer(data->xfer, usc->usc_rx_data_pipe, data, data->buf, - ATHN_USB_RXBUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, + usbd_setup_xfer(data->xfer, data, data->buf, + ATHN_USB_RXBUFSZ, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, athn_usb_rxeof); error = usbd_transfer(data->xfer); if (error != 0 && error != USBD_IN_PROGRESS) diff --git a/sys/dev/usb/if_athn_usb.h b/sys/dev/usb/if_athn_usb.h index 46f3f09aff6..68fb3e77860 100644 --- a/sys/dev/usb/if_athn_usb.h +++ b/sys/dev/usb/if_athn_usb.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_athn_usb.h,v 1.2 2013/03/30 14:14:31 christos Exp $ */ +/* $NetBSD: if_athn_usb.h,v 1.3 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_athn_usb.h,v 1.3 2012/11/10 14:35:06 mikeb Exp $ */ /*- @@ -394,13 +394,13 @@ struct athn_usb_rx_stream { struct athn_usb_rx_data { struct athn_usb_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; }; struct athn_usb_tx_data { struct athn_usb_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; TAILQ_ENTRY(athn_usb_tx_data) next; }; @@ -443,12 +443,13 @@ struct athn_usb_softc { int usc_athn_attached; + kcondvar_t usc_task_cv; kmutex_t usc_task_mtx; kmutex_t usc_tx_mtx; /* USB specific goo. */ - usbd_device_handle usc_udev; - usbd_interface_handle usc_iface; + struct usbd_device *usc_udev; + struct usbd_interface *usc_iface; struct usb_task usc_task; int usc_dying; @@ -458,11 +459,12 @@ struct athn_usb_softc { struct athn_usb_rx_stream usc_rx_stream; - usbd_pipe_handle usc_tx_data_pipe; - usbd_pipe_handle usc_rx_data_pipe; - usbd_pipe_handle usc_rx_intr_pipe; - usbd_pipe_handle usc_tx_intr_pipe; + struct usbd_pipe *usc_tx_data_pipe; + struct usbd_pipe *usc_rx_data_pipe; + struct usbd_pipe *usc_rx_intr_pipe; + struct usbd_pipe *usc_tx_intr_pipe; uint8_t *usc_ibuf; + size_t usc_ibufsize; struct ar_wmi_cmd_reg_write usc_wbuf[AR_MAX_WRITE_COUNT]; int usc_wcount; diff --git a/sys/dev/usb/if_atu.c b/sys/dev/usb/if_atu.c index 91912f7dddb..7b36d5c62ed 100644 --- a/sys/dev/usb/if_atu.c +++ b/sys/dev/usb/if_atu.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_atu.c,v 1.50 2014/10/18 08:33:28 snj Exp $ */ +/* $NetBSD: if_atu.c,v 1.51 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_atu.c,v 1.48 2004/12/30 01:53:21 dlg Exp $ */ /* * Copyright (c) 2003, 2004 @@ -48,7 +48,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_atu.c,v 1.50 2014/10/18 08:33:28 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_atu.c,v 1.51 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/sockio.h> @@ -56,7 +56,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_atu.c,v 1.50 2014/10/18 08:33:28 snj Exp $"); #include <sys/kernel.h> #include <sys/socket.h> #include <sys/systm.h> -#include <sys/malloc.h> #include <sys/kthread.h> #include <sys/queue.h> #include <sys/device.h> @@ -230,46 +229,46 @@ struct atu_radfirm { }; int atu_newbuf(struct atu_softc *, struct atu_chain *, struct mbuf *); -void atu_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -void atu_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +void atu_rxeof(struct usbd_xfer *, void *, usbd_status); +void atu_txeof(struct usbd_xfer *, void *, usbd_status); void atu_start(struct ifnet *); int atu_ioctl(struct ifnet *, u_long, void *); int atu_init(struct ifnet *); void atu_stop(struct ifnet *, int); void atu_watchdog(struct ifnet *); -usbd_status atu_usb_request(struct atu_softc *sc, u_int8_t type, - u_int8_t request, u_int16_t value, u_int16_t index, - u_int16_t length, u_int8_t *data); -int atu_send_command(struct atu_softc *sc, u_int8_t *command, int size); -int atu_get_cmd_status(struct atu_softc *sc, u_int8_t cmd, - u_int8_t *status); -int atu_wait_completion(struct atu_softc *sc, u_int8_t cmd, - u_int8_t *status); -int atu_send_mib(struct atu_softc *sc, u_int8_t type, - u_int8_t size, u_int8_t index, void *data); -int atu_get_mib(struct atu_softc *sc, u_int8_t type, - u_int8_t size, u_int8_t index, u_int8_t *buf); +usbd_status atu_usb_request(struct atu_softc *, uint8_t, + uint8_t, uint16_t, uint16_t, + uint16_t, uint8_t *); +int atu_send_command(struct atu_softc *, uint8_t *, int); +int atu_get_cmd_status(struct atu_softc *, uint8_t, + uint8_t *); +int atu_wait_completion(struct atu_softc *, uint8_t, + uint8_t *); +int atu_send_mib(struct atu_softc *, uint8_t, + uint8_t, uint8_t, void *); +int atu_get_mib(struct atu_softc *, uint8_t, + uint8_t, uint8_t, uint8_t *); #if 0 -int atu_start_ibss(struct atu_softc *sc); +int atu_start_ibss(struct atu_softc *); #endif -int atu_start_scan(struct atu_softc *sc); -int atu_switch_radio(struct atu_softc *sc, int state); -int atu_initial_config(struct atu_softc *sc); -int atu_join(struct atu_softc *sc, struct ieee80211_node *node); -int8_t atu_get_dfu_state(struct atu_softc *sc); -u_int8_t atu_get_opmode(struct atu_softc *sc, u_int8_t *mode); +int atu_start_scan(struct atu_softc *); +int atu_switch_radio(struct atu_softc *, int); +int atu_initial_config(struct atu_softc *); +int atu_join(struct atu_softc *, struct ieee80211_node *); +int8_t atu_get_dfu_state(struct atu_softc *); +uint8_t atu_get_opmode(struct atu_softc *, uint8_t *); void atu_internal_firmware(device_t); void atu_external_firmware(device_t); -int atu_get_card_config(struct atu_softc *sc); -int atu_media_change(struct ifnet *ifp); -void atu_media_status(struct ifnet *ifp, struct ifmediareq *req); +int atu_get_card_config(struct atu_softc *); +int atu_media_change(struct ifnet *); +void atu_media_status(struct ifnet *, struct ifmediareq *); int atu_tx_list_init(struct atu_softc *); int atu_rx_list_init(struct atu_softc *); -void atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch, - int listlen); +void atu_xfer_list_free(struct atu_softc *, struct atu_chain *, + int); #ifdef ATU_DEBUG -void atu_debug_print(struct atu_softc *sc); +void atu_debug_print(struct atu_softc *); #endif void atu_task(void *); @@ -277,7 +276,7 @@ int atu_newstate(struct ieee80211com *, enum ieee80211_state, int); int atu_tx_start(struct atu_softc *, struct ieee80211_node *, struct atu_chain *, struct mbuf *); void atu_complete_attach(struct atu_softc *); -u_int8_t atu_calculate_padding(int); +uint8_t atu_calculate_padding(int); int atu_match(device_t, cfdata_t, void *); void atu_attach(device_t, device_t, void *); @@ -288,12 +287,12 @@ CFATTACH_DECL_NEW(atu, sizeof(struct atu_softc), atu_match, atu_attach, atu_detach, atu_activate); usbd_status -atu_usb_request(struct atu_softc *sc, u_int8_t type, - u_int8_t request, u_int16_t value, u_int16_t index, u_int16_t length, - u_int8_t *data) +atu_usb_request(struct atu_softc *sc, uint8_t type, + uint8_t request, uint16_t value, uint16_t index, uint16_t length, + uint8_t *data) { usb_device_request_t req; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; usbd_status err; int total_len = 0, s; @@ -313,9 +312,15 @@ atu_usb_request(struct atu_softc *sc, u_int8_t type, s = splnet(); - xfer = usbd_alloc_xfer(sc->atu_udev); + struct usbd_pipe *pipe0 = usbd_get_pipe0(sc->atu_udev); + int error = usbd_create_xfer(pipe0, length, USBD_SHORT_XFER_OK, 0, + &xfer); + if (error) { + splx(s); + return USBD_IOERROR; + } usbd_setup_default_xfer(xfer, sc->atu_udev, 0, 500000, &req, data, - length, USBD_SHORT_XFER_OK, 0); + length, USBD_SHORT_XFER_OK, NULL); err = usbd_sync_transfer(xfer); @@ -334,21 +339,21 @@ atu_usb_request(struct atu_softc *sc, u_int8_t type, } #endif /* ATU_DEBUG */ - usbd_free_xfer(xfer); + usbd_destroy_xfer(xfer); splx(s); return(err); } int -atu_send_command(struct atu_softc *sc, u_int8_t *command, int size) +atu_send_command(struct atu_softc *sc, uint8_t *command, int size) { return atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0000, 0x0000, size, command); } int -atu_get_cmd_status(struct atu_softc *sc, u_int8_t cmd, u_int8_t *status) +atu_get_cmd_status(struct atu_softc *sc, uint8_t cmd, uint8_t *status) { /* * all other drivers (including Windoze) request 40 bytes of status @@ -364,10 +369,10 @@ atu_get_cmd_status(struct atu_softc *sc, u_int8_t cmd, u_int8_t *status) } int -atu_wait_completion(struct atu_softc *sc, u_int8_t cmd, u_int8_t *status) +atu_wait_completion(struct atu_softc *sc, uint8_t cmd, uint8_t *status) { int idle_count = 0, err; - u_int8_t statusreq[6]; + uint8_t statusreq[6]; DPRINTFN(15, ("%s: wait-completion: cmd=%02x\n", device_xname(sc->atu_dev), cmd)); @@ -406,8 +411,8 @@ atu_wait_completion(struct atu_softc *sc, u_int8_t cmd, u_int8_t *status) } int -atu_send_mib(struct atu_softc *sc, u_int8_t type, u_int8_t size, - u_int8_t index, void *data) +atu_send_mib(struct atu_softc *sc, uint8_t type, uint8_t size, + uint8_t index, void *data) { int err; struct atu_cmd_set_mib request; @@ -449,7 +454,7 @@ atu_send_mib(struct atu_softc *sc, u_int8_t type, u_int8_t size, err = atu_usb_request(sc, UT_WRITE_VENDOR_DEVICE, 0x0e, 0x0000, 0x0000, size+8, (uByte *)&request); if (err) - return (err); + return err; DPRINTFN(15, ("%s: sendmib : waitcompletion...\n", device_xname(sc->atu_dev))); @@ -457,8 +462,8 @@ atu_send_mib(struct atu_softc *sc, u_int8_t type, u_int8_t size, } int -atu_get_mib(struct atu_softc *sc, u_int8_t type, u_int8_t size, - u_int8_t index, u_int8_t *buf) +atu_get_mib(struct atu_softc *sc, uint8_t type, uint8_t size, + uint8_t index, uint8_t *buf) { /* linux/at76c503.c - 478 */ @@ -483,14 +488,14 @@ atu_start_ibss(struct atu_softc *sc) memcpy(Request.SSID, ic->ic_des_ssid, ic->ic_des_ssidlen); Request.SSIDSize = ic->ic_des_ssidlen; if (sc->atu_desired_channel != IEEE80211_CHAN_ANY) - Request.Channel = (u_int8_t)sc->atu_desired_channel; + Request.Channel = (uint8_t)sc->atu_desired_channel; else Request.Channel = ATU_DEFAULT_CHANNEL; Request.BSSType = AD_HOC_MODE; memset(Request.Res, 0x00, sizeof(Request.Res)); /* Write config to adapter */ - err = atu_send_command(sc, (u_int8_t *)&Request, sizeof(Request)); + err = atu_send_command(sc, (uint8_t *)&Request, sizeof(Request)); if (err) { DPRINTF(("%s: start ibss failed!\n", device_xname(sc->atu_dev))); @@ -544,7 +549,7 @@ atu_start_scan(struct atu_softc *sc) /* default values for scan */ Scan.ScanType = ATU_SCAN_ACTIVE; if (sc->atu_desired_channel != IEEE80211_CHAN_ANY) - Scan.Channel = (u_int8_t)sc->atu_desired_channel; + Scan.Channel = (uint8_t)sc->atu_desired_channel; else Scan.Channel = sc->atu_channel; @@ -567,7 +572,7 @@ atu_start_scan(struct atu_softc *sc) #endif /* ATU_DEBUG */ /* Write config to adapter */ - err = atu_send_command(sc, (u_int8_t *)&Scan, sizeof(Scan)); + err = atu_send_command(sc, (uint8_t *)&Scan, sizeof(Scan)); if (err) return err; @@ -604,7 +609,7 @@ atu_switch_radio(struct atu_softc *sc, int state) if (state == 0) CmdRadio.Cmd = CMD_RADIO_OFF; - err = atu_send_command(sc, (u_int8_t *)&CmdRadio, + err = atu_send_command(sc, (uint8_t *)&CmdRadio, sizeof(CmdRadio)); if (err) return err; @@ -624,12 +629,12 @@ int atu_initial_config(struct atu_softc *sc) { struct ieee80211com *ic = &sc->sc_ic; - u_int32_t i; + uint32_t i; usbd_status err; -/* u_int8_t rates[4] = {0x82, 0x84, 0x8B, 0x96};*/ - u_int8_t rates[4] = {0x82, 0x04, 0x0B, 0x16}; +/* uint8_t rates[4] = {0x82, 0x84, 0x8B, 0x96};*/ + uint8_t rates[4] = {0x82, 0x04, 0x0B, 0x16}; struct atu_cmd_card_config cmd; - u_int8_t reg_domain; + uint8_t reg_domain; DPRINTFN(10, ("%s: sending mac-addr\n", device_xname(sc->atu_dev))); err = atu_send_mib(sc, MIB_MAC_ADDR__ADDR, ic->ic_myaddr); @@ -655,7 +660,7 @@ atu_initial_config(struct atu_softc *sc) USETW(cmd.Size, sizeof(cmd) - 4); if (sc->atu_desired_channel != IEEE80211_CHAN_ANY) - cmd.Channel = (u_int8_t)sc->atu_desired_channel; + cmd.Channel = (uint8_t)sc->atu_desired_channel; else cmd.Channel = sc->atu_channel; cmd.AutoRateFallback = 1; @@ -731,7 +736,7 @@ atu_initial_config(struct atu_softc *sc) /* Windoze : driver says exclude-unencrypted=1 & encr-type=1 */ - err = atu_send_command(sc, (u_int8_t *)&cmd, sizeof(cmd)); + err = atu_send_command(sc, (uint8_t *)&cmd, sizeof(cmd)); if (err) return err; err = atu_wait_completion(sc, CMD_STARTUP, NULL); @@ -778,7 +783,7 @@ int atu_join(struct atu_softc *sc, struct ieee80211_node *node) { struct atu_cmd_join join; - u_int8_t status = 0; /* XXX: GCC */ + uint8_t status = 0; /* XXX: GCC */ usbd_status err; memset(&join, 0, sizeof(join)); @@ -806,7 +811,7 @@ atu_join(struct atu_softc *sc, struct ieee80211_node *node) DPRINTFN(10, ("%s: trying to join BSSID=%s\n", device_xname(sc->atu_dev), ether_sprintf(join.bssid))); - err = atu_send_command(sc, (u_int8_t *)&join, sizeof(join)); + err = atu_send_command(sc, (uint8_t *)&join, sizeof(join)); if (err) { DPRINTF(("%s: ERROR trying to join IBSS\n", device_xname(sc->atu_dev))); @@ -834,7 +839,7 @@ atu_join(struct atu_softc *sc, struct ieee80211_node *node) int8_t atu_get_dfu_state(struct atu_softc *sc) { - u_int8_t state; + uint8_t state; if (atu_usb_request(sc, DFU_GETSTATE, 0, 0, 1, &state)) return -1; @@ -844,8 +849,8 @@ atu_get_dfu_state(struct atu_softc *sc) /* * Get MAC opmode */ -u_int8_t -atu_get_opmode(struct atu_softc *sc, u_int8_t *mode) +uint8_t +atu_get_opmode(struct atu_softc *sc, uint8_t *mode) { return atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33, 0x0001, @@ -1056,7 +1061,7 @@ atu_get_card_config(struct atu_softc *sc) case AT76C505_rfmd: err = atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33, 0x0a02, 0x0000, sizeof(rfmd_conf), - (u_int8_t *)&rfmd_conf); + (uint8_t *)&rfmd_conf); if (err) { DPRINTF(("%s: could not get rfmd config!\n", device_xname(sc->atu_dev))); @@ -1069,7 +1074,7 @@ atu_get_card_config(struct atu_softc *sc) case AT76C503_i3863: err = atu_usb_request(sc, UT_READ_VENDOR_INTERFACE, 0x33, 0x0902, 0x0000, sizeof(intersil_conf), - (u_int8_t *)&intersil_conf); + (uint8_t *)&intersil_conf); if (err) { DPRINTF(("%s: could not get intersil config!\n", device_xname(sc->atu_dev))); @@ -1094,8 +1099,8 @@ atu_match(device_t parent, cfdata_t match, void *aux) for (i = 0; i < __arraycount(atu_devs); i++) { struct atu_type *t = &atu_devs[i]; - if (uaa->vendor == t->atu_vid && - uaa->product == t->atu_pid) { + if (uaa->uaa_vendor == t->atu_vid && + uaa->uaa_product == t->atu_pid) { return(UMATCH_VENDOR_PRODUCT); } } @@ -1124,7 +1129,7 @@ atu_media_change(struct ifnet *ifp) err = 0; } - return (err); + return err; } void @@ -1207,7 +1212,7 @@ atu_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) /* handle this ourselves */ ic->ic_state = nstate; - return (0); + return 0; case IEEE80211_S_AUTH: case IEEE80211_S_RUN: @@ -1236,8 +1241,8 @@ atu_attach(device_t parent, device_t self, void *aux) struct usb_attach_arg *uaa = aux; char *devinfop; usbd_status err; - usbd_device_handle dev = uaa->device; - u_int8_t mode, channel; + struct usbd_device *dev = uaa->uaa_device; + uint8_t mode, channel; int i; sc->atu_dev = self; @@ -1273,8 +1278,8 @@ atu_attach(device_t parent, device_t self, void *aux) for (i = 0; i < __arraycount(atu_devs); i++) { struct atu_type *t = &atu_devs[i]; - if (uaa->vendor == t->atu_vid && - uaa->product == t->atu_pid) { + if (uaa->uaa_vendor == t->atu_vid && + uaa->uaa_product == t->atu_pid) { sc->atu_radio = t->atu_radio; sc->atu_quirk = t->atu_quirk; } @@ -1365,7 +1370,7 @@ atu_complete_attach(struct atu_softc *sc) ed = usbd_interface2endpoint_descriptor(sc->atu_iface, i); if (!ed) { DPRINTF(("%s: num_endp:%d\n", device_xname(sc->atu_dev), - sc->atu_iface->idesc->bNumEndpoints)); + sc->atu_iface->ui_idesc->bNumEndpoints)); DPRINTF(("%s: couldn't get ep %d\n", device_xname(sc->atu_dev), i)); return; @@ -1389,7 +1394,7 @@ atu_complete_attach(struct atu_softc *sc) #ifdef ATU_DEBUG /* DEBUG : try to get firmware version */ - err = atu_get_mib(sc, MIB_FW_VERSION, sizeof(fw), 0, (u_int8_t *)&fw); + err = atu_get_mib(sc, MIB_FW_VERSION, sizeof(fw), 0, (uint8_t *)&fw); if (!err) { DPRINTFN(15, ("%s: firmware: maj:%d min:%d patch:%d " "build:%d\n", device_xname(sc->atu_dev), fw.major, fw.minor, @@ -1550,18 +1555,16 @@ atu_rx_list_init(struct atu_softc *sc) c->atu_sc = sc; c->atu_idx = i; if (c->atu_xfer == NULL) { - c->atu_xfer = usbd_alloc_xfer(sc->atu_udev); - if (c->atu_xfer == NULL) - return (ENOBUFS); - c->atu_buf = usbd_alloc_buffer(c->atu_xfer, - ATU_RX_BUFSZ); - if (c->atu_buf == NULL) /* XXX free xfer */ - return (ENOBUFS); + int err = usbd_create_xfer(sc->atu_ep[ATU_ENDPT_RX], + ATU_RX_BUFSZ, USBD_SHORT_XFER_OK, 0, &c->atu_xfer); + if (err) + return err; + c->atu_buf = usbd_get_buffer(c->atu_xfer); if (atu_newbuf(sc, c, NULL) == ENOBUFS) /* XXX free? */ return(ENOBUFS); } } - return (0); + return 0; } int @@ -1582,14 +1585,12 @@ atu_tx_list_init(struct atu_softc *sc) c->atu_sc = sc; c->atu_idx = i; if (c->atu_xfer == NULL) { - c->atu_xfer = usbd_alloc_xfer(sc->atu_udev); - if (c->atu_xfer == NULL) - return(ENOBUFS); - c->atu_mbuf = NULL; - c->atu_buf = usbd_alloc_buffer(c->atu_xfer, - ATU_TX_BUFSZ); - if (c->atu_buf == NULL) - return(ENOBUFS); /* XXX free xfer */ + int err = usbd_create_xfer(sc->atu_ep[ATU_ENDPT_TX], + ATU_TX_BUFSZ, 0, 0, &c->atu_xfer); + if (err) { + return err; + } + c->atu_buf = usbd_get_buffer(c->atu_xfer); SLIST_INSERT_HEAD(&cd->atu_tx_free, c, atu_list); } } @@ -1611,7 +1612,7 @@ atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch, ch[i].atu_mbuf = NULL; } if (ch[i].atu_xfer != NULL) { - usbd_free_xfer(ch[i].atu_xfer); + usbd_destroy_xfer(ch[i].atu_xfer); ch[i].atu_xfer = NULL; } } @@ -1622,7 +1623,7 @@ atu_xfer_list_free(struct atu_softc *sc, struct atu_chain *ch, * the higher level protocols. */ void -atu_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +atu_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct atu_chain *c = (struct atu_chain *)priv; struct atu_softc *sc = c->atu_sc; @@ -1632,7 +1633,7 @@ atu_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) struct ieee80211_frame_min *wh; struct ieee80211_node *ni; struct mbuf *m; - u_int32_t len; + uint32_t len; int s; DPRINTFN(25, ("%s: atu_rxeof\n", device_xname(sc->atu_dev))); @@ -1721,9 +1722,8 @@ done1: splx(s); done: /* Setup new transfer. */ - usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_RX], c, c->atu_buf, - ATU_RX_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, - atu_rxeof); + usbd_setup_xfer(c->atu_xfer, c, c->atu_buf, ATU_RX_BUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, atu_rxeof); usbd_transfer(c->atu_xfer); } @@ -1732,7 +1732,7 @@ done: * the list buffers. */ void -atu_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, +atu_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct atu_chain *c = (struct atu_chain *)priv; @@ -1778,16 +1778,16 @@ atu_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, atu_start(ifp); } -u_int8_t +uint8_t atu_calculate_padding(int size) { size %= 64; if (size < 50) - return (50 - size); + return 50 - size; if (size >=61) - return (64 + 50 - size); - return (0); + return 64 + 50 - size; + return 0; } int @@ -1797,7 +1797,7 @@ atu_tx_start(struct atu_softc *sc, struct ieee80211_node *ni, int len; struct atu_tx_hdr *h; usbd_status err; - u_int8_t pad; + uint8_t pad; DPRINTFN(25, ("%s: atu_tx_start\n", device_xname(sc->atu_dev))); @@ -1828,9 +1828,8 @@ atu_tx_start(struct atu_softc *sc, struct ieee80211_node *ni, c->atu_length = len; c->atu_mbuf = m; - usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_TX], - c, c->atu_buf, c->atu_length, USBD_NO_COPY, ATU_TX_TIMEOUT, - atu_txeof); + usbd_setup_xfer(c->atu_xfer, c, c->atu_buf, c->atu_length, 0, + ATU_TX_TIMEOUT, atu_txeof); /* Let's get this thing into the air! */ c->atu_in_xfer = 1; @@ -1843,7 +1842,7 @@ atu_tx_start(struct atu_softc *sc, struct ieee80211_node *ni, return(EIO); } - return (0); + return 0; } void @@ -1982,14 +1981,6 @@ atu_init(struct ifnet *ifp) return(0); } - /* Init TX ring */ - if (atu_tx_list_init(sc)) - printf("%s: tx list init failed\n", device_xname(sc->atu_dev)); - - /* Init RX ring */ - if (atu_rx_list_init(sc)) - printf("%s: rx list init failed\n", device_xname(sc->atu_dev)); - /* Load the multicast filter. */ /*atu_setmulti(sc); */ @@ -2012,13 +2003,20 @@ atu_init(struct ifnet *ifp) return(EIO); } + /* Init TX ring */ + if (atu_tx_list_init(sc)) + printf("%s: tx list init failed\n", device_xname(sc->atu_dev)); + + /* Init RX ring */ + if (atu_rx_list_init(sc)) + printf("%s: rx list init failed\n", device_xname(sc->atu_dev)); + /* Start up the receive pipe. */ for (i = 0; i < ATU_RX_LIST_CNT; i++) { c = &sc->atu_cdata.atu_rx_chain[i]; - usbd_setup_xfer(c->atu_xfer, sc->atu_ep[ATU_ENDPT_RX], c, - c->atu_buf, ATU_RX_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, atu_rxeof); + usbd_setup_xfer(c->atu_xfer, c, c->atu_buf, ATU_RX_BUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, atu_rxeof); usbd_transfer(c->atu_xfer); } @@ -2065,7 +2063,7 @@ void atu_debug_print(struct atu_softc *sc) { usbd_status err; - u_int8_t tmp[32]; + uint8_t tmp[32]; /* DEBUG */ if ((err = atu_get_mib(sc, MIB_MAC_MGMT__CURRENT_BSSID, tmp))) @@ -2179,7 +2177,7 @@ atu_ioctl(struct ifnet *ifp, u_long command, void *data) } splx(s); - return (err); + return err; } void @@ -2249,6 +2247,23 @@ atu_stop(struct ifnet *ifp, int disable) DPRINTF(("%s: abort rx pipe failed: %s\n", device_xname(sc->atu_dev), usbd_errstr(err))); } + } + + if (sc->atu_ep[ATU_ENDPT_TX] != NULL) { + err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]); + if (err) { + DPRINTF(("%s: abort tx pipe failed: %s\n", + device_xname(sc->atu_dev), usbd_errstr(err))); + } + } + + /* Free RX/TX/MGMT list resources. */ + cd = &sc->atu_cdata; + atu_xfer_list_free(sc, cd->atu_rx_chain, ATU_RX_LIST_CNT); + atu_xfer_list_free(sc, cd->atu_tx_chain, ATU_TX_LIST_CNT); + + /* Close pipes */ + if (sc->atu_ep[ATU_ENDPT_RX] != NULL) { err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_RX]); if (err) { DPRINTF(("%s: close rx pipe failed: %s\n", @@ -2258,11 +2273,6 @@ atu_stop(struct ifnet *ifp, int disable) } if (sc->atu_ep[ATU_ENDPT_TX] != NULL) { - err = usbd_abort_pipe(sc->atu_ep[ATU_ENDPT_TX]); - if (err) { - DPRINTF(("%s: abort tx pipe failed: %s\n", - device_xname(sc->atu_dev), usbd_errstr(err))); - } err = usbd_close_pipe(sc->atu_ep[ATU_ENDPT_TX]); if (err) { DPRINTF(("%s: close tx pipe failed: %s\n", @@ -2271,11 +2281,6 @@ atu_stop(struct ifnet *ifp, int disable) sc->atu_ep[ATU_ENDPT_TX] = NULL; } - /* Free RX/TX/MGMT list resources. */ - cd = &sc->atu_cdata; - atu_xfer_list_free(sc, cd->atu_rx_chain, ATU_RX_LIST_CNT); - atu_xfer_list_free(sc, cd->atu_tx_chain, ATU_TX_LIST_CNT); - /* Let's be nice and turn off the radio before we leave */ atu_switch_radio(sc, 0); diff --git a/sys/dev/usb/if_atureg.h b/sys/dev/usb/if_atureg.h index 8bd68ffd537..26a22f82524 100644 --- a/sys/dev/usb/if_atureg.h +++ b/sys/dev/usb/if_atureg.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_atureg.h,v 1.10 2012/09/23 01:08:17 chs Exp $ */ +/* $NetBSD: if_atureg.h,v 1.11 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_atureg.h,v 1.21 2004/12/23 13:19:38 dlg Exp $ */ /* * Copyright (c) 2003 @@ -98,21 +98,21 @@ enum atu_radio_type { }; struct atu_type { - u_int16_t atu_vid; - u_int16_t atu_pid; + uint16_t atu_vid; + uint16_t atu_pid; enum atu_radio_type atu_radio; - u_int16_t atu_quirk; + uint16_t atu_quirk; }; struct atu_softc; struct atu_chain { struct atu_softc *atu_sc; - usbd_xfer_handle atu_xfer; + struct usbd_xfer *atu_xfer; char *atu_buf; struct mbuf *atu_mbuf; - u_int8_t atu_idx; - u_int16_t atu_length; + uint8_t atu_idx; + uint16_t atu_length; int atu_in_xfer; SLIST_ENTRY(atu_chain) atu_list; }; @@ -124,8 +124,8 @@ struct atu_cdata { SLIST_HEAD(atu_list_head, atu_chain) atu_rx_free; struct atu_list_head atu_tx_free; - u_int8_t atu_tx_inuse; - u_int8_t atu_tx_last_idx; + uint8_t atu_tx_inuse; + uint8_t atu_tx_last_idx; }; #define MAX_SSID_LEN 32 @@ -148,12 +148,12 @@ struct atu_softc { #define ATU_C_JOIN 2 struct usb_task sc_task; - usbd_device_handle atu_udev; - usbd_interface_handle atu_iface; + struct usbd_device *atu_udev; + struct usbd_interface *atu_iface; struct ethercom atu_ec; struct ifmedia atu_media; int atu_ed[ATU_ENDPT_MAX]; - usbd_pipe_handle atu_ep[ATU_ENDPT_MAX]; + struct usbd_pipe *atu_ep[ATU_ENDPT_MAX]; int atu_unit; int atu_if_flags; @@ -161,25 +161,25 @@ struct atu_softc { struct timeval atu_rx_notice; - u_int8_t atu_bssid[ETHER_ADDR_LEN]; + uint8_t atu_bssid[ETHER_ADDR_LEN]; enum atu_radio_type atu_radio; - u_int16_t atu_quirk; + uint16_t atu_quirk; - u_int8_t atu_channel; - u_int16_t atu_desired_channel; - u_int8_t atu_mode; + uint8_t atu_channel; + uint16_t atu_desired_channel; + uint8_t atu_mode; #define NO_MODE_YET 0 #define AD_HOC_MODE 1 #define INFRASTRUCTURE_MODE 2 - u_int8_t atu_radio_on; - u_int8_t atu_encrypt; + uint8_t atu_radio_on; + uint8_t atu_encrypt; #define ATU_WEP_RX 0x01 #define ATU_WEP_TX 0x02 #define ATU_WEP_TXRX (ATU_WEP_RX | ATU_WEP_TX) int atu_wepkey; int atu_wepkeylen; - u_int8_t atu_wepkeys[4][13]; + uint8_t atu_wepkeys[4][13]; }; #define sc_if sc_ec.ec_if @@ -337,39 +337,39 @@ struct atu_cmd_start_ibss { /* The config structure of an RFMD radio */ struct atu_rfmd_conf { - u_int8_t CR20[14]; - u_int8_t CR21[14]; - u_int8_t BB_CR[14]; - u_int8_t PidVid[4]; - u_int8_t MACAddr[ETHER_ADDR_LEN]; - u_int8_t RegulatoryDomain; - u_int8_t LowPowerValues[14]; - u_int8_t NormalPowerValues[14]; - u_int8_t Reserved[3]; + uint8_t CR20[14]; + uint8_t CR21[14]; + uint8_t BB_CR[14]; + uint8_t PidVid[4]; + uint8_t MACAddr[ETHER_ADDR_LEN]; + uint8_t RegulatoryDomain; + uint8_t LowPowerValues[14]; + uint8_t NormalPowerValues[14]; + uint8_t Reserved[3]; /* then we have 84 bytes, somehow Windows reads 95?? */ - u_int8_t Rest[11]; + uint8_t Rest[11]; } UPACKED; /* The config structure of an Intersil radio */ struct atu_intersil_conf { - u_int8_t MACAddr[ETHER_ADDR_LEN]; + uint8_t MACAddr[ETHER_ADDR_LEN]; /* From the HFA3861B manual : */ /* Manual TX power control (7bit : -64 to 63) */ - u_int8_t CR31[14]; + uint8_t CR31[14]; /* TX power measurement */ - u_int8_t CR58[14]; - u_int8_t PidVid[4]; - u_int8_t RegulatoryDomain; - u_int8_t Reserved[1]; + uint8_t CR58[14]; + uint8_t PidVid[4]; + uint8_t RegulatoryDomain; + uint8_t Reserved[1]; } UPACKED; /* Firmware information request */ struct atu_fw { - u_int8_t major; - u_int8_t minor; - u_int8_t patch; - u_int8_t build; + uint8_t major; + uint8_t minor; + uint8_t patch; + uint8_t build; } UPACKED; /* diff --git a/sys/dev/usb/if_aue.c b/sys/dev/usb/if_aue.c index 58f66c0fd63..e655b2bd4f3 100644 --- a/sys/dev/usb/if_aue.c +++ b/sys/dev/usb/if_aue.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_aue.c,v 1.134 2016/02/09 08:32:12 ozaki-r Exp $ */ +/* $NetBSD: if_aue.c,v 1.135 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 @@ -78,7 +78,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.134 2016/02/09 08:32:12 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.135 2016/04/23 10:15:31 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -89,7 +89,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_aue.c,v 1.134 2016/02/09 08:32:12 ozaki-r Exp $") #include <sys/sockio.h> #include <sys/mutex.h> #include <sys/mbuf.h> -#include <sys/malloc.h> #include <sys/kernel.h> #include <sys/socket.h> #include <sys/device.h> @@ -137,7 +136,7 @@ int auedebug = 0; */ struct aue_type { struct usb_devno aue_dev; - u_int16_t aue_flags; + uint16_t aue_flags; #define LSYS 0x0001 /* use Linksys reset */ #define PNA 0x0002 /* has Home PNA */ #define PII 0x0004 /* Pegasus II chip */ @@ -219,14 +218,14 @@ CFATTACH_DECL_NEW(aue, sizeof(struct aue_softc), aue_match, aue_attach, Static void aue_multithread(void *); -Static void aue_reset_pegasus_II(struct aue_softc *sc); +Static void aue_reset_pegasus_II(struct aue_softc *); Static int aue_tx_list_init(struct aue_softc *); Static int aue_rx_list_init(struct aue_softc *); Static int aue_newbuf(struct aue_softc *, struct aue_chain *, struct mbuf *); Static int aue_send(struct aue_softc *, struct mbuf *, int); -Static void aue_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); -Static void aue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -Static void aue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void aue_intr(struct usbd_xfer *, void *, usbd_status); +Static void aue_rxeof(struct usbd_xfer *, void *, usbd_status); +Static void aue_txeof(struct usbd_xfer *, void *, usbd_status); Static void aue_tick(void *); Static void aue_tick_task(void *); Static void aue_start(struct ifnet *); @@ -247,7 +246,7 @@ Static void aue_lock_mii(struct aue_softc *); Static void aue_unlock_mii(struct aue_softc *); Static void aue_setmulti(struct aue_softc *); -Static u_int32_t aue_crc(void *); +Static uint32_t aue_crc(void *); Static void aue_reset(struct aue_softc *); Static int aue_csr_read_1(struct aue_softc *, int); @@ -269,7 +268,7 @@ aue_csr_read_1(struct aue_softc *sc, int reg) uByte val = 0; if (sc->aue_dying) - return (0); + return 0; req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = AUE_UR_READREG; @@ -282,10 +281,10 @@ aue_csr_read_1(struct aue_softc *sc, int reg) if (err) { DPRINTF(("%s: aue_csr_read_1: reg=0x%x err=%s\n", device_xname(sc->aue_dev), reg, usbd_errstr(err))); - return (0); + return 0; } - return (val); + return val; } Static int @@ -296,7 +295,7 @@ aue_csr_read_2(struct aue_softc *sc, int reg) uWord val; if (sc->aue_dying) - return (0); + return 0; req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = AUE_UR_READREG; @@ -309,10 +308,10 @@ aue_csr_read_2(struct aue_softc *sc, int reg) if (err) { DPRINTF(("%s: aue_csr_read_2: reg=0x%x err=%s\n", device_xname(sc->aue_dev), reg, usbd_errstr(err))); - return (0); + return 0; } - return (UGETW(val)); + return UGETW(val); } Static int @@ -323,7 +322,7 @@ aue_csr_write_1(struct aue_softc *sc, int reg, int aval) uByte val; if (sc->aue_dying) - return (0); + return 0; val = aval; req.bmRequestType = UT_WRITE_VENDOR_DEVICE; @@ -337,10 +336,10 @@ aue_csr_write_1(struct aue_softc *sc, int reg, int aval) if (err) { DPRINTF(("%s: aue_csr_write_1: reg=0x%x err=%s\n", device_xname(sc->aue_dev), reg, usbd_errstr(err))); - return (-1); + return -1; } - return (0); + return 0; } Static int @@ -351,7 +350,7 @@ aue_csr_write_2(struct aue_softc *sc, int reg, int aval) uWord val; if (sc->aue_dying) - return (0); + return 0; USETW(val, aval); req.bmRequestType = UT_WRITE_VENDOR_DEVICE; @@ -365,10 +364,10 @@ aue_csr_write_2(struct aue_softc *sc, int reg, int aval) if (err) { DPRINTF(("%s: aue_csr_write_2: reg=0x%x err=%s\n", device_xname(sc->aue_dev), reg, usbd_errstr(err))); - return (-1); + return -1; } - return (0); + return 0; } /* @@ -392,7 +391,7 @@ aue_eeprom_getword(struct aue_softc *sc, int addr) device_xname(sc->aue_dev)); } - return (aue_csr_read_2(sc, AUE_EE_DATA)); + return aue_csr_read_2(sc, AUE_EE_DATA); } /* @@ -435,7 +434,7 @@ aue_miibus_readreg(device_t dev, int phy, int reg) { struct aue_softc *sc = device_private(dev); int i; - u_int16_t val; + uint16_t val; if (sc->aue_dying) { #ifdef DIAGNOSTIC @@ -458,7 +457,7 @@ aue_miibus_readreg(device_t dev, int phy, int reg) if (sc->aue_vendor == USB_VENDOR_ADMTEK && sc->aue_product == USB_PRODUCT_ADMTEK_PEGASUS) { if (phy == 3) - return (0); + return 0; } #endif @@ -481,7 +480,7 @@ aue_miibus_readreg(device_t dev, int phy, int reg) device_xname(sc->aue_dev), __func__, phy, reg, val)); aue_unlock_mii(sc); - return (val); + return val; } Static void @@ -548,7 +547,7 @@ aue_miibus_statchg(struct ifnet *ifp) * register of the Broadcom PHY. */ if (!sc->aue_dying && (sc->aue_flags & LSYS)) { - u_int16_t auxmode; + uint16_t auxmode; auxmode = aue_miibus_readreg(sc->aue_dev, 0, 0x1b); aue_miibus_writereg(sc->aue_dev, 0, 0x1b, auxmode | 0x04); } @@ -558,10 +557,10 @@ aue_miibus_statchg(struct ifnet *ifp) #define AUE_POLY 0xEDB88320 #define AUE_BITS 6 -Static u_int32_t +Static uint32_t aue_crc(void *addrv) { - u_int32_t idx, bit, data, crc; + uint32_t idx, bit, data, crc; char *addr = addrv; /* Compute CRC for the address value. */ @@ -572,7 +571,7 @@ aue_crc(void *addrv) crc = (crc >> 1) ^ (((crc ^ data) & 1) ? AUE_POLY : 0); } - return (crc & ((1 << AUE_BITS) - 1)); + return crc & ((1 << AUE_BITS) - 1); } Static void @@ -581,7 +580,7 @@ aue_setmulti(struct aue_softc *sc) struct ifnet *ifp; struct ether_multi *enm; struct ether_multistep step; - u_int32_t h = 0, i; + uint32_t h = 0, i; DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->aue_dev), __func__)); @@ -699,18 +698,18 @@ aue_match(device_t parent, cfdata_t match, void *aux) * If this turns out to be more common, we could use a quirk * table. */ - if (uaa->vendor == USB_VENDOR_BELKIN && - uaa->product == USB_PRODUCT_BELKIN_USB2LAN) { + if (uaa->uaa_vendor == USB_VENDOR_BELKIN && + uaa->uaa_product == USB_PRODUCT_BELKIN_USB2LAN) { usb_device_descriptor_t *dd; - dd = usbd_get_device_descriptor(uaa->device); + dd = usbd_get_device_descriptor(uaa->uaa_device); if (dd != NULL && dd->bDeviceClass != UDCLASS_IN_INTERFACE) - return (UMATCH_NONE); + return UMATCH_NONE; } - return (aue_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return aue_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } /* @@ -727,8 +726,8 @@ aue_attach(device_t parent, device_t self, void *aux) u_char eaddr[ETHER_ADDR_LEN]; struct ifnet *ifp; struct mii_data *mii; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface; + struct usbd_device *dev = uaa->uaa_device; + struct usbd_interface *iface; usbd_status err; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; @@ -741,7 +740,7 @@ aue_attach(device_t parent, device_t self, void *aux) aprint_naive("\n"); aprint_normal("\n"); - devinfop = usbd_devinfo_alloc(uaa->device, 0); + devinfop = usbd_devinfo_alloc(uaa->uaa_device, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); @@ -776,12 +775,12 @@ aue_attach(device_t parent, device_t self, void *aux) "creating multicast configuration thread\n"); return; } - sc->aue_flags = aue_lookup(uaa->vendor, uaa->product)->aue_flags; + sc->aue_flags = aue_lookup(uaa->uaa_vendor, uaa->uaa_product)->aue_flags; sc->aue_udev = dev; sc->aue_iface = iface; - sc->aue_product = uaa->product; - sc->aue_vendor = uaa->vendor; + sc->aue_product = uaa->uaa_product; + sc->aue_vendor = uaa->uaa_vendor; id = usbd_get_interface_descriptor(iface); @@ -882,7 +881,7 @@ aue_detach(device_t self, int flags) if (!sc->aue_attached) { /* Detached before attached finished, so just bail out. */ - return (0); + return 0; } callout_stop(&sc->aue_stat_ch); @@ -937,7 +936,7 @@ aue_detach(device_t self, int flags) #if 0 mutex_destroy(&sc->wkmtx); #endif - return (0); + return 0; } int @@ -972,7 +971,7 @@ aue_newbuf(struct aue_softc *sc, struct aue_chain *c, struct mbuf *m) if (m_new == NULL) { aprint_error_dev(sc->aue_dev, "no memory for rx list " "-- packet dropped!\n"); - return (ENOBUFS); + return ENOBUFS; } MCLGET(m_new, M_DONTWAIT); @@ -980,7 +979,7 @@ aue_newbuf(struct aue_softc *sc, struct aue_chain *c, struct mbuf *m) aprint_error_dev(sc->aue_dev, "no memory for rx " "list -- packet dropped!\n"); m_freem(m_new); - return (ENOBUFS); + return ENOBUFS; } m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; } else { @@ -992,7 +991,7 @@ aue_newbuf(struct aue_softc *sc, struct aue_chain *c, struct mbuf *m) m_adj(m_new, ETHER_ALIGN); c->aue_mbuf = m_new; - return (0); + return 0; } Static int @@ -1010,18 +1009,18 @@ aue_rx_list_init(struct aue_softc *sc) c->aue_sc = sc; c->aue_idx = i; if (aue_newbuf(sc, c, NULL) == ENOBUFS) - return (ENOBUFS); + return ENOBUFS; if (c->aue_xfer == NULL) { - c->aue_xfer = usbd_alloc_xfer(sc->aue_udev); - if (c->aue_xfer == NULL) - return (ENOBUFS); - c->aue_buf = usbd_alloc_buffer(c->aue_xfer, AUE_BUFSZ); - if (c->aue_buf == NULL) - return (ENOBUFS); /* XXX free xfer */ + int err = usbd_create_xfer(sc->aue_ep[AUE_ENDPT_RX], + AUE_BUFSZ, USBD_SHORT_XFER_OK, 0, &c->aue_xfer); + if (err) { + return err; + } + c->aue_buf = usbd_get_buffer(c->aue_xfer); } } - return (0); + return 0; } Static int @@ -1040,20 +1039,20 @@ aue_tx_list_init(struct aue_softc *sc) c->aue_idx = i; c->aue_mbuf = NULL; if (c->aue_xfer == NULL) { - c->aue_xfer = usbd_alloc_xfer(sc->aue_udev); - if (c->aue_xfer == NULL) - return (ENOBUFS); - c->aue_buf = usbd_alloc_buffer(c->aue_xfer, AUE_BUFSZ); - if (c->aue_buf == NULL) - return (ENOBUFS); + int err = usbd_create_xfer(sc->aue_ep[AUE_ENDPT_TX], + AUE_BUFSZ, USBD_FORCE_SHORT_XFER, 0, &c->aue_xfer); + if (err) { + return err; + } + c->aue_buf = usbd_get_buffer(c->aue_xfer); } } - return (0); + return 0; } Static void -aue_intr(usbd_xfer_handle xfer, usbd_private_handle priv, +aue_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct aue_softc *sc = priv; @@ -1096,13 +1095,13 @@ aue_intr(usbd_xfer_handle xfer, usbd_private_handle priv, * the higher level protocols. */ Static void -aue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +aue_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct aue_chain *c = priv; struct aue_softc *sc = c->aue_sc; struct ifnet *ifp = GET_IFP(sc); struct mbuf *m; - u_int32_t total_len; + uint32_t total_len; struct aue_rxpkt r; int s; @@ -1180,10 +1179,8 @@ aue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) done: /* Setup new transfer. */ - usbd_setup_xfer(xfer, sc->aue_ep[AUE_ENDPT_RX], - c, c->aue_buf, AUE_BUFSZ, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, aue_rxeof); + usbd_setup_xfer(xfer, c, c->aue_buf, AUE_BUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, aue_rxeof); usbd_transfer(xfer); DPRINTFN(10,("%s: %s: start rx\n", device_xname(sc->aue_dev), @@ -1196,7 +1193,7 @@ aue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) */ Static void -aue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, +aue_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct aue_chain *c = priv; @@ -1319,13 +1316,12 @@ aue_send(struct aue_softc *sc, struct mbuf *m, int idx) * transfer, however it actually seems to ignore this info * and base the frame size on the bulk transfer length. */ - c->aue_buf[0] = (u_int8_t)m->m_pkthdr.len; - c->aue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8); + c->aue_buf[0] = (uint8_t)m->m_pkthdr.len; + c->aue_buf[1] = (uint8_t)(m->m_pkthdr.len >> 8); total_len = m->m_pkthdr.len + 2; - usbd_setup_xfer(c->aue_xfer, sc->aue_ep[AUE_ENDPT_TX], - c, c->aue_buf, total_len, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - AUE_TX_TIMEOUT, aue_txeof); + usbd_setup_xfer(c->aue_xfer, c, c->aue_buf, total_len, + USBD_FORCE_SHORT_XFER, AUE_TX_TIMEOUT, aue_txeof); /* Transmit */ err = usbd_transfer(c->aue_xfer); @@ -1335,14 +1331,14 @@ aue_send(struct aue_softc *sc, struct mbuf *m, int idx) /* Stop the interface from process context. */ usb_add_task(sc->aue_udev, &sc->aue_stop_task, USB_TASKQ_DRIVER); - return (EIO); + return EIO; } DPRINTFN(5,("%s: %s: send %d bytes\n", device_xname(sc->aue_dev), __func__, total_len)); sc->aue_cdata.aue_tx_cnt++; - return (0); + return 0; } Static void @@ -1422,20 +1418,38 @@ aue_init(void *xsc) else AUE_CLRBIT(sc, AUE_CTL2, AUE_CTL2_RX_PROMISC); + if (sc->aue_ep[AUE_ENDPT_RX] == NULL) { + if (aue_openpipes(sc)) { + splx(s); + return; + } + } /* Init TX ring. */ - if (aue_tx_list_init(sc) == ENOBUFS) { + if (aue_tx_list_init(sc)) { aprint_error_dev(sc->aue_dev, "tx list init failed\n"); splx(s); return; } /* Init RX ring. */ - if (aue_rx_list_init(sc) == ENOBUFS) { + if (aue_rx_list_init(sc)) { aprint_error_dev(sc->aue_dev, "rx list init failed\n"); splx(s); return; } + /* Start up the receive pipe. */ + for (i = 0; i < AUE_RX_LIST_CNT; i++) { + struct aue_chain *c = &sc->aue_cdata.aue_rx_chain[i]; + + usbd_setup_xfer(c->aue_xfer, c, c->aue_buf, AUE_BUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, aue_rxeof); + (void)usbd_transfer(c->aue_xfer); /* XXX */ + DPRINTFN(5,("%s: %s: start read\n", device_xname(sc->aue_dev), + __func__)); + + } + /* Load the multicast filter. */ aue_setmulti(sc); @@ -1446,13 +1460,6 @@ aue_init(void *xsc) mii_mediachg(mii); - if (sc->aue_ep[AUE_ENDPT_RX] == NULL) { - if (aue_openpipes(sc)) { - splx(s); - return; - } - } - ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; @@ -1464,9 +1471,7 @@ aue_init(void *xsc) Static int aue_openpipes(struct aue_softc *sc) { - struct aue_chain *c; usbd_status err; - int i; /* Open RX and TX pipes. */ err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_RX], @@ -1474,14 +1479,14 @@ aue_openpipes(struct aue_softc *sc) if (err) { aprint_error_dev(sc->aue_dev, "open rx pipe failed: %s\n", usbd_errstr(err)); - return (EIO); + return EIO; } err = usbd_open_pipe(sc->aue_iface, sc->aue_ed[AUE_ENDPT_TX], USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_TX]); if (err) { aprint_error_dev(sc->aue_dev, "open tx pipe failed: %s\n", usbd_errstr(err)); - return (EIO); + return EIO; } err = usbd_open_pipe_intr(sc->aue_iface, sc->aue_ed[AUE_ENDPT_INTR], USBD_EXCLUSIVE_USE, &sc->aue_ep[AUE_ENDPT_INTR], sc, @@ -1490,22 +1495,10 @@ aue_openpipes(struct aue_softc *sc) if (err) { aprint_error_dev(sc->aue_dev, "open intr pipe failed: %s\n", usbd_errstr(err)); - return (EIO); + return EIO; } - /* Start up the receive pipe. */ - for (i = 0; i < AUE_RX_LIST_CNT; i++) { - c = &sc->aue_cdata.aue_rx_chain[i]; - usbd_setup_xfer(c->aue_xfer, sc->aue_ep[AUE_ENDPT_RX], - c, c->aue_buf, AUE_BUFSZ, - USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, - aue_rxeof); - (void)usbd_transfer(c->aue_xfer); /* XXX */ - DPRINTFN(5,("%s: %s: start read\n", device_xname(sc->aue_dev), - __func__)); - - } - return (0); + return 0; } /* @@ -1521,7 +1514,7 @@ aue_ifmedia_upd(struct ifnet *ifp) DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->aue_dev), __func__)); if (sc->aue_dying) - return (0); + return 0; sc->aue_link = 0; @@ -1539,7 +1532,7 @@ aue_ioctl(struct ifnet *ifp, u_long command, void *data) int s, error = 0; if (sc->aue_dying) - return (EIO); + return EIO; s = splnet(); @@ -1603,7 +1596,7 @@ aue_ioctl(struct ifnet *ifp, u_long command, void *data) splx(s); - return (error); + return error; } Static void @@ -1671,12 +1664,6 @@ aue_stop(struct aue_softc *sc) printf("%s: abort tx pipe failed: %s\n", device_xname(sc->aue_dev), usbd_errstr(err)); } - err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_TX]); - if (err) { - printf("%s: close tx pipe failed: %s\n", - device_xname(sc->aue_dev), usbd_errstr(err)); - } - sc->aue_ep[AUE_ENDPT_TX] = NULL; } if (sc->aue_ep[AUE_ENDPT_INTR] != NULL) { @@ -1685,12 +1672,6 @@ aue_stop(struct aue_softc *sc) printf("%s: abort intr pipe failed: %s\n", device_xname(sc->aue_dev), usbd_errstr(err)); } - err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_INTR]); - if (err) { - printf("%s: close intr pipe failed: %s\n", - device_xname(sc->aue_dev), usbd_errstr(err)); - } - sc->aue_ep[AUE_ENDPT_INTR] = NULL; } /* Free RX resources. */ @@ -1700,7 +1681,7 @@ aue_stop(struct aue_softc *sc) sc->aue_cdata.aue_rx_chain[i].aue_mbuf = NULL; } if (sc->aue_cdata.aue_rx_chain[i].aue_xfer != NULL) { - usbd_free_xfer(sc->aue_cdata.aue_rx_chain[i].aue_xfer); + usbd_destroy_xfer(sc->aue_cdata.aue_rx_chain[i].aue_xfer); sc->aue_cdata.aue_rx_chain[i].aue_xfer = NULL; } } @@ -1712,11 +1693,30 @@ aue_stop(struct aue_softc *sc) sc->aue_cdata.aue_tx_chain[i].aue_mbuf = NULL; } if (sc->aue_cdata.aue_tx_chain[i].aue_xfer != NULL) { - usbd_free_xfer(sc->aue_cdata.aue_tx_chain[i].aue_xfer); + usbd_destroy_xfer(sc->aue_cdata.aue_tx_chain[i].aue_xfer); sc->aue_cdata.aue_tx_chain[i].aue_xfer = NULL; } } + /* Close pipes */ + if (sc->aue_ep[AUE_ENDPT_TX] != NULL) { + err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_TX]); + if (err) { + printf("%s: close tx pipe failed: %s\n", + device_xname(sc->aue_dev), usbd_errstr(err)); + } + sc->aue_ep[AUE_ENDPT_TX] = NULL; + } + + if (sc->aue_ep[AUE_ENDPT_INTR] != NULL) { + err = usbd_close_pipe(sc->aue_ep[AUE_ENDPT_INTR]); + if (err) { + printf("%s: close intr pipe failed: %s\n", + device_xname(sc->aue_dev), usbd_errstr(err)); + } + sc->aue_ep[AUE_ENDPT_INTR] = NULL; + } + sc->aue_link = 0; ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); diff --git a/sys/dev/usb/if_auereg.h b/sys/dev/usb/if_auereg.h index 27ba2da1261..e0ff2d7b736 100644 --- a/sys/dev/usb/if_auereg.h +++ b/sys/dev/usb/if_auereg.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_auereg.h,v 1.26 2015/04/14 20:32:36 riastradh Exp $ */ +/* $NetBSD: if_auereg.h,v 1.27 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 1997, 1998, 1999 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. @@ -176,14 +176,14 @@ #define AUE_GPIO_SEL1 0x20 struct aue_intrpkt { - u_int8_t aue_txstat0; - u_int8_t aue_txstat1; - u_int8_t aue_rxstat; - u_int8_t aue_rxlostpkt0; - u_int8_t aue_rxlostpkt1; - u_int8_t aue_wakeupstat; - u_int8_t aue_rsvd; - u_int8_t _pad; + uint8_t aue_txstat0; + uint8_t aue_txstat1; + uint8_t aue_rxstat; + uint8_t aue_rxlostpkt0; + uint8_t aue_rxlostpkt1; + uint8_t aue_wakeupstat; + uint8_t aue_rsvd; + uint8_t _pad; }; #define AUE_INTR_PKTLEN 8 @@ -209,7 +209,7 @@ struct aue_softc; struct aue_chain { struct aue_softc *aue_sc; - usbd_xfer_handle aue_xfer; + struct usbd_xfer *aue_xfer; char *aue_buf; struct mbuf *aue_mbuf; int aue_idx; @@ -241,17 +241,17 @@ struct aue_softc { struct callout aue_stat_ch; - usbd_device_handle aue_udev; - usbd_interface_handle aue_iface; - u_int16_t aue_vendor; - u_int16_t aue_product; + struct usbd_device *aue_udev; + struct usbd_interface *aue_iface; + uint16_t aue_vendor; + uint16_t aue_product; int aue_ed[AUE_ENDPT_MAX]; - usbd_pipe_handle aue_ep[AUE_ENDPT_MAX]; - u_int8_t aue_link; + struct usbd_pipe *aue_ep[AUE_ENDPT_MAX]; + uint8_t aue_link; int aue_if_flags; struct aue_cdata aue_cdata; - u_int16_t aue_flags; + uint16_t aue_flags; int aue_refcnt; char aue_dying; diff --git a/sys/dev/usb/if_axe.c b/sys/dev/usb/if_axe.c index b8a84b96dd7..43d34152375 100644 --- a/sys/dev/usb/if_axe.c +++ b/sys/dev/usb/if_axe.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_axe.c,v 1.70 2016/02/09 08:32:12 ozaki-r Exp $ */ +/* $NetBSD: if_axe.c,v 1.71 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_axe.c,v 1.96 2010/01/09 05:33:08 jsg Exp $ */ /* @@ -89,7 +89,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.70 2016/02/09 08:32:12 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_axe.c,v 1.71 2016/04/23 10:15:31 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -186,8 +186,8 @@ CFATTACH_DECL_NEW(axe, sizeof(struct axe_softc), static int axe_tx_list_init(struct axe_softc *); static int axe_rx_list_init(struct axe_softc *); static int axe_encap(struct axe_softc *, struct mbuf *, int); -static void axe_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void axe_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +static void axe_rxeof(struct usbd_xfer *, void *, usbd_status); +static void axe_txeof(struct usbd_xfer *, void *, usbd_status); static void axe_tick(void *); static void axe_tick_task(void *); static void axe_start(struct ifnet *); @@ -201,13 +201,13 @@ static void axe_miibus_writereg_locked(device_t, int, int, int); static void axe_miibus_writereg(device_t, int, int, int); static void axe_miibus_statchg(struct ifnet *); static int axe_cmd(struct axe_softc *, int, int, int, void *); -static void axe_reset(struct axe_softc *sc); +static void axe_reset(struct axe_softc *); static int axe_ifmedia_upd(struct ifnet *); static void axe_ifmedia_sts(struct ifnet *, struct ifmediareq *); static void axe_setmulti(struct axe_softc *); -static void axe_lock_mii(struct axe_softc *sc); -static void axe_unlock_mii(struct axe_softc *sc); +static void axe_lock_mii(struct axe_softc *); +static void axe_unlock_mii(struct axe_softc *); static void axe_ax88178_init(struct axe_softc *); static void axe_ax88772_init(struct axe_softc *); @@ -676,7 +676,7 @@ axe_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return axe_lookup(uaa->vendor, uaa->product) != NULL ? + return axe_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } @@ -689,7 +689,7 @@ axe_attach(device_t parent, device_t self, void *aux) { struct axe_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; + struct usbd_device *dev = uaa->uaa_device; usbd_status err; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; @@ -717,7 +717,7 @@ axe_attach(device_t parent, device_t self, void *aux) return; } - sc->axe_flags = axe_lookup(uaa->vendor, uaa->product)->axe_flags; + sc->axe_flags = axe_lookup(uaa->uaa_vendor, uaa->uaa_product)->axe_flags; mutex_init(&sc->axe_mii_lock, MUTEX_DEFAULT, IPL_NONE); usb_init_task(&sc->axe_tick_task, axe_tick_task, sc, 0); @@ -728,14 +728,14 @@ axe_attach(device_t parent, device_t self, void *aux) return; } - sc->axe_product = uaa->product; - sc->axe_vendor = uaa->vendor; + sc->axe_product = uaa->uaa_product; + sc->axe_vendor = uaa->uaa_vendor; id = usbd_get_interface_descriptor(sc->axe_iface); /* decide on what our bufsize will be */ if (sc->axe_flags & AX178 || sc->axe_flags & AX772) - sc->axe_bufsz = (sc->axe_udev->speed == USB_SPEED_HIGH) ? + sc->axe_bufsz = (sc->axe_udev->ud_speed == USB_SPEED_HIGH) ? AXE_178_MAX_BUFSZ : AXE_178_MIN_BUFSZ; else sc->axe_bufsz = AXE_172_BUFSZ; @@ -945,15 +945,11 @@ axe_rx_list_init(struct axe_softc *sc) c->axe_sc = sc; c->axe_idx = i; if (c->axe_xfer == NULL) { - c->axe_xfer = usbd_alloc_xfer(sc->axe_udev); - if (c->axe_xfer == NULL) - return ENOBUFS; - c->axe_buf = usbd_alloc_buffer(c->axe_xfer, - sc->axe_bufsz); - if (c->axe_buf == NULL) { - usbd_free_xfer(c->axe_xfer); - return ENOBUFS; - } + int err = usbd_create_xfer(sc->axe_ep[AXE_ENDPT_RX], + sc->axe_bufsz, USBD_SHORT_XFER_OK, 0, &c->axe_xfer); + if (err) + return err; + c->axe_buf = usbd_get_buffer(c->axe_xfer); } } @@ -975,15 +971,12 @@ axe_tx_list_init(struct axe_softc *sc) c->axe_sc = sc; c->axe_idx = i; if (c->axe_xfer == NULL) { - c->axe_xfer = usbd_alloc_xfer(sc->axe_udev); - if (c->axe_xfer == NULL) - return ENOBUFS; - c->axe_buf = usbd_alloc_buffer(c->axe_xfer, - sc->axe_bufsz); - if (c->axe_buf == NULL) { - usbd_free_xfer(c->axe_xfer); - return ENOBUFS; - } + int err = usbd_create_xfer(sc->axe_ep[AXE_ENDPT_TX], + sc->axe_bufsz, USBD_FORCE_SHORT_XFER, 0, + &c->axe_xfer); + if (err) + return err; + c->axe_buf = usbd_get_buffer(c->axe_xfer); } } @@ -995,7 +988,7 @@ axe_tx_list_init(struct axe_softc *sc) * the higher level protocols. */ static void -axe_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +axe_rxeof(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct axe_softc *sc; struct axe_chain *c; @@ -1104,10 +1097,8 @@ axe_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) done: /* Setup new transfer. */ - usbd_setup_xfer(xfer, sc->axe_ep[AXE_ENDPT_RX], - c, c->axe_buf, sc->axe_bufsz, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, axe_rxeof); + usbd_setup_xfer(xfer, c, c->axe_buf, sc->axe_bufsz, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, axe_rxeof); usbd_transfer(xfer); DPRINTFN(10,("%s: %s: start rx\n", device_xname(sc->axe_dev), __func__)); @@ -1119,7 +1110,7 @@ axe_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) */ static void -axe_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +axe_txeof(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct axe_softc *sc; struct axe_chain *c; @@ -1232,7 +1223,7 @@ axe_encap(struct axe_softc *sc, struct mbuf *m, int idx) * bytes at the beginning to hold the frame length. */ if (sc->axe_flags & AX178 || sc->axe_flags & AX772) { - boundary = (sc->axe_udev->speed == USB_SPEED_HIGH) ? 512 : 64; + boundary = (sc->axe_udev->ud_speed == USB_SPEED_HIGH) ? 512 : 64; hdr.len = htole16(m->m_pkthdr.len); hdr.ilen = ~hdr.len; @@ -1254,9 +1245,8 @@ axe_encap(struct axe_softc *sc, struct mbuf *m, int idx) length = m->m_pkthdr.len; } - usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_TX], - c, c->axe_buf, length, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, 10000, - axe_txeof); + usbd_setup_xfer(c->axe_xfer, c, c->axe_buf, length, + USBD_FORCE_SHORT_XFER, 10000, axe_txeof); /* Transmit */ err = usbd_transfer(c->axe_xfer); @@ -1340,22 +1330,6 @@ axe_init(struct ifnet *ifp) axe_unlock_mii(sc); } - /* Enable RX logic. */ - - /* Init RX ring. */ - if (axe_rx_list_init(sc) == ENOBUFS) { - aprint_error_dev(sc->axe_dev, "rx list init failed\n"); - splx(s); - return ENOBUFS; - } - - /* Init TX ring. */ - if (axe_tx_list_init(sc) == ENOBUFS) { - aprint_error_dev(sc->axe_dev, "tx list init failed\n"); - splx(s); - return ENOBUFS; - } - /* Set transmitter IPG values */ axe_lock_mii(sc); if (sc->axe_flags & AX178 || sc->axe_flags & AX772) @@ -1372,7 +1346,7 @@ axe_init(struct ifnet *ifp) if (sc->axe_flags & AX772B) rxmode |= AXE_772B_RXCMD_RH1M; else if (sc->axe_flags & AX178 || sc->axe_flags & AX772) { - if (sc->axe_udev->speed == USB_SPEED_HIGH) { + if (sc->axe_udev->ud_speed == USB_SPEED_HIGH) { /* Largest possible USB buffer size for AX88178 */ rxmode |= AXE_178_RXCMD_MFB; } @@ -1411,13 +1385,25 @@ axe_init(struct ifnet *ifp) return EIO; } + /* Init RX ring. */ + if (axe_rx_list_init(sc) != 0) { + aprint_error_dev(sc->axe_dev, "rx list init failed\n"); + splx(s); + return ENOBUFS; + } + + /* Init TX ring. */ + if (axe_tx_list_init(sc) != 0) { + aprint_error_dev(sc->axe_dev, "tx list init failed\n"); + splx(s); + return ENOBUFS; + } + /* Start up the receive pipe. */ for (i = 0; i < AXE_RX_LIST_CNT; i++) { c = &sc->axe_cdata.axe_rx_chain[i]; - usbd_setup_xfer(c->axe_xfer, sc->axe_ep[AXE_ENDPT_RX], - c, c->axe_buf, sc->axe_bufsz, - USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, - axe_rxeof); + usbd_setup_xfer(c->axe_xfer, c, c->axe_buf, sc->axe_bufsz, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, axe_rxeof); usbd_transfer(c->axe_xfer); } @@ -1524,12 +1510,6 @@ axe_stop(struct ifnet *ifp, int disable) aprint_error_dev(sc->axe_dev, "abort rx pipe failed: %s\n", usbd_errstr(err)); } - err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_RX]); - if (err) { - aprint_error_dev(sc->axe_dev, - "close rx pipe failed: %s\n", usbd_errstr(err)); - } - sc->axe_ep[AXE_ENDPT_RX] = NULL; } if (sc->axe_ep[AXE_ENDPT_TX] != NULL) { @@ -1538,12 +1518,6 @@ axe_stop(struct ifnet *ifp, int disable) aprint_error_dev(sc->axe_dev, "abort tx pipe failed: %s\n", usbd_errstr(err)); } - err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_TX]); - if (err) { - aprint_error_dev(sc->axe_dev, - "close tx pipe failed: %s\n", usbd_errstr(err)); - } - sc->axe_ep[AXE_ENDPT_TX] = NULL; } if (sc->axe_ep[AXE_ENDPT_INTR] != NULL) { @@ -1552,18 +1526,12 @@ axe_stop(struct ifnet *ifp, int disable) aprint_error_dev(sc->axe_dev, "abort intr pipe failed: %s\n", usbd_errstr(err)); } - err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_INTR]); - if (err) { - aprint_error_dev(sc->axe_dev, - "close intr pipe failed: %s\n", usbd_errstr(err)); - } - sc->axe_ep[AXE_ENDPT_INTR] = NULL; } /* Free RX resources. */ for (i = 0; i < AXE_RX_LIST_CNT; i++) { if (sc->axe_cdata.axe_rx_chain[i].axe_xfer != NULL) { - usbd_free_xfer(sc->axe_cdata.axe_rx_chain[i].axe_xfer); + usbd_destroy_xfer(sc->axe_cdata.axe_rx_chain[i].axe_xfer); sc->axe_cdata.axe_rx_chain[i].axe_xfer = NULL; } } @@ -1571,11 +1539,39 @@ axe_stop(struct ifnet *ifp, int disable) /* Free TX resources. */ for (i = 0; i < AXE_TX_LIST_CNT; i++) { if (sc->axe_cdata.axe_tx_chain[i].axe_xfer != NULL) { - usbd_free_xfer(sc->axe_cdata.axe_tx_chain[i].axe_xfer); + usbd_destroy_xfer(sc->axe_cdata.axe_tx_chain[i].axe_xfer); sc->axe_cdata.axe_tx_chain[i].axe_xfer = NULL; } } + /* Close pipes. */ + if (sc->axe_ep[AXE_ENDPT_RX] != NULL) { + err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_RX]); + if (err) { + aprint_error_dev(sc->axe_dev, + "close rx pipe failed: %s\n", usbd_errstr(err)); + } + sc->axe_ep[AXE_ENDPT_RX] = NULL; + } + + if (sc->axe_ep[AXE_ENDPT_TX] != NULL) { + err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_TX]); + if (err) { + aprint_error_dev(sc->axe_dev, + "close tx pipe failed: %s\n", usbd_errstr(err)); + } + sc->axe_ep[AXE_ENDPT_TX] = NULL; + } + + if (sc->axe_ep[AXE_ENDPT_INTR] != NULL) { + err = usbd_close_pipe(sc->axe_ep[AXE_ENDPT_INTR]); + if (err) { + aprint_error_dev(sc->axe_dev, + "close intr pipe failed: %s\n", usbd_errstr(err)); + } + sc->axe_ep[AXE_ENDPT_INTR] = NULL; + } + sc->axe_link = 0; } diff --git a/sys/dev/usb/if_axen.c b/sys/dev/usb/if_axen.c index 53073dba68f..16656410aa8 100644 --- a/sys/dev/usb/if_axen.c +++ b/sys/dev/usb/if_axen.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_axen.c,v 1.7 2016/02/09 08:32:12 ozaki-r Exp $ */ +/* $NetBSD: if_axen.c,v 1.8 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_axen.c,v 1.3 2013/10/21 10:10:22 yuo Exp $ */ /* @@ -19,11 +19,11 @@ /* * ASIX Electronics AX88178a USB 2.0 ethernet and AX88179 USB 3.0 Ethernet - * driver. + * driver. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_axen.c,v 1.7 2016/02/09 08:32:12 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_axen.c,v 1.8 2016/04/23 10:15:31 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -95,8 +95,8 @@ static int axen_tx_list_init(struct axen_softc *); static int axen_rx_list_init(struct axen_softc *); static struct mbuf *axen_newbuf(void); static int axen_encap(struct axen_softc *, struct mbuf *, int); -static void axen_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void axen_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +static void axen_rxeof(struct usbd_xfer *, void *, usbd_status); +static void axen_txeof(struct usbd_xfer *, void *, usbd_status); static void axen_tick(void *); static void axen_tick_task(void *); static void axen_start(struct ifnet *); @@ -110,14 +110,14 @@ static void axen_miibus_statchg(struct ifnet *); static int axen_cmd(struct axen_softc *, int, int, int, void *); static int axen_ifmedia_upd(struct ifnet *); static void axen_ifmedia_sts(struct ifnet *, struct ifmediareq *); -static void axen_reset(struct axen_softc *sc); +static void axen_reset(struct axen_softc *); #if 0 static int axen_ax88179_eeprom(struct axen_softc *, void *); #endif static void axen_iff(struct axen_softc *); -static void axen_lock_mii(struct axen_softc *sc); -static void axen_unlock_mii(struct axen_softc *sc); +static void axen_lock_mii(struct axen_softc *); +static void axen_unlock_mii(struct axen_softc *); static void axen_ax88179_init(struct axen_softc *); @@ -433,7 +433,7 @@ axen_ax88179_eeprom(struct axen_softc *sc, void *addr) } while ((le16toh(buf) & 0xff) & AXEN_EEPROM_BUSY); /* read data */ - axen_cmd(sc, AXEN_CMD_MAC_READ2, 2, AXEN_EEPROM_READ, + axen_cmd(sc, AXEN_CMD_MAC_READ2, 2, AXEN_EEPROM_READ, &eeprom[i * 2]); /* sanity check */ @@ -635,7 +635,7 @@ axen_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return axen_lookup(uaa->vendor, uaa->product) != NULL ? + return axen_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } @@ -644,7 +644,7 @@ axen_attach(device_t parent, device_t self, void *aux) { struct axen_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - struct usbd_device *dev = uaa->device; + struct usbd_device *dev = uaa->uaa_device; usbd_status err; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; @@ -672,7 +672,7 @@ axen_attach(device_t parent, device_t self, void *aux) return; } - sc->axen_flags = axen_lookup(uaa->vendor, uaa->product)->axen_flags; + sc->axen_flags = axen_lookup(uaa->uaa_vendor, uaa->uaa_product)->axen_flags; rw_init(&sc->axen_mii_lock); usb_init_task(&sc->axen_tick_task, axen_tick_task, sc, 0); @@ -683,13 +683,13 @@ axen_attach(device_t parent, device_t self, void *aux) return; } - sc->axen_product = uaa->product; - sc->axen_vendor = uaa->vendor; + sc->axen_product = uaa->uaa_product; + sc->axen_vendor = uaa->uaa_vendor; id = usbd_get_interface_descriptor(sc->axen_iface); /* decide on what our bufsize will be */ - switch (sc->axen_udev->speed) { + switch (sc->axen_udev->ud_speed) { case USB_SPEED_SUPER: sc->axen_bufsz = AXEN_BUFSZ_SS * 1024; break; @@ -919,15 +919,12 @@ axen_rx_list_init(struct axen_softc *sc) c->axen_sc = sc; c->axen_idx = i; if (c->axen_xfer == NULL) { - c->axen_xfer = usbd_alloc_xfer(sc->axen_udev); - if (c->axen_xfer == NULL) - return ENOBUFS; - c->axen_buf = usbd_alloc_buffer(c->axen_xfer, - sc->axen_bufsz); - if (c->axen_buf == NULL) { - usbd_free_xfer(c->axen_xfer); - return ENOBUFS; - } + int err = usbd_create_xfer(sc->axen_ep[AXEN_ENDPT_RX], + sc->axen_bufsz, USBD_SHORT_XFER_OK, 0, + &c->axen_xfer); + if (err) + return err; + c->axen_buf = usbd_get_buffer(c->axen_xfer); } } @@ -949,15 +946,12 @@ axen_tx_list_init(struct axen_softc *sc) c->axen_sc = sc; c->axen_idx = i; if (c->axen_xfer == NULL) { - c->axen_xfer = usbd_alloc_xfer(sc->axen_udev); - if (c->axen_xfer == NULL) - return ENOBUFS; - c->axen_buf = usbd_alloc_buffer(c->axen_xfer, - sc->axen_bufsz); - if (c->axen_buf == NULL) { - usbd_free_xfer(c->axen_xfer); - return ENOBUFS; - } + int err = usbd_create_xfer(sc->axen_ep[AXEN_ENDPT_TX], + sc->axen_bufsz, USBD_FORCE_SHORT_XFER, 0, + &c->axen_xfer); + if (err) + return err; + c->axen_buf = usbd_get_buffer(c->axen_xfer); } } @@ -969,7 +963,7 @@ axen_tx_list_init(struct axen_softc *sc) * the higher level protocols. */ static void -axen_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +axen_rxeof(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct axen_chain *c = (struct axen_chain *)priv; struct axen_softc *sc = c->axen_sc; @@ -1011,7 +1005,7 @@ axen_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) goto done; } - /* + /* * buffer map * [packet #0]...[packet #n][pkt hdr#0]..[pkt hdr#n][recv_hdr] * each packet has 0xeeee as psuedo header.. @@ -1025,7 +1019,7 @@ axen_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) aprint_error_dev(sc->axen_dev, "rxeof: too large transfer\n"); goto done; } - + /* sanity check */ if (hdr_offset > total_len) { ifp->if_ierrors++; @@ -1042,9 +1036,9 @@ axen_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) */ #if 1 /* XXX: paranoiac check. need to remove later */ -#define AXEN_MAX_PACKED_PACKET 200 +#define AXEN_MAX_PACKED_PACKET 200 if (pkt_count > AXEN_MAX_PACKED_PACKET) { - DPRINTF(("%s: Too many packets (%d) in a transaction, discard.\n", + DPRINTF(("%s: Too many packets (%d) in a transaction, discard.\n", device_xname(sc->axen_dev), pkt_count)); goto done; } @@ -1061,7 +1055,7 @@ axen_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) pkt_hdr = le32toh(*hdr_p); pkt_len = (pkt_hdr >> 16) & 0x1fff; DPRINTFN(10, - ("%s: rxeof: packet#%d, pkt_hdr 0x%08x, pkt_len %zu\n", + ("%s: rxeof: packet#%d, pkt_hdr 0x%08x, pkt_len %zu\n", device_xname(sc->axen_dev), pkt_count, pkt_hdr, pkt_len)); if ((pkt_hdr & AXEN_RXHDR_CRC_ERR) || @@ -1088,7 +1082,7 @@ axen_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) #ifdef AXEN_TOE /* cheksum err */ - if ((pkt_hdr & AXEN_RXHDR_L3CSUM_ERR) || + if ((pkt_hdr & AXEN_RXHDR_L3CSUM_ERR) || (pkt_hdr & AXEN_RXHDR_L4CSUM_ERR)) { aprint_error_dev(sc->axen_dev, "checksum err (pkt#%d)\n", pkt_count); @@ -1097,7 +1091,7 @@ axen_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) m->m_pkthdr.csum_flags |= M_CSUM_IPv4; } - int l4_type = (pkt_hdr & AXEN_RXHDR_L4_TYPE_MASK) >> + int l4_type = (pkt_hdr & AXEN_RXHDR_L4_TYPE_MASK) >> AXEN_RXHDR_L4_TYPE_OFFSET; if ((l4_type == AXEN_RXHDR_L4_TYPE_TCP) || @@ -1117,7 +1111,7 @@ axen_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) nextpkt: /* - * prepare next packet + * prepare next packet * as each packet will be aligned 8byte boundary, * need to fix up the start point of the buffer. */ @@ -1132,10 +1126,8 @@ done: memset(c->axen_buf, 0, sc->axen_bufsz); /* Setup new transfer. */ - usbd_setup_xfer(xfer, sc->axen_ep[AXEN_ENDPT_RX], - c, c->axen_buf, sc->axen_bufsz, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, axen_rxeof); + usbd_setup_xfer(xfer, c, c->axen_buf, sc->axen_bufsz, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, axen_rxeof); usbd_transfer(xfer); DPRINTFN(10,("%s: %s: start rx\n",device_xname(sc->axen_dev),__func__)); @@ -1146,7 +1138,7 @@ done: * the list buffers. */ static void -axen_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +axen_txeof(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct axen_chain *c = (struct axen_chain *)priv; struct axen_softc *sc = c->axen_sc; @@ -1249,7 +1241,7 @@ axen_encap(struct axen_softc *sc, struct mbuf *m, int idx) c = &sc->axen_cdata.axen_tx_chain[idx]; - boundary = (sc->axen_udev->speed == USB_SPEED_HIGH) ? 512 : 64; + boundary = (sc->axen_udev->ud_speed == USB_SPEED_HIGH) ? 512 : 64; hdr.plen = htole32(m->m_pkthdr.len); hdr.gso = 0; /* disable segmentation offloading */ @@ -1267,9 +1259,8 @@ axen_encap(struct axen_softc *sc, struct mbuf *m, int idx) length += sizeof(hdr); } - usbd_setup_xfer(c->axen_xfer, sc->axen_ep[AXEN_ENDPT_TX], - c, c->axen_buf, length, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - 10000, axen_txeof); + usbd_setup_xfer(c->axen_xfer, c, c->axen_buf, length, + USBD_FORCE_SHORT_XFER, 10000, axen_txeof); /* Transmit */ err = usbd_transfer(c->axen_xfer); @@ -1349,22 +1340,6 @@ axen_init(struct ifnet *ifp) axen_cmd(sc, AXEN_CMD_MAC_WRITE, 1, AXEN_UNK_28, &bval); axen_unlock_mii(sc); - /* Init RX ring. */ - if (axen_rx_list_init(sc) == ENOBUFS) { - aprint_error_dev(sc->axen_dev, "rx list init failed\n"); - axen_unlock_mii(sc); - splx(s); - return ENOBUFS; - } - - /* Init TX ring. */ - if (axen_tx_list_init(sc) == ENOBUFS) { - aprint_error_dev(sc->axen_dev, "tx list init failed\n"); - axen_unlock_mii(sc); - splx(s); - return ENOBUFS; - } - /* Program promiscuous mode and multicast filters. */ axen_iff(sc); @@ -1396,13 +1371,26 @@ axen_init(struct ifnet *ifp) return EIO; } + /* Init RX ring. */ + if (axen_rx_list_init(sc)) { + aprint_error_dev(sc->axen_dev, "rx list init failed\n"); + splx(s); + return ENOBUFS; + } + + /* Init TX ring. */ + if (axen_tx_list_init(sc)) { + aprint_error_dev(sc->axen_dev, "tx list init failed\n"); + splx(s); + return ENOBUFS; + } + /* Start up the receive pipe. */ for (i = 0; i < AXEN_RX_LIST_CNT; i++) { c = &sc->axen_cdata.axen_rx_chain[i]; - usbd_setup_xfer(c->axen_xfer, sc->axen_ep[AXEN_ENDPT_RX], - c, c->axen_buf, sc->axen_bufsz, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, axen_rxeof); + + usbd_setup_xfer(c->axen_xfer, c, c->axen_buf, sc->axen_bufsz, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, axen_rxeof); usbd_transfer(c->axen_xfer); } @@ -1510,12 +1498,6 @@ axen_stop(struct ifnet *ifp, int disable) "abort rx pipe failed: %s\n", usbd_errstr(err)); } - err = usbd_close_pipe(sc->axen_ep[AXEN_ENDPT_RX]); - if (err) { - aprint_error_dev(sc->axen_dev, - "close rx pipe failed: %s\n", usbd_errstr(err)); - } - sc->axen_ep[AXEN_ENDPT_RX] = NULL; } if (sc->axen_ep[AXEN_ENDPT_TX] != NULL) { @@ -1524,12 +1506,6 @@ axen_stop(struct ifnet *ifp, int disable) aprint_error_dev(sc->axen_dev, "abort tx pipe failed: %s\n", usbd_errstr(err)); } - err = usbd_close_pipe(sc->axen_ep[AXEN_ENDPT_TX]); - if (err) { - aprint_error_dev(sc->axen_dev, - "close tx pipe failed: %s\n", usbd_errstr(err)); - } - sc->axen_ep[AXEN_ENDPT_TX] = NULL; } if (sc->axen_ep[AXEN_ENDPT_INTR] != NULL) { @@ -1538,18 +1514,12 @@ axen_stop(struct ifnet *ifp, int disable) aprint_error_dev(sc->axen_dev, "abort intr pipe failed: %s\n", usbd_errstr(err)); } - err = usbd_close_pipe(sc->axen_ep[AXEN_ENDPT_INTR]); - if (err) { - aprint_error_dev(sc->axen_dev, - "close intr pipe failed: %s\n", usbd_errstr(err)); - } - sc->axen_ep[AXEN_ENDPT_INTR] = NULL; } /* Free RX resources. */ for (i = 0; i < AXEN_RX_LIST_CNT; i++) { if (sc->axen_cdata.axen_rx_chain[i].axen_xfer != NULL) { - usbd_free_xfer(sc->axen_cdata.axen_rx_chain[i].axen_xfer); + usbd_destroy_xfer(sc->axen_cdata.axen_rx_chain[i].axen_xfer); sc->axen_cdata.axen_rx_chain[i].axen_xfer = NULL; } } @@ -1557,11 +1527,39 @@ axen_stop(struct ifnet *ifp, int disable) /* Free TX resources. */ for (i = 0; i < AXEN_TX_LIST_CNT; i++) { if (sc->axen_cdata.axen_tx_chain[i].axen_xfer != NULL) { - usbd_free_xfer(sc->axen_cdata.axen_tx_chain[i].axen_xfer); + usbd_destroy_xfer(sc->axen_cdata.axen_tx_chain[i].axen_xfer); sc->axen_cdata.axen_tx_chain[i].axen_xfer = NULL; } } + /* Close pipes. */ + if (sc->axen_ep[AXEN_ENDPT_RX] != NULL) { + err = usbd_close_pipe(sc->axen_ep[AXEN_ENDPT_RX]); + if (err) { + aprint_error_dev(sc->axen_dev, + "close rx pipe failed: %s\n", usbd_errstr(err)); + } + sc->axen_ep[AXEN_ENDPT_RX] = NULL; + } + + if (sc->axen_ep[AXEN_ENDPT_TX] != NULL) { + err = usbd_close_pipe(sc->axen_ep[AXEN_ENDPT_TX]); + if (err) { + aprint_error_dev(sc->axen_dev, + "close tx pipe failed: %s\n", usbd_errstr(err)); + } + sc->axen_ep[AXEN_ENDPT_TX] = NULL; + } + + if (sc->axen_ep[AXEN_ENDPT_INTR] != NULL) { + err = usbd_close_pipe(sc->axen_ep[AXEN_ENDPT_INTR]); + if (err) { + aprint_error_dev(sc->axen_dev, + "close intr pipe failed: %s\n", usbd_errstr(err)); + } + sc->axen_ep[AXEN_ENDPT_INTR] = NULL; + } + sc->axen_link = 0; } diff --git a/sys/dev/usb/if_axenreg.h b/sys/dev/usb/if_axenreg.h index 891ab84a32a..7700bba55f2 100644 --- a/sys/dev/usb/if_axenreg.h +++ b/sys/dev/usb/if_axenreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_axenreg.h,v 1.2 2015/04/14 20:32:36 riastradh Exp $ */ +/* $NetBSD: if_axenreg.h,v 1.3 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_axenreg.h,v 1.1 2013/10/07 05:37:41 yuo Exp $ */ /* @@ -24,7 +24,7 @@ /* recieve header */ -/* +/* * +-multicast/broadcast * | +-rx_ok * | | ++-----L3_type (1:ipv4, 0/2:ipv6) @@ -86,7 +86,7 @@ #define AXEN_CMD_CMD(x) ((x) & 0x00FF) /* ---MAC--- */ -/* 1byte cmd */ +/* 1byte cmd */ #define AXEN_CMD_MAC_READ 0x1001 #define AXEN_CMD_MAC_WRITE 0x1101 @@ -143,7 +143,7 @@ #define AXEN_PAUSE_LOW_WATERMARK 0x55 -/* 2byte cmd */ +/* 2byte cmd */ #define AXEN_CMD_MAC_READ2 0x2001 #define AXEN_CMD_MAC_WRITE2 0x2101 @@ -151,7 +151,7 @@ #define AXEN_RXCTL_STOP 0x0000 #define AXEN_RXCTL_PROMISC 0x0001 #define AXEN_RXCTL_ACPT_ALL_MCAST 0x0002 -#define AXEN_RXCTL_HA8B 0x0004 +#define AXEN_RXCTL_HA8B 0x0004 #define AXEN_RXCTL_AUTOB 0x0008 #define AXEN_RXCTL_ACPT_BCAST 0x0010 #define AXEN_RXCTL_ACPT_PHY_MCAST 0x0020 @@ -178,21 +178,21 @@ #define AXEN_CMD_EEPROM_READ 0x2004 #define AXEN_EEPROM_STAT 0x43 -/* 5byte cmd */ +/* 5byte cmd */ #define AXEN_CMD_MAC_SET_RXSR 0x5101 #define AXEN_RX_BULKIN_QCTRL 0x2e -/* 6byte cmd */ +/* 6byte cmd */ #define AXEN_CMD_MAC_READ_ETHER 0x6001 #define AXEN_CMD_MAC_NODE_ID 0x10 -/* 8byte cmd */ +/* 8byte cmd */ #define AXEN_CMD_MAC_READ_FILTER 0x8001 #define AXEN_CMD_MAC_WRITE_FILTER 0x8101 #define AXEN_FILTER_MULTI 0x16 /* ---PHY--- */ -/* 2byte cmd */ +/* 2byte cmd */ #define AXEN_CMD_MII_READ_REG 0x2002 #define AXEN_CMD_MII_WRITE_REG 0x2102 @@ -270,8 +270,8 @@ struct axen_softc { struct ethercom axen_ec; struct mii_data axen_mii; krndsource_t rnd_source; - usbd_device_handle axen_udev; - usbd_interface_handle axen_iface; + struct usbd_device * axen_udev; + struct usbd_interface * axen_iface; uint16_t axen_vendor; uint16_t axen_product; diff --git a/sys/dev/usb/if_axereg.h b/sys/dev/usb/if_axereg.h index 903bd4cc081..9c3b450457e 100644 --- a/sys/dev/usb/if_axereg.h +++ b/sys/dev/usb/if_axereg.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_axereg.h,v 1.17 2015/04/14 20:32:36 riastradh Exp $ */ +/* $NetBSD: if_axereg.h,v 1.18 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000-2003 @@ -220,7 +220,7 @@ struct axe_softc; struct axe_chain { struct axe_softc *axe_sc; - usbd_xfer_handle axe_xfer; + struct usbd_xfer *axe_xfer; uint8_t *axe_buf; int axe_accum; int axe_idx; @@ -245,15 +245,15 @@ struct axe_softc { struct ethercom axe_ec; struct mii_data axe_mii; krndsource_t rnd_source; - usbd_device_handle axe_udev; - usbd_interface_handle axe_iface; + struct usbd_device * axe_udev; + struct usbd_interface * axe_iface; uint16_t axe_vendor; uint16_t axe_product; uint16_t axe_flags; int axe_ed[AXE_ENDPT_MAX]; - usbd_pipe_handle axe_ep[AXE_ENDPT_MAX]; + struct usbd_pipe * axe_ep[AXE_ENDPT_MAX]; int axe_if_flags; struct axe_cdata axe_cdata; struct callout axe_stat_ch; diff --git a/sys/dev/usb/if_cdce.c b/sys/dev/usb/if_cdce.c index a0f7903d1a6..1aac5f2eeac 100644 --- a/sys/dev/usb/if_cdce.c +++ b/sys/dev/usb/if_cdce.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_cdce.c,v 1.40 2016/02/09 08:32:12 ozaki-r Exp $ */ +/* $NetBSD: if_cdce.c,v 1.41 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wpaul@windriver.com> @@ -41,7 +41,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_cdce.c,v 1.40 2016/02/09 08:32:12 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_cdce.c,v 1.41 2016/04/23 10:15:31 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -83,8 +83,8 @@ Static int cdce_rx_list_init(struct cdce_softc *); Static int cdce_newbuf(struct cdce_softc *, struct cdce_chain *, struct mbuf *); Static int cdce_encap(struct cdce_softc *, struct mbuf *, int); -Static void cdce_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -Static void cdce_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void cdce_rxeof(struct usbd_xfer *, void *, usbd_status); +Static void cdce_txeof(struct usbd_xfer *, void *, usbd_status); Static void cdce_start(struct ifnet *); Static int cdce_ioctl(struct ifnet *, u_long, void *); Static void cdce_init(void *); @@ -118,27 +118,27 @@ CFATTACH_DECL_NEW(cdce, sizeof(struct cdce_softc), cdce_match, cdce_attach, int cdce_match(device_t parent, cfdata_t match, void *aux) { - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; - if (cdce_lookup(uaa->vendor, uaa->product) != NULL) - return (UMATCH_VENDOR_PRODUCT); + if (cdce_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product) != NULL) + return UMATCH_VENDOR_PRODUCT; - if (uaa->class == UICLASS_CDC && uaa->subclass == + if (uiaa->uiaa_class == UICLASS_CDC && uiaa->uiaa_subclass == UISUBCLASS_ETHERNET_NETWORKING_CONTROL_MODEL) - return (UMATCH_IFACECLASS_GENERIC); + return UMATCH_IFACECLASS_GENERIC; - return (UMATCH_NONE); + return UMATCH_NONE; } void cdce_attach(device_t parent, device_t self, void *aux) { struct cdce_softc *sc = device_private(self); - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; char *devinfop; int s; struct ifnet *ifp; - usbd_device_handle dev = uaa->device; + struct usbd_device *dev = uiaa->uiaa_device; const struct cdce_type *t; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; @@ -159,10 +159,10 @@ cdce_attach(device_t parent, device_t self, void *aux) aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); - sc->cdce_udev = uaa->device; - sc->cdce_ctl_iface = uaa->iface; + sc->cdce_udev = uiaa->uiaa_device; + sc->cdce_ctl_iface = uiaa->uiaa_iface; - t = cdce_lookup(uaa->vendor, uaa->product); + t = cdce_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product); if (t) sc->cdce_flags = t->cdce_flags; @@ -177,14 +177,14 @@ cdce_attach(device_t parent, device_t self, void *aux) } data_ifcno = ud->bSlaveInterface[0]; - for (i = 0; i < uaa->nifaces; i++) { - if (uaa->ifaces[i] != NULL) { + for (i = 0; i < uiaa->uiaa_nifaces; i++) { + if (uiaa->uiaa_ifaces[i] != NULL) { id = usbd_get_interface_descriptor( - uaa->ifaces[i]); + uiaa->uiaa_ifaces[i]); if (id != NULL && id->bInterfaceNumber == data_ifcno) { - sc->cdce_data_iface = uaa->ifaces[i]; - uaa->ifaces[i] = NULL; + sc->cdce_data_iface = uiaa->uiaa_ifaces[i]; + uiaa->uiaa_ifaces[i] = NULL; } } } @@ -313,7 +313,7 @@ cdce_detach(device_t self, int flags) if (!sc->cdce_attached) { splx(s); - return (0); + return 0; } if (ifp->if_flags & IFF_RUNNING) @@ -326,7 +326,7 @@ cdce_detach(device_t self, int flags) sc->cdce_attached = 0; splx(s); - return (0); + return 0; } Static void @@ -376,18 +376,17 @@ cdce_encap(struct cdce_softc *sc, struct mbuf *m, int idx) } c->cdce_mbuf = m; - usbd_setup_xfer(c->cdce_xfer, sc->cdce_bulkout_pipe, c, c->cdce_buf, - m->m_pkthdr.len + extra, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - 10000, cdce_txeof); + usbd_setup_xfer(c->cdce_xfer, c, c->cdce_buf, m->m_pkthdr.len + extra, + USBD_FORCE_SHORT_XFER, 10000, cdce_txeof); err = usbd_transfer(c->cdce_xfer); if (err != USBD_IN_PROGRESS) { cdce_stop(sc); - return (EIO); + return EIO; } sc->cdce_cdata.cdce_tx_cnt++; - return (0); + return 0; } Static void @@ -404,11 +403,6 @@ cdce_stop(struct cdce_softc *sc) if (err) printf("%s: abort rx pipe failed: %s\n", device_xname(sc->cdce_dev), usbd_errstr(err)); - err = usbd_close_pipe(sc->cdce_bulkin_pipe); - if (err) - printf("%s: close rx pipe failed: %s\n", - device_xname(sc->cdce_dev), usbd_errstr(err)); - sc->cdce_bulkin_pipe = NULL; } if (sc->cdce_bulkout_pipe != NULL) { @@ -416,11 +410,6 @@ cdce_stop(struct cdce_softc *sc) if (err) printf("%s: abort tx pipe failed: %s\n", device_xname(sc->cdce_dev), usbd_errstr(err)); - err = usbd_close_pipe(sc->cdce_bulkout_pipe); - if (err) - printf("%s: close tx pipe failed: %s\n", - device_xname(sc->cdce_dev), usbd_errstr(err)); - sc->cdce_bulkout_pipe = NULL; } for (i = 0; i < CDCE_RX_LIST_CNT; i++) { @@ -429,7 +418,7 @@ cdce_stop(struct cdce_softc *sc) sc->cdce_cdata.cdce_rx_chain[i].cdce_mbuf = NULL; } if (sc->cdce_cdata.cdce_rx_chain[i].cdce_xfer != NULL) { - usbd_free_xfer + usbd_destroy_xfer (sc->cdce_cdata.cdce_rx_chain[i].cdce_xfer); sc->cdce_cdata.cdce_rx_chain[i].cdce_xfer = NULL; } @@ -441,12 +430,28 @@ cdce_stop(struct cdce_softc *sc) sc->cdce_cdata.cdce_tx_chain[i].cdce_mbuf = NULL; } if (sc->cdce_cdata.cdce_tx_chain[i].cdce_xfer != NULL) { - usbd_free_xfer( + usbd_destroy_xfer( sc->cdce_cdata.cdce_tx_chain[i].cdce_xfer); sc->cdce_cdata.cdce_tx_chain[i].cdce_xfer = NULL; } } + if (sc->cdce_bulkin_pipe != NULL) { + err = usbd_close_pipe(sc->cdce_bulkin_pipe); + if (err) + printf("%s: close rx pipe failed: %s\n", + device_xname(sc->cdce_dev), usbd_errstr(err)); + sc->cdce_bulkin_pipe = NULL; + } + + if (sc->cdce_bulkout_pipe != NULL) { + err = usbd_close_pipe(sc->cdce_bulkout_pipe); + if (err) + printf("%s: close tx pipe failed: %s\n", + device_xname(sc->cdce_dev), usbd_errstr(err)); + sc->cdce_bulkout_pipe = NULL; + } + ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); } @@ -459,7 +464,7 @@ cdce_ioctl(struct ifnet *ifp, u_long command, void *data) int s, error = 0; if (sc->cdce_dying) - return (EIO); + return EIO; s = splnet(); @@ -509,7 +514,7 @@ cdce_ioctl(struct ifnet *ifp, u_long command, void *data) if (error == ENETRESET) error = 0; - return (error); + return error; } Static void @@ -538,18 +543,6 @@ cdce_init(void *xsc) s = splnet(); - if (cdce_tx_list_init(sc) == ENOBUFS) { - printf("%s: tx list init failed\n", device_xname(sc->cdce_dev)); - splx(s); - return; - } - - if (cdce_rx_list_init(sc) == ENOBUFS) { - printf("%s: rx list init failed\n", device_xname(sc->cdce_dev)); - splx(s); - return; - } - /* Maybe set multicast / broadcast here??? */ err = usbd_open_pipe(sc->cdce_data_iface, sc->cdce_bulkin_no, @@ -570,11 +563,23 @@ cdce_init(void *xsc) return; } + if (cdce_tx_list_init(sc)) { + printf("%s: tx list init failed\n", device_xname(sc->cdce_dev)); + splx(s); + return; + } + + if (cdce_rx_list_init(sc)) { + printf("%s: rx list init failed\n", device_xname(sc->cdce_dev)); + splx(s); + return; + } + for (i = 0; i < CDCE_RX_LIST_CNT; i++) { c = &sc->cdce_cdata.cdce_rx_chain[i]; - usbd_setup_xfer(c->cdce_xfer, sc->cdce_bulkin_pipe, c, - c->cdce_buf, CDCE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, cdce_rxeof); + + usbd_setup_xfer(c->cdce_xfer, c, c->cdce_buf, CDCE_BUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, cdce_rxeof); usbd_transfer(c->cdce_xfer); } @@ -594,14 +599,14 @@ cdce_newbuf(struct cdce_softc *sc, struct cdce_chain *c, struct mbuf *m) if (m_new == NULL) { printf("%s: no memory for rx list " "-- packet dropped!\n", device_xname(sc->cdce_dev)); - return (ENOBUFS); + return ENOBUFS; } MCLGET(m_new, M_DONTWAIT); if (!(m_new->m_flags & M_EXT)) { printf("%s: no memory for rx list " "-- packet dropped!\n", device_xname(sc->cdce_dev)); m_freem(m_new); - return (ENOBUFS); + return ENOBUFS; } m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; } else { @@ -610,7 +615,7 @@ cdce_newbuf(struct cdce_softc *sc, struct cdce_chain *c, struct mbuf *m) m_new->m_data = m_new->m_ext.ext_buf; } c->cdce_mbuf = m_new; - return (0); + return 0; } Static int @@ -626,19 +631,17 @@ cdce_rx_list_init(struct cdce_softc *sc) c->cdce_sc = sc; c->cdce_idx = i; if (cdce_newbuf(sc, c, NULL) == ENOBUFS) - return (ENOBUFS); + return ENOBUFS; if (c->cdce_xfer == NULL) { - c->cdce_xfer = usbd_alloc_xfer(sc->cdce_udev); - if (c->cdce_xfer == NULL) - return (ENOBUFS); - c->cdce_buf = usbd_alloc_buffer(c->cdce_xfer, - CDCE_BUFSZ); - if (c->cdce_buf == NULL) - return (ENOBUFS); + int err = usbd_create_xfer(sc->cdce_bulkin_pipe, + CDCE_BUFSZ, USBD_SHORT_XFER_OK, 0, &c->cdce_xfer); + if (err) + return err; + c->cdce_buf = usbd_get_buffer(c->cdce_xfer); } } - return (0); + return 0; } Static int @@ -655,20 +658,20 @@ cdce_tx_list_init(struct cdce_softc *sc) c->cdce_idx = i; c->cdce_mbuf = NULL; if (c->cdce_xfer == NULL) { - c->cdce_xfer = usbd_alloc_xfer(sc->cdce_udev); - if (c->cdce_xfer == NULL) - return (ENOBUFS); - c->cdce_buf = usbd_alloc_buffer(c->cdce_xfer, CDCE_BUFSZ); - if (c->cdce_buf == NULL) - return (ENOBUFS); + int err = usbd_create_xfer(sc->cdce_bulkout_pipe, + CDCE_BUFSZ, USBD_FORCE_SHORT_XFER, 0, + &c->cdce_xfer); + if (err) + return err; + c->cdce_buf = usbd_get_buffer(c->cdce_xfer); } } - return (0); + return 0; } Static void -cdce_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +cdce_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct cdce_chain *c = priv; struct cdce_softc *sc = c->cdce_sc; @@ -729,14 +732,13 @@ done1: done: /* Setup new transfer. */ - usbd_setup_xfer(c->cdce_xfer, sc->cdce_bulkin_pipe, c, c->cdce_buf, - CDCE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, - cdce_rxeof); + usbd_setup_xfer(c->cdce_xfer, c, c->cdce_buf, CDCE_BUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, cdce_rxeof); usbd_transfer(c->cdce_xfer); } Static void -cdce_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, +cdce_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct cdce_chain *c = priv; diff --git a/sys/dev/usb/if_cdcereg.h b/sys/dev/usb/if_cdcereg.h index b4cb41a304b..8f511d0b224 100644 --- a/sys/dev/usb/if_cdcereg.h +++ b/sys/dev/usb/if_cdcereg.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_cdcereg.h,v 1.8 2015/04/13 16:34:43 riastradh Exp $ */ +/* $NetBSD: if_cdcereg.h,v 1.9 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000-2003 Bill Paul <wpaul@windriver.com> @@ -42,7 +42,7 @@ struct cdce_type { struct usb_devno cdce_dev; - u_int16_t cdce_flags; + uint16_t cdce_flags; #define CDCE_ZAURUS 1 #define CDCE_NO_UNION 2 }; @@ -51,7 +51,7 @@ struct cdce_softc; struct cdce_chain { struct cdce_softc *cdce_sc; - usbd_xfer_handle cdce_xfer; + struct usbd_xfer *cdce_xfer; char *cdce_buf; struct mbuf *cdce_mbuf; int cdce_accum; @@ -72,17 +72,17 @@ struct cdce_softc { struct ethercom cdce_ec; krndsource_t rnd_source; #define GET_IFP(sc) (&(sc)->cdce_ec.ec_if) - usbd_device_handle cdce_udev; - usbd_interface_handle cdce_ctl_iface; - usbd_interface_handle cdce_data_iface; + struct usbd_device * cdce_udev; + struct usbd_interface * cdce_ctl_iface; + struct usbd_interface * cdce_data_iface; int cdce_bulkin_no; - usbd_pipe_handle cdce_bulkin_pipe; + struct usbd_pipe * cdce_bulkin_pipe; int cdce_bulkout_no; - usbd_pipe_handle cdce_bulkout_pipe; + struct usbd_pipe * cdce_bulkout_pipe; char cdce_dying; int cdce_unit; struct cdce_cdata cdce_cdata; int cdce_rxeof_errors; - u_int16_t cdce_flags; + uint16_t cdce_flags; char cdce_attached; }; diff --git a/sys/dev/usb/if_cue.c b/sys/dev/usb/if_cue.c index 6fd48a31cc1..52849451db6 100644 --- a/sys/dev/usb/if_cue.c +++ b/sys/dev/usb/if_cue.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_cue.c,v 1.71 2016/02/09 08:32:12 ozaki-r Exp $ */ +/* $NetBSD: if_cue.c,v 1.72 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. @@ -56,7 +56,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_cue.c,v 1.71 2016/02/09 08:32:12 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_cue.c,v 1.72 2016/04/23 10:15:31 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -67,7 +67,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_cue.c,v 1.71 2016/02/09 08:32:12 ozaki-r Exp $"); #include <sys/callout.h> #include <sys/sockio.h> #include <sys/mbuf.h> -#include <sys/malloc.h> #include <sys/kernel.h> #include <sys/socket.h> #include <sys/bus.h> @@ -125,8 +124,8 @@ Static int cue_tx_list_init(struct cue_softc *); Static int cue_rx_list_init(struct cue_softc *); Static int cue_newbuf(struct cue_softc *, struct cue_chain *, struct mbuf *); Static int cue_send(struct cue_softc *, struct mbuf *, int); -Static void cue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -Static void cue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void cue_rxeof(struct usbd_xfer *, void *, usbd_status); +Static void cue_txeof(struct usbd_xfer *, void *, usbd_status); Static void cue_tick(void *); Static void cue_tick_task(void *); Static void cue_start(struct ifnet *); @@ -136,7 +135,7 @@ Static void cue_stop(struct cue_softc *); Static void cue_watchdog(struct ifnet *); Static void cue_setmulti(struct cue_softc *); -Static u_int32_t cue_crc(const char *); +Static uint32_t cue_crc(const char *); Static void cue_reset(struct cue_softc *); Static int cue_csr_read_1(struct cue_softc *, int); @@ -159,10 +158,10 @@ cue_csr_read_1(struct cue_softc *sc, int reg) { usb_device_request_t req; usbd_status err; - u_int8_t val = 0; + uint8_t val = 0; if (sc->cue_dying) - return (0); + return 0; req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = CUE_CMD_READREG; @@ -175,13 +174,13 @@ cue_csr_read_1(struct cue_softc *sc, int reg) if (err) { DPRINTF(("%s: cue_csr_read_1: reg=0x%x err=%s\n", device_xname(sc->cue_dev), reg, usbd_errstr(err))); - return (0); + return 0; } DPRINTFN(10,("%s: cue_csr_read_1 reg=0x%x val=0x%x\n", device_xname(sc->cue_dev), reg, val)); - return (val); + return val; } Static int @@ -192,7 +191,7 @@ cue_csr_read_2(struct cue_softc *sc, int reg) uWord val; if (sc->cue_dying) - return (0); + return 0; req.bmRequestType = UT_READ_VENDOR_DEVICE; req.bRequest = CUE_CMD_READREG; @@ -208,10 +207,10 @@ cue_csr_read_2(struct cue_softc *sc, int reg) if (err) { DPRINTF(("%s: cue_csr_read_2: reg=0x%x err=%s\n", device_xname(sc->cue_dev), reg, usbd_errstr(err))); - return (0); + return 0; } - return (UGETW(val)); + return UGETW(val); } Static int @@ -221,7 +220,7 @@ cue_csr_write_1(struct cue_softc *sc, int reg, int val) usbd_status err; if (sc->cue_dying) - return (0); + return 0; DPRINTFN(10,("%s: cue_csr_write_1 reg=0x%x val=0x%x\n", device_xname(sc->cue_dev), reg, val)); @@ -237,13 +236,13 @@ cue_csr_write_1(struct cue_softc *sc, int reg, int val) if (err) { DPRINTF(("%s: cue_csr_write_1: reg=0x%x err=%s\n", device_xname(sc->cue_dev), reg, usbd_errstr(err))); - return (-1); + return -1; } DPRINTFN(20,("%s: cue_csr_write_1, after reg=0x%x val=0x%x\n", device_xname(sc->cue_dev), reg, cue_csr_read_1(sc, reg))); - return (0); + return 0; } #if 0 @@ -256,7 +255,7 @@ cue_csr_write_2(struct cue_softc *sc, int reg, int aval) int s; if (sc->cue_dying) - return (0); + return 0; DPRINTFN(10,("%s: cue_csr_write_2 reg=0x%x val=0x%x\n", device_xname(sc->cue_dev), reg, aval)); @@ -273,10 +272,10 @@ cue_csr_write_2(struct cue_softc *sc, int reg, int aval) if (err) { DPRINTF(("%s: cue_csr_write_2: reg=0x%x err=%s\n", device_xname(sc->cue_dev), reg, usbd_errstr(err))); - return (-1); + return -1; } - return (0); + return 0; } #endif @@ -303,10 +302,10 @@ cue_mem(struct cue_softc *sc, int cmd, int addr, void *buf, int len) if (err) { DPRINTF(("%s: cue_csr_mem: addr=0x%x err=%s\n", device_xname(sc->cue_dev), addr, usbd_errstr(err))); - return (-1); + return -1; } - return (0); + return 0; } Static int @@ -328,19 +327,19 @@ cue_getmac(struct cue_softc *sc, void *buf) if (err) { printf("%s: read MAC address failed\n", device_xname(sc->cue_dev)); - return (-1); + return -1; } - return (0); + return 0; } #define CUE_POLY 0xEDB88320 #define CUE_BITS 9 -Static u_int32_t +Static uint32_t cue_crc(const char *addr) { - u_int32_t idx, bit, data, crc; + uint32_t idx, bit, data, crc; /* Compute CRC for the address value. */ crc = 0xFFFFFFFF; /* initial value */ @@ -350,7 +349,7 @@ cue_crc(const char *addr) crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CUE_POLY : 0); } - return (crc & ((1 << CUE_BITS) - 1)); + return crc & ((1 << CUE_BITS) - 1); } Static void @@ -359,7 +358,7 @@ cue_setmulti(struct cue_softc *sc) struct ifnet *ifp; struct ether_multi *enm; struct ether_multistep step; - u_int32_t h, i; + uint32_t h, i; ifp = GET_IFP(sc); @@ -441,8 +440,8 @@ cue_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (cue_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return cue_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } /* @@ -457,8 +456,8 @@ cue_attach(device_t parent, device_t self, void *aux) char *devinfop; int s; u_char eaddr[ETHER_ADDR_LEN]; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface; + struct usbd_device * dev = uaa->uaa_device; + struct usbd_interface * iface; usbd_status err; struct ifnet *ifp; usb_interface_descriptor_t *id; @@ -484,8 +483,8 @@ cue_attach(device_t parent, device_t self, void *aux) } sc->cue_udev = dev; - sc->cue_product = uaa->product; - sc->cue_vendor = uaa->vendor; + sc->cue_product = uaa->uaa_product; + sc->cue_vendor = uaa->uaa_vendor; usb_init_task(&sc->cue_tick_task, cue_tick_task, sc, 0); usb_init_task(&sc->cue_stop_task, (void (*)(void *))cue_stop, sc, 0); @@ -581,7 +580,7 @@ cue_detach(device_t self, int flags) if (!sc->cue_attached) { /* Detached before attached finished, so just bail out. */ - return (0); + return 0; } s = splusb(); @@ -606,7 +605,7 @@ cue_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->cue_udev, sc->cue_dev); - return (0); + return 0; } int @@ -640,7 +639,7 @@ cue_newbuf(struct cue_softc *sc, struct cue_chain *c, struct mbuf *m) if (m_new == NULL) { printf("%s: no memory for rx list " "-- packet dropped!\n", device_xname(sc->cue_dev)); - return (ENOBUFS); + return ENOBUFS; } MCLGET(m_new, M_DONTWAIT); @@ -648,7 +647,7 @@ cue_newbuf(struct cue_softc *sc, struct cue_chain *c, struct mbuf *m) printf("%s: no memory for rx list " "-- packet dropped!\n", device_xname(sc->cue_dev)); m_freem(m_new); - return (ENOBUFS); + return ENOBUFS; } m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; } else { @@ -660,7 +659,7 @@ cue_newbuf(struct cue_softc *sc, struct cue_chain *c, struct mbuf *m) m_adj(m_new, ETHER_ALIGN); c->cue_mbuf = m_new; - return (0); + return 0; } Static int @@ -676,20 +675,17 @@ cue_rx_list_init(struct cue_softc *sc) c->cue_sc = sc; c->cue_idx = i; if (cue_newbuf(sc, c, NULL) == ENOBUFS) - return (ENOBUFS); + return ENOBUFS; if (c->cue_xfer == NULL) { - c->cue_xfer = usbd_alloc_xfer(sc->cue_udev); - if (c->cue_xfer == NULL) - return (ENOBUFS); - c->cue_buf = usbd_alloc_buffer(c->cue_xfer, CUE_BUFSZ); - if (c->cue_buf == NULL) { - usbd_free_xfer(c->cue_xfer); - return (ENOBUFS); - } + int error = usbd_create_xfer(sc->cue_ep[CUE_ENDPT_RX], + CUE_BUFSZ, USBD_SHORT_XFER_OK, 0, &c->cue_xfer); + if (error) + return error; + c->cue_buf = usbd_get_buffer(c->cue_xfer); } } - return (0); + return 0; } Static int @@ -706,18 +702,15 @@ cue_tx_list_init(struct cue_softc *sc) c->cue_idx = i; c->cue_mbuf = NULL; if (c->cue_xfer == NULL) { - c->cue_xfer = usbd_alloc_xfer(sc->cue_udev); - if (c->cue_xfer == NULL) - return (ENOBUFS); - c->cue_buf = usbd_alloc_buffer(c->cue_xfer, CUE_BUFSZ); - if (c->cue_buf == NULL) { - usbd_free_xfer(c->cue_xfer); - return (ENOBUFS); - } + int error = usbd_create_xfer(sc->cue_ep[CUE_ENDPT_TX], + CUE_BUFSZ, 0, 0, &c->cue_xfer); + if (error) + return error; + c->cue_buf = usbd_get_buffer(c->cue_xfer); } } - return (0); + return 0; } /* @@ -725,14 +718,14 @@ cue_tx_list_init(struct cue_softc *sc) * the higher level protocols. */ Static void -cue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +cue_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct cue_chain *c = priv; struct cue_softc *sc = c->cue_sc; struct ifnet *ifp = GET_IFP(sc); struct mbuf *m; int total_len = 0; - u_int16_t len; + uint16_t len; int s; DPRINTFN(10,("%s: %s: enter status=%d\n", device_xname(sc->cue_dev), @@ -764,7 +757,7 @@ cue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) memcpy(mtod(c->cue_mbuf, char *), c->cue_buf, total_len); m = c->cue_mbuf; - len = UGETW(mtod(m, u_int8_t *)); + len = UGETW(mtod(m, uint8_t *)); /* No errors; receive the packet. */ total_len = len; @@ -775,7 +768,7 @@ cue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) } ifp->if_ipackets++; - m_adj(m, sizeof(u_int16_t)); + m_adj(m, sizeof(uint16_t)); m->m_pkthdr.len = m->m_len = total_len; m->m_pkthdr.rcvif = ifp; @@ -803,10 +796,10 @@ cue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) splx(s); done: + /* Setup new transfer. */ - usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX], - c, c->cue_buf, CUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, cue_rxeof); + usbd_setup_xfer(c->cue_xfer, c, c->cue_buf, CUE_BUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, cue_rxeof); usbd_transfer(c->cue_xfer); DPRINTFN(10,("%s: %s: start rx\n", device_xname(sc->cue_dev), @@ -818,7 +811,7 @@ done: * the list buffers. */ Static void -cue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, +cue_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct cue_chain *c = priv; @@ -922,12 +915,12 @@ cue_send(struct cue_softc *sc, struct mbuf *m, int idx) device_xname(sc->cue_dev), __func__, total_len)); /* The first two bytes are the frame length */ - c->cue_buf[0] = (u_int8_t)m->m_pkthdr.len; - c->cue_buf[1] = (u_int8_t)(m->m_pkthdr.len >> 8); + c->cue_buf[0] = (uint8_t)m->m_pkthdr.len; + c->cue_buf[1] = (uint8_t)(m->m_pkthdr.len >> 8); /* XXX 10000 */ - usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_TX], - c, c->cue_buf, total_len, USBD_NO_COPY, 10000, cue_txeof); + usbd_setup_xfer(c->cue_xfer, c, c->cue_buf, total_len, 0, 10000, + cue_txeof); /* Transmit */ err = usbd_transfer(c->cue_xfer); @@ -937,12 +930,12 @@ cue_send(struct cue_softc *sc, struct mbuf *m, int idx) /* Stop the interface from process context. */ usb_add_task(sc->cue_udev, &sc->cue_stop_task, USB_TASKQ_DRIVER); - return (EIO); + return EIO; } sc->cue_cdata.cue_tx_cnt++; - return (0); + return 0; } Static void @@ -1024,20 +1017,6 @@ cue_init(void *xsc) ctl |= CUE_ETHCTL_PROMISC; cue_csr_write_1(sc, CUE_ETHCTL, ctl); - /* Init TX ring. */ - if (cue_tx_list_init(sc) == ENOBUFS) { - printf("%s: tx list init failed\n", device_xname(sc->cue_dev)); - splx(s); - return; - } - - /* Init RX ring. */ - if (cue_rx_list_init(sc) == ENOBUFS) { - printf("%s: rx list init failed\n", device_xname(sc->cue_dev)); - splx(s); - return; - } - /* Load the multicast filter. */ cue_setmulti(sc); @@ -1061,6 +1040,20 @@ cue_init(void *xsc) return; } } + /* Init TX ring. */ + if (cue_tx_list_init(sc)) { + printf("%s: tx list init failed\n", device_xname(sc->cue_dev)); + splx(s); + return; + } + + /* Init RX ring. */ + if (cue_rx_list_init(sc)) { + printf("%s: rx list init failed\n", device_xname(sc->cue_dev)); + splx(s); + return; + } + ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; @@ -1083,27 +1076,26 @@ cue_open_pipes(struct cue_softc *sc) if (err) { printf("%s: open rx pipe failed: %s\n", device_xname(sc->cue_dev), usbd_errstr(err)); - return (EIO); + return EIO; } err = usbd_open_pipe(sc->cue_iface, sc->cue_ed[CUE_ENDPT_TX], USBD_EXCLUSIVE_USE, &sc->cue_ep[CUE_ENDPT_TX]); if (err) { printf("%s: open tx pipe failed: %s\n", device_xname(sc->cue_dev), usbd_errstr(err)); - return (EIO); + return EIO; } /* Start up the receive pipe. */ for (i = 0; i < CUE_RX_LIST_CNT; i++) { c = &sc->cue_cdata.cue_rx_chain[i]; - usbd_setup_xfer(c->cue_xfer, sc->cue_ep[CUE_ENDPT_RX], - c, c->cue_buf, CUE_BUFSZ, - USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, - cue_rxeof); + + usbd_setup_xfer(c->cue_xfer, c, c->cue_buf, CUE_BUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, cue_rxeof); usbd_transfer(c->cue_xfer); } - return (0); + return 0; } Static int @@ -1115,7 +1107,7 @@ cue_ioctl(struct ifnet *ifp, u_long command, void *data) int s, error = 0; if (sc->cue_dying) - return (EIO); + return EIO; s = splnet(); @@ -1175,7 +1167,7 @@ cue_ioctl(struct ifnet *ifp, u_long command, void *data) splx(s); - return (error); + return error; } Static void @@ -1231,12 +1223,6 @@ cue_stop(struct cue_softc *sc) printf("%s: abort rx pipe failed: %s\n", device_xname(sc->cue_dev), usbd_errstr(err)); } - err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_RX]); - if (err) { - printf("%s: close rx pipe failed: %s\n", - device_xname(sc->cue_dev), usbd_errstr(err)); - } - sc->cue_ep[CUE_ENDPT_RX] = NULL; } if (sc->cue_ep[CUE_ENDPT_TX] != NULL) { @@ -1245,12 +1231,6 @@ cue_stop(struct cue_softc *sc) printf("%s: abort tx pipe failed: %s\n", device_xname(sc->cue_dev), usbd_errstr(err)); } - err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_TX]); - if (err) { - printf("%s: close tx pipe failed: %s\n", - device_xname(sc->cue_dev), usbd_errstr(err)); - } - sc->cue_ep[CUE_ENDPT_TX] = NULL; } if (sc->cue_ep[CUE_ENDPT_INTR] != NULL) { @@ -1259,22 +1239,12 @@ cue_stop(struct cue_softc *sc) printf("%s: abort intr pipe failed: %s\n", device_xname(sc->cue_dev), usbd_errstr(err)); } - err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_INTR]); - if (err) { - printf("%s: close intr pipe failed: %s\n", - device_xname(sc->cue_dev), usbd_errstr(err)); - } - sc->cue_ep[CUE_ENDPT_INTR] = NULL; } /* Free RX resources. */ for (i = 0; i < CUE_RX_LIST_CNT; i++) { - if (sc->cue_cdata.cue_rx_chain[i].cue_mbuf != NULL) { - m_freem(sc->cue_cdata.cue_rx_chain[i].cue_mbuf); - sc->cue_cdata.cue_rx_chain[i].cue_mbuf = NULL; - } if (sc->cue_cdata.cue_rx_chain[i].cue_xfer != NULL) { - usbd_free_xfer(sc->cue_cdata.cue_rx_chain[i].cue_xfer); + usbd_destroy_xfer(sc->cue_cdata.cue_rx_chain[i].cue_xfer); sc->cue_cdata.cue_rx_chain[i].cue_xfer = NULL; } } @@ -1286,10 +1256,38 @@ cue_stop(struct cue_softc *sc) sc->cue_cdata.cue_tx_chain[i].cue_mbuf = NULL; } if (sc->cue_cdata.cue_tx_chain[i].cue_xfer != NULL) { - usbd_free_xfer(sc->cue_cdata.cue_tx_chain[i].cue_xfer); + usbd_destroy_xfer(sc->cue_cdata.cue_tx_chain[i].cue_xfer); sc->cue_cdata.cue_tx_chain[i].cue_xfer = NULL; } } + /* Stop transfers. */ + if (sc->cue_ep[CUE_ENDPT_RX] != NULL) { + err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_RX]); + if (err) { + printf("%s: close rx pipe failed: %s\n", + device_xname(sc->cue_dev), usbd_errstr(err)); + } + sc->cue_ep[CUE_ENDPT_RX] = NULL; + } + + if (sc->cue_ep[CUE_ENDPT_TX] != NULL) { + err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_TX]); + if (err) { + printf("%s: close tx pipe failed: %s\n", + device_xname(sc->cue_dev), usbd_errstr(err)); + } + sc->cue_ep[CUE_ENDPT_TX] = NULL; + } + + if (sc->cue_ep[CUE_ENDPT_INTR] != NULL) { + err = usbd_close_pipe(sc->cue_ep[CUE_ENDPT_INTR]); + if (err) { + printf("%s: close intr pipe failed: %s\n", + device_xname(sc->cue_dev), usbd_errstr(err)); + } + sc->cue_ep[CUE_ENDPT_INTR] = NULL; + } + ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); } diff --git a/sys/dev/usb/if_cuereg.h b/sys/dev/usb/if_cuereg.h index 255c59f1b88..a6e1114f122 100644 --- a/sys/dev/usb/if_cuereg.h +++ b/sys/dev/usb/if_cuereg.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_cuereg.h,v 1.19 2015/04/14 21:09:48 riastradh Exp $ */ +/* $NetBSD: if_cuereg.h,v 1.20 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. @@ -142,15 +142,15 @@ #define CUE_ENDPT_MAX 0x3 struct cue_type { - u_int16_t cue_vid; - u_int16_t cue_did; + uint16_t cue_vid; + uint16_t cue_did; }; struct cue_softc; struct cue_chain { struct cue_softc *cue_sc; - usbd_xfer_handle cue_xfer; + struct usbd_xfer *cue_xfer; char *cue_buf; struct mbuf *cue_mbuf; int cue_idx; @@ -174,15 +174,15 @@ struct cue_softc { struct callout cue_stat_ch; - usbd_device_handle cue_udev; - usbd_interface_handle cue_iface; - u_int16_t cue_vendor; - u_int16_t cue_product; + struct usbd_device * cue_udev; + struct usbd_interface * cue_iface; + uint16_t cue_vendor; + uint16_t cue_product; int cue_ed[CUE_ENDPT_MAX]; - usbd_pipe_handle cue_ep[CUE_ENDPT_MAX]; - u_int8_t cue_mctab[CUE_MCAST_TABLE_LEN]; + struct usbd_pipe * cue_ep[CUE_ENDPT_MAX]; + uint8_t cue_mctab[CUE_MCAST_TABLE_LEN]; int cue_if_flags; - u_int16_t cue_rxfilt; + uint16_t cue_rxfilt; struct cue_cdata cue_cdata; char cue_dying; diff --git a/sys/dev/usb/if_kue.c b/sys/dev/usb/if_kue.c index a709820d741..fa6f32d944f 100644 --- a/sys/dev/usb/if_kue.c +++ b/sys/dev/usb/if_kue.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_kue.c,v 1.83 2016/02/09 08:32:12 ozaki-r Exp $ */ +/* $NetBSD: if_kue.c,v 1.84 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 @@ -71,7 +71,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_kue.c,v 1.83 2016/02/09 08:32:12 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_kue.c,v 1.84 2016/04/23 10:15:31 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -81,7 +81,7 @@ __KERNEL_RCSID(0, "$NetBSD: if_kue.c,v 1.83 2016/02/09 08:32:12 ozaki-r Exp $"); #include <sys/systm.h> #include <sys/sockio.h> #include <sys/mbuf.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/kernel.h> #include <sys/socket.h> #include <sys/device.h> @@ -168,8 +168,8 @@ static int kue_tx_list_init(struct kue_softc *); static int kue_rx_list_init(struct kue_softc *); static int kue_send(struct kue_softc *, struct mbuf *, int); static int kue_open_pipes(struct kue_softc *); -static void kue_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void kue_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +static void kue_rxeof(struct usbd_xfer *, void *, usbd_status); +static void kue_txeof(struct usbd_xfer *, void *, usbd_status); static void kue_start(struct ifnet *); static int kue_ioctl(struct ifnet *, u_long, void *); static void kue_init(void *); @@ -197,7 +197,7 @@ kue_setword(struct kue_softc *sc, uint8_t breq, uint16_t word) USETW(req.wIndex, 0); USETW(req.wLength, 0); - return (usbd_do_request(sc->kue_udev, &req, NULL)); + return usbd_do_request(sc->kue_udev, &req, NULL); } static usbd_status @@ -219,7 +219,7 @@ kue_ctl(struct kue_softc *sc, int rw, uint8_t breq, uint16_t val, USETW(req.wIndex, 0); USETW(req.wLength, len); - return (usbd_do_request(sc->kue_udev, &req, data)); + return usbd_do_request(sc->kue_udev, &req, data); } static int @@ -245,11 +245,11 @@ kue_load_fw(struct kue_softc *sc) * running. */ if (usbd_get_device_desc(sc->kue_udev, &dd)) - return (EIO); + return EIO; if (UGETW(dd.bcdDevice) == KUE_WARM_REV) { printf("%s: warm boot, no firmware download\n", device_xname(sc->kue_dev)); - return (0); + return 0; } printf("%s: cold boot, downloading firmware\n", @@ -264,7 +264,7 @@ kue_load_fw(struct kue_softc *sc) if (err) { printf("%s: failed to load code segment: %s\n", device_xname(sc->kue_dev), usbd_errstr(err)); - return (EIO); + return EIO; } /* Load fixup segment */ @@ -276,7 +276,7 @@ kue_load_fw(struct kue_softc *sc) if (err) { printf("%s: failed to load fixup segment: %s\n", device_xname(sc->kue_dev), usbd_errstr(err)); - return (EIO); + return EIO; } /* Send trigger command. */ @@ -288,7 +288,7 @@ kue_load_fw(struct kue_softc *sc) if (err) { printf("%s: failed to load trigger segment: %s\n", device_xname(sc->kue_dev), usbd_errstr(err)); - return (EIO); + return EIO; } usbd_delay_ms(sc->kue_udev, 10); @@ -308,7 +308,7 @@ kue_load_fw(struct kue_softc *sc) /* Reset the adapter. */ kue_reset(sc); - return (0); + return 0; } static void @@ -383,8 +383,8 @@ kue_match(device_t parent, cfdata_t match, void *aux) DPRINTFN(25,("kue_match: enter\n")); - return (kue_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return kue_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } /* @@ -399,8 +399,8 @@ kue_attach(device_t parent, device_t self, void *aux) char *devinfop; int s; struct ifnet *ifp; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface; + struct usbd_device * dev = uaa->uaa_device; + struct usbd_interface * iface; usbd_status err; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; @@ -425,8 +425,8 @@ kue_attach(device_t parent, device_t self, void *aux) } sc->kue_udev = dev; - sc->kue_product = uaa->product; - sc->kue_vendor = uaa->vendor; + sc->kue_product = uaa->uaa_product; + sc->kue_vendor = uaa->uaa_vendor; /* Load the firmware into the NIC. */ if (kue_load_fw(sc)) { @@ -475,8 +475,8 @@ kue_attach(device_t parent, device_t self, void *aux) return; } - sc->kue_mcfilters = malloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN, - M_USBDEV, M_NOWAIT); + sc->kue_mcfilters = kmem_alloc(KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN, + KM_SLEEP); if (sc->kue_mcfilters == NULL) { aprint_error_dev(self, "no memory for multicast filter buffer\n"); @@ -528,14 +528,15 @@ kue_detach(device_t self, int flags) s = splusb(); /* XXX why? */ if (sc->kue_mcfilters != NULL) { - free(sc->kue_mcfilters, M_USBDEV); + kmem_free(sc->kue_mcfilters, + KUE_MCFILTCNT(sc) * ETHER_ADDR_LEN); sc->kue_mcfilters = NULL; } if (!sc->kue_attached) { /* Detached before attached finished, so just bail out. */ splx(s); - return (0); + return 0; } if (ifp->if_flags & IFF_RUNNING) @@ -556,7 +557,7 @@ kue_detach(device_t self, int flags) sc->kue_attached = false; splx(s); - return (0); + return 0; } int @@ -592,16 +593,15 @@ kue_rx_list_init(struct kue_softc *sc) c->kue_sc = sc; c->kue_idx = i; if (c->kue_xfer == NULL) { - c->kue_xfer = usbd_alloc_xfer(sc->kue_udev); - if (c->kue_xfer == NULL) - return (ENOBUFS); - c->kue_buf = usbd_alloc_buffer(c->kue_xfer, KUE_BUFSZ); - if (c->kue_buf == NULL) - return (ENOBUFS); /* XXX free xfer */ + int error = usbd_create_xfer(sc->kue_ep[KUE_ENDPT_RX], + KUE_BUFSZ, USBD_SHORT_XFER_OK, 0, &c->kue_xfer); + if (error) + return error; + c->kue_buf = usbd_get_buffer(c->kue_xfer); } } - return (0); + return 0; } static int @@ -619,16 +619,15 @@ kue_tx_list_init(struct kue_softc *sc) c->kue_sc = sc; c->kue_idx = i; if (c->kue_xfer == NULL) { - c->kue_xfer = usbd_alloc_xfer(sc->kue_udev); - if (c->kue_xfer == NULL) - return (ENOBUFS); - c->kue_buf = usbd_alloc_buffer(c->kue_xfer, KUE_BUFSZ); - if (c->kue_buf == NULL) - return (ENOBUFS); + int error = usbd_create_xfer(sc->kue_ep[KUE_ENDPT_TX], + KUE_BUFSZ, 0, 0, &c->kue_xfer); + if (error) + return error; + c->kue_buf = usbd_get_buffer(c->kue_xfer); } } - return (0); + return 0; } /* @@ -636,7 +635,7 @@ kue_tx_list_init(struct kue_softc *sc) * the higher level protocols. */ static void -kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +kue_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct kue_chain *c = priv; struct kue_softc *sc = c->kue_sc; @@ -730,9 +729,8 @@ kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) done: /* Setup new transfer. */ - usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX], - c, c->kue_buf, KUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, kue_rxeof); + usbd_setup_xfer(c->kue_xfer, c, c->kue_buf, KUE_BUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, kue_rxeof); usbd_transfer(c->kue_xfer); DPRINTFN(10,("%s: %s: start rx\n", device_xname(sc->kue_dev), @@ -745,7 +743,7 @@ kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) */ static void -kue_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, +kue_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct kue_chain *c = priv; @@ -809,9 +807,8 @@ kue_send(struct kue_softc *sc, struct mbuf *m, int idx) total_len = 2 + m->m_pkthdr.len; total_len = roundup2(total_len, 64); - usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_TX], - c, c->kue_buf, total_len, USBD_NO_COPY, USBD_DEFAULT_TIMEOUT, - kue_txeof); + usbd_setup_xfer(c->kue_xfer, c, c->kue_buf, total_len, 0, + USBD_DEFAULT_TIMEOUT, kue_txeof); /* Transmit */ err = usbd_transfer(c->kue_xfer); @@ -819,12 +816,12 @@ kue_send(struct kue_softc *sc, struct mbuf *m, int idx) printf("%s: kue_send error=%s\n", device_xname(sc->kue_dev), usbd_errstr(err)); kue_stop(sc); - return (EIO); + return EIO; } sc->kue_cdata.kue_tx_cnt++; - return (0); + return 0; } static void @@ -904,28 +901,37 @@ kue_init(void *xsc) #endif kue_setword(sc, KUE_CMD_SET_URB_SIZE, 64); + /* Load the multicast filter. */ + kue_setmulti(sc); + + if (sc->kue_ep[KUE_ENDPT_RX] == NULL) { + if (kue_open_pipes(sc)) { + splx(s); + return; + } + } /* Init TX ring. */ - if (kue_tx_list_init(sc) == ENOBUFS) { + if (kue_tx_list_init(sc)) { printf("%s: tx list init failed\n", device_xname(sc->kue_dev)); splx(s); return; } /* Init RX ring. */ - if (kue_rx_list_init(sc) == ENOBUFS) { + if (kue_rx_list_init(sc)) { printf("%s: rx list init failed\n", device_xname(sc->kue_dev)); splx(s); return; } - /* Load the multicast filter. */ - kue_setmulti(sc); - - if (sc->kue_ep[KUE_ENDPT_RX] == NULL) { - if (kue_open_pipes(sc)) { - splx(s); - return; - } + /* Start up the receive pipe. */ + for (size_t i = 0; i < KUE_RX_LIST_CNT; i++) { + struct kue_chain *c = &sc->kue_cdata.kue_rx_chain[i]; + usbd_setup_xfer(c->kue_xfer, c, c->kue_buf, KUE_BUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, kue_rxeof); + DPRINTFN(5,("%s: %s: start read\n", device_xname(sc->kue_dev), + __func__)); + usbd_transfer(c->kue_xfer); } ifp->if_flags |= IFF_RUNNING; @@ -938,8 +944,6 @@ static int kue_open_pipes(struct kue_softc *sc) { usbd_status err; - struct kue_chain *c; - int i; DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->kue_dev),__func__)); @@ -949,7 +953,7 @@ kue_open_pipes(struct kue_softc *sc) if (err) { printf("%s: open rx pipe failed: %s\n", device_xname(sc->kue_dev), usbd_errstr(err)); - return (EIO); + return EIO; } err = usbd_open_pipe(sc->kue_iface, sc->kue_ed[KUE_ENDPT_TX], @@ -957,22 +961,10 @@ kue_open_pipes(struct kue_softc *sc) if (err) { printf("%s: open tx pipe failed: %s\n", device_xname(sc->kue_dev), usbd_errstr(err)); - return (EIO); + return EIO; } - /* Start up the receive pipe. */ - for (i = 0; i < KUE_RX_LIST_CNT; i++) { - c = &sc->kue_cdata.kue_rx_chain[i]; - usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX], - c, c->kue_buf, KUE_BUFSZ, - USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, - kue_rxeof); - DPRINTFN(5,("%s: %s: start read\n", device_xname(sc->kue_dev), - __func__)); - usbd_transfer(c->kue_xfer); - } - - return (0); + return 0; } static int @@ -986,7 +978,7 @@ kue_ioctl(struct ifnet *ifp, u_long command, void *data) DPRINTFN(5,("%s: %s: enter\n", device_xname(sc->kue_dev),__func__)); if (sc->kue_dying) - return (EIO); + return EIO; s = splnet(); @@ -1052,7 +1044,7 @@ kue_ioctl(struct ifnet *ifp, u_long command, void *data) splx(s); - return (error); + return error; } static void @@ -1104,12 +1096,6 @@ kue_stop(struct kue_softc *sc) printf("%s: abort rx pipe failed: %s\n", device_xname(sc->kue_dev), usbd_errstr(err)); } - err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_RX]); - if (err) { - printf("%s: close rx pipe failed: %s\n", - device_xname(sc->kue_dev), usbd_errstr(err)); - } - sc->kue_ep[KUE_ENDPT_RX] = NULL; } if (sc->kue_ep[KUE_ENDPT_TX] != NULL) { @@ -1118,12 +1104,6 @@ kue_stop(struct kue_softc *sc) printf("%s: abort tx pipe failed: %s\n", device_xname(sc->kue_dev), usbd_errstr(err)); } - err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_TX]); - if (err) { - printf("%s: close tx pipe failed: %s\n", - device_xname(sc->kue_dev), usbd_errstr(err)); - } - sc->kue_ep[KUE_ENDPT_TX] = NULL; } if (sc->kue_ep[KUE_ENDPT_INTR] != NULL) { @@ -1132,18 +1112,12 @@ kue_stop(struct kue_softc *sc) printf("%s: abort intr pipe failed: %s\n", device_xname(sc->kue_dev), usbd_errstr(err)); } - err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_INTR]); - if (err) { - printf("%s: close intr pipe failed: %s\n", - device_xname(sc->kue_dev), usbd_errstr(err)); - } - sc->kue_ep[KUE_ENDPT_INTR] = NULL; } /* Free RX resources. */ for (i = 0; i < KUE_RX_LIST_CNT; i++) { if (sc->kue_cdata.kue_rx_chain[i].kue_xfer != NULL) { - usbd_free_xfer(sc->kue_cdata.kue_rx_chain[i].kue_xfer); + usbd_destroy_xfer(sc->kue_cdata.kue_rx_chain[i].kue_xfer); sc->kue_cdata.kue_rx_chain[i].kue_xfer = NULL; } } @@ -1151,10 +1125,38 @@ kue_stop(struct kue_softc *sc) /* Free TX resources. */ for (i = 0; i < KUE_TX_LIST_CNT; i++) { if (sc->kue_cdata.kue_tx_chain[i].kue_xfer != NULL) { - usbd_free_xfer(sc->kue_cdata.kue_tx_chain[i].kue_xfer); + usbd_destroy_xfer(sc->kue_cdata.kue_tx_chain[i].kue_xfer); sc->kue_cdata.kue_tx_chain[i].kue_xfer = NULL; } } + /* Close pipes. */ + if (sc->kue_ep[KUE_ENDPT_RX] != NULL) { + err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_RX]); + if (err) { + printf("%s: close rx pipe failed: %s\n", + device_xname(sc->kue_dev), usbd_errstr(err)); + } + sc->kue_ep[KUE_ENDPT_RX] = NULL; + } + + if (sc->kue_ep[KUE_ENDPT_TX] != NULL) { + err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_TX]); + if (err) { + printf("%s: close tx pipe failed: %s\n", + device_xname(sc->kue_dev), usbd_errstr(err)); + } + sc->kue_ep[KUE_ENDPT_TX] = NULL; + } + + if (sc->kue_ep[KUE_ENDPT_INTR] != NULL) { + err = usbd_close_pipe(sc->kue_ep[KUE_ENDPT_INTR]); + if (err) { + printf("%s: close intr pipe failed: %s\n", + device_xname(sc->kue_dev), usbd_errstr(err)); + } + sc->kue_ep[KUE_ENDPT_INTR] = NULL; + } + ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); } diff --git a/sys/dev/usb/if_kuereg.h b/sys/dev/usb/if_kuereg.h index 9656b0092f4..1b8c2d514cf 100644 --- a/sys/dev/usb/if_kuereg.h +++ b/sys/dev/usb/if_kuereg.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_kuereg.h,v 1.19 2015/04/14 20:32:36 riastradh Exp $ */ +/* $NetBSD: if_kuereg.h,v 1.20 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 1997, 1998, 1999, 2000 * Bill Paul <wpaul@ee.columbia.edu>. All rights reserved. @@ -146,7 +146,7 @@ struct kue_softc; struct kue_chain { struct kue_softc *kue_sc; - usbd_xfer_handle kue_xfer; + struct usbd_xfer *kue_xfer; uint8_t *kue_buf; int kue_idx; }; @@ -167,13 +167,13 @@ struct kue_softc { krndsource_t rnd_source; #define GET_IFP(sc) (&(sc)->kue_ec.ec_if) - usbd_device_handle kue_udev; - usbd_interface_handle kue_iface; + struct usbd_device * kue_udev; + struct usbd_interface * kue_iface; uint16_t kue_vendor; uint16_t kue_product; struct kue_ether_desc kue_desc; int kue_ed[KUE_ENDPT_MAX]; - usbd_pipe_handle kue_ep[KUE_ENDPT_MAX]; + struct usbd_pipe * kue_ep[KUE_ENDPT_MAX]; int kue_if_flags; uint16_t kue_rxfilt; uint8_t *kue_mcfilters; diff --git a/sys/dev/usb/if_otus.c b/sys/dev/usb/if_otus.c index 8ce517fd7bb..b5f399ee700 100644 --- a/sys/dev/usb/if_otus.c +++ b/sys/dev/usb/if_otus.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_otus.c,v 1.25 2013/10/17 21:07:37 christos Exp $ */ +/* $NetBSD: if_otus.c,v 1.26 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_otus.c,v 1.18 2010/08/27 17:08:00 jsg Exp $ */ /*- @@ -23,12 +23,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_otus.c,v 1.25 2013/10/17 21:07:37 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_otus.c,v 1.26 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/sockio.h> #include <sys/mbuf.h> #include <sys/kernel.h> +#include <sys/kmem.h> #include <sys/kthread.h> #include <sys/systm.h> #include <sys/callout.h> @@ -129,11 +130,11 @@ Static struct ieee80211_node *otus_node_alloc(struct ieee80211_node_table *); Static int otus_media_change(struct ifnet *); Static int otus_read_eeprom(struct otus_softc *); Static void otus_newassoc(struct ieee80211_node *, int); -Static void otus_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void otus_intr(struct usbd_xfer *, void *, usbd_status); Static void otus_cmd_rxeof(struct otus_softc *, uint8_t *, int); Static void otus_sub_rxeof(struct otus_softc *, uint8_t *, int); -Static void otus_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -Static void otus_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void otus_rxeof(struct usbd_xfer *, void *, usbd_status); +Static void otus_txeof(struct usbd_xfer *, void *, usbd_status); Static int otus_tx(struct otus_softc *, struct mbuf *, struct ieee80211_node *, struct otus_tx_data *); Static void otus_start(struct ifnet *); @@ -596,9 +597,9 @@ otus_match(device_t parent, cfdata_t match, void *aux) DPRINTFN(DBG_FN, DBG_NO_SC, "otus_match: vendor=0x%x product=0x%x revision=0x%x\n", - uaa->vendor, uaa->product, uaa->release); + uaa->uaa_vendor, uaa->uaa_product, uaa->uaa_release); - return usb_lookup(otus_devs, uaa->vendor, uaa->product) != NULL ? + return usb_lookup(otus_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } @@ -616,7 +617,7 @@ otus_attach(device_t parent, device_t self, void *aux) sc->sc_dev = self; uaa = aux; - sc->sc_udev = uaa->device; + sc->sc_udev = uaa->uaa_device; aprint_naive("\n"); aprint_normal("\n"); @@ -973,7 +974,7 @@ Static int otus_open_pipes(struct otus_softc *sc) { usb_endpoint_descriptor_t *ed; - int i, isize, error; + int i, error; DPRINTFN(DBG_FN, sc, "\n"); @@ -990,21 +991,21 @@ otus_open_pipes(struct otus_softc *sc) "could not retrieve Rx intr pipe descriptor\n"); goto fail; } - isize = UGETW(ed->wMaxPacketSize); - if (isize == 0) { + sc->sc_ibuf_size = UGETW(ed->wMaxPacketSize); + if (sc->sc_ibuf_size == 0) { aprint_error_dev(sc->sc_dev, "invalid Rx intr pipe descriptor\n"); goto fail; } - sc->sc_ibuf = malloc(isize, M_USBDEV, M_NOWAIT); + sc->sc_ibuf = kmem_alloc(sc->sc_ibuf_size, KM_SLEEP); if (sc->sc_ibuf == NULL) { aprint_error_dev(sc->sc_dev, "could not allocate Rx intr buffer\n"); goto fail; } error = usbd_open_pipe_intr(sc->sc_iface, AR_EPT_INTR_RX_NO, - USBD_SHORT_XFER_OK, &sc->sc_cmd_rx_pipe, sc, sc->sc_ibuf, isize, - otus_intr, USBD_DEFAULT_INTERVAL); + USBD_SHORT_XFER_OK, &sc->sc_cmd_rx_pipe, sc, sc->sc_ibuf, + sc->sc_ibuf_size, otus_intr, USBD_DEFAULT_INTERVAL); if (error != 0) { aprint_error_dev(sc->sc_dev, "could not open Rx intr pipe\n"); goto fail; @@ -1030,23 +1031,21 @@ otus_open_pipes(struct otus_softc *sc) goto fail; } - if (otus_alloc_tx_data_list(sc) != 0) { + if (otus_alloc_tx_data_list(sc)) { aprint_error_dev(sc->sc_dev, "could not allocate Tx xfers\n"); goto fail; } - if (otus_alloc_rx_data_list(sc) != 0) { + if (otus_alloc_rx_data_list(sc)) { aprint_error_dev(sc->sc_dev, "could not allocate Rx xfers\n"); goto fail; } for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++) { - struct otus_rx_data *data; + struct otus_rx_data *data = &sc->sc_rx_data[i]; - data = &sc->sc_rx_data[i]; - usbd_setup_xfer(data->xfer, sc->sc_data_rx_pipe, data, data->buf, - OTUS_RXBUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, otus_rxeof); + usbd_setup_xfer(data->xfer, data, data->buf, OTUS_RXBUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, otus_rxeof); error = usbd_transfer(data->xfer); if (error != USBD_IN_PROGRESS && error != 0) { aprint_error_dev(sc->sc_dev, @@ -1077,7 +1076,7 @@ otus_close_pipes(struct otus_softc *sc) usbd_close_pipe(sc->sc_cmd_rx_pipe); } if (sc->sc_ibuf != NULL) - free(sc->sc_ibuf, M_USBDEV); + kmem_free(sc->sc_ibuf, sc->sc_ibuf_size); if (sc->sc_data_tx_pipe != NULL) usbd_close_pipe(sc->sc_data_tx_pipe); if (sc->sc_cmd_tx_pipe != NULL) @@ -1092,19 +1091,14 @@ otus_alloc_tx_cmd(struct otus_softc *sc) DPRINTFN(DBG_FN, sc, "\n"); cmd = &sc->sc_tx_cmd; - cmd->xfer = usbd_alloc_xfer(sc->sc_udev); - if (cmd->xfer == NULL) { - aprint_error_dev(sc->sc_dev, - "could not allocate xfer\n"); - return ENOMEM; - } - cmd->buf = usbd_alloc_buffer(cmd->xfer, OTUS_MAX_TXCMDSZ); - if (cmd->buf == NULL) { - aprint_error_dev(sc->sc_dev, - "could not allocate xfer buffer\n"); - usbd_free_xfer(cmd->xfer); - return ENOMEM; - } + + int error = usbd_create_xfer(sc->sc_cmd_tx_pipe, OTUS_MAX_TXCMDSZ, + USBD_FORCE_SHORT_XFER, 0, &cmd->xfer); + if (error) + return error; + + cmd->buf = usbd_get_buffer(cmd->xfer); + return 0; } @@ -1119,7 +1113,7 @@ otus_free_tx_cmd(struct otus_softc *sc) mutex_enter(&sc->sc_cmd_mtx); if (sc->sc_tx_cmd.xfer != NULL) - usbd_free_xfer(sc->sc_tx_cmd.xfer); + usbd_destroy_xfer(sc->sc_tx_cmd.xfer); sc->sc_tx_cmd.xfer = NULL; sc->sc_tx_cmd.buf = NULL; mutex_exit(&sc->sc_cmd_mtx); @@ -1141,20 +1135,14 @@ otus_alloc_tx_data_list(struct otus_softc *sc) data->sc = sc; /* Backpointer for callbacks. */ - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { + error = usbd_create_xfer(sc->sc_data_tx_pipe, OTUS_TXBUFSZ, + USBD_FORCE_SHORT_XFER, 0, &data->xfer); + if (error) { aprint_error_dev(sc->sc_dev, "could not allocate xfer\n"); - error = ENOMEM; - break; - } - data->buf = usbd_alloc_buffer(data->xfer, OTUS_TXBUFSZ); - if (data->buf == NULL) { - aprint_error_dev(sc->sc_dev, - "could not allocate xfer buffer\n"); - error = ENOMEM; break; } + data->buf = usbd_get_buffer(data->xfer); /* Append this Tx buffer to our free list. */ TAILQ_INSERT_TAIL(&sc->sc_tx_free_list, data, next); } @@ -1176,7 +1164,7 @@ otus_free_tx_data_list(struct otus_softc *sc) for (i = 0; i < OTUS_TX_DATA_LIST_COUNT; i++) { if (sc->sc_tx_data[i].xfer != NULL) - usbd_free_xfer(sc->sc_tx_data[i].xfer); + usbd_destroy_xfer(sc->sc_tx_data[i].xfer); } } @@ -1193,20 +1181,15 @@ otus_alloc_rx_data_list(struct otus_softc *sc) data->sc = sc; /* Backpointer for callbacks. */ - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { + error = usbd_create_xfer(sc->sc_data_rx_pipe, OTUS_RXBUFSZ, + USBD_SHORT_XFER_OK, 0, &data->xfer); + + if (error) { aprint_error_dev(sc->sc_dev, "could not allocate xfer\n"); - error = ENOMEM; - goto fail; - } - data->buf = usbd_alloc_buffer(data->xfer, OTUS_RXBUFSZ); - if (data->buf == NULL) { - aprint_error_dev(sc->sc_dev, - "could not allocate xfer buffer\n"); - error = ENOMEM; goto fail; } + data->buf = usbd_get_buffer(data->xfer); } return 0; @@ -1226,7 +1209,7 @@ otus_free_rx_data_list(struct otus_softc *sc) for (i = 0; i < OTUS_RX_DATA_LIST_COUNT; i++) if (sc->sc_rx_data[i].xfer != NULL) - usbd_free_xfer(sc->sc_rx_data[i].xfer); + usbd_destroy_xfer(sc->sc_rx_data[i].xfer); } Static void @@ -1439,8 +1422,8 @@ otus_cmd(struct otus_softc *sc, uint8_t code, const void *idata, int ilen, s = splusb(); cmd->odata = odata; cmd->done = 0; - usbd_setup_xfer(cmd->xfer, sc->sc_cmd_tx_pipe, cmd, cmd->buf, xferlen, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, OTUS_CMD_TIMEOUT, NULL); + usbd_setup_xfer(cmd->xfer, cmd, cmd->buf, xferlen, + USBD_FORCE_SHORT_XFER, OTUS_CMD_TIMEOUT, NULL); error = usbd_sync_transfer(cmd->xfer); if (error != 0) { splx(s); @@ -1603,7 +1586,7 @@ otus_newassoc(struct ieee80211_node *ni, int isnew) /* ARGSUSED */ Static void -otus_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +otus_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) { #if 0 struct otus_softc *sc; @@ -1844,7 +1827,7 @@ otus_sub_rxeof(struct otus_softc *sc, uint8_t *buf, int len) } Static void -otus_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +otus_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct otus_rx_data *data; struct otus_softc *sc; @@ -1896,13 +1879,13 @@ otus_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) } resubmit: - usbd_setup_xfer(xfer, sc->sc_data_rx_pipe, data, data->buf, OTUS_RXBUFSZ, - USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, otus_rxeof); + usbd_setup_xfer(xfer, data, data->buf, OTUS_RXBUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, otus_rxeof); (void)usbd_transfer(data->xfer); } Static void -otus_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +otus_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct otus_tx_data *data; struct otus_softc *sc; @@ -2053,8 +2036,8 @@ otus_tx(struct otus_softc *sc, struct mbuf *m, struct ieee80211_node *ni, DPRINTFN(DBG_TX, sc, "queued len=%d mac=0x%04x phy=0x%08x rate=%d\n", head->len, head->macctl, head->phyctl, otus_rates[ridx].rate); - usbd_setup_xfer(data->xfer, sc->sc_data_tx_pipe, data, data->buf, xferlen, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, OTUS_TX_TIMEOUT, otus_txeof); + usbd_setup_xfer(data->xfer, data, data->buf, xferlen, + USBD_FORCE_SHORT_XFER, OTUS_TX_TIMEOUT, otus_txeof); error = usbd_transfer(data->xfer); if (__predict_false( error != USBD_NORMAL_COMPLETION && diff --git a/sys/dev/usb/if_otusvar.h b/sys/dev/usb/if_otusvar.h index c76f5d2d198..544b1a77c02 100644 --- a/sys/dev/usb/if_otusvar.h +++ b/sys/dev/usb/if_otusvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_otusvar.h,v 1.7 2013/03/30 01:10:00 christos Exp $ */ +/* $NetBSD: if_otusvar.h,v 1.8 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_otusreg.h,v 1.6 2009/04/06 18:17:01 damien Exp $ */ /*- @@ -28,11 +28,11 @@ * EDCA AC parameters. */ struct ieee80211_edca_ac_params { - u_int8_t ac_ecwmin; /* CWmin = 2^ECWmin - 1 */ - u_int8_t ac_ecwmax; /* CWmax = 2^ECWmax - 1 */ - u_int8_t ac_aifsn; - u_int16_t ac_txoplimit; /* 32TU */ - u_int8_t ac_acm; + uint8_t ac_ecwmin; /* CWmin = 2^ECWmin - 1 */ + uint8_t ac_ecwmax; /* CWmax = 2^ECWmax - 1 */ + uint8_t ac_aifsn; + uint16_t ac_txoplimit; /* 32TU */ + uint8_t ac_acm; }; /************************************************************/ #endif /* ! HAVE_EDCA */ @@ -111,7 +111,7 @@ struct otus_tx_radiotap_header { struct otus_softc; struct otus_tx_cmd { - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; void *odata; uint16_t token; @@ -120,13 +120,13 @@ struct otus_tx_cmd { struct otus_rx_data { struct otus_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; }; struct otus_tx_data { struct otus_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; TAILQ_ENTRY(otus_tx_data) next; }; @@ -169,19 +169,20 @@ struct otus_softc { enum ieee80211_state, int); void (*sc_led_newstate)(struct otus_softc *); - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device * sc_udev; + struct usbd_interface * sc_iface; struct ar5416eeprom sc_eeprom; uint8_t sc_capflags; uint8_t sc_rxmask; uint8_t sc_txmask; - usbd_pipe_handle sc_data_tx_pipe; - usbd_pipe_handle sc_data_rx_pipe; - usbd_pipe_handle sc_cmd_tx_pipe; - usbd_pipe_handle sc_cmd_rx_pipe; + struct usbd_pipe * sc_data_tx_pipe; + struct usbd_pipe * sc_data_rx_pipe; + struct usbd_pipe * sc_cmd_tx_pipe; + struct usbd_pipe * sc_cmd_rx_pipe; uint8_t *sc_ibuf; + size_t sc_ibuf_size; int sc_if_flags; int sc_tx_timer; diff --git a/sys/dev/usb/if_rum.c b/sys/dev/usb/if_rum.c index 49158c4f28c..6b3719ea7b3 100644 --- a/sys/dev/usb/if_rum.c +++ b/sys/dev/usb/if_rum.c @@ -1,5 +1,5 @@ /* $OpenBSD: if_rum.c,v 1.40 2006/09/18 16:20:20 damien Exp $ */ -/* $NetBSD: if_rum.c,v 1.51 2015/08/30 13:09:48 ryoon Exp $ */ +/* $NetBSD: if_rum.c,v 1.52 2016/04/23 10:15:31 skrll Exp $ */ /*- * Copyright (c) 2005-2007 Damien Bergamini <damien.bergamini@free.fr> @@ -24,7 +24,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_rum.c,v 1.51 2015/08/30 13:09:48 ryoon Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_rum.c,v 1.52 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/sockio.h> @@ -33,7 +33,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_rum.c,v 1.51 2015/08/30 13:09:48 ryoon Exp $"); #include <sys/kernel.h> #include <sys/socket.h> #include <sys/systm.h> -#include <sys/malloc.h> #include <sys/module.h> #include <sys/conf.h> #include <sys/device.h> @@ -148,9 +147,9 @@ static void rum_next_scan(void *); static void rum_task(void *); static int rum_newstate(struct ieee80211com *, enum ieee80211_state, int); -static void rum_txeof(usbd_xfer_handle, usbd_private_handle, +static void rum_txeof(struct usbd_xfer *, void *, usbd_status); -static void rum_rxeof(usbd_xfer_handle, usbd_private_handle, +static void rum_rxeof(struct usbd_xfer *, void *, usbd_status); static uint8_t rum_rxrate(const struct rum_rx_desc *); static int rum_ack_rate(struct ieee80211com *, int); @@ -200,8 +199,8 @@ static void rum_newassoc(struct ieee80211_node *, int); static void rum_amrr_start(struct rum_softc *, struct ieee80211_node *); static void rum_amrr_timeout(void *); -static void rum_amrr_update(usbd_xfer_handle, usbd_private_handle, - usbd_status status); +static void rum_amrr_update(struct usbd_xfer *, void *, + usbd_status); /* * Supported rates for 802.11a/b/g modes (in 500Kbps unit). @@ -251,7 +250,7 @@ rum_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (usb_lookup(rum_devs, uaa->vendor, uaa->product) != NULL) ? + return (usb_lookup(rum_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL) ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } @@ -315,7 +314,7 @@ rum_attach(device_t parent, device_t self, void *aux) uint32_t tmp; sc->sc_dev = self; - sc->sc_udev = uaa->device; + sc->sc_udev = uaa->uaa_device; sc->sc_flags = 0; aprint_naive("\n"); @@ -467,14 +466,14 @@ rum_attach(device_t parent, device_t self, void *aux) ieee80211_media_init(ic, rum_media_change, ieee80211_media_status); bpf_attach2(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN, + sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN, &sc->sc_drvbpf); - sc->sc_rxtap_len = sizeof sc->sc_rxtapu; + sc->sc_rxtap_len = sizeof(sc->sc_rxtapu); sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2573_RX_RADIOTAP_PRESENT); - sc->sc_txtap_len = sizeof sc->sc_txtapu; + sc->sc_txtap_len = sizeof(sc->sc_txtapu); sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); sc->sc_txtap.wt_ihdr.it_present = htole32(RT2573_TX_RADIOTAP_PRESENT); @@ -509,21 +508,6 @@ rum_detach(device_t self, int flags) callout_stop(&sc->sc_scan_ch); callout_stop(&sc->sc_amrr_ch); - if (sc->amrr_xfer != NULL) { - usbd_free_xfer(sc->amrr_xfer); - sc->amrr_xfer = NULL; - } - - if (sc->sc_rx_pipeh != NULL) { - usbd_abort_pipe(sc->sc_rx_pipeh); - usbd_close_pipe(sc->sc_rx_pipeh); - } - - if (sc->sc_tx_pipeh != NULL) { - usbd_abort_pipe(sc->sc_tx_pipeh); - usbd_close_pipe(sc->sc_tx_pipeh); - } - bpf_detach(ifp); ieee80211_ifdetach(ic); /* free all nodes */ if_detach(ifp); @@ -548,22 +532,15 @@ rum_alloc_tx_list(struct rum_softc *sc) data->sc = sc; - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { + error = usbd_create_xfer(sc->sc_tx_pipeh, + RT2573_TX_DESC_SIZE + IEEE80211_MAX_LEN, + USBD_FORCE_SHORT_XFER, 0, &data->xfer); + if (error) { printf("%s: could not allocate tx xfer\n", device_xname(sc->sc_dev)); - error = ENOMEM; - goto fail; - } - - data->buf = usbd_alloc_buffer(data->xfer, - RT2573_TX_DESC_SIZE + IEEE80211_MAX_LEN); - if (data->buf == NULL) { - printf("%s: could not allocate tx buffer\n", - device_xname(sc->sc_dev)); - error = ENOMEM; goto fail; } + data->buf = usbd_get_buffer(data->xfer); /* clean Tx descriptor */ memset(data->buf, 0, RT2573_TX_DESC_SIZE); @@ -585,7 +562,7 @@ rum_free_tx_list(struct rum_softc *sc) data = &sc->tx_data[i]; if (data->xfer != NULL) { - usbd_free_xfer(data->xfer); + usbd_destroy_xfer(data->xfer); data->xfer = NULL; } @@ -607,18 +584,11 @@ rum_alloc_rx_list(struct rum_softc *sc) data->sc = sc; - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { + error = usbd_create_xfer(sc->sc_rx_pipeh, MCLBYTES, + USBD_SHORT_XFER_OK, 0, &data->xfer); + if (error) { printf("%s: could not allocate rx xfer\n", device_xname(sc->sc_dev)); - error = ENOMEM; - goto fail; - } - - if (usbd_alloc_buffer(data->xfer, MCLBYTES) == NULL) { - printf("%s: could not allocate rx buffer\n", - device_xname(sc->sc_dev)); - error = ENOMEM; goto fail; } @@ -657,7 +627,7 @@ rum_free_rx_list(struct rum_softc *sc) data = &sc->rx_data[i]; if (data->xfer != NULL) { - usbd_free_xfer(data->xfer); + usbd_destroy_xfer(data->xfer); data->xfer = NULL; } @@ -792,7 +762,7 @@ rum_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) #define RUM_CTS_SIZE 14 /* 10 + 4(FCS) */ static void -rum_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +rum_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct rum_tx_data *data = priv; struct rum_softc *sc = data->sc; @@ -831,7 +801,7 @@ rum_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) } static void -rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +rum_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct rum_rx_data *data = priv; struct rum_softc *sc = data->sc; @@ -929,8 +899,8 @@ rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) DPRINTFN(15, ("rx done\n")); skip: /* setup a new transfer */ - usbd_setup_xfer(xfer, sc->sc_rx_pipeh, data, data->buf, MCLBYTES, - USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rum_rxeof); + usbd_setup_xfer(xfer, data, data->buf, MCLBYTES, USBD_SHORT_XFER_OK, + USBD_NO_TIMEOUT, rum_rxeof); usbd_transfer(xfer); } @@ -1198,8 +1168,8 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) /* mbuf is no longer needed */ m_freem(mprot); - usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, - xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, + usbd_setup_xfer(data->xfer, data, data->buf, + xferlen, USBD_FORCE_SHORT_XFER, RUM_TX_TIMEOUT, rum_txeof); error = usbd_transfer(data->xfer); if (error != USBD_NORMAL_COMPLETION && @@ -1265,8 +1235,8 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) /* mbuf is no longer needed */ m_freem(m0); - usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof); + usbd_setup_xfer(data->xfer, data, data->buf, xferlen, + USBD_FORCE_SHORT_XFER, RUM_TX_TIMEOUT, rum_txeof); error = usbd_transfer(data->xfer); if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) return error; @@ -1444,7 +1414,7 @@ rum_read(struct rum_softc *sc, uint16_t reg) { uint32_t val; - rum_read_multi(sc, reg, &val, sizeof val); + rum_read_multi(sc, reg, &val, sizeof(val)); return le32toh(val); } @@ -1473,7 +1443,7 @@ rum_write(struct rum_softc *sc, uint16_t reg, uint32_t val) { uint32_t tmp = htole32(val); - rum_write_multi(sc, reg, &tmp, sizeof tmp); + rum_write_multi(sc, reg, &tmp, sizeof(tmp)); } static void @@ -1924,7 +1894,7 @@ rum_read_eeprom(struct rum_softc *sc) /* read Tx power for all a/b/g channels */ rum_eeprom_read(sc, RT2573_EEPROM_TXPOWER, sc->txpow, 14); /* XXX default Tx power for 802.11a channels */ - memset(sc->txpow + 14, 24, sizeof (sc->txpow) - 14); + memset(sc->txpow + 14, 24, sizeof(sc->txpow) - 14); #ifdef RUM_DEBUG for (i = 0; i < 14; i++) DPRINTF(("Channel=%d Tx power=%d\n", i + 1, sc->txpow[i])); @@ -1945,7 +1915,6 @@ rum_read_eeprom(struct rum_softc *sc) static int rum_bbp_init(struct rum_softc *sc) { -#define N(a) (sizeof (a) / sizeof ((a)[0])) unsigned int i, ntries; uint8_t val; @@ -1963,7 +1932,7 @@ rum_bbp_init(struct rum_softc *sc) } /* initialize BBP registers to default values */ - for (i = 0; i < N(rum_def_bbp); i++) + for (i = 0; i < __arraycount(rum_def_bbp); i++) rum_bbp_write(sc, rum_def_bbp[i].reg, rum_def_bbp[i].val); /* write vendor-specific BBP values (from EEPROM) */ @@ -1974,16 +1943,13 @@ rum_bbp_init(struct rum_softc *sc) } return 0; -#undef N } static int rum_init(struct ifnet *ifp) { -#define N(a) (sizeof (a) / sizeof ((a)[0])) struct rum_softc *sc = ifp->if_softc; struct ieee80211com *ic = &sc->sc_ic; - struct rum_rx_data *data; uint32_t tmp; usbd_status error = 0; unsigned int i, ntries; @@ -1996,7 +1962,7 @@ rum_init(struct ifnet *ifp) rum_stop(ifp, 0); /* initialize MAC registers to default values */ - for (i = 0; i < N(rum_def_mac); i++) + for (i = 0; i < __arraycount(rum_def_mac); i++) rum_write(sc, rum_def_mac[i].reg, rum_def_mac[i].val); /* set host ready */ @@ -2025,7 +1991,7 @@ rum_init(struct ifnet *ifp) rum_set_chan(sc, ic->ic_curchan); /* clear STA registers */ - rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta); + rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof(sc->sta)); IEEE80211_ADDR_COPY(ic->ic_myaddr, CLLADDR(ifp->if_sadl)); rum_set_macaddr(sc, ic->ic_myaddr); @@ -2036,8 +2002,10 @@ rum_init(struct ifnet *ifp) /* * Allocate xfer for AMRR statistics requests. */ - sc->amrr_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->amrr_xfer == NULL) { + struct usbd_pipe *pipe0 = usbd_get_pipe0(sc->sc_udev); + error = usbd_create_xfer(pipe0, sizeof(sc->sta), 0, 0, + &sc->amrr_xfer); + if (error) { printf("%s: could not allocate AMRR xfer\n", device_xname(sc->sc_dev)); goto fail; @@ -2083,10 +2051,12 @@ rum_init(struct ifnet *ifp) * Start up the receive pipe. */ for (i = 0; i < RUM_RX_LIST_COUNT; i++) { + struct rum_rx_data *data; + data = &sc->rx_data[i]; - usbd_setup_xfer(data->xfer, sc->sc_rx_pipeh, data, data->buf, - MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rum_rxeof); + usbd_setup_xfer(data->xfer, data, data->buf, MCLBYTES, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, rum_rxeof); error = usbd_transfer(data->xfer); if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { @@ -2122,7 +2092,6 @@ rum_init(struct ifnet *ifp) fail: rum_stop(ifp, 1); return error; -#undef N } static void @@ -2147,24 +2116,30 @@ rum_stop(struct ifnet *ifp, int disable) rum_write(sc, RT2573_MAC_CSR1, 0); if (sc->amrr_xfer != NULL) { - usbd_free_xfer(sc->amrr_xfer); + usbd_destroy_xfer(sc->amrr_xfer); sc->amrr_xfer = NULL; } if (sc->sc_rx_pipeh != NULL) { usbd_abort_pipe(sc->sc_rx_pipeh); - usbd_close_pipe(sc->sc_rx_pipeh); - sc->sc_rx_pipeh = NULL; } if (sc->sc_tx_pipeh != NULL) { usbd_abort_pipe(sc->sc_tx_pipeh); - usbd_close_pipe(sc->sc_tx_pipeh); - sc->sc_tx_pipeh = NULL; } rum_free_rx_list(sc); rum_free_tx_list(sc); + + if (sc->sc_rx_pipeh != NULL) { + usbd_close_pipe(sc->sc_rx_pipeh); + sc->sc_rx_pipeh = NULL; + } + + if (sc->sc_tx_pipeh != NULL) { + usbd_close_pipe(sc->sc_tx_pipeh); + sc->sc_tx_pipeh = NULL; + } } static int @@ -2238,7 +2213,7 @@ rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni) int i; /* clear statistic registers (STA_CSR0 to STA_CSR5) */ - rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta); + rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof(sc->sta)); ieee80211_amrr_node_init(&sc->amrr, &sc->amn); @@ -2264,16 +2239,16 @@ rum_amrr_timeout(void *arg) req.bRequest = RT2573_READ_MULTI_MAC; USETW(req.wValue, 0); USETW(req.wIndex, RT2573_STA_CSR0); - USETW(req.wLength, sizeof sc->sta); + USETW(req.wLength, sizeof(sc->sta)); usbd_setup_default_xfer(sc->amrr_xfer, sc->sc_udev, sc, - USBD_DEFAULT_TIMEOUT, &req, sc->sta, sizeof sc->sta, 0, + USBD_DEFAULT_TIMEOUT, &req, sc->sta, sizeof(sc->sta), 0, rum_amrr_update); (void)usbd_transfer(sc->amrr_xfer); } static void -rum_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv, +rum_amrr_update(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct rum_softc *sc = (struct rum_softc *)priv; diff --git a/sys/dev/usb/if_rumreg.h b/sys/dev/usb/if_rumreg.h index f05344c67bc..19b945670c6 100644 --- a/sys/dev/usb/if_rumreg.h +++ b/sys/dev/usb/if_rumreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_rumreg.h,v 1.4 2011/02/21 23:50:42 jmcneill Exp $ */ +/* $NetBSD: if_rumreg.h,v 1.5 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_rumreg.h,v 1.14 2009/08/10 18:04:56 damien Exp $ */ /*- @@ -18,8 +18,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RT2573_TX_DESC_SIZE (sizeof (struct rum_tx_desc)) -#define RT2573_RX_DESC_SIZE (sizeof (struct rum_rx_desc)) +#define RT2573_TX_DESC_SIZE (sizeof(struct rum_tx_desc)) +#define RT2573_RX_DESC_SIZE (sizeof(struct rum_rx_desc)) #define RT2573_CONFIG_NO 1 #define RT2573_IFACE_INDEX 0 diff --git a/sys/dev/usb/if_rumvar.h b/sys/dev/usb/if_rumvar.h index ea5a2676ff4..966cbf460bd 100644 --- a/sys/dev/usb/if_rumvar.h +++ b/sys/dev/usb/if_rumvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_rumvar.h,v 1.9 2011/02/21 23:50:42 jmcneill Exp $ */ +/* $NetBSD: if_rumvar.h,v 1.10 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_rumvar.h,v 1.7 2006/11/13 20:06:38 damien Exp $ */ /*- @@ -57,7 +57,7 @@ struct rum_softc; struct rum_tx_data { struct rum_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; struct mbuf *m; struct ieee80211_node *ni; @@ -65,7 +65,7 @@ struct rum_tx_data { struct rum_rx_data { struct rum_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; struct mbuf *m; }; @@ -78,8 +78,8 @@ struct rum_softc { int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int); - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device * sc_udev; + struct usbd_interface * sc_iface; int sc_flags; #define RT2573_FWLOADED (1 << 0) @@ -92,10 +92,10 @@ struct rum_softc { uint8_t rf_rev; uint8_t rffreq; - usbd_xfer_handle amrr_xfer; + struct usbd_xfer * amrr_xfer; - usbd_pipe_handle sc_rx_pipeh; - usbd_pipe_handle sc_tx_pipeh; + struct usbd_pipe * sc_rx_pipeh; + struct usbd_pipe * sc_tx_pipeh; enum ieee80211_state sc_state; int sc_arg; diff --git a/sys/dev/usb/if_run.c b/sys/dev/usb/if_run.c index d3f3bcb1050..4efec650eca 100644 --- a/sys/dev/usb/if_run.c +++ b/sys/dev/usb/if_run.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_run.c,v 1.11 2015/03/13 15:33:04 nonaka Exp $ */ +/* $NetBSD: if_run.c,v 1.12 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_run.c,v 1.90 2012/03/24 15:11:04 jsg Exp $ */ /*- @@ -23,7 +23,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_run.c,v 1.11 2015/03/13 15:33:04 nonaka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_run.c,v 1.12 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/sockio.h> @@ -368,9 +368,9 @@ static void run_calibrate_to(void *); static void run_calibrate_cb(struct run_softc *, void *); static void run_newassoc(struct ieee80211_node *, int); static void run_rx_frame(struct run_softc *, uint8_t *, int); -static void run_rxeof(usbd_xfer_handle, usbd_private_handle, +static void run_rxeof(struct usbd_xfer *, void *, usbd_status); -static void run_txeof(usbd_xfer_handle, usbd_private_handle, +static void run_txeof(struct usbd_xfer *, void *, usbd_status); static int run_tx(struct run_softc *, struct mbuf *, struct ieee80211_node *); @@ -451,17 +451,17 @@ firmware_load(const char *dname, const char *iname, uint8_t **ucodep, int error; if ((error = firmware_open(dname, iname, &fh)) != 0) - return (error); + return error; *sizep = firmware_get_size(fh); if ((*ucodep = firmware_malloc(*sizep)) == NULL) { firmware_close(fh); - return (ENOMEM); + return ENOMEM; } if ((error = firmware_read(fh, 0, *ucodep, *sizep)) != 0) firmware_free(*ucodep, *sizep); firmware_close(fh); - return (error); + return error; } static int @@ -469,7 +469,7 @@ run_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (usb_lookup(run_devs, uaa->vendor, uaa->product) != NULL) ? + return (usb_lookup(run_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL) ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } @@ -490,7 +490,7 @@ run_attach(device_t parent, device_t self, void *aux) aprint_normal("\n"); sc->sc_dev = self; - sc->sc_udev = uaa->device; + sc->sc_udev = uaa->uaa_device; devinfop = usbd_devinfo_alloc(sc->sc_udev, 0); aprint_normal_dev(sc->sc_dev, "%s\n", devinfop); @@ -676,7 +676,7 @@ run_detach(device_t self, int flags) int s; if (ifp->if_softc == NULL) - return (0); + return 0; pmf_device_deregister(self); @@ -701,7 +701,7 @@ run_detach(device_t self, int flags) callout_destroy(&sc->scan_to); callout_destroy(&sc->calib_to); - return (0); + return 0; } static int @@ -712,9 +712,9 @@ run_activate(device_t self, enum devact act) switch (act) { case DVACT_DEACTIVATE: if_deactivate(sc->sc_ic.ic_ifp); - return (0); + return 0; default: - return (EOPNOTSUPP); + return EOPNOTSUPP; } } @@ -733,20 +733,16 @@ run_alloc_rx_ring(struct run_softc *sc) data->sc = sc; /* backpointer for callbacks */ - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { - error = ENOMEM; + error = usbd_create_xfer(sc->rxq.pipeh, RUN_MAX_RXSZ, + USBD_SHORT_XFER_OK, 0, &data->xfer); + if (error) goto fail; - } - data->buf = usbd_alloc_buffer(data->xfer, RUN_MAX_RXSZ); - if (data->buf == NULL) { - error = ENOMEM; - goto fail; - } + + data->buf = usbd_get_buffer(data->xfer); } if (error != 0) fail: run_free_rx_ring(sc); - return (error); + return error; } static void @@ -757,14 +753,16 @@ run_free_rx_ring(struct run_softc *sc) if (rxq->pipeh != NULL) { usbd_abort_pipe(rxq->pipeh); - usbd_close_pipe(rxq->pipeh); - rxq->pipeh = NULL; } for (i = 0; i < RUN_RX_RING_COUNT; i++) { if (rxq->data[i].xfer != NULL) - usbd_free_xfer(rxq->data[i].xfer); + usbd_destroy_xfer(rxq->data[i].xfer); rxq->data[i].xfer = NULL; } + if (rxq->pipeh != NULL) { + usbd_close_pipe(rxq->pipeh); + rxq->pipeh = NULL; + } } static int @@ -785,23 +783,19 @@ run_alloc_tx_ring(struct run_softc *sc, int qid) data->sc = sc; /* backpointer for callbacks */ data->qid = qid; - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { - error = ENOMEM; + error = usbd_create_xfer(txq->pipeh, RUN_MAX_TXSZ, + USBD_FORCE_SHORT_XFER, 0, &data->xfer); + if (error) goto fail; - } - data->buf = usbd_alloc_buffer(data->xfer, RUN_MAX_TXSZ); - if (data->buf == NULL) { - error = ENOMEM; - goto fail; - } + + data->buf = usbd_get_buffer(data->xfer); /* zeroize the TXD + TXWI part */ - memset(data->buf, 0, sizeof (struct rt2870_txd) + - sizeof (struct rt2860_txwi)); + memset(data->buf, 0, sizeof(struct rt2870_txd) + + sizeof(struct rt2860_txwi)); } if (error != 0) fail: run_free_tx_ring(sc, qid); - return (error); + return error; } static void @@ -817,7 +811,7 @@ run_free_tx_ring(struct run_softc *sc, int qid) } for (i = 0; i < RUN_TX_RING_COUNT; i++) { if (txq->data[i].xfer != NULL) - usbd_free_xfer(txq->data[i].xfer); + usbd_destroy_xfer(txq->data[i].xfer); txq->data[i].xfer = NULL; } } @@ -843,13 +837,13 @@ run_load_microcode(struct run_softc *sc) if ((error = firmware_load("run", fwname, &ucode, &size)) != 0) { aprint_error_dev(sc->sc_dev, "error %d, could not read firmware %s\n", error, fwname); - return (error); + return error; } if (size != 4096) { aprint_error_dev(sc->sc_dev, "invalid firmware size (should be 4KB)\n"); firmware_free(ucode, size); - return (EINVAL); + return EINVAL; } run_read(sc, RT2860_ASIC_VER_ID, &tmp); @@ -865,17 +859,17 @@ run_load_microcode(struct run_softc *sc) USETW(req.wIndex, 0); USETW(req.wLength, 0); if ((error = usbd_do_request(sc->sc_udev, &req, NULL)) != 0) - return (error); + return error; usbd_delay_ms(sc->sc_udev, 10); run_write(sc, RT2860_H2M_MAILBOX, 0); if ((error = run_mcu_cmd(sc, RT2860_MCU_CMD_RFRESET, 0)) != 0) - return (error); + return error; /* wait until microcontroller is ready */ for (ntries = 0; ntries < 1000; ntries++) { if ((error = run_read(sc, RT2860_SYS_CTRL, &tmp)) != 0) - return (error); + return error; if (tmp & RT2860_MCU_READY) break; DELAY(1000); @@ -883,13 +877,13 @@ run_load_microcode(struct run_softc *sc) if (ntries == 1000) { aprint_error_dev(sc->sc_dev, "timeout waiting for MCU to initialize\n"); - return (ETIMEDOUT); + return ETIMEDOUT; } sc->sc_flags |= RUN_FWLOADED; DPRINTF(("microcode successfully loaded after %d tries\n", ntries)); - return (0); + return 0; } static int @@ -911,12 +905,12 @@ run_read(struct run_softc *sc, uint16_t reg, uint32_t *val) uint32_t tmp; int error; - error = run_read_region_1(sc, reg, (uint8_t *)&tmp, sizeof tmp); + error = run_read_region_1(sc, reg, (uint8_t *)&tmp, sizeof(tmp)); if (error == 0) *val = le32toh(tmp); else *val = 0xffffffff; - return (error); + return error; } static int @@ -952,7 +946,7 @@ run_write(struct run_softc *sc, uint16_t reg, uint32_t val) if ((error = run_write_2(sc, reg, val & 0xffff)) == 0) error = run_write_2(sc, reg + 2, val >> 16); - return (error); + return error; } static int @@ -968,7 +962,7 @@ run_write_region_1(struct run_softc *sc, uint16_t reg, const uint8_t *buf, KASSERT((len & 1) == 0); for (i = 0; i < len && error == 0; i += 2) error = run_write_2(sc, reg + i, buf[i] | buf[i + 1] << 8); - return (error); + return error; #else usb_device_request_t req; @@ -988,7 +982,7 @@ run_set_region_4(struct run_softc *sc, uint16_t reg, uint32_t val, int count) for (; count > 0 && error == 0; count--, reg += 4) error = run_write(sc, reg, val); - return (error); + return error; } /* Read 16-bit from eFUSE ROM (RT3070 only.) */ @@ -1000,7 +994,7 @@ run_efuse_read_2(struct run_softc *sc, uint16_t addr, uint16_t *val) int error, ntries; if ((error = run_read(sc, RT3070_EFUSE_CTRL, &tmp)) != 0) - return (error); + return error; addr *= 2; /*- @@ -1015,25 +1009,25 @@ run_efuse_read_2(struct run_softc *sc, uint16_t addr, uint16_t *val) run_write(sc, RT3070_EFUSE_CTRL, tmp); for (ntries = 0; ntries < 100; ntries++) { if ((error = run_read(sc, RT3070_EFUSE_CTRL, &tmp)) != 0) - return (error); + return error; if (!(tmp & RT3070_EFSROM_KICK)) break; DELAY(2); } if (ntries == 100) - return (ETIMEDOUT); + return ETIMEDOUT; if ((tmp & RT3070_EFUSE_AOUT_MASK) == RT3070_EFUSE_AOUT_MASK) { *val = 0xffff; /* address not found */ - return (0); + return 0; } /* determine to which 32-bit register our 16-bit word belongs */ reg = RT3070_EFUSE_DATA3 - (addr & 0xc); if ((error = run_read(sc, reg, &tmp)) != 0) - return (error); + return error; *val = (addr & 2) ? tmp >> 16 : tmp & 0xffff; - return (0); + return 0; } static int @@ -1048,13 +1042,13 @@ run_eeprom_read_2(struct run_softc *sc, uint16_t addr, uint16_t *val) req.bRequest = RT2870_EEPROM_READ; USETW(req.wValue, 0); USETW(req.wIndex, addr); - USETW(req.wLength, sizeof tmp); + USETW(req.wLength, sizeof(tmp)); error = usbd_do_request(sc->sc_udev, &req, &tmp); if (error == 0) *val = le16toh(tmp); else *val = 0xffff; - return (error); + return error; } static __inline int @@ -1073,12 +1067,12 @@ run_rt2870_rf_write(struct run_softc *sc, uint8_t reg, uint32_t val) for (ntries = 0; ntries < 10; ntries++) { if ((error = run_read(sc, RT2860_RF_CSR_CFG0, &tmp)) != 0) - return (error); + return error; if (!(tmp & RT2860_RF_REG_CTRL)) break; } if (ntries == 10) - return (ETIMEDOUT); + return ETIMEDOUT; /* RF registers are 24-bit on the RT2860 */ tmp = RT2860_RF_REG_CTRL | 24 << RT2860_RF_REG_WIDTH_SHIFT | @@ -1094,28 +1088,28 @@ run_rt3070_rf_read(struct run_softc *sc, uint8_t reg, uint8_t *val) for (ntries = 0; ntries < 100; ntries++) { if ((error = run_read(sc, RT3070_RF_CSR_CFG, &tmp)) != 0) - return (error); + return error; if (!(tmp & RT3070_RF_KICK)) break; } if (ntries == 100) - return (ETIMEDOUT); + return ETIMEDOUT; tmp = RT3070_RF_KICK | reg << 8; if ((error = run_write(sc, RT3070_RF_CSR_CFG, tmp)) != 0) - return (error); + return error; for (ntries = 0; ntries < 100; ntries++) { if ((error = run_read(sc, RT3070_RF_CSR_CFG, &tmp)) != 0) - return (error); + return error; if (!(tmp & RT3070_RF_KICK)) break; } if (ntries == 100) - return (ETIMEDOUT); + return ETIMEDOUT; *val = tmp & 0xff; - return (0); + return 0; } static int @@ -1126,12 +1120,12 @@ run_rt3070_rf_write(struct run_softc *sc, uint8_t reg, uint8_t val) for (ntries = 0; ntries < 10; ntries++) { if ((error = run_read(sc, RT3070_RF_CSR_CFG, &tmp)) != 0) - return (error); + return error; if (!(tmp & RT3070_RF_KICK)) break; } if (ntries == 10) - return (ETIMEDOUT); + return ETIMEDOUT; tmp = RT3070_RF_WRITE | RT3070_RF_KICK | reg << 8 | val; return run_write(sc, RT3070_RF_CSR_CFG, tmp); @@ -1145,28 +1139,28 @@ run_bbp_read(struct run_softc *sc, uint8_t reg, uint8_t *val) for (ntries = 0; ntries < 10; ntries++) { if ((error = run_read(sc, RT2860_BBP_CSR_CFG, &tmp)) != 0) - return (error); + return error; if (!(tmp & RT2860_BBP_CSR_KICK)) break; } if (ntries == 10) - return (ETIMEDOUT); + return ETIMEDOUT; tmp = RT2860_BBP_CSR_READ | RT2860_BBP_CSR_KICK | reg << 8; if ((error = run_write(sc, RT2860_BBP_CSR_CFG, tmp)) != 0) - return (error); + return error; for (ntries = 0; ntries < 10; ntries++) { if ((error = run_read(sc, RT2860_BBP_CSR_CFG, &tmp)) != 0) - return (error); + return error; if (!(tmp & RT2860_BBP_CSR_KICK)) break; } if (ntries == 10) - return (ETIMEDOUT); + return ETIMEDOUT; *val = tmp & 0xff; - return (0); + return 0; } static int @@ -1177,12 +1171,12 @@ run_bbp_write(struct run_softc *sc, uint8_t reg, uint8_t val) for (ntries = 0; ntries < 10; ntries++) { if ((error = run_read(sc, RT2860_BBP_CSR_CFG, &tmp)) != 0) - return (error); + return error; if (!(tmp & RT2860_BBP_CSR_KICK)) break; } if (ntries == 10) - return (ETIMEDOUT); + return ETIMEDOUT; tmp = RT2860_BBP_CSR_KICK | reg << 8 | val; return run_write(sc, RT2860_BBP_CSR_CFG, tmp); @@ -1199,17 +1193,17 @@ run_mcu_cmd(struct run_softc *sc, uint8_t cmd, uint16_t arg) for (ntries = 0; ntries < 100; ntries++) { if ((error = run_read(sc, RT2860_H2M_MAILBOX, &tmp)) != 0) - return (error); + return error; if (!(tmp & RT2860_H2M_BUSY)) break; } if (ntries == 100) - return (ETIMEDOUT); + return ETIMEDOUT; tmp = RT2860_H2M_BUSY | RT2860_TOKEN_NO_INTR << 16 | arg; if ((error = run_write(sc, RT2860_H2M_MAILBOX, tmp)) == 0) error = run_write(sc, RT2860_HOST_CMD, cmd); - return (error); + return error; } /* @@ -1230,7 +1224,7 @@ b4inc(uint32_t b32, int8_t delta) b4 = 0xf; b32 = b32 >> 4 | b4 << 28; } - return (b32); + return b32; } static const char * @@ -1500,15 +1494,15 @@ run_read_eeprom(struct run_softc *sc) sc->rssi_5ghz[ant] = 0; } } - return (0); + return 0; } static struct ieee80211_node * run_node_alloc(struct ieee80211_node_table *nt) { struct run_node *rn = - malloc(sizeof (struct run_node), M_DEVBUF, M_NOWAIT | M_ZERO); - return (rn) ? &rn->ni : NULL; + malloc(sizeof(struct run_node), M_DEVBUF, M_NOWAIT | M_ZERO); + return rn ? &rn->ni : NULL; } static int @@ -1521,7 +1515,7 @@ run_media_change(struct ifnet *ifp) error = ieee80211_media_change(ifp); if (error != ENETRESET) - return (error); + return error; if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) { rate = ic->ic_sup_rates[ic->ic_curmode]. @@ -1535,7 +1529,7 @@ run_media_change(struct ifnet *ifp) if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) run_init(ifp); - return (0); + return 0; } static void @@ -1584,7 +1578,7 @@ run_do_async(struct run_softc *sc, void (*cb)(struct run_softc *, void *), s = splusb(); cmd = &ring->cmd[ring->cur]; cmd->cb = cb; - KASSERT(len <= sizeof (cmd->data)); + KASSERT(len <= sizeof(cmd->data)); memcpy(cmd->data, arg, len); ring->cur = (ring->cur + 1) % RUN_HOST_CMD_RING_COUNT; @@ -1606,8 +1600,8 @@ run_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) /* do it in a process context */ cmd.state = nstate; cmd.arg = arg; - run_do_async(sc, run_newstate_cb, &cmd, sizeof cmd); - return (0); + run_do_async(sc, run_newstate_cb, &cmd, sizeof(cmd)); + return 0; } static void @@ -1682,7 +1676,7 @@ run_newstate_cb(struct run_softc *sc, void *arg) /* clear statistic registers used by AMRR */ run_read_region_1(sc, RT2860_TX_STA_CNT0, - (uint8_t *)sta, sizeof sta); + (uint8_t *)sta, sizeof(sta)); /* start calibration timer */ callout_schedule(&sc->calib_to, hz); } @@ -1703,7 +1697,7 @@ run_updateedca(struct ieee80211com *ic) /* do it in a process context */ run_do_async(ic->ic_ifp->if_softc, run_updateedca_cb, NULL, 0); - return (0); + return 0; } /* ARGSUSED */ @@ -1760,7 +1754,7 @@ run_set_key(struct ieee80211com *ic, const struct ieee80211_key *k, /* do it in a process context */ cmd.key = *k; cmd.associd = (ni != NULL) ? ni->ni_associd : 0; - run_do_async(sc, run_set_key_cb, &cmd, sizeof cmd); + run_do_async(sc, run_set_key_cb, &cmd, sizeof(cmd)); return 1; } @@ -1825,7 +1819,7 @@ run_set_key_cb(struct run_softc *sc, void *arg) (k->wk_flags & IEEE80211_KEY_XMIT)) { /* set initial packet number in IV+EIV */ if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP) { - memset(iv, 0, sizeof iv); + memset(iv, 0, sizeof(iv)); iv[3] = sc->sc_ic.ic_crypto.cs_def_txkey << 6; } else { if (k->wk_cipher->ic_cipher == IEEE80211_CIPHER_TKIP) { @@ -1870,7 +1864,7 @@ run_delete_key(struct ieee80211com *ic, const struct ieee80211_key *k) /* do it in a process context */ cmd.key = *k; cmd.associd = (ni != NULL) ? ni->ni_associd : 0; - run_do_async(sc, run_delete_key_cb, &cmd, sizeof cmd); + run_do_async(sc, run_delete_key_cb, &cmd, sizeof(cmd)); return 1; } @@ -1920,7 +1914,7 @@ run_calibrate_cb(struct run_softc *sc, void *arg) /* read statistic counters (clear on read) and update AMRR state */ error = run_read_region_1(sc, RT2860_TX_STA_CNT0, (uint8_t *)sta, - sizeof sta); + sizeof(sta)); if (error != 0) goto skip; @@ -2002,7 +1996,7 @@ run_maxrssi_chain(struct run_softc *sc, const struct rt2860_rxwi *rxwi) if (rxwi->rssi[2] > rxwi->rssi[rxchain]) rxchain = 2; } - return (rxchain); + return rxchain; } static void @@ -2146,7 +2140,7 @@ run_rx_frame(struct run_softc *sc, uint8_t *buf, int dmalen) } static void -run_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +run_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct run_rx_data *data = priv; struct run_softc *sc = data->sc; @@ -2184,19 +2178,19 @@ run_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) dmalen + 8, xferlen)); break; } - run_rx_frame(sc, buf + sizeof (uint32_t), dmalen); + run_rx_frame(sc, buf + sizeof(uint32_t), dmalen); buf += dmalen + 8; xferlen -= dmalen + 8; } skip: /* setup a new transfer */ - usbd_setup_xfer(xfer, sc->rxq.pipeh, data, data->buf, RUN_MAX_RXSZ, - USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, run_rxeof); + usbd_setup_xfer(xfer, data, data->buf, RUN_MAX_RXSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, run_rxeof); (void)usbd_transfer(data->xfer); } static void -run_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +run_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct run_tx_data *data = priv; struct run_softc *sc = data->sc; @@ -2247,7 +2241,7 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni) k = ieee80211_crypto_encap(ic, ni, m); if (k == NULL) { m_freem(m); - return (ENOBUFS); + return ENOBUFS; } /* packet header may have moved, reset our local pointer */ @@ -2284,7 +2278,7 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni) /* get MCS code from rate index */ mcs = rt2860_rates[ridx].mcs; - xferlen = sizeof (*txwi) + m->m_pkthdr.len; + xferlen = sizeof(*txwi) + m->m_pkthdr.len; /* roundup to 32-bit alignment */ xferlen = (xferlen + 3) & ~3; @@ -2347,14 +2341,14 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni) m_copydata(m, 0, m->m_pkthdr.len, (void *)(txwi + 1)); m_freem(m); - xferlen += sizeof (*txd) + 4; + xferlen += sizeof(*txd) + 4; - usbd_setup_xfer(data->xfer, ring->pipeh, data, data->buf, xferlen, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUN_TX_TIMEOUT, run_txeof); + usbd_setup_xfer(data->xfer, data, data->buf, xferlen, + USBD_FORCE_SHORT_XFER, RUN_TX_TIMEOUT, run_txeof); error = usbd_transfer(data->xfer); if (__predict_false(error != USBD_IN_PROGRESS && error != USBD_NORMAL_COMPLETION)) - return (error); + return error; ieee80211_free_node(ni); @@ -2362,7 +2356,7 @@ run_tx(struct run_softc *sc, struct mbuf *m, struct ieee80211_node *ni) if (++ring->queued >= RUN_TX_RING_COUNT) sc->qfullmsk |= 1 << qid; - return (0); + return 0; } static void @@ -2502,7 +2496,7 @@ run_ioctl(struct ifnet *ifp, u_long cmd, void *data) splx(s); - return (error); + return error; } static void @@ -2880,7 +2874,7 @@ run_set_chan(struct run_softc *sc, struct ieee80211_channel *c) chan = ieee80211_chan2ieee(ic, c); if (chan == 0 || chan == IEEE80211_CHAN_ANY) - return (EINVAL); + return EINVAL; if (sc->mac_ver == 0x3572) run_rt3572_set_chan(sc, chan); @@ -2903,7 +2897,7 @@ run_set_chan(struct run_softc *sc, struct ieee80211_channel *c) run_select_chan_group(sc, group); DELAY(1000); - return (0); + return 0; } static void @@ -3060,7 +3054,7 @@ run_rssi2dbm(struct run_softc *sc, uint8_t rssi, uint8_t rxchain) } else delta = sc->rssi_2ghz[rxchain] - sc->lna[0]; - return (-12 - delta - rssi); + return -12 - delta - rssi; } static int @@ -3072,12 +3066,12 @@ run_bbp_init(struct run_softc *sc) /* wait for BBP to wake up */ for (ntries = 0; ntries < 20; ntries++) { if ((error = run_bbp_read(sc, 0, &bbp0)) != 0) - return (error); + return error; if (bbp0 != 0 && bbp0 != 0xff) break; } if (ntries == 20) - return (ETIMEDOUT); + return ETIMEDOUT; /* initialize BBP registers to default values */ for (i = 0; i < (int)__arraycount(rt2860_def_bbp); i++) { @@ -3097,7 +3091,7 @@ run_bbp_init(struct run_softc *sc) run_bbp_write(sc, 69, 0x16); run_bbp_write(sc, 73, 0x12); } - return (0); + return 0; } static int @@ -3230,7 +3224,7 @@ run_rt3070_rf_init(struct run_softc *sc) rf |= 0x03; run_rt3070_rf_write(sc, 27, rf); } - return (0); + return 0; } static int @@ -3262,7 +3256,7 @@ run_rt3070_filter_calib(struct run_softc *sc, uint8_t init, uint8_t target, break; } if (ntries == 100) - return (ETIMEDOUT); + return ETIMEDOUT; /* set power and frequency of stopband test tone */ run_bbp_write(sc, 24, 0x06); @@ -3295,7 +3289,7 @@ run_rt3070_filter_calib(struct run_softc *sc, uint8_t init, uint8_t target, run_rt3070_rf_read(sc, 22, &rf22); run_rt3070_rf_write(sc, 22, rf22 & ~0x01); - return (0); + return 0; } static void @@ -3385,13 +3379,13 @@ run_txrx_enable(struct run_softc *sc) run_write(sc, RT2860_MAC_SYS_CTRL, RT2860_MAC_TX_EN); for (ntries = 0; ntries < 200; ntries++) { if ((error = run_read(sc, RT2860_WPDMA_GLO_CFG, &tmp)) != 0) - return (error); + return error; if ((tmp & (RT2860_TX_DMA_BUSY | RT2860_RX_DMA_BUSY)) == 0) break; DELAY(1000); } if (ntries == 200) - return (ETIMEDOUT); + return ETIMEDOUT; DELAY(50); @@ -3418,7 +3412,7 @@ run_txrx_enable(struct run_softc *sc) run_write(sc, RT2860_MAC_SYS_CTRL, RT2860_MAC_RX_EN | RT2860_MAC_TX_EN); - return (0); + return 0; } static int @@ -3624,9 +3618,8 @@ run_init(struct ifnet *ifp) for (i = 0; i < RUN_RX_RING_COUNT; i++) { struct run_rx_data *data = &sc->rxq.data[i]; - usbd_setup_xfer(data->xfer, sc->rxq.pipeh, data, data->buf, - RUN_MAX_RXSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, run_rxeof); + usbd_setup_xfer(data->xfer, data, data->buf, RUN_MAX_RXSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, run_rxeof); error = usbd_transfer(data->xfer); if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) @@ -3646,7 +3639,7 @@ run_init(struct ifnet *ifp) if (error != 0) fail: run_stop(ifp, 1); - return (error); + return error; } static void @@ -3708,9 +3701,9 @@ run_setup_beacon(struct run_softc *sc) int ridx; if ((m = ieee80211_beacon_alloc(ic, ic->ic_bss, &sc->sc_bo)) == NULL) - return (ENOBUFS); + return ENOBUFS; - memset(&txwi, 0, sizeof txwi); + memset(&txwi, 0, sizeof(txwi)); txwi.wcid = 0xff; txwi.len = htole16(m->m_pkthdr.len); /* send beacons at the lowest available rate */ @@ -3723,13 +3716,13 @@ run_setup_beacon(struct run_softc *sc) txwi.flags = RT2860_TX_TS; run_write_region_1(sc, RT2860_BCN_BASE(0), - (uint8_t *)&txwi, sizeof txwi); - run_write_region_1(sc, RT2860_BCN_BASE(0) + sizeof txwi, + (uint8_t *)&txwi, sizeof(txwi)); + run_write_region_1(sc, RT2860_BCN_BASE(0) + sizeof(txwi), mtod(m, uint8_t *), m->m_pkthdr.len); m_freem(m); - return (0); + return 0; } #endif @@ -3750,14 +3743,14 @@ if_run_modcmd(modcmd_t cmd, void *arg) error = config_init_component(cfdriver_ioconf_run, cfattach_ioconf_run, cfdata_ioconf_run); #endif - return (error); + return error; case MODULE_CMD_FINI: #ifdef _MODULE error = config_fini_component(cfdriver_ioconf_run, cfattach_ioconf_run, cfdata_ioconf_run); #endif - return (error); + return error; default: - return (ENOTTY); + return ENOTTY; } } diff --git a/sys/dev/usb/if_runvar.h b/sys/dev/usb/if_runvar.h index 56fc1ec9914..1ce657f09c9 100644 --- a/sys/dev/usb/if_runvar.h +++ b/sys/dev/usb/if_runvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_runvar.h,v 1.1 2012/05/30 14:30:35 nonaka Exp $ */ +/* $NetBSD: if_runvar.h,v 1.2 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_runvar.h,v 1.8 2010/02/08 18:46:47 damien Exp $ */ /*- @@ -20,16 +20,16 @@ #define RUN_MAX_RXSZ \ 4096 #if 0 - (sizeof (uint32_t) + \ - sizeof (struct rt2860_rxwi) + \ - sizeof (uint16_t) + \ + (sizeof(uint32_t) + \ + sizeof(struct rt2860_rxwi) + \ + sizeof(uint16_t) + \ MCLBYTES + \ - sizeof (struct rt2870_rxd)) + sizeof(struct rt2870_rxd)) #endif /* NB: "11" is the maximum number of padding bytes needed for Tx */ #define RUN_MAX_TXSZ \ - (sizeof (struct rt2870_txd) + \ - sizeof (struct rt2860_rxwi) + \ + (sizeof(struct rt2870_txd) + \ + sizeof(struct rt2860_rxwi) + \ MCLBYTES + 11) #define RUN_TX_TIMEOUT 5000 /* ms */ @@ -78,20 +78,20 @@ struct run_softc; struct run_tx_data { struct run_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; uint8_t qid; }; struct run_rx_data { struct run_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; }; struct run_tx_ring { struct run_tx_data data[RUN_TX_RING_COUNT]; - usbd_pipe_handle pipeh; + struct usbd_pipe * pipeh; int cur; int queued; uint8_t pipe_no; @@ -99,7 +99,7 @@ struct run_tx_ring { struct run_rx_ring { struct run_rx_data data[RUN_RX_RING_COUNT]; - usbd_pipe_handle pipeh; + struct usbd_pipe * pipeh; uint8_t pipe_no; }; @@ -142,8 +142,8 @@ struct run_softc { int (*sc_srom_read)(struct run_softc *, uint16_t, uint16_t *); - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device * sc_udev; + struct usbd_interface * sc_iface; uint16_t mac_ver; uint16_t mac_rev; diff --git a/sys/dev/usb/if_smsc.c b/sys/dev/usb/if_smsc.c index 8d47c4b7f9e..1de541b5a15 100644 --- a/sys/dev/usb/if_smsc.c +++ b/sys/dev/usb/if_smsc.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_smsc.c,v 1.26 2016/03/07 10:52:17 skrll Exp $ */ +/* $NetBSD: if_smsc.c,v 1.27 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_smsc.c,v 1.4 2012/09/27 12:38:11 jsg Exp $ */ /* $FreeBSD: src/sys/dev/usb/net/if_smsc.c,v 1.1 2012/08/15 04:03:55 gonzo Exp $ */ @@ -181,8 +181,8 @@ void smsc_unlock_mii(struct smsc_softc *); int smsc_tx_list_init(struct smsc_softc *); int smsc_rx_list_init(struct smsc_softc *); int smsc_encap(struct smsc_softc *, struct mbuf *, int); -void smsc_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -void smsc_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +void smsc_rxeof(struct usbd_xfer *, void *, usbd_status); +void smsc_txeof(struct usbd_xfer *, void *, usbd_status); int smsc_read_reg(struct smsc_softc *, uint32_t, uint32_t *); int smsc_write_reg(struct smsc_softc *, uint32_t, uint32_t); @@ -211,7 +211,7 @@ smsc_read_reg(struct smsc_softc *sc, uint32_t off, uint32_t *data) *data = le32toh(buf); - return (err); + return err; } int @@ -233,7 +233,7 @@ smsc_write_reg(struct smsc_softc *sc, uint32_t off, uint32_t data) if (err != 0) smsc_warn_printf(sc, "Failed to write register 0x%0x\n", off); - return (err); + return err; } int @@ -244,13 +244,13 @@ smsc_wait_for_bits(struct smsc_softc *sc, uint32_t reg, uint32_t bits) for (i = 0; i < 100; i++) { if ((err = smsc_read_reg(sc, reg, &val)) != 0) - return (err); + return err; if (!(val & bits)) - return (0); + return 0; DELAY(5); } - return (1); + return 1; } int @@ -277,7 +277,7 @@ smsc_miibus_readreg(device_t dev, int phy, int reg) done: smsc_unlock_mii(sc); - return (val & 0xFFFF); + return val & 0xFFFF; } void @@ -395,7 +395,7 @@ smsc_ifmedia_upd(struct ifnet *ifp) mii_phy_reset(miisc); } err = mii_mediachg(mii); - return (err); + return err; } void @@ -479,7 +479,7 @@ smsc_sethwcsum(struct smsc_softc *sc) if (err != 0) { smsc_warn_printf(sc, "failed to read SMSC_COE_CTRL (err=%d)\n", err); - return (err); + return err; } /* Enable/disable the Rx checksum */ @@ -500,10 +500,10 @@ smsc_sethwcsum(struct smsc_softc *sc) if (err != 0) { smsc_warn_printf(sc, "failed to write SMSC_COE_CTRL (err=%d)\n", err); - return (err); + return err; } - return (0); + return 0; } int @@ -524,7 +524,7 @@ smsc_setmacaddress(struct smsc_softc *sc, const uint8_t *addr) err = smsc_write_reg(sc, SMSC_MAC_ADDRH, val); done: - return (err); + return err; } void @@ -560,20 +560,6 @@ smsc_init(struct ifnet *ifp) /* Reset the ethernet interface. */ smsc_reset(sc); - /* Init RX ring. */ - if (smsc_rx_list_init(sc) == ENOBUFS) { - aprint_error_dev(sc->sc_dev, "rx list init failed\n"); - splx(s); - return EIO; - } - - /* Init TX ring. */ - if (smsc_tx_list_init(sc) == ENOBUFS) { - aprint_error_dev(sc->sc_dev, "tx list init failed\n"); - splx(s); - return EIO; - } - /* Load the multicast filter. */ smsc_setmulti(sc); @@ -599,13 +585,25 @@ smsc_init(struct ifnet *ifp) return EIO; } + /* Init RX ring. */ + if (smsc_rx_list_init(sc)) { + aprint_error_dev(sc->sc_dev, "rx list init failed\n"); + splx(s); + return EIO; + } + + /* Init TX ring. */ + if (smsc_tx_list_init(sc)) { + aprint_error_dev(sc->sc_dev, "tx list init failed\n"); + splx(s); + return EIO; + } + /* Start up the receive pipe. */ for (i = 0; i < SMSC_RX_LIST_CNT; i++) { c = &sc->sc_cdata.rx_chain[i]; - usbd_setup_xfer(c->sc_xfer, sc->sc_ep[SMSC_ENDPT_RX], - c, c->sc_buf, sc->sc_bufsz, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, smsc_rxeof); + usbd_setup_xfer(c->sc_xfer, c, c->sc_buf, sc->sc_bufsz, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, smsc_rxeof); usbd_transfer(c->sc_xfer); } @@ -690,12 +688,6 @@ smsc_stop(struct ifnet *ifp, int disable) printf("%s: abort rx pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); } - err = usbd_close_pipe(sc->sc_ep[SMSC_ENDPT_RX]); - if (err) { - printf("%s: close rx pipe failed: %s\n", - device_xname(sc->sc_dev), usbd_errstr(err)); - } - sc->sc_ep[SMSC_ENDPT_RX] = NULL; } if (sc->sc_ep[SMSC_ENDPT_TX] != NULL) { @@ -704,12 +696,6 @@ smsc_stop(struct ifnet *ifp, int disable) printf("%s: abort tx pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); } - err = usbd_close_pipe(sc->sc_ep[SMSC_ENDPT_TX]); - if (err) { - printf("%s: close tx pipe failed: %s\n", - device_xname(sc->sc_dev), usbd_errstr(err)); - } - sc->sc_ep[SMSC_ENDPT_TX] = NULL; } if (sc->sc_ep[SMSC_ENDPT_INTR] != NULL) { @@ -718,12 +704,6 @@ smsc_stop(struct ifnet *ifp, int disable) printf("%s: abort intr pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); } - err = usbd_close_pipe(sc->sc_ep[SMSC_ENDPT_INTR]); - if (err) { - printf("%s: close intr pipe failed: %s\n", - device_xname(sc->sc_dev), usbd_errstr(err)); - } - sc->sc_ep[SMSC_ENDPT_INTR] = NULL; } /* Free RX resources. */ @@ -733,7 +713,7 @@ smsc_stop(struct ifnet *ifp, int disable) sc->sc_cdata.rx_chain[i].sc_mbuf = NULL; } if (sc->sc_cdata.rx_chain[i].sc_xfer != NULL) { - usbd_free_xfer(sc->sc_cdata.rx_chain[i].sc_xfer); + usbd_destroy_xfer(sc->sc_cdata.rx_chain[i].sc_xfer); sc->sc_cdata.rx_chain[i].sc_xfer = NULL; } } @@ -745,10 +725,37 @@ smsc_stop(struct ifnet *ifp, int disable) sc->sc_cdata.tx_chain[i].sc_mbuf = NULL; } if (sc->sc_cdata.tx_chain[i].sc_xfer != NULL) { - usbd_free_xfer(sc->sc_cdata.tx_chain[i].sc_xfer); + usbd_destroy_xfer(sc->sc_cdata.tx_chain[i].sc_xfer); sc->sc_cdata.tx_chain[i].sc_xfer = NULL; } } + /* Close pipes */ + if (sc->sc_ep[SMSC_ENDPT_RX] != NULL) { + err = usbd_close_pipe(sc->sc_ep[SMSC_ENDPT_RX]); + if (err) { + printf("%s: close rx pipe failed: %s\n", + device_xname(sc->sc_dev), usbd_errstr(err)); + } + sc->sc_ep[SMSC_ENDPT_RX] = NULL; + } + + if (sc->sc_ep[SMSC_ENDPT_TX] != NULL) { + err = usbd_close_pipe(sc->sc_ep[SMSC_ENDPT_TX]); + if (err) { + printf("%s: close tx pipe failed: %s\n", + device_xname(sc->sc_dev), usbd_errstr(err)); + } + sc->sc_ep[SMSC_ENDPT_TX] = NULL; + } + + if (sc->sc_ep[SMSC_ENDPT_INTR] != NULL) { + err = usbd_close_pipe(sc->sc_ep[SMSC_ENDPT_INTR]); + if (err) { + printf("%s: close intr pipe failed: %s\n", + device_xname(sc->sc_dev), usbd_errstr(err)); + } + sc->sc_ep[SMSC_ENDPT_INTR] = NULL; + } } int @@ -813,7 +820,7 @@ smsc_chip_init(struct smsc_softc *sc) * data/ethernet frames. */ - if (sc->sc_udev->speed == USB_SPEED_HIGH) + if (sc->sc_udev->ud_speed == USB_SPEED_HIGH) burst_cap = 37; else burst_cap = 128; @@ -892,11 +899,11 @@ smsc_chip_init(struct smsc_softc *sc) sc->sc_mac_csr |= SMSC_MAC_CSR_RXEN; smsc_write_reg(sc, SMSC_MAC_CSR, sc->sc_mac_csr); - return (0); + return 0; init_failed: smsc_err_printf(sc, "smsc_chip_init failed (err=%d)\n", err); - return (err); + return err; } int @@ -969,7 +976,7 @@ smsc_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (usb_lookup(smsc_devs, uaa->vendor, uaa->product) != NULL) ? + return (usb_lookup(smsc_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL) ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } @@ -978,7 +985,7 @@ smsc_attach(device_t parent, device_t self, void *aux) { struct smsc_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; + struct usbd_device *dev = uaa->uaa_device; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devinfop; @@ -1016,7 +1023,7 @@ smsc_attach(device_t parent, device_t self, void *aux) id = usbd_get_interface_descriptor(sc->sc_iface); - if (sc->sc_udev->speed >= USB_SPEED_HIGH) + if (sc->sc_udev->ud_speed >= USB_SPEED_HIGH) sc->sc_bufsz = SMSC_MAX_BUFSZ; else sc->sc_bufsz = SMSC_MIN_BUFSZ; @@ -1185,7 +1192,7 @@ smsc_detach(device_t self, int flags) mutex_destroy(&sc->sc_mii_lock); - return (0); + return 0; } void @@ -1229,7 +1236,7 @@ smsc_activate(device_t self, enum devact act) default: return EOPNOTSUPP; } - return (0); + return 0; } void @@ -1248,7 +1255,7 @@ smsc_unlock_mii(struct smsc_softc *sc) } void -smsc_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +smsc_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct smsc_chain *c = (struct smsc_chain *)priv; struct smsc_softc *sc = c->sc_sc; @@ -1416,9 +1423,7 @@ smsc_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) done: /* Setup new transfer. */ - usbd_setup_xfer(xfer, sc->sc_ep[SMSC_ENDPT_RX], - c, c->sc_buf, sc->sc_bufsz, - USBD_SHORT_XFER_OK | USBD_NO_COPY, + usbd_setup_xfer(xfer, c, c->sc_buf, sc->sc_bufsz, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, smsc_rxeof); usbd_transfer(xfer); @@ -1426,7 +1431,7 @@ done: } void -smsc_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +smsc_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct smsc_softc *sc; struct smsc_chain *c; @@ -1483,19 +1488,16 @@ smsc_tx_list_init(struct smsc_softc *sc) c->sc_idx = i; c->sc_mbuf = NULL; if (c->sc_xfer == NULL) { - c->sc_xfer = usbd_alloc_xfer(sc->sc_udev); - if (c->sc_xfer == NULL) - return (ENOBUFS); - c->sc_buf = usbd_alloc_buffer(c->sc_xfer, - sc->sc_bufsz); - if (c->sc_buf == NULL) { - usbd_free_xfer(c->sc_xfer); - return (ENOBUFS); - } + int error = usbd_create_xfer(sc->sc_ep[SMSC_ENDPT_TX], + sc->sc_bufsz, USBD_FORCE_SHORT_XFER, 0, + &c->sc_xfer); + if (error) + ; + c->sc_buf = usbd_get_buffer(c->sc_xfer); } } - return (0); + return 0; } int @@ -1512,19 +1514,15 @@ smsc_rx_list_init(struct smsc_softc *sc) c->sc_idx = i; c->sc_mbuf = NULL; if (c->sc_xfer == NULL) { - c->sc_xfer = usbd_alloc_xfer(sc->sc_udev); - if (c->sc_xfer == NULL) - return (ENOBUFS); - c->sc_buf = usbd_alloc_buffer(c->sc_xfer, - sc->sc_bufsz); - if (c->sc_buf == NULL) { - usbd_free_xfer(c->sc_xfer); - return (ENOBUFS); - } + int error = usbd_create_xfer(sc->sc_ep[SMSC_ENDPT_RX], + sc->sc_bufsz, USBD_SHORT_XFER_OK, 0, &c->sc_xfer); + if (error) + return error; + c->sc_buf = usbd_get_buffer(c->sc_xfer); } } - return (0); + return 0; } struct mbuf * @@ -1534,15 +1532,15 @@ smsc_newbuf(void) MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) - return (NULL); + return NULL; MCLGET(m, M_DONTWAIT); if (!(m->m_flags & M_EXT)) { m_freem(m); - return (NULL); + return NULL; } - return (m); + return m; } int @@ -1577,18 +1575,17 @@ smsc_encap(struct smsc_softc *sc, struct mbuf *m, int idx) c->sc_mbuf = m; - usbd_setup_xfer(c->sc_xfer, sc->sc_ep[SMSC_ENDPT_TX], - c, c->sc_buf, frm_len, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - 10000, smsc_txeof); + usbd_setup_xfer(c->sc_xfer, c, c->sc_buf, frm_len, + USBD_FORCE_SHORT_XFER, 10000, smsc_txeof); err = usbd_transfer(c->sc_xfer); /* XXXNH get task to stop interface */ if (err != USBD_IN_PROGRESS) { smsc_stop(ifp, 0); - return (EIO); + return EIO; } sc->sc_cdata.tx_cnt++; - return (0); + return 0; } diff --git a/sys/dev/usb/if_smscvar.h b/sys/dev/usb/if_smscvar.h index 01fd4f9c822..359c83db75e 100644 --- a/sys/dev/usb/if_smscvar.h +++ b/sys/dev/usb/if_smscvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_smscvar.h,v 1.4 2015/04/14 20:32:36 riastradh Exp $ */ +/* $NetBSD: if_smscvar.h,v 1.5 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_smscreg.h,v 1.2 2012/09/27 12:38:11 jsg Exp $ */ /*- @@ -36,7 +36,7 @@ struct smsc_chain { struct smsc_softc *sc_sc; - usbd_xfer_handle sc_xfer; + struct usbd_xfer *sc_xfer; char *sc_buf; struct mbuf *sc_mbuf; int sc_accum; @@ -54,7 +54,7 @@ struct smsc_cdata { struct smsc_softc { device_t sc_dev; - usbd_device_handle sc_udev; + struct usbd_device * sc_udev; bool sc_dying; uint8_t sc_enaddr[ETHER_ADDR_LEN]; @@ -62,7 +62,7 @@ struct smsc_softc { struct mii_data sc_mii; krndsource_t sc_rnd_source; int sc_phyno; - usbd_interface_handle sc_iface; + struct usbd_interface * sc_iface; /* * The following stores the settings in the mac control (MAC_CSR) @@ -80,7 +80,7 @@ struct smsc_softc { struct usb_task sc_stop_task; int sc_ed[SMSC_ENDPT_MAX]; - usbd_pipe_handle sc_ep[SMSC_ENDPT_MAX]; + struct usbd_pipe * sc_ep[SMSC_ENDPT_MAX]; kmutex_t sc_mii_lock; diff --git a/sys/dev/usb/if_udav.c b/sys/dev/usb/if_udav.c index 634eb414690..77f5da62ea5 100644 --- a/sys/dev/usb/if_udav.c +++ b/sys/dev/usb/if_udav.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_udav.c,v 1.45 2016/02/09 08:32:12 ozaki-r Exp $ */ +/* $NetBSD: if_udav.c,v 1.46 2016/04/23 10:15:31 skrll Exp $ */ /* $nabe: if_udav.c,v 1.3 2003/08/21 16:57:19 nabe Exp $ */ /* @@ -45,7 +45,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.45 2016/02/09 08:32:12 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_udav.c,v 1.46 2016/04/23 10:15:31 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -98,8 +98,8 @@ Static int udav_tx_list_init(struct udav_softc *); Static int udav_newbuf(struct udav_softc *, struct udav_chain *, struct mbuf *); Static void udav_start(struct ifnet *); Static int udav_send(struct udav_softc *, struct mbuf *, int); -Static void udav_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -Static void udav_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void udav_txeof(struct usbd_xfer *, void *, usbd_status); +Static void udav_rxeof(struct usbd_xfer *, void *, usbd_status); Static void udav_tick(void *); Static void udav_tick_task(void *); Static int udav_ioctl(struct ifnet *, u_long, void *); @@ -146,7 +146,7 @@ int udavdebug = 0; static const struct udav_type { struct usb_devno udav_dev; - u_int16_t udav_flags; + uint16_t udav_flags; #define UDAV_EXT_PHY 0x0001 #define UDAV_NO_PHY 0x0002 } udav_devs [] = { @@ -177,8 +177,8 @@ udav_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (udav_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return udav_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } /* Attach */ @@ -187,8 +187,8 @@ udav_attach(device_t parent, device_t self, void *aux) { struct udav_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface; + struct usbd_device *dev = uaa->uaa_device; + struct usbd_interface *iface; usbd_status err; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; @@ -229,7 +229,7 @@ udav_attach(device_t parent, device_t self, void *aux) sc->sc_udev = dev; sc->sc_ctl_iface = iface; - sc->sc_flags = udav_lookup(uaa->vendor, uaa->product)->udav_flags; + sc->sc_flags = udav_lookup(uaa->uaa_vendor, uaa->uaa_product)->udav_flags; /* get interface descriptor */ id = usbd_get_interface_descriptor(sc->sc_ctl_iface); @@ -346,7 +346,7 @@ udav_detach(device_t self, int flags) /* Detached before attached finished */ if (!sc->sc_attached) - return (0); + return 0; callout_stop(&sc->sc_stat_ch); @@ -386,7 +386,7 @@ udav_detach(device_t self, int flags) mutex_destroy(&sc->sc_mii_lock); - return (0); + return 0; } #if 0 @@ -398,13 +398,13 @@ udav_mem_read(struct udav_softc *sc, int offset, void *buf, int len) usbd_status err; if (sc == NULL) - return (0); + return 0; DPRINTFN(0x200, ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (0); + return 0; offset &= 0xffff; len &= 0xff; @@ -424,7 +424,7 @@ udav_mem_read(struct udav_softc *sc, int offset, void *buf, int len) device_xname(sc->sc_dev), __func__, offset, err)); } - return (err); + return err; } /* write memory */ @@ -435,13 +435,13 @@ udav_mem_write(struct udav_softc *sc, int offset, void *buf, int len) usbd_status err; if (sc == NULL) - return (0); + return 0; DPRINTFN(0x200, ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (0); + return 0; offset &= 0xffff; len &= 0xff; @@ -461,7 +461,7 @@ udav_mem_write(struct udav_softc *sc, int offset, void *buf, int len) device_xname(sc->sc_dev), __func__, offset, err)); } - return (err); + return err; } /* write memory */ @@ -472,13 +472,13 @@ udav_mem_write1(struct udav_softc *sc, int offset, unsigned char ch) usbd_status err; if (sc == NULL) - return (0); + return 0; DPRINTFN(0x200, ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (0); + return 0; offset &= 0xffff; @@ -497,7 +497,7 @@ udav_mem_write1(struct udav_softc *sc, int offset, unsigned char ch) device_xname(sc->sc_dev), __func__, offset, err)); } - return (err); + return err; } #endif @@ -509,13 +509,13 @@ udav_csr_read(struct udav_softc *sc, int offset, void *buf, int len) usbd_status err; if (sc == NULL) - return (0); + return 0; DPRINTFN(0x200, ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (0); + return 0; offset &= 0xff; len &= 0xff; @@ -535,7 +535,7 @@ udav_csr_read(struct udav_softc *sc, int offset, void *buf, int len) device_xname(sc->sc_dev), __func__, offset, err)); } - return (err); + return err; } /* write register(s) */ @@ -546,13 +546,13 @@ udav_csr_write(struct udav_softc *sc, int offset, void *buf, int len) usbd_status err; if (sc == NULL) - return (0); + return 0; DPRINTFN(0x200, ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (0); + return 0; offset &= 0xff; len &= 0xff; @@ -572,24 +572,24 @@ udav_csr_write(struct udav_softc *sc, int offset, void *buf, int len) device_xname(sc->sc_dev), __func__, offset, err)); } - return (err); + return err; } Static int udav_csr_read1(struct udav_softc *sc, int offset) { - u_int8_t val = 0; + uint8_t val = 0; if (sc == NULL) - return (0); + return 0; DPRINTFN(0x200, ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (0); + return 0; - return (udav_csr_read(sc, offset, &val, 1) ? 0 : val); + return udav_csr_read(sc, offset, &val, 1) ? 0 : val; } /* write a register */ @@ -600,13 +600,13 @@ udav_csr_write1(struct udav_softc *sc, int offset, unsigned char ch) usbd_status err; if (sc == NULL) - return (0); + return 0; DPRINTFN(0x200, ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (0); + return 0; offset &= 0xff; @@ -625,7 +625,7 @@ udav_csr_write1(struct udav_softc *sc, int offset, unsigned char ch) device_xname(sc->sc_dev), __func__, offset, err)); } - return (err); + return err; } Static int @@ -639,7 +639,7 @@ udav_init(struct ifnet *ifp) DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (EIO); + return EIO; s = splnet(); @@ -662,20 +662,6 @@ udav_init(struct ifnet *ifp) else UDAV_CLRBIT(sc, UDAV_RCR, UDAV_RCR_ALL|UDAV_RCR_PRMSC); - /* Initialize transmit ring */ - if (udav_tx_list_init(sc) == ENOBUFS) { - printf("%s: tx list init failed\n", device_xname(sc->sc_dev)); - splx(s); - return (EIO); - } - - /* Initialize receive ring */ - if (udav_rx_list_init(sc) == ENOBUFS) { - printf("%s: rx list init failed\n", device_xname(sc->sc_dev)); - splx(s); - return (EIO); - } - /* Load the multicast filter */ udav_setmulti(sc); @@ -694,10 +680,34 @@ udav_init(struct ifnet *ifp) if (sc->sc_pipe_tx == NULL || sc->sc_pipe_rx == NULL) { if (udav_openpipes(sc)) { splx(s); - return (EIO); + return EIO; } } + /* Initialize transmit ring */ + if (udav_tx_list_init(sc)) { + printf("%s: tx list init failed\n", device_xname(sc->sc_dev)); + splx(s); + return EIO; + } + + /* Initialize receive ring */ + if (udav_rx_list_init(sc)) { + printf("%s: rx list init failed\n", device_xname(sc->sc_dev)); + splx(s); + return EIO; + } + + /* Start up the receive pipe. */ + for (size_t i = 0; i < UDAV_RX_LIST_CNT; i++) { + struct udav_chain *c = &sc->sc_cdata.udav_rx_chain[i]; + usbd_setup_xfer(c->udav_xfer, c, c->udav_buf, UDAV_BUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, udav_rxeof); + (void)usbd_transfer(c->udav_xfer); + DPRINTF(("%s: %s: start read\n", device_xname(sc->sc_dev), + __func__)); + } + ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; @@ -771,7 +781,7 @@ udav_setmulti(struct udav_softc *sc) struct ifnet *ifp; struct ether_multi *enm; struct ether_multistep step; - u_int8_t hashes[8]; + uint8_t hashes[8]; int h = 0; DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); @@ -826,13 +836,11 @@ udav_setmulti(struct udav_softc *sc) Static int udav_openpipes(struct udav_softc *sc) { - struct udav_chain *c; usbd_status err; - int i; int error = 0; if (sc->sc_dying) - return (EIO); + return EIO; sc->sc_refcnt++; @@ -870,25 +878,11 @@ udav_openpipes(struct udav_softc *sc) goto done; } #endif - - - /* Start up the receive pipe. */ - for (i = 0; i < UDAV_RX_LIST_CNT; i++) { - c = &sc->sc_cdata.udav_rx_chain[i]; - usbd_setup_xfer(c->udav_xfer, sc->sc_pipe_rx, - c, c->udav_buf, UDAV_BUFSZ, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, udav_rxeof); - (void)usbd_transfer(c->udav_xfer); - DPRINTF(("%s: %s: start read\n", device_xname(sc->sc_dev), - __func__)); - } - done: if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); - return (error); + return error; } Static int @@ -903,14 +897,14 @@ udav_newbuf(struct udav_softc *sc, struct udav_chain *c, struct mbuf *m) if (m_new == NULL) { printf("%s: no memory for rx list " "-- packet dropped!\n", device_xname(sc->sc_dev)); - return (ENOBUFS); + return ENOBUFS; } MCLGET(m_new, M_DONTWAIT); if (!(m_new->m_flags & M_EXT)) { printf("%s: no memory for rx list " "-- packet dropped!\n", device_xname(sc->sc_dev)); m_freem(m_new); - return (ENOBUFS); + return ENOBUFS; } m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; } else { @@ -922,7 +916,7 @@ udav_newbuf(struct udav_softc *sc, struct udav_chain *c, struct mbuf *m) m_adj(m_new, ETHER_ALIGN); c->udav_mbuf = m_new; - return (0); + return 0; } @@ -941,20 +935,17 @@ udav_rx_list_init(struct udav_softc *sc) c->udav_sc = sc; c->udav_idx = i; if (udav_newbuf(sc, c, NULL) == ENOBUFS) - return (ENOBUFS); + return ENOBUFS; if (c->udav_xfer == NULL) { - c->udav_xfer = usbd_alloc_xfer(sc->sc_udev); - if (c->udav_xfer == NULL) - return (ENOBUFS); - c->udav_buf = usbd_alloc_buffer(c->udav_xfer, UDAV_BUFSZ); - if (c->udav_buf == NULL) { - usbd_free_xfer(c->udav_xfer); - return (ENOBUFS); - } + int error = usbd_create_xfer(sc->sc_pipe_rx, UDAV_BUFSZ, + USBD_SHORT_XFER_OK, 0, &c->udav_xfer); + if (error) + return error; + c->udav_buf = usbd_get_buffer(c->udav_xfer); } } - return (0); + return 0; } Static int @@ -973,18 +964,15 @@ udav_tx_list_init(struct udav_softc *sc) c->udav_idx = i; c->udav_mbuf = NULL; if (c->udav_xfer == NULL) { - c->udav_xfer = usbd_alloc_xfer(sc->sc_udev); - if (c->udav_xfer == NULL) - return (ENOBUFS); - c->udav_buf = usbd_alloc_buffer(c->udav_xfer, UDAV_BUFSZ); - if (c->udav_buf == NULL) { - usbd_free_xfer(c->udav_xfer); - return (ENOBUFS); - } + int error = usbd_create_xfer(sc->sc_pipe_tx, UDAV_BUFSZ, + USBD_FORCE_SHORT_XFER, 0, &c->udav_xfer); + if (error) + return error; + c->udav_buf = usbd_get_buffer(c->udav_xfer); } } - return (0); + return 0; } Static void @@ -1047,13 +1035,12 @@ udav_send(struct udav_softc *sc, struct mbuf *m, int idx) } /* Frame length is specified in the first 2bytes of the buffer */ - c->udav_buf[0] = (u_int8_t)total_len; - c->udav_buf[1] = (u_int8_t)(total_len >> 8); + c->udav_buf[0] = (uint8_t)total_len; + c->udav_buf[1] = (uint8_t)(total_len >> 8); total_len += 2; - usbd_setup_xfer(c->udav_xfer, sc->sc_pipe_tx, c, c->udav_buf, total_len, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - UDAV_TX_TIMEOUT, udav_txeof); + usbd_setup_xfer(c->udav_xfer, c, c->udav_buf, total_len, + USBD_FORCE_SHORT_XFER, UDAV_TX_TIMEOUT, udav_txeof); /* Transmit */ sc->sc_refcnt++; @@ -1066,7 +1053,7 @@ udav_send(struct udav_softc *sc, struct mbuf *m, int idx) /* Stop the interface */ usb_add_task(sc->sc_udev, &sc->sc_stop_task, USB_TASKQ_DRIVER); - return (EIO); + return EIO; } DPRINTF(("%s: %s: send %d bytes\n", device_xname(sc->sc_dev), @@ -1074,11 +1061,11 @@ udav_send(struct udav_softc *sc, struct mbuf *m, int idx) sc->sc_cdata.udav_tx_cnt++; - return (0); + return 0; } Static void -udav_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, +udav_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct udav_chain *c = priv; @@ -1126,14 +1113,14 @@ udav_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, } Static void -udav_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +udav_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct udav_chain *c = priv; struct udav_softc *sc = c->udav_sc; struct ifnet *ifp = GET_IFP(sc); struct mbuf *m; - u_int32_t total_len; - u_int8_t *pktstat; + uint32_t total_len; + uint8_t *pktstat; int s; DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev),__func__)); @@ -1167,13 +1154,13 @@ udav_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) memcpy(mtod(m, char *), c->udav_buf, total_len); /* first byte in received data */ - pktstat = mtod(m, u_int8_t *); - m_adj(m, sizeof(u_int8_t)); + pktstat = mtod(m, uint8_t *); + m_adj(m, sizeof(uint8_t)); DPRINTF(("%s: RX Status: 0x%02x\n", device_xname(sc->sc_dev), *pktstat)); - total_len = UGETW(mtod(m, u_int8_t *)); - m_adj(m, sizeof(u_int16_t)); + total_len = UGETW(mtod(m, uint8_t *)); + m_adj(m, sizeof(uint16_t)); if (*pktstat & UDAV_RSR_LCS) { ifp->if_collisions++; @@ -1210,9 +1197,8 @@ udav_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) done: /* Setup new transfer */ - usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, c->udav_buf, UDAV_BUFSZ, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, udav_rxeof); + usbd_setup_xfer(xfer, c, c->udav_buf, UDAV_BUFSZ, USBD_SHORT_XFER_OK, + USBD_NO_TIMEOUT, udav_rxeof); sc->sc_refcnt++; usbd_transfer(xfer); if (--sc->sc_refcnt < 0) @@ -1236,7 +1222,7 @@ udav_ioctl(struct ifnet *ifp, u_long cmd, void *data) DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (EIO); + return EIO; s = splnet(); @@ -1249,7 +1235,7 @@ udav_ioctl(struct ifnet *ifp, u_long cmd, void *data) splx(s); - return (error); + return error; } Static void @@ -1304,11 +1290,6 @@ udav_stop(struct ifnet *ifp, int disable) if (err) printf("%s: abort rx pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); - err = usbd_close_pipe(sc->sc_pipe_rx); - if (err) - printf("%s: close rx pipe failed: %s\n", - device_xname(sc->sc_dev), usbd_errstr(err)); - sc->sc_pipe_rx = NULL; } /* TX endpoint */ @@ -1317,11 +1298,6 @@ udav_stop(struct ifnet *ifp, int disable) if (err) printf("%s: abort tx pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); - err = usbd_close_pipe(sc->sc_pipe_tx); - if (err) - printf("%s: close tx pipe failed: %s\n", - device_xname(sc->sc_dev), usbd_errstr(err)); - sc->sc_pipe_tx = NULL; } #if 0 @@ -1347,7 +1323,7 @@ udav_stop(struct ifnet *ifp, int disable) sc->sc_cdata.udav_rx_chain[i].udav_mbuf = NULL; } if (sc->sc_cdata.udav_rx_chain[i].udav_xfer != NULL) { - usbd_free_xfer(sc->sc_cdata.udav_rx_chain[i].udav_xfer); + usbd_destroy_xfer(sc->sc_cdata.udav_rx_chain[i].udav_xfer); sc->sc_cdata.udav_rx_chain[i].udav_xfer = NULL; } } @@ -1359,11 +1335,30 @@ udav_stop(struct ifnet *ifp, int disable) sc->sc_cdata.udav_tx_chain[i].udav_mbuf = NULL; } if (sc->sc_cdata.udav_tx_chain[i].udav_xfer != NULL) { - usbd_free_xfer(sc->sc_cdata.udav_tx_chain[i].udav_xfer); + usbd_destroy_xfer(sc->sc_cdata.udav_tx_chain[i].udav_xfer); sc->sc_cdata.udav_tx_chain[i].udav_xfer = NULL; } } + /* Close pipes */ + /* RX endpoint */ + if (sc->sc_pipe_rx != NULL) { + err = usbd_close_pipe(sc->sc_pipe_rx); + if (err) + printf("%s: close rx pipe failed: %s\n", + device_xname(sc->sc_dev), usbd_errstr(err)); + sc->sc_pipe_rx = NULL; + } + + /* TX endpoint */ + if (sc->sc_pipe_tx != NULL) { + err = usbd_close_pipe(sc->sc_pipe_tx); + if (err) + printf("%s: close tx pipe failed: %s\n", + device_xname(sc->sc_dev), usbd_errstr(err)); + sc->sc_pipe_tx = NULL; + } + if (!ISSET(sc->sc_flags, UDAV_NO_PHY)) sc->sc_link = 0; ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); @@ -1380,7 +1375,7 @@ udav_ifmedia_change(struct ifnet *ifp) DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (0); + return 0; sc->sc_link = 0; if ((rc = mii_mediachg(mii)) == ENXIO) @@ -1490,11 +1485,11 @@ Static int udav_miibus_readreg(device_t dev, int phy, int reg) { struct udav_softc *sc; - u_int8_t val[2]; - u_int16_t data16; + uint8_t val[2]; + uint16_t data16; if (dev == NULL) - return (0); + return 0; sc = device_private(dev); @@ -1506,14 +1501,14 @@ udav_miibus_readreg(device_t dev, int phy, int reg) printf("%s: %s: dying\n", device_xname(sc->sc_dev), __func__); #endif - return (0); + return 0; } /* XXX: one PHY only for the internal PHY */ if (phy != 0) { DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", device_xname(sc->sc_dev), __func__, phy)); - return (0); + return 0; } udav_lock_mii(sc); @@ -1540,14 +1535,14 @@ udav_miibus_readreg(device_t dev, int phy, int reg) DPRINTFN(0xff, ("%s: %s: phy=%d reg=0x%04x => 0x%04x\n", device_xname(sc->sc_dev), __func__, phy, reg, data16)); - return (data16); + return data16; } Static void udav_miibus_writereg(device_t dev, int phy, int reg, int data) { struct udav_softc *sc; - u_int8_t val[2]; + uint8_t val[2]; if (dev == NULL) return; diff --git a/sys/dev/usb/if_udavreg.h b/sys/dev/usb/if_udavreg.h index 31a68a8d037..3344289de92 100644 --- a/sys/dev/usb/if_udavreg.h +++ b/sys/dev/usb/if_udavreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_udavreg.h,v 1.10 2015/04/14 20:32:36 riastradh Exp $ */ +/* $NetBSD: if_udavreg.h,v 1.11 2016/04/23 10:15:31 skrll Exp $ */ /* $nabe: if_udavreg.h,v 1.2 2003/08/21 16:26:40 nabe Exp $ */ /* * Copyright (c) 2003 @@ -148,7 +148,7 @@ struct udav_chain { struct udav_softc *udav_sc; - usbd_xfer_handle udav_xfer; + struct usbd_xfer *udav_xfer; char *udav_buf; struct mbuf *udav_mbuf; int udav_idx; @@ -169,17 +169,17 @@ struct udav_cdata { struct udav_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; + struct usbd_device * sc_udev; /* USB */ - usbd_interface_handle sc_ctl_iface; + struct usbd_interface * sc_ctl_iface; /* int sc_ctl_iface_no; */ int sc_bulkin_no; /* bulk in endpoint */ int sc_bulkout_no; /* bulk out endpoint */ int sc_intrin_no; /* intr in endpoint */ - usbd_pipe_handle sc_pipe_rx; - usbd_pipe_handle sc_pipe_tx; - usbd_pipe_handle sc_pipe_intr; + struct usbd_pipe * sc_pipe_rx; + struct usbd_pipe * sc_pipe_tx; + struct usbd_pipe * sc_pipe_intr; struct callout sc_stat_ch; u_int sc_rx_errs; /* u_int sc_intr_errs; */ @@ -201,5 +201,5 @@ struct udav_softc { struct usb_task sc_tick_task; struct usb_task sc_stop_task; - u_int16_t sc_flags; + uint16_t sc_flags; }; diff --git a/sys/dev/usb/if_upgt.c b/sys/dev/usb/if_upgt.c index dd35ed72c51..095681d9ec7 100644 --- a/sys/dev/usb/if_upgt.c +++ b/sys/dev/usb/if_upgt.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_upgt.c,v 1.13 2016/03/11 18:34:59 christos Exp $ */ +/* $NetBSD: if_upgt.c,v 1.14 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_upgt.c,v 1.49 2010/04/20 22:05:43 tedu Exp $ */ /* @@ -18,7 +18,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_upgt.c,v 1.13 2016/03/11 18:34:59 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_upgt.c,v 1.14 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/callout.h> @@ -119,11 +119,11 @@ static void upgt_start(struct ifnet *); static void upgt_watchdog(struct ifnet *); static void upgt_tx_task(void *); static void upgt_tx_done(struct upgt_softc *, uint8_t *); -static void upgt_rx_cb(usbd_xfer_handle, usbd_private_handle, usbd_status); +static void upgt_rx_cb(struct usbd_xfer *, void *, usbd_status); static void upgt_rx(struct upgt_softc *, uint8_t *, int); static void upgt_setup_rates(struct upgt_softc *); static uint8_t upgt_rx_rate(struct upgt_softc *, const int); -static int upgt_set_macfilter(struct upgt_softc *, uint8_t state); +static int upgt_set_macfilter(struct upgt_softc *, uint8_t); static int upgt_set_channel(struct upgt_softc *, unsigned); static void upgt_set_led(struct upgt_softc *, int); static void upgt_set_led_blink(void *); @@ -136,7 +136,7 @@ static void upgt_free_tx(struct upgt_softc *); static void upgt_free_rx(struct upgt_softc *); static void upgt_free_cmd(struct upgt_softc *); static int upgt_bulk_xmit(struct upgt_softc *, struct upgt_data *, - usbd_pipe_handle, uint32_t *, int); + struct usbd_pipe *, uint32_t *, int); #if 0 static void upgt_hexdump(void *, int); @@ -207,10 +207,10 @@ upgt_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - if (usb_lookup(upgt_devs_1, uaa->vendor, uaa->product) != NULL) + if (usb_lookup(upgt_devs_1, uaa->uaa_vendor, uaa->uaa_product) != NULL) return UMATCH_VENDOR_PRODUCT; - if (usb_lookup(upgt_devs_2, uaa->vendor, uaa->product) != NULL) + if (usb_lookup(upgt_devs_2, uaa->uaa_vendor, uaa->uaa_product) != NULL) return UMATCH_VENDOR_PRODUCT; return UMATCH_NONE; @@ -234,14 +234,14 @@ upgt_attach(device_t parent, device_t self, void *aux) * Attach USB device. */ sc->sc_dev = self; - sc->sc_udev = uaa->device; + sc->sc_udev = uaa->uaa_device; devinfop = usbd_devinfo_alloc(sc->sc_udev, 0); aprint_normal_dev(sc->sc_dev, "%s\n", devinfop); usbd_devinfo_free(devinfop); /* check device type */ - if (upgt_device_type(sc, uaa->vendor, uaa->product) != 0) + if (upgt_device_type(sc, uaa->uaa_vendor, uaa->uaa_product) != 0) return; /* set configuration number */ @@ -399,7 +399,7 @@ upgt_attach_hook(device_t arg) */ struct upgt_data *data_rx = &sc->rx_data; - usbd_setup_xfer(data_rx->xfer, sc->sc_rx_pipeh, data_rx, data_rx->buf, + usbd_setup_xfer(data_rx->xfer, data_rx, data_rx->buf, MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, upgt_rx_cb); error = usbd_transfer(data_rx->xfer); if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { @@ -508,11 +508,9 @@ upgt_detach(device_t self, int flags) /* abort and close TX / RX pipes */ if (sc->sc_tx_pipeh != NULL) { usbd_abort_pipe(sc->sc_tx_pipeh); - usbd_close_pipe(sc->sc_tx_pipeh); } if (sc->sc_rx_pipeh != NULL) { usbd_abort_pipe(sc->sc_rx_pipeh); - usbd_close_pipe(sc->sc_rx_pipeh); } /* free xfers */ @@ -520,6 +518,14 @@ upgt_detach(device_t self, int flags) upgt_free_rx(sc); upgt_free_cmd(sc); + /* Close TX / RX pipes */ + if (sc->sc_tx_pipeh != NULL) { + usbd_close_pipe(sc->sc_tx_pipeh); + } + if (sc->sc_rx_pipeh != NULL) { + usbd_close_pipe(sc->sc_rx_pipeh); + } + /* free firmware */ upgt_fw_free(sc); @@ -1660,9 +1666,8 @@ upgt_tx_task(void *arg) DPRINTF(2, "%s: TX start data sending\n", device_xname(sc->sc_dev)); - usbd_setup_xfer(data_tx->xfer, sc->sc_tx_pipeh, data_tx, - data_tx->buf, len, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - UPGT_USB_TIMEOUT, NULL); + usbd_setup_xfer(data_tx->xfer, data_tx, data_tx->buf, len, + USBD_FORCE_SHORT_XFER, UPGT_USB_TIMEOUT, NULL); error = usbd_transfer(data_tx->xfer); if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { @@ -1730,7 +1735,7 @@ upgt_tx_done(struct upgt_softc *sc, uint8_t *data) } static void -upgt_rx_cb(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +upgt_rx_cb(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct upgt_data *data_rx = priv; struct upgt_softc *sc = data_rx->sc; @@ -1802,7 +1807,7 @@ upgt_rx_cb(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) } skip: /* setup new transfer */ - usbd_setup_xfer(xfer, sc->sc_rx_pipeh, data_rx, data_rx->buf, MCLBYTES, + usbd_setup_xfer(xfer, data_rx, data_rx->buf, MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, upgt_rx_cb); (void)usbd_transfer(xfer); } @@ -2250,19 +2255,15 @@ upgt_alloc_tx(struct upgt_softc *sc) data_tx->sc = sc; - data_tx->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data_tx->xfer == NULL) { + int err = usbd_create_xfer(sc->sc_tx_pipeh, MCLBYTES, 0, 0, + &data_tx->xfer); + if (err) { aprint_error_dev(sc->sc_dev, "could not allocate TX xfer\n"); - return ENOMEM; + return err; } - data_tx->buf = usbd_alloc_buffer(data_tx->xfer, MCLBYTES); - if (data_tx->buf == NULL) { - aprint_error_dev(sc->sc_dev, - "could not allocate TX buffer\n"); - return ENOMEM; - } + data_tx->buf = usbd_get_buffer(data_tx->xfer); } return 0; @@ -2275,18 +2276,14 @@ upgt_alloc_rx(struct upgt_softc *sc) data_rx->sc = sc; - data_rx->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data_rx->xfer == NULL) { + int err = usbd_create_xfer(sc->sc_rx_pipeh, MCLBYTES, + USBD_SHORT_XFER_OK, 0, &data_rx->xfer); + if (err) { aprint_error_dev(sc->sc_dev, "could not allocate RX xfer\n"); - return ENOMEM; + return err; } - data_rx->buf = usbd_alloc_buffer(data_rx->xfer, MCLBYTES); - if (data_rx->buf == NULL) { - aprint_error_dev(sc->sc_dev, - "could not allocate RX buffer\n"); - return ENOMEM; - } + data_rx->buf = usbd_get_buffer(data_rx->xfer); return 0; } @@ -2298,20 +2295,16 @@ upgt_alloc_cmd(struct upgt_softc *sc) data_cmd->sc = sc; - data_cmd->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data_cmd->xfer == NULL) { + int err = usbd_create_xfer(sc->sc_tx_pipeh, MCLBYTES, + USBD_FORCE_SHORT_XFER, 0, &data_cmd->xfer); + if (err) { aprint_error_dev(sc->sc_dev, "could not allocate RX xfer\n"); - return ENOMEM; + return err; } - data_cmd->buf = usbd_alloc_buffer(data_cmd->xfer, MCLBYTES); - if (data_cmd->buf == NULL) { - aprint_error_dev(sc->sc_dev, - "could not allocate RX buffer\n"); - return ENOMEM; - } + data_cmd->buf = usbd_get_buffer(data_cmd->xfer); - mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_SOFTNET); + mutex_init(&sc->sc_mtx, MUTEX_DEFAULT, IPL_NONE); return 0; } @@ -2325,7 +2318,7 @@ upgt_free_tx(struct upgt_softc *sc) struct upgt_data *data_tx = &sc->tx_data[i]; if (data_tx->xfer != NULL) { - usbd_free_xfer(data_tx->xfer); + usbd_destroy_xfer(data_tx->xfer); data_tx->xfer = NULL; } @@ -2339,7 +2332,7 @@ upgt_free_rx(struct upgt_softc *sc) struct upgt_data *data_rx = &sc->rx_data; if (data_rx->xfer != NULL) { - usbd_free_xfer(data_rx->xfer); + usbd_destroy_xfer(data_rx->xfer); data_rx->xfer = NULL; } @@ -2352,7 +2345,7 @@ upgt_free_cmd(struct upgt_softc *sc) struct upgt_data *data_cmd = &sc->cmd_data; if (data_cmd->xfer != NULL) { - usbd_free_xfer(data_cmd->xfer); + usbd_destroy_xfer(data_cmd->xfer); data_cmd->xfer = NULL; } @@ -2361,13 +2354,12 @@ upgt_free_cmd(struct upgt_softc *sc) static int upgt_bulk_xmit(struct upgt_softc *sc, struct upgt_data *data, - usbd_pipe_handle pipeh, uint32_t *size, int flags) + struct usbd_pipe *pipeh, uint32_t *size, int flags) { usbd_status status; - status = usbd_bulk_transfer(data->xfer, pipeh, - USBD_NO_COPY | flags, UPGT_USB_TIMEOUT, data->buf, size, - "upgt_bulk_xmit"); + status = usbd_bulk_transfer(data->xfer, pipeh, flags, UPGT_USB_TIMEOUT, + data->buf, size); if (status != USBD_NORMAL_COMPLETION) { aprint_error_dev(sc->sc_dev, "%s: error %s\n", __func__, usbd_errstr(status)); diff --git a/sys/dev/usb/if_upgtvar.h b/sys/dev/usb/if_upgtvar.h index f66b6effbdc..a5eb2ff7640 100644 --- a/sys/dev/usb/if_upgtvar.h +++ b/sys/dev/usb/if_upgtvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_upgtvar.h,v 1.1 2010/07/04 15:21:58 tsutsui Exp $ */ +/* $NetBSD: if_upgtvar.h,v 1.2 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_upgtvar.h,v 1.15 2009/08/10 20:02:19 deraadt Exp $ */ /* @@ -77,7 +77,7 @@ struct upgt_tx_radiotap_header { */ struct upgt_data { struct upgt_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; struct ieee80211_node *ni; struct mbuf *m; @@ -398,14 +398,14 @@ struct upgt_softc { struct ethercom sc_ec; #define sc_if sc_ec.ec_if - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device * sc_udev; + struct usbd_interface * sc_iface; int sc_rx_no; int sc_tx_no; struct usb_task sc_task_newstate; struct usb_task sc_task_tx; - usbd_pipe_handle sc_rx_pipeh; - usbd_pipe_handle sc_tx_pipeh; + struct usbd_pipe * sc_rx_pipeh; + struct usbd_pipe * sc_tx_pipeh; struct upgt_data tx_data[UPGT_TX_COUNT]; struct upgt_data rx_data; diff --git a/sys/dev/usb/if_upl.c b/sys/dev/usb/if_upl.c index 662f866bc15..2b480ddd0eb 100644 --- a/sys/dev/usb/if_upl.c +++ b/sys/dev/usb/if_upl.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_upl.c,v 1.50 2016/04/20 09:01:04 knakahara Exp $ */ +/* $NetBSD: if_upl.c,v 1.51 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. * All rights reserved. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_upl.c,v 1.50 2016/04/20 09:01:04 knakahara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_upl.c,v 1.51 2016/04/23 10:15:31 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -45,7 +45,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_upl.c,v 1.50 2016/04/20 09:01:04 knakahara Exp $" #include <sys/callout.h> #include <sys/sockio.h> #include <sys/mbuf.h> -#include <sys/malloc.h> #include <sys/kernel.h> #include <sys/socket.h> @@ -106,15 +105,15 @@ __KERNEL_RCSID(0, "$NetBSD: if_upl.c,v 1.50 2016/04/20 09:01:04 knakahara Exp $" #define UPL_ENDPT_MAX 0x3 struct upl_type { - u_int16_t upl_vid; - u_int16_t upl_did; + uint16_t upl_vid; + uint16_t upl_did; }; struct upl_softc; struct upl_chain { struct upl_softc *upl_sc; - usbd_xfer_handle upl_xfer; + struct usbd_xfer *upl_xfer; char *upl_buf; struct mbuf *upl_mbuf; int upl_idx; @@ -137,12 +136,12 @@ struct upl_softc { struct callout sc_stat_ch; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; - u_int16_t sc_vendor; - u_int16_t sc_product; + struct usbd_device * sc_udev; + struct usbd_interface * sc_iface; + uint16_t sc_vendor; + uint16_t sc_product; int sc_ed[UPL_ENDPT_MAX]; - usbd_pipe_handle sc_ep[UPL_ENDPT_MAX]; + struct usbd_pipe * sc_ep[UPL_ENDPT_MAX]; struct upl_cdata sc_cdata; uByte sc_ibuf; @@ -184,9 +183,9 @@ Static int upl_tx_list_init(struct upl_softc *); Static int upl_rx_list_init(struct upl_softc *); Static int upl_newbuf(struct upl_softc *, struct upl_chain *, struct mbuf *); Static int upl_send(struct upl_softc *, struct mbuf *, int); -Static void upl_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); -Static void upl_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -Static void upl_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void upl_intr(struct usbd_xfer *, void *, usbd_status); +Static void upl_rxeof(struct usbd_xfer *, void *, usbd_status); +Static void upl_txeof(struct usbd_xfer *, void *, usbd_status); Static void upl_start(struct ifnet *); Static int upl_ioctl(struct ifnet *, u_long, void *); Static void upl_init(void *); @@ -207,10 +206,10 @@ upl_match(device_t parent, cfdata_t match, void *aux) struct upl_type *t; for (t = sc_devs; t->upl_vid != 0; t++) - if (uaa->vendor == t->upl_vid && uaa->product == t->upl_did) - return (UMATCH_VENDOR_PRODUCT); + if (uaa->uaa_vendor == t->upl_vid && uaa->uaa_product == t->upl_did) + return UMATCH_VENDOR_PRODUCT; - return (UMATCH_NONE); + return UMATCH_NONE; } void @@ -220,8 +219,8 @@ upl_attach(device_t parent, device_t self, void *aux) struct usb_attach_arg *uaa = aux; char *devinfop; int s; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface; + struct usbd_device * dev = uaa->uaa_device; + struct usbd_interface * iface; usbd_status err; struct ifnet *ifp; usb_interface_descriptor_t *id; @@ -247,8 +246,8 @@ upl_attach(device_t parent, device_t self, void *aux) } sc->sc_udev = dev; - sc->sc_product = uaa->product; - sc->sc_vendor = uaa->vendor; + sc->sc_product = uaa->uaa_product; + sc->sc_vendor = uaa->uaa_vendor; err = usbd_device2interface_handle(dev, UPL_IFACE_IDX, &iface); if (err) { @@ -337,7 +336,7 @@ upl_detach(device_t self, int flags) if (!sc->sc_attached) { /* Detached before attached finished, so just bail out. */ splx(s); - return (0); + return 0; } if (ifp->if_flags & IFF_RUNNING) @@ -361,7 +360,7 @@ upl_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - return (0); + return 0; } int @@ -397,7 +396,7 @@ upl_newbuf(struct upl_softc *sc, struct upl_chain *c, struct mbuf *m) if (m_new == NULL) { printf("%s: no memory for rx list " "-- packet dropped!\n", device_xname(sc->sc_dev)); - return (ENOBUFS); + return ENOBUFS; } MCLGET(m_new, M_DONTWAIT); @@ -405,7 +404,7 @@ upl_newbuf(struct upl_softc *sc, struct upl_chain *c, struct mbuf *m) printf("%s: no memory for rx list " "-- packet dropped!\n", device_xname(sc->sc_dev)); m_freem(m_new); - return (ENOBUFS); + return ENOBUFS; } m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; } else { @@ -416,7 +415,7 @@ upl_newbuf(struct upl_softc *sc, struct upl_chain *c, struct mbuf *m) c->upl_mbuf = m_new; - return (0); + return 0; } Static int @@ -434,20 +433,17 @@ upl_rx_list_init(struct upl_softc *sc) c->upl_sc = sc; c->upl_idx = i; if (upl_newbuf(sc, c, NULL) == ENOBUFS) - return (ENOBUFS); + return ENOBUFS; if (c->upl_xfer == NULL) { - c->upl_xfer = usbd_alloc_xfer(sc->sc_udev); - if (c->upl_xfer == NULL) - return (ENOBUFS); - c->upl_buf = usbd_alloc_buffer(c->upl_xfer, UPL_BUFSZ); - if (c->upl_buf == NULL) { - usbd_free_xfer(c->upl_xfer); - return (ENOBUFS); - } + int error = usbd_create_xfer(sc->sc_ep[UPL_ENDPT_RX], + UPL_BUFSZ, USBD_SHORT_XFER_OK, 0, &c->upl_xfer); + if (error) + return error; + c->upl_buf = usbd_get_buffer(c->upl_xfer); } } - return (0); + return 0; } Static int @@ -466,18 +462,15 @@ upl_tx_list_init(struct upl_softc *sc) c->upl_idx = i; c->upl_mbuf = NULL; if (c->upl_xfer == NULL) { - c->upl_xfer = usbd_alloc_xfer(sc->sc_udev); - if (c->upl_xfer == NULL) - return (ENOBUFS); - c->upl_buf = usbd_alloc_buffer(c->upl_xfer, UPL_BUFSZ); - if (c->upl_buf == NULL) { - usbd_free_xfer(c->upl_xfer); - return (ENOBUFS); - } + int error = usbd_create_xfer(sc->sc_ep[UPL_ENDPT_TX], + UPL_BUFSZ, 0, 0, &c->upl_xfer); + if (error) + return error; + c->upl_buf = usbd_get_buffer(c->upl_xfer); } } - return (0); + return 0; } /* @@ -485,7 +478,7 @@ upl_tx_list_init(struct upl_softc *sc) * the higher level protocols. */ Static void -upl_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +upl_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct upl_chain *c = priv; struct upl_softc *sc = c->upl_sc; @@ -555,9 +548,8 @@ upl_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) done: #if 1 /* Setup new transfer. */ - usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX], - c, c->upl_buf, UPL_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, upl_rxeof); + usbd_setup_xfer(c->upl_xfer, c, c->upl_buf, UPL_BUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, upl_rxeof); usbd_transfer(c->upl_xfer); DPRINTFN(10,("%s: %s: start rx\n", device_xname(sc->sc_dev), @@ -570,7 +562,7 @@ upl_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) * the list buffers. */ Static void -upl_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, +upl_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct upl_chain *c = priv; @@ -635,9 +627,8 @@ upl_send(struct upl_softc *sc, struct mbuf *m, int idx) DPRINTFN(10,("%s: %s: total_len=%d\n", device_xname(sc->sc_dev), __func__, total_len)); - usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_TX], - c, c->upl_buf, total_len, USBD_NO_COPY, USBD_DEFAULT_TIMEOUT, - upl_txeof); + usbd_setup_xfer(c->upl_xfer, c, c->upl_buf, total_len, 0, + USBD_DEFAULT_TIMEOUT, upl_txeof); /* Transmit */ err = usbd_transfer(c->upl_xfer); @@ -645,12 +636,12 @@ upl_send(struct upl_softc *sc, struct mbuf *m, int idx) printf("%s: upl_send error=%s\n", device_xname(sc->sc_dev), usbd_errstr(err)); upl_stop(sc); - return (EIO); + return EIO; } sc->sc_cdata.upl_tx_cnt++; - return (0); + return 0; } Static void @@ -709,25 +700,33 @@ upl_init(void *xsc) s = splnet(); + if (sc->sc_ep[UPL_ENDPT_RX] == NULL) { + if (upl_openpipes(sc)) { + splx(s); + return; + } + } /* Init TX ring. */ - if (upl_tx_list_init(sc) == ENOBUFS) { + if (upl_tx_list_init(sc)) { printf("%s: tx list init failed\n", device_xname(sc->sc_dev)); splx(s); return; } /* Init RX ring. */ - if (upl_rx_list_init(sc) == ENOBUFS) { + if (upl_rx_list_init(sc)) { printf("%s: rx list init failed\n", device_xname(sc->sc_dev)); splx(s); return; } - if (sc->sc_ep[UPL_ENDPT_RX] == NULL) { - if (upl_openpipes(sc)) { - splx(s); - return; - } + /* Start up the receive pipe. */ + for (int i = 0; i < UPL_RX_LIST_CNT; i++) { + struct upl_chain *c = &sc->sc_cdata.upl_rx_chain[i]; + usbd_setup_xfer(c->upl_xfer, c, c->upl_buf, UPL_BUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, + upl_rxeof); + usbd_transfer(c->upl_xfer); } ifp->if_flags |= IFF_RUNNING; @@ -739,9 +738,7 @@ upl_init(void *xsc) Static int upl_openpipes(struct upl_softc *sc) { - struct upl_chain *c; usbd_status err; - int i; /* Open RX and TX pipes. */ err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_RX], @@ -749,14 +746,14 @@ upl_openpipes(struct upl_softc *sc) if (err) { printf("%s: open rx pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); - return (EIO); + return EIO; } err = usbd_open_pipe(sc->sc_iface, sc->sc_ed[UPL_ENDPT_TX], USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_TX]); if (err) { printf("%s: open tx pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); - return (EIO); + return EIO; } err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_ed[UPL_ENDPT_INTR], USBD_EXCLUSIVE_USE, &sc->sc_ep[UPL_ENDPT_INTR], sc, @@ -765,27 +762,14 @@ upl_openpipes(struct upl_softc *sc) if (err) { printf("%s: open intr pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); - return (EIO); - } - - -#if 1 - /* Start up the receive pipe. */ - for (i = 0; i < UPL_RX_LIST_CNT; i++) { - c = &sc->sc_cdata.upl_rx_chain[i]; - usbd_setup_xfer(c->upl_xfer, sc->sc_ep[UPL_ENDPT_RX], - c, c->upl_buf, UPL_BUFSZ, - USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, - upl_rxeof); - usbd_transfer(c->upl_xfer); + return EIO; } -#endif - return (0); + return 0; } Static void -upl_intr(usbd_xfer_handle xfer, usbd_private_handle priv, +upl_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct upl_softc *sc = priv; @@ -835,7 +819,7 @@ upl_ioctl(struct ifnet *ifp, u_long command, void *data) int s, error = 0; if (sc->sc_dying) - return (EIO); + return EIO; DPRINTFN(5,("%s: %s: cmd=0x%08lx\n", device_xname(sc->sc_dev), __func__, command)); @@ -884,7 +868,7 @@ upl_ioctl(struct ifnet *ifp, u_long command, void *data) splx(s); - return (error); + return error; } Static void @@ -930,12 +914,6 @@ upl_stop(struct upl_softc *sc) printf("%s: abort rx pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); } - err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_RX]); - if (err) { - printf("%s: close rx pipe failed: %s\n", - device_xname(sc->sc_dev), usbd_errstr(err)); - } - sc->sc_ep[UPL_ENDPT_RX] = NULL; } if (sc->sc_ep[UPL_ENDPT_TX] != NULL) { @@ -944,12 +922,6 @@ upl_stop(struct upl_softc *sc) printf("%s: abort tx pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); } - err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_TX]); - if (err) { - printf("%s: close tx pipe failed: %s\n", - device_xname(sc->sc_dev), usbd_errstr(err)); - } - sc->sc_ep[UPL_ENDPT_TX] = NULL; } if (sc->sc_ep[UPL_ENDPT_INTR] != NULL) { @@ -958,12 +930,6 @@ upl_stop(struct upl_softc *sc) printf("%s: abort intr pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); } - err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_INTR]); - if (err) { - printf("%s: close intr pipe failed: %s\n", - device_xname(sc->sc_dev), usbd_errstr(err)); - } - sc->sc_ep[UPL_ENDPT_INTR] = NULL; } /* Free RX resources. */ @@ -972,10 +938,6 @@ upl_stop(struct upl_softc *sc) m_freem(sc->sc_cdata.upl_rx_chain[i].upl_mbuf); sc->sc_cdata.upl_rx_chain[i].upl_mbuf = NULL; } - if (sc->sc_cdata.upl_rx_chain[i].upl_xfer != NULL) { - usbd_free_xfer(sc->sc_cdata.upl_rx_chain[i].upl_xfer); - sc->sc_cdata.upl_rx_chain[i].upl_xfer = NULL; - } } /* Free TX resources. */ @@ -985,11 +947,39 @@ upl_stop(struct upl_softc *sc) sc->sc_cdata.upl_tx_chain[i].upl_mbuf = NULL; } if (sc->sc_cdata.upl_tx_chain[i].upl_xfer != NULL) { - usbd_free_xfer(sc->sc_cdata.upl_tx_chain[i].upl_xfer); + usbd_destroy_xfer(sc->sc_cdata.upl_tx_chain[i].upl_xfer); sc->sc_cdata.upl_tx_chain[i].upl_xfer = NULL; } } + /* Close pipes */ + if (sc->sc_ep[UPL_ENDPT_RX] != NULL) { + err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_RX]); + if (err) { + printf("%s: close rx pipe failed: %s\n", + device_xname(sc->sc_dev), usbd_errstr(err)); + } + sc->sc_ep[UPL_ENDPT_RX] = NULL; + } + + if (sc->sc_ep[UPL_ENDPT_TX] != NULL) { + err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_TX]); + if (err) { + printf("%s: close tx pipe failed: %s\n", + device_xname(sc->sc_dev), usbd_errstr(err)); + } + sc->sc_ep[UPL_ENDPT_TX] = NULL; + } + + if (sc->sc_ep[UPL_ENDPT_INTR] != NULL) { + err = usbd_close_pipe(sc->sc_ep[UPL_ENDPT_INTR]); + if (err) { + printf("%s: close intr pipe failed: %s\n", + device_xname(sc->sc_dev), usbd_errstr(err)); + } + sc->sc_ep[UPL_ENDPT_INTR] = NULL; + } + ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); } @@ -1019,14 +1009,14 @@ upl_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, if (error) { /* mbuf is already freed */ splx(s); - return (error); + return error; } ifp->if_obytes += len; if ((ifp->if_flags & IFF_OACTIVE) == 0) (*ifp->if_start)(ifp); splx(s); - return (0); + return 0; } Static void diff --git a/sys/dev/usb/if_ural.c b/sys/dev/usb/if_ural.c index be579792ac2..25973bfbec0 100644 --- a/sys/dev/usb/if_ural.c +++ b/sys/dev/usb/if_ural.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_ural.c,v 1.45 2015/04/08 12:29:42 nonaka Exp $ */ +/* $NetBSD: if_ural.c,v 1.46 2016/04/23 10:15:31 skrll Exp $ */ /* $FreeBSD: /repoman/r/ncvs/src/sys/dev/usb/if_ural.c,v 1.40 2006/06/02 23:14:40 sam Exp $ */ /*- @@ -24,7 +24,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_ural.c,v 1.45 2015/04/08 12:29:42 nonaka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_ural.c,v 1.46 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/sockio.h> @@ -33,7 +33,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_ural.c,v 1.45 2015/04/08 12:29:42 nonaka Exp $"); #include <sys/kernel.h> #include <sys/socket.h> #include <sys/systm.h> -#include <sys/malloc.h> #include <sys/conf.h> #include <sys/device.h> @@ -116,9 +115,9 @@ Static void ural_task(void *); Static int ural_newstate(struct ieee80211com *, enum ieee80211_state, int); Static int ural_rxrate(struct ural_rx_desc *); -Static void ural_txeof(usbd_xfer_handle, usbd_private_handle, +Static void ural_txeof(struct usbd_xfer *, void *, usbd_status); -Static void ural_rxeof(usbd_xfer_handle, usbd_private_handle, +Static void ural_rxeof(struct usbd_xfer *, void *, usbd_status); Static int ural_ack_rate(struct ieee80211com *, int); Static uint16_t ural_txtime(int, int, uint32_t); @@ -167,7 +166,7 @@ Static void ural_stop(struct ifnet *, int); Static void ural_amrr_start(struct ural_softc *, struct ieee80211_node *); Static void ural_amrr_timeout(void *); -Static void ural_amrr_update(usbd_xfer_handle, usbd_private_handle, +Static void ural_amrr_update(struct usbd_xfer *, void *, usbd_status status); /* @@ -356,7 +355,7 @@ ural_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (usb_lookup(ural_devs, uaa->vendor, uaa->product) != NULL) ? + return (usb_lookup(ural_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL) ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } @@ -374,7 +373,7 @@ ural_attach(device_t parent, device_t self, void *aux) int i; sc->sc_dev = self; - sc->sc_udev = uaa->device; + sc->sc_udev = uaa->uaa_device; aprint_naive("\n"); aprint_normal("\n"); @@ -509,13 +508,13 @@ ural_attach(device_t parent, device_t self, void *aux) ieee80211_media_init(ic, ural_media_change, ieee80211_media_status); bpf_attach2(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + 64, &sc->sc_drvbpf); + sizeof(struct ieee80211_frame) + 64, &sc->sc_drvbpf); - sc->sc_rxtap_len = sizeof sc->sc_rxtapu; + sc->sc_rxtap_len = sizeof(sc->sc_rxtapu); sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); sc->sc_rxtap.wr_ihdr.it_present = htole32(RAL_RX_RADIOTAP_PRESENT); - sc->sc_txtap_len = sizeof sc->sc_txtapu; + sc->sc_txtap_len = sizeof(sc->sc_txtapu); sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); sc->sc_txtap.wt_ihdr.it_present = htole32(RAL_TX_RADIOTAP_PRESENT); @@ -547,21 +546,6 @@ ural_detach(device_t self, int flags) callout_stop(&sc->sc_scan_ch); callout_stop(&sc->sc_amrr_ch); - if (sc->amrr_xfer != NULL) { - usbd_free_xfer(sc->amrr_xfer); - sc->amrr_xfer = NULL; - } - - if (sc->sc_rx_pipeh != NULL) { - usbd_abort_pipe(sc->sc_rx_pipeh); - usbd_close_pipe(sc->sc_rx_pipeh); - } - - if (sc->sc_tx_pipeh != NULL) { - usbd_abort_pipe(sc->sc_tx_pipeh); - usbd_close_pipe(sc->sc_tx_pipeh); - } - bpf_detach(ifp); ieee80211_ifdetach(ic); if_detach(ifp); @@ -586,23 +570,16 @@ ural_alloc_tx_list(struct ural_softc *sc) data = &sc->tx_data[i]; data->sc = sc; - - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { + error = usbd_create_xfer(sc->sc_tx_pipeh, + RAL_TX_DESC_SIZE + MCLBYTES, USBD_FORCE_SHORT_XFER, 0, + &data->xfer); + if (error) { printf("%s: could not allocate tx xfer\n", device_xname(sc->sc_dev)); - error = ENOMEM; goto fail; } - data->buf = usbd_alloc_buffer(data->xfer, - RAL_TX_DESC_SIZE + MCLBYTES); - if (data->buf == NULL) { - printf("%s: could not allocate tx buffer\n", - device_xname(sc->sc_dev)); - error = ENOMEM; - goto fail; - } + data->buf = usbd_get_buffer(data->xfer); } return 0; @@ -621,7 +598,7 @@ ural_free_tx_list(struct ural_softc *sc) data = &sc->tx_data[i]; if (data->xfer != NULL) { - usbd_free_xfer(data->xfer); + usbd_destroy_xfer(data->xfer); data->xfer = NULL; } @@ -643,18 +620,11 @@ ural_alloc_rx_list(struct ural_softc *sc) data->sc = sc; - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { + error = usbd_create_xfer(sc->sc_rx_pipeh, MCLBYTES, + USBD_SHORT_XFER_OK, 0, &data->xfer); + if (error) { printf("%s: could not allocate rx xfer\n", device_xname(sc->sc_dev)); - error = ENOMEM; - goto fail; - } - - if (usbd_alloc_buffer(data->xfer, MCLBYTES) == NULL) { - printf("%s: could not allocate rx buffer\n", - device_xname(sc->sc_dev)); - error = ENOMEM; goto fail; } @@ -693,7 +663,7 @@ ural_free_rx_list(struct ural_softc *sc) data = &sc->rx_data[i]; if (data->xfer != NULL) { - usbd_free_xfer(data->xfer); + usbd_destroy_xfer(data->xfer); data->xfer = NULL; } @@ -876,7 +846,7 @@ ural_rxrate(struct ural_rx_desc *desc) } Static void -ural_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, +ural_txeof(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct ural_tx_data *data = priv; @@ -918,7 +888,7 @@ ural_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, } Static void -ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +ural_rxeof(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct ural_rx_data *data = priv; struct ural_softc *sc = data->sc; @@ -1013,7 +983,7 @@ ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) DPRINTFN(15, ("rx done\n")); skip: /* setup a new transfer */ - usbd_setup_xfer(xfer, sc->sc_rx_pipeh, data, data->buf, MCLBYTES, + usbd_setup_xfer(xfer, data, data->buf, MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ural_rxeof); usbd_transfer(xfer); } @@ -1115,7 +1085,7 @@ ural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc, desc->flags |= htole32(len << 16); desc->wme = htole16(RAL_AIFSN(2) | RAL_LOGCWMIN(3) | RAL_LOGCWMAX(5)); - desc->wme |= htole16(RAL_IVOFFSET(sizeof (struct ieee80211_frame))); + desc->wme |= htole16(RAL_IVOFFSET(sizeof(struct ieee80211_frame))); /* setup PLCP fields */ desc->plcp_signal = ural_plcp_signal(rate); @@ -1152,7 +1122,7 @@ Static int ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { struct ural_tx_desc *desc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t cmd = 0; usbd_status error; uint8_t *buf; @@ -1160,25 +1130,22 @@ ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) rate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2; - xfer = usbd_alloc_xfer(sc->sc_udev); - if (xfer == NULL) - return ENOMEM; - /* xfer length needs to be a multiple of two! */ xferlen = (RAL_TX_DESC_SIZE + m0->m_pkthdr.len + 1) & ~1; - buf = usbd_alloc_buffer(xfer, xferlen); - if (buf == NULL) { - usbd_free_xfer(xfer); - return ENOMEM; - } + error = usbd_create_xfer(sc->sc_tx_pipeh, xferlen, + USBD_FORCE_SHORT_XFER, 0, &xfer); + if (error) + return error; + + buf = usbd_get_buffer(xfer); - usbd_setup_xfer(xfer, sc->sc_tx_pipeh, NULL, &cmd, sizeof cmd, - USBD_FORCE_SHORT_XFER, RAL_TX_TIMEOUT, NULL); + usbd_setup_xfer(xfer, NULL, &cmd, sizeof(cmd), USBD_FORCE_SHORT_XFER, + RAL_TX_TIMEOUT, NULL); error = usbd_sync_transfer(xfer); if (error != 0) { - usbd_free_xfer(xfer); + usbd_destroy_xfer(xfer); return error; } @@ -1191,11 +1158,11 @@ ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) DPRINTFN(10, ("sending beacon frame len=%u rate=%u xfer len=%u\n", m0->m_pkthdr.len, rate, xferlen)); - usbd_setup_xfer(xfer, sc->sc_tx_pipeh, NULL, buf, xferlen, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT, NULL); + usbd_setup_xfer(xfer, NULL, buf, xferlen, USBD_FORCE_SHORT_XFER, + RAL_TX_TIMEOUT, NULL); error = usbd_sync_transfer(xfer); - usbd_free_xfer(xfer); + usbd_destroy_xfer(xfer); return error; } @@ -1275,9 +1242,8 @@ ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) DPRINTFN(10, ("sending mgt frame len=%u rate=%u xfer len=%u\n", m0->m_pkthdr.len, rate, xferlen)); - usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, - xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT, - ural_txeof); + usbd_setup_xfer(data->xfer, data, data->buf, xferlen, + USBD_FORCE_SHORT_XFER, RAL_TX_TIMEOUT, ural_txeof); error = usbd_transfer(data->xfer); if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { @@ -1365,10 +1331,8 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) DPRINTFN(10, ("sending data frame len=%u rate=%u xfer len=%u\n", m0->m_pkthdr.len, rate, xferlen)); - - usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, - xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT, - ural_txeof); + usbd_setup_xfer(data->xfer, data, data->buf, xferlen, + USBD_FORCE_SHORT_XFER, RAL_TX_TIMEOUT, ural_txeof); error = usbd_transfer(data->xfer); if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) @@ -1415,8 +1379,8 @@ ural_start(struct ifnet *ifp) break; } - if (m0->m_len < sizeof (struct ether_header) && - !(m0 = m_pullup(m0, sizeof (struct ether_header)))) + if (m0->m_len < sizeof(struct ether_header) && + !(m0 = m_pullup(m0, sizeof(struct ether_header)))) continue; eh = mtod(m0, struct ether_header *); @@ -1589,7 +1553,7 @@ ural_read(struct ural_softc *sc, uint16_t reg) req.bRequest = RAL_READ_MAC; USETW(req.wValue, 0); USETW(req.wIndex, reg); - USETW(req.wLength, sizeof (uint16_t)); + USETW(req.wLength, sizeof(uint16_t)); error = usbd_do_request(sc->sc_udev, &req, &val); if (error != 0) { @@ -2028,7 +1992,6 @@ ural_read_eeprom(struct ural_softc *sc) Static int ural_bbp_init(struct ural_softc *sc) { -#define N(a) (sizeof (a) / sizeof ((a)[0])) int i, ntries; /* wait for BBP to be ready */ @@ -2043,7 +2006,7 @@ ural_bbp_init(struct ural_softc *sc) } /* initialize BBP registers to default values */ - for (i = 0; i < N(ural_def_bbp); i++) + for (i = 0; i < __arraycount(ural_def_bbp); i++) ural_bbp_write(sc, ural_def_bbp[i].reg, ural_def_bbp[i].val); #if 0 @@ -2056,7 +2019,6 @@ ural_bbp_init(struct ural_softc *sc) #endif return 0; -#undef N } Static void @@ -2111,11 +2073,9 @@ ural_set_rxantenna(struct ural_softc *sc, int antenna) Static int ural_init(struct ifnet *ifp) { -#define N(a) (sizeof (a) / sizeof ((a)[0])) struct ural_softc *sc = ifp->if_softc; struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_key *wk; - struct ural_rx_data *data; uint16_t tmp; usbd_status error; int i, ntries; @@ -2126,7 +2086,7 @@ ural_init(struct ifnet *ifp) ural_stop(ifp, 0); /* initialize MAC registers to default values */ - for (i = 0; i < N(ural_def_mac); i++) + for (i = 0; i < __arraycount(ural_def_mac); i++) ural_write(sc, ural_def_mac[i].reg, ural_def_mac[i].val); /* wait for BBP and RF to wake up (this can take a long time!) */ @@ -2158,7 +2118,7 @@ ural_init(struct ifnet *ifp) ural_set_chan(sc, ic->ic_curchan); /* clear statistic registers (STA_CSR0 to STA_CSR10) */ - ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta); + ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof(sc->sta)); ural_set_txantenna(sc, sc->tx_ant); ural_set_rxantenna(sc, sc->rx_ant); @@ -2178,8 +2138,9 @@ ural_init(struct ifnet *ifp) /* * Allocate xfer for AMRR statistics requests. */ - sc->amrr_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->amrr_xfer == NULL) { + struct usbd_pipe *pipe0 = usbd_get_pipe0(sc->sc_udev); + error = usbd_create_xfer(pipe0, sizeof(sc->sta), 0, 0, &sc->amrr_xfer); + if (error) { printf("%s: could not allocate AMRR xfer\n", device_xname(sc->sc_dev)); goto fail; @@ -2225,10 +2186,10 @@ ural_init(struct ifnet *ifp) * Start up the receive pipe. */ for (i = 0; i < RAL_RX_LIST_COUNT; i++) { - data = &sc->rx_data[i]; + struct ural_rx_data *data = &sc->rx_data[i]; - usbd_setup_xfer(data->xfer, sc->sc_rx_pipeh, data, data->buf, - MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ural_rxeof); + usbd_setup_xfer(data->xfer, data, data->buf, MCLBYTES, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ural_rxeof); usbd_transfer(data->xfer); } @@ -2256,7 +2217,6 @@ ural_init(struct ifnet *ifp) fail: ural_stop(ifp, 1); return error; -#undef N } Static void @@ -2279,24 +2239,30 @@ ural_stop(struct ifnet *ifp, int disable) ural_write(sc, RAL_MAC_CSR1, 0); if (sc->amrr_xfer != NULL) { - usbd_free_xfer(sc->amrr_xfer); + usbd_destroy_xfer(sc->amrr_xfer); sc->amrr_xfer = NULL; } if (sc->sc_rx_pipeh != NULL) { usbd_abort_pipe(sc->sc_rx_pipeh); - usbd_close_pipe(sc->sc_rx_pipeh); - sc->sc_rx_pipeh = NULL; } if (sc->sc_tx_pipeh != NULL) { usbd_abort_pipe(sc->sc_tx_pipeh); - usbd_close_pipe(sc->sc_tx_pipeh); - sc->sc_tx_pipeh = NULL; } ural_free_rx_list(sc); ural_free_tx_list(sc); + + if (sc->sc_rx_pipeh != NULL) { + usbd_close_pipe(sc->sc_rx_pipeh); + sc->sc_rx_pipeh = NULL; + } + + if (sc->sc_tx_pipeh != NULL) { + usbd_close_pipe(sc->sc_tx_pipeh); + sc->sc_tx_pipeh = NULL; + } } int @@ -2319,7 +2285,7 @@ ural_amrr_start(struct ural_softc *sc, struct ieee80211_node *ni) int i; /* clear statistic registers (STA_CSR0 to STA_CSR10) */ - ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta); + ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof(sc->sta)); ieee80211_amrr_node_init(&sc->amrr, &sc->amn); @@ -2348,10 +2314,10 @@ ural_amrr_timeout(void *arg) req.bRequest = RAL_READ_MULTI_MAC; USETW(req.wValue, 0); USETW(req.wIndex, RAL_STA_CSR0); - USETW(req.wLength, sizeof sc->sta); + USETW(req.wLength, sizeof(sc->sta)); usbd_setup_default_xfer(sc->amrr_xfer, sc->sc_udev, sc, - USBD_DEFAULT_TIMEOUT, &req, sc->sta, sizeof sc->sta, 0, + USBD_DEFAULT_TIMEOUT, &req, sc->sta, sizeof(sc->sta), 0, ural_amrr_update); (void)usbd_transfer(sc->amrr_xfer); @@ -2359,7 +2325,7 @@ ural_amrr_timeout(void *arg) } Static void -ural_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv, +ural_amrr_update(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct ural_softc *sc = (struct ural_softc *)priv; diff --git a/sys/dev/usb/if_uralreg.h b/sys/dev/usb/if_uralreg.h index 845c633d9f6..63b8d644703 100644 --- a/sys/dev/usb/if_uralreg.h +++ b/sys/dev/usb/if_uralreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_uralreg.h,v 1.3 2006/07/05 18:46:42 perry Exp $ */ +/* $NetBSD: if_uralreg.h,v 1.4 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_ralreg.h,v 1.5 2005/04/01 13:13:43 damien Exp $ */ /*- @@ -18,8 +18,8 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#define RAL_RX_DESC_SIZE (sizeof (struct ural_rx_desc)) -#define RAL_TX_DESC_SIZE (sizeof (struct ural_tx_desc)) +#define RAL_RX_DESC_SIZE (sizeof(struct ural_rx_desc)) +#define RAL_TX_DESC_SIZE (sizeof(struct ural_tx_desc)) #define RAL_CONFIG_NO 1 #define RAL_IFACE_INDEX 0 diff --git a/sys/dev/usb/if_uralvar.h b/sys/dev/usb/if_uralvar.h index 5114a1189ea..4b8e0eec057 100644 --- a/sys/dev/usb/if_uralvar.h +++ b/sys/dev/usb/if_uralvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_uralvar.h,v 1.11 2010/11/03 22:30:50 dyoung Exp $ */ +/* $NetBSD: if_uralvar.h,v 1.12 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_ralvar.h,v 1.2 2005/05/13 18:42:50 damien Exp $ */ /*- @@ -57,7 +57,7 @@ struct ural_softc; struct ural_tx_data { struct ural_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; struct mbuf *m; struct ieee80211_node *ni; @@ -65,7 +65,7 @@ struct ural_tx_data { struct ural_rx_data { struct ural_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; struct mbuf *m; }; @@ -78,8 +78,8 @@ struct ural_softc { int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int); - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device * sc_udev; + struct usbd_interface * sc_iface; int sc_rx_no; int sc_tx_no; @@ -87,10 +87,10 @@ struct ural_softc { uint32_t asic_rev; uint8_t rf_rev; - usbd_xfer_handle amrr_xfer; + struct usbd_xfer * amrr_xfer; - usbd_pipe_handle sc_rx_pipeh; - usbd_pipe_handle sc_tx_pipeh; + struct usbd_pipe * sc_rx_pipeh; + struct usbd_pipe * sc_tx_pipeh; enum ieee80211_state sc_state; struct usb_task sc_task; diff --git a/sys/dev/usb/if_url.c b/sys/dev/usb/if_url.c index 718e503221a..cbbe1d905d0 100644 --- a/sys/dev/usb/if_url.c +++ b/sys/dev/usb/if_url.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_url.c,v 1.50 2016/02/09 08:32:12 ozaki-r Exp $ */ +/* $NetBSD: if_url.c,v 1.51 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 2001, 2002 @@ -44,7 +44,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_url.c,v 1.50 2016/02/09 08:32:12 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_url.c,v 1.51 2016/04/23 10:15:31 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -99,8 +99,8 @@ Static int url_tx_list_init(struct url_softc *); Static int url_newbuf(struct url_softc *, struct url_chain *, struct mbuf *); Static void url_start(struct ifnet *); Static int url_send(struct url_softc *, struct mbuf *, int); -Static void url_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -Static void url_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void url_txeof(struct usbd_xfer *, void *, usbd_status); +Static void url_rxeof(struct usbd_xfer *, void *, usbd_status); Static void url_tick(void *); Static void url_tick_task(void *); Static int url_ioctl(struct ifnet *, u_long, void *); @@ -149,7 +149,7 @@ int urldebug = 0; static const struct url_type { struct usb_devno url_dev; - u_int16_t url_flags; + uint16_t url_flags; #define URL_EXT_PHY 0x0001 } url_devs [] = { /* MELCO LUA-KTX */ @@ -172,8 +172,8 @@ url_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (url_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return url_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } /* Attach */ void @@ -181,8 +181,8 @@ url_attach(device_t parent, device_t self, void *aux) { struct url_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface; + struct usbd_device *dev = uaa->uaa_device; + struct usbd_interface *iface; usbd_status err; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; @@ -223,7 +223,7 @@ url_attach(device_t parent, device_t self, void *aux) sc->sc_udev = dev; sc->sc_ctl_iface = iface; - sc->sc_flags = url_lookup(uaa->vendor, uaa->product)->url_flags; + sc->sc_flags = url_lookup(uaa->uaa_vendor, uaa->uaa_product)->url_flags; /* get interface descriptor */ id = usbd_get_interface_descriptor(sc->sc_ctl_iface); @@ -342,7 +342,7 @@ url_detach(device_t self, int flags) /* Detached before attached finished */ if (!sc->sc_attached) - return (0); + return 0; callout_stop(&sc->sc_stat_ch); @@ -383,7 +383,7 @@ url_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - return (0); + return 0; } /* read/write memory */ @@ -394,13 +394,13 @@ url_mem(struct url_softc *sc, int cmd, int offset, void *buf, int len) usbd_status err; if (sc == NULL) - return (0); + return 0; DPRINTFN(0x200, ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (0); + return 0; if (cmd == URL_CMD_READMEM) req.bmRequestType = UT_READ_VENDOR_DEVICE; @@ -422,22 +422,22 @@ url_mem(struct url_softc *sc, int cmd, int offset, void *buf, int len) offset, err)); } - return (err); + return err; } /* read 1byte from register */ Static int url_csr_read_1(struct url_softc *sc, int reg) { - u_int8_t val = 0; + uint8_t val = 0; DPRINTFN(0x100, ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (0); + return 0; - return (url_mem(sc, URL_CMD_READMEM, reg, &val, 1) ? 0 : val); + return url_mem(sc, URL_CMD_READMEM, reg, &val, 1) ? 0 : val; } /* read 2bytes from register */ @@ -450,25 +450,25 @@ url_csr_read_2(struct url_softc *sc, int reg) ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (0); + return 0; USETW(val, 0); - return (url_mem(sc, URL_CMD_READMEM, reg, &val, 2) ? 0 : UGETW(val)); + return url_mem(sc, URL_CMD_READMEM, reg, &val, 2) ? 0 : UGETW(val); } /* write 1byte to register */ Static int url_csr_write_1(struct url_softc *sc, int reg, int aval) { - u_int8_t val = aval; + uint8_t val = aval; DPRINTFN(0x100, ("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (0); + return 0; - return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 1) ? -1 : 0); + return url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 1) ? -1 : 0; } /* write 2bytes to register */ @@ -483,9 +483,9 @@ url_csr_write_2(struct url_softc *sc, int reg, int aval) USETW(val, aval); if (sc->sc_dying) - return (0); + return 0; - return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 2) ? -1 : 0); + return url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 2) ? -1 : 0; } /* write 4bytes to register */ @@ -500,9 +500,9 @@ url_csr_write_4(struct url_softc *sc, int reg, int aval) USETDW(val, aval); if (sc->sc_dying) - return (0); + return 0; - return (url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 4) ? -1 : 0); + return url_mem(sc, URL_CMD_WRITEMEM, reg, &val, 4) ? -1 : 0; } Static int @@ -516,7 +516,7 @@ url_init(struct ifnet *ifp) DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (EIO); + return EIO; s = splnet(); @@ -547,20 +547,6 @@ url_init(struct ifnet *ifp) URL_CLRBIT2(sc, URL_RCR, URL_RCR_AAM|URL_RCR_AAP); - /* Initialize transmit ring */ - if (url_tx_list_init(sc) == ENOBUFS) { - printf("%s: tx list init failed\n", device_xname(sc->sc_dev)); - splx(s); - return (EIO); - } - - /* Initialize receive ring */ - if (url_rx_list_init(sc) == ENOBUFS) { - printf("%s: rx list init failed\n", device_xname(sc->sc_dev)); - splx(s); - return (EIO); - } - /* Load the multicast filter */ url_setmulti(sc); @@ -575,9 +561,32 @@ url_init(struct ifnet *ifp) if (sc->sc_pipe_tx == NULL || sc->sc_pipe_rx == NULL) { if (url_openpipes(sc)) { splx(s); - return (EIO); + return EIO; } } + /* Initialize transmit ring */ + if (url_tx_list_init(sc)) { + printf("%s: tx list init failed\n", device_xname(sc->sc_dev)); + splx(s); + return EIO; + } + + /* Initialize receive ring */ + if (url_rx_list_init(sc)) { + printf("%s: rx list init failed\n", device_xname(sc->sc_dev)); + splx(s); + return EIO; + } + /* Start up the receive pipe. */ + for (i = 0; i < URL_RX_LIST_CNT; i++) { + struct url_chain *c = &sc->sc_cdata.url_rx_chain[i]; + + usbd_setup_xfer(c->url_xfer, c, c->url_buf, URL_BUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, url_rxeof); + (void)usbd_transfer(c->url_xfer); + DPRINTF(("%s: %s: start read\n", device_xname(sc->sc_dev), + __func__)); + } ifp->if_flags |= IFF_RUNNING; ifp->if_flags &= ~IFF_OACTIVE; @@ -637,7 +646,7 @@ url_setmulti(struct url_softc *sc) struct ifnet *ifp; struct ether_multi *enm; struct ether_multistep step; - u_int32_t hashes[2] = { 0, 0 }; + uint32_t hashes[2] = { 0, 0 }; int h = 0; int mcnt = 0; @@ -695,13 +704,11 @@ url_setmulti(struct url_softc *sc) Static int url_openpipes(struct url_softc *sc) { - struct url_chain *c; usbd_status err; - int i; int error = 0; if (sc->sc_dying) - return (EIO); + return EIO; sc->sc_refcnt++; @@ -740,24 +747,11 @@ url_openpipes(struct url_softc *sc) } #endif - - /* Start up the receive pipe. */ - for (i = 0; i < URL_RX_LIST_CNT; i++) { - c = &sc->sc_cdata.url_rx_chain[i]; - usbd_setup_xfer(c->url_xfer, sc->sc_pipe_rx, - c, c->url_buf, URL_BUFSZ, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, url_rxeof); - (void)usbd_transfer(c->url_xfer); - DPRINTF(("%s: %s: start read\n", device_xname(sc->sc_dev), - __func__)); - } - done: if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); - return (error); + return error; } Static int @@ -772,14 +766,14 @@ url_newbuf(struct url_softc *sc, struct url_chain *c, struct mbuf *m) if (m_new == NULL) { printf("%s: no memory for rx list " "-- packet dropped!\n", device_xname(sc->sc_dev)); - return (ENOBUFS); + return ENOBUFS; } MCLGET(m_new, M_DONTWAIT); if (!(m_new->m_flags & M_EXT)) { printf("%s: no memory for rx list " "-- packet dropped!\n", device_xname(sc->sc_dev)); m_freem(m_new); - return (ENOBUFS); + return ENOBUFS; } m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; } else { @@ -791,7 +785,7 @@ url_newbuf(struct url_softc *sc, struct url_chain *c, struct mbuf *m) m_adj(m_new, ETHER_ALIGN); c->url_mbuf = m_new; - return (0); + return 0; } @@ -810,20 +804,17 @@ url_rx_list_init(struct url_softc *sc) c->url_sc = sc; c->url_idx = i; if (url_newbuf(sc, c, NULL) == ENOBUFS) - return (ENOBUFS); + return ENOBUFS; if (c->url_xfer == NULL) { - c->url_xfer = usbd_alloc_xfer(sc->sc_udev); - if (c->url_xfer == NULL) - return (ENOBUFS); - c->url_buf = usbd_alloc_buffer(c->url_xfer, URL_BUFSZ); - if (c->url_buf == NULL) { - usbd_free_xfer(c->url_xfer); - return (ENOBUFS); - } + int error = usbd_create_xfer(sc->sc_pipe_rx, URL_BUFSZ, + USBD_SHORT_XFER_OK, 0, &c->url_xfer); + if (error) + return error; + c->url_buf = usbd_get_buffer(c->url_xfer); } } - return (0); + return 0; } Static int @@ -842,18 +833,15 @@ url_tx_list_init(struct url_softc *sc) c->url_idx = i; c->url_mbuf = NULL; if (c->url_xfer == NULL) { - c->url_xfer = usbd_alloc_xfer(sc->sc_udev); - if (c->url_xfer == NULL) - return (ENOBUFS); - c->url_buf = usbd_alloc_buffer(c->url_xfer, URL_BUFSZ); - if (c->url_buf == NULL) { - usbd_free_xfer(c->url_xfer); - return (ENOBUFS); - } + int error = usbd_create_xfer(sc->sc_pipe_tx, URL_BUFSZ, + USBD_FORCE_SHORT_XFER, 0, &c->url_xfer); + if (error) + return error; + c->url_buf = usbd_get_buffer(c->url_xfer); } } - return (0); + return 0; } Static void @@ -914,9 +902,8 @@ url_send(struct url_softc *sc, struct mbuf *m, int idx) URL_MIN_FRAME_LEN - total_len); total_len = URL_MIN_FRAME_LEN; } - usbd_setup_xfer(c->url_xfer, sc->sc_pipe_tx, c, c->url_buf, total_len, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - URL_TX_TIMEOUT, url_txeof); + usbd_setup_xfer(c->url_xfer,c, c->url_buf, total_len, + USBD_FORCE_SHORT_XFER, URL_TX_TIMEOUT, url_txeof); /* Transmit */ sc->sc_refcnt++; @@ -929,7 +916,7 @@ url_send(struct url_softc *sc, struct mbuf *m, int idx) /* Stop the interface */ usb_add_task(sc->sc_udev, &sc->sc_stop_task, USB_TASKQ_DRIVER); - return (EIO); + return EIO; } DPRINTF(("%s: %s: send %d bytes\n", device_xname(sc->sc_dev), @@ -937,11 +924,11 @@ url_send(struct url_softc *sc, struct mbuf *m, int idx) sc->sc_cdata.url_tx_cnt++; - return (0); + return 0; } Static void -url_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, +url_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct url_chain *c = priv; @@ -989,13 +976,13 @@ url_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, } Static void -url_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +url_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct url_chain *c = priv; struct url_softc *sc = c->url_sc; struct ifnet *ifp = GET_IFP(sc); struct mbuf *m; - u_int32_t total_len; + uint32_t total_len; url_rxhdr_t rxhdr; int s; @@ -1072,9 +1059,8 @@ url_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) done: /* Setup new transfer */ - usbd_setup_xfer(xfer, sc->sc_pipe_rx, c, c->url_buf, URL_BUFSZ, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, url_rxeof); + usbd_setup_xfer(xfer, c, c->url_buf, URL_BUFSZ, USBD_SHORT_XFER_OK, + USBD_NO_TIMEOUT, url_rxeof); sc->sc_refcnt++; usbd_transfer(xfer); if (--sc->sc_refcnt < 0) @@ -1098,7 +1084,7 @@ url_ioctl(struct ifnet *ifp, u_long cmd, void *data) DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (EIO); + return EIO; s = splnet(); @@ -1111,7 +1097,7 @@ url_ioctl(struct ifnet *ifp, u_long cmd, void *data) splx(s); - return (error); + return error; } Static void @@ -1166,11 +1152,6 @@ url_stop(struct ifnet *ifp, int disable) if (err) printf("%s: abort rx pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); - err = usbd_close_pipe(sc->sc_pipe_rx); - if (err) - printf("%s: close rx pipe failed: %s\n", - device_xname(sc->sc_dev), usbd_errstr(err)); - sc->sc_pipe_rx = NULL; } /* TX endpoint */ @@ -1179,11 +1160,6 @@ url_stop(struct ifnet *ifp, int disable) if (err) printf("%s: abort tx pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); - err = usbd_close_pipe(sc->sc_pipe_tx); - if (err) - printf("%s: close tx pipe failed: %s\n", - device_xname(sc->sc_dev), usbd_errstr(err)); - sc->sc_pipe_tx = NULL; } #if 0 @@ -1209,7 +1185,7 @@ url_stop(struct ifnet *ifp, int disable) sc->sc_cdata.url_rx_chain[i].url_mbuf = NULL; } if (sc->sc_cdata.url_rx_chain[i].url_xfer != NULL) { - usbd_free_xfer(sc->sc_cdata.url_rx_chain[i].url_xfer); + usbd_destroy_xfer(sc->sc_cdata.url_rx_chain[i].url_xfer); sc->sc_cdata.url_rx_chain[i].url_xfer = NULL; } } @@ -1221,11 +1197,30 @@ url_stop(struct ifnet *ifp, int disable) sc->sc_cdata.url_tx_chain[i].url_mbuf = NULL; } if (sc->sc_cdata.url_tx_chain[i].url_xfer != NULL) { - usbd_free_xfer(sc->sc_cdata.url_tx_chain[i].url_xfer); + usbd_destroy_xfer(sc->sc_cdata.url_tx_chain[i].url_xfer); sc->sc_cdata.url_tx_chain[i].url_xfer = NULL; } } + /* Close pipes */ + /* RX endpoint */ + if (sc->sc_pipe_rx != NULL) { + err = usbd_close_pipe(sc->sc_pipe_rx); + if (err) + printf("%s: close rx pipe failed: %s\n", + device_xname(sc->sc_dev), usbd_errstr(err)); + sc->sc_pipe_rx = NULL; + } + + /* TX endpoint */ + if (sc->sc_pipe_tx != NULL) { + err = usbd_close_pipe(sc->sc_pipe_tx); + if (err) + printf("%s: close tx pipe failed: %s\n", + device_xname(sc->sc_dev), usbd_errstr(err)); + sc->sc_pipe_tx = NULL; + } + sc->sc_link = 0; ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); } @@ -1241,7 +1236,7 @@ url_ifmedia_change(struct ifnet *ifp) DPRINTF(("%s: %s: enter\n", device_xname(sc->sc_dev), __func__)); if (sc->sc_dying) - return (0); + return 0; sc->sc_link = 0; if ((rc = mii_mediachg(mii)) == ENXIO) @@ -1350,10 +1345,10 @@ Static int url_int_miibus_readreg(device_t dev, int phy, int reg) { struct url_softc *sc; - u_int16_t val; + uint16_t val; if (dev == NULL) - return (0); + return 0; sc = device_private(dev); @@ -1365,14 +1360,14 @@ url_int_miibus_readreg(device_t dev, int phy, int reg) printf("%s: %s: dying\n", device_xname(sc->sc_dev), __func__); #endif - return (0); + return 0; } /* XXX: one PHY only for the RTL8150 internal PHY */ if (phy != 0) { DPRINTFN(0xff, ("%s: %s: phy=%d is not supported\n", device_xname(sc->sc_dev), __func__, phy)); - return (0); + return 0; } url_lock_mii(sc); @@ -1416,7 +1411,7 @@ url_int_miibus_readreg(device_t dev, int phy, int reg) device_xname(sc->sc_dev), __func__, phy, reg, val)); url_unlock_mii(sc); - return (val); + return val; } Static void @@ -1506,7 +1501,7 @@ Static int url_ext_miibus_redreg(device_t dev, int phy, int reg) { struct url_softc *sc = device_private(dev); - u_int16_t val; + uint16_t val; DPRINTF(("%s: %s: enter, phy=%d reg=0x%04x\n", device_xname(sc->sc_dev), __func__, phy, reg)); @@ -1516,7 +1511,7 @@ url_ext_miibus_redreg(device_t dev, int phy, int reg) printf("%s: %s: dying\n", device_xname(sc->sc_dev), __func__); #endif - return (0); + return 0; } url_lock_mii(sc); @@ -1543,7 +1538,7 @@ url_ext_miibus_redreg(device_t dev, int phy, int reg) device_xname(sc->sc_dev), __func__, phy, reg, val)); url_unlock_mii(sc); - return (val); + return val; } Static void diff --git a/sys/dev/usb/if_urlreg.h b/sys/dev/usb/if_urlreg.h index b139c1e836a..e2f3f845f9f 100644 --- a/sys/dev/usb/if_urlreg.h +++ b/sys/dev/usb/if_urlreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_urlreg.h,v 1.10 2015/04/14 20:32:36 riastradh Exp $ */ +/* $NetBSD: if_urlreg.h,v 1.11 2016/04/23 10:15:31 skrll Exp $ */ /* * Copyright (c) 2001, 2002 * Shingo WATANABE <nabe@nabechan.org>. All rights reserved. @@ -134,7 +134,7 @@ typedef uWord url_rxhdr_t; /* Recive Header */ struct url_chain { struct url_softc *url_sc; - usbd_xfer_handle url_xfer; + struct usbd_xfer *url_xfer; char *url_buf; struct mbuf *url_mbuf; int url_idx; @@ -155,17 +155,17 @@ struct url_cdata { struct url_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; + struct usbd_device * sc_udev; /* USB */ - usbd_interface_handle sc_ctl_iface; + struct usbd_interface * sc_ctl_iface; /* int sc_ctl_iface_no; */ int sc_bulkin_no; /* bulk in endpoint */ int sc_bulkout_no; /* bulk out endpoint */ int sc_intrin_no; /* intr in endpoint */ - usbd_pipe_handle sc_pipe_rx; - usbd_pipe_handle sc_pipe_tx; - usbd_pipe_handle sc_pipe_intr; + struct usbd_pipe * sc_pipe_rx; + struct usbd_pipe * sc_pipe_tx; + struct usbd_pipe * sc_pipe_intr; struct callout sc_stat_ch; u_int sc_rx_errs; /* u_int sc_intr_errs; */ @@ -187,5 +187,5 @@ struct url_softc { struct usb_task sc_tick_task; struct usb_task sc_stop_task; - u_int16_t sc_flags; + uint16_t sc_flags; }; diff --git a/sys/dev/usb/if_urndis.c b/sys/dev/usb/if_urndis.c index 539684d3990..a384d706507 100644 --- a/sys/dev/usb/if_urndis.c +++ b/sys/dev/usb/if_urndis.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_urndis.c,v 1.10 2016/02/09 08:32:12 ozaki-r Exp $ */ +/* $NetBSD: if_urndis.c,v 1.11 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_urndis.c,v 1.31 2011/07/03 15:47:17 matthew Exp $ */ /* @@ -21,7 +21,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_urndis.c,v 1.10 2016/02/09 08:32:12 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_urndis.c,v 1.11 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -71,8 +71,8 @@ static void urndis_watchdog(struct ifnet *); #endif static void urndis_start(struct ifnet *); -static void urndis_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void urndis_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +static void urndis_rxeof(struct usbd_xfer *, void *, usbd_status); +static void urndis_txeof(struct usbd_xfer *, void *, usbd_status); static int urndis_rx_list_init(struct urndis_softc *); static int urndis_tx_list_init(struct urndis_softc *); @@ -729,7 +729,7 @@ urndis_encap(struct urndis_softc *sc, struct mbuf *m, int idx) { struct urndis_chain *c; usbd_status err; - struct urndis_packet_msg *msg; + struct urndis_packet_msg *msg; c = &sc->sc_data.sc_tx_chain[idx]; @@ -754,9 +754,8 @@ urndis_encap(struct urndis_softc *sc, struct mbuf *m, int idx) c->sc_mbuf = m; - usbd_setup_xfer(c->sc_xfer, sc->sc_bulkout_pipe, c, c->sc_buf, - le32toh(msg->rm_len), USBD_FORCE_SHORT_XFER | USBD_NO_COPY, 10000, - urndis_txeof); + usbd_setup_xfer(c->sc_xfer, c, c->sc_buf, le32toh(msg->rm_len), + USBD_FORCE_SHORT_XFER, 10000, urndis_txeof); /* Transmit */ err = usbd_transfer(c->sc_xfer); @@ -892,20 +891,20 @@ urndis_newbuf(struct urndis_softc *sc, struct urndis_chain *c) if (m_new == NULL) { printf("%s: no memory for rx list -- packet dropped!\n", DEVNAME(sc)); - return (ENOBUFS); + return ENOBUFS; } MCLGET(m_new, M_DONTWAIT); if (!(m_new->m_flags & M_EXT)) { printf("%s: no memory for rx list -- packet dropped!\n", DEVNAME(sc)); m_freem(m_new); - return (ENOBUFS); + return ENOBUFS; } m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; m_adj(m_new, ETHER_ALIGN); c->sc_mbuf = m_new; - return (0); + return 0; } static int @@ -922,20 +921,18 @@ urndis_rx_list_init(struct urndis_softc *sc) c->sc_idx = i; if (urndis_newbuf(sc, c) == ENOBUFS) - return (ENOBUFS); + return ENOBUFS; if (c->sc_xfer == NULL) { - c->sc_xfer = usbd_alloc_xfer(sc->sc_udev); - if (c->sc_xfer == NULL) - return (ENOBUFS); - c->sc_buf = usbd_alloc_buffer(c->sc_xfer, - RNDIS_BUFSZ); - if (c->sc_buf == NULL) - return (ENOBUFS); + int err = usbd_create_xfer(sc->sc_bulkin_pipe, + RNDIS_BUFSZ, USBD_SHORT_XFER_OK, 0, &c->sc_xfer); + if (err) + return err; + c->sc_buf = usbd_get_buffer(c->sc_xfer); } } - return (0); + return 0; } static int @@ -952,16 +949,14 @@ urndis_tx_list_init(struct urndis_softc *sc) c->sc_idx = i; c->sc_mbuf = NULL; if (c->sc_xfer == NULL) { - c->sc_xfer = usbd_alloc_xfer(sc->sc_udev); - if (c->sc_xfer == NULL) - return (ENOBUFS); - c->sc_buf = usbd_alloc_buffer(c->sc_xfer, - RNDIS_BUFSZ); - if (c->sc_buf == NULL) - return (ENOBUFS); + int err = usbd_create_xfer(sc->sc_bulkout_pipe, + RNDIS_BUFSZ, USBD_FORCE_SHORT_XFER, 0, &c->sc_xfer); + if (err) + return err; + c->sc_buf = usbd_get_buffer(c->sc_xfer); } } - return (0); + return 0; } static int @@ -974,7 +969,7 @@ urndis_ioctl(struct ifnet *ifp, unsigned long command, void *data) error = 0; if (sc->sc_dying) - return (EIO); + return EIO; s = splnet(); @@ -1001,7 +996,7 @@ urndis_ioctl(struct ifnet *ifp, unsigned long command, void *data) error = 0; splx(s); - return (error); + return error; } #if 0 @@ -1041,22 +1036,6 @@ urndis_init(struct ifnet *ifp) s = splnet(); - err = urndis_tx_list_init(sc); - if (err) { - printf("%s: tx list init failed\n", - DEVNAME(sc)); - splx(s); - return err; - } - - err = urndis_rx_list_init(sc); - if (err) { - printf("%s: rx list init failed\n", - DEVNAME(sc)); - splx(s); - return err; - } - usberr = usbd_open_pipe(sc->sc_iface_data, sc->sc_bulkin_no, USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe); if (usberr) { @@ -1075,14 +1054,29 @@ urndis_init(struct ifnet *ifp) return EIO; } + err = urndis_tx_list_init(sc); + if (err) { + printf("%s: tx list init failed\n", + DEVNAME(sc)); + splx(s); + return err; + } + + err = urndis_rx_list_init(sc); + if (err) { + printf("%s: rx list init failed\n", + DEVNAME(sc)); + splx(s); + return err; + } + for (i = 0; i < RNDIS_RX_LIST_CNT; i++) { struct urndis_chain *c; c = &sc->sc_data.sc_rx_chain[i]; - usbd_setup_xfer(c->sc_xfer, sc->sc_bulkin_pipe, c, - c->sc_buf, RNDIS_BUFSZ, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, urndis_rxeof); + + usbd_setup_xfer(c->sc_xfer, c, c->sc_buf, RNDIS_BUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urndis_rxeof); usbd_transfer(c->sc_xfer); } @@ -1110,11 +1104,6 @@ urndis_stop(struct ifnet *ifp) if (err) printf("%s: abort rx pipe failed: %s\n", DEVNAME(sc), usbd_errstr(err)); - err = usbd_close_pipe(sc->sc_bulkin_pipe); - if (err) - printf("%s: close rx pipe failed: %s\n", - DEVNAME(sc), usbd_errstr(err)); - sc->sc_bulkin_pipe = NULL; } if (sc->sc_bulkout_pipe != NULL) { @@ -1122,11 +1111,6 @@ urndis_stop(struct ifnet *ifp) if (err) printf("%s: abort tx pipe failed: %s\n", DEVNAME(sc), usbd_errstr(err)); - err = usbd_close_pipe(sc->sc_bulkout_pipe); - if (err) - printf("%s: close tx pipe failed: %s\n", - DEVNAME(sc), usbd_errstr(err)); - sc->sc_bulkout_pipe = NULL; } for (i = 0; i < RNDIS_RX_LIST_CNT; i++) { @@ -1135,7 +1119,7 @@ urndis_stop(struct ifnet *ifp) sc->sc_data.sc_rx_chain[i].sc_mbuf = NULL; } if (sc->sc_data.sc_rx_chain[i].sc_xfer != NULL) { - usbd_free_xfer(sc->sc_data.sc_rx_chain[i].sc_xfer); + usbd_destroy_xfer(sc->sc_data.sc_rx_chain[i].sc_xfer); sc->sc_data.sc_rx_chain[i].sc_xfer = NULL; } } @@ -1146,10 +1130,27 @@ urndis_stop(struct ifnet *ifp) sc->sc_data.sc_tx_chain[i].sc_mbuf = NULL; } if (sc->sc_data.sc_tx_chain[i].sc_xfer != NULL) { - usbd_free_xfer(sc->sc_data.sc_tx_chain[i].sc_xfer); + usbd_destroy_xfer(sc->sc_data.sc_tx_chain[i].sc_xfer); sc->sc_data.sc_tx_chain[i].sc_xfer = NULL; } } + + /* Close pipes. */ + if (sc->sc_bulkin_pipe != NULL) { + err = usbd_close_pipe(sc->sc_bulkin_pipe); + if (err) + printf("%s: close rx pipe failed: %s\n", + DEVNAME(sc), usbd_errstr(err)); + sc->sc_bulkin_pipe = NULL; + } + + if (sc->sc_bulkout_pipe != NULL) { + err = usbd_close_pipe(sc->sc_bulkout_pipe); + if (err) + printf("%s: close tx pipe failed: %s\n", + DEVNAME(sc), usbd_errstr(err)); + sc->sc_bulkout_pipe = NULL; + } } static void @@ -1190,8 +1191,8 @@ urndis_start(struct ifnet *ifp) } static void -urndis_rxeof(usbd_xfer_handle xfer, - usbd_private_handle priv, +urndis_rxeof(struct usbd_xfer *xfer, + void *priv, usbd_status status) { struct urndis_chain *c; @@ -1225,15 +1226,14 @@ urndis_rxeof(usbd_xfer_handle xfer, done: /* Setup new transfer. */ - usbd_setup_xfer(c->sc_xfer, sc->sc_bulkin_pipe, c, c->sc_buf, - RNDIS_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, - urndis_rxeof); + usbd_setup_xfer(c->sc_xfer, c, c->sc_buf, RNDIS_BUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urndis_rxeof); usbd_transfer(c->sc_xfer); } static void -urndis_txeof(usbd_xfer_handle xfer, - usbd_private_handle priv, +urndis_txeof(struct usbd_xfer *xfer, + void *priv, usbd_status status) { struct urndis_chain *c; @@ -1291,24 +1291,22 @@ urndis_txeof(usbd_xfer_handle xfer, static int urndis_match(device_t parent, cfdata_t match, void *aux) { - struct usbif_attach_arg *uaa; + struct usbif_attach_arg *uiaa = aux; usb_interface_descriptor_t *id; - uaa = aux; - - if (!uaa->iface) - return (UMATCH_NONE); + if (!uiaa->uiaa_iface) + return UMATCH_NONE; - id = usbd_get_interface_descriptor(uaa->iface); + id = usbd_get_interface_descriptor(uiaa->uiaa_iface); if (id == NULL) - return (UMATCH_NONE); + return UMATCH_NONE; if (id->bInterfaceClass == UICLASS_WIRELESS && id->bInterfaceSubClass == UISUBCLASS_RF && id->bInterfaceProtocol == UIPROTO_RNDIS) - return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO); + return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO; - return (usb_lookup(urndis_devs, uaa->vendor, uaa->product) != NULL) ? + return usb_lookup(urndis_devs, uiaa->uiaa_vendor, uiaa->uiaa_product) != NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } @@ -1316,7 +1314,7 @@ static void urndis_attach(device_t parent, device_t self, void *aux) { struct urndis_softc *sc; - struct usbif_attach_arg *uaa; + struct usbif_attach_arg *uiaa; struct ifnet *ifp; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; @@ -1334,18 +1332,18 @@ urndis_attach(device_t parent, device_t self, void *aux) char *devinfop; sc = device_private(self); - uaa = aux; + uiaa = aux; sc->sc_dev = self; - sc->sc_udev = uaa->device; + sc->sc_udev = uiaa->uiaa_device; aprint_naive("\n"); aprint_normal("\n"); - devinfop = usbd_devinfo_alloc(uaa->device, 0); + devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); - sc->sc_iface_ctl = uaa->iface; + sc->sc_iface_ctl = uiaa->uiaa_iface; id = usbd_get_interface_descriptor(sc->sc_iface_ctl); if_ctl = id->bInterfaceNumber; sc->sc_ifaceno_ctl = if_ctl; @@ -1373,14 +1371,14 @@ urndis_attach(device_t parent, device_t self, void *aux) } else { DPRINTF(("urndis_attach: union interface: ctl %u, data %u\n", if_ctl, if_data)); - for (i = 0; i < uaa->nifaces; i++) { - if (uaa->ifaces[i] != NULL) { + for (i = 0; i < uiaa->uiaa_nifaces; i++) { + if (uiaa->uiaa_ifaces[i] != NULL) { id = usbd_get_interface_descriptor( - uaa->ifaces[i]); + uiaa->uiaa_ifaces[i]); if (id != NULL && id->bInterfaceNumber == if_data) { - sc->sc_iface_data = uaa->ifaces[i]; - uaa->ifaces[i] = NULL; + sc->sc_iface_data = uiaa->uiaa_ifaces[i]; + uiaa->uiaa_ifaces[i] = NULL; } } } diff --git a/sys/dev/usb/if_urndisreg.h b/sys/dev/usb/if_urndisreg.h index 073f623e08f..91219f4ce6e 100644 --- a/sys/dev/usb/if_urndisreg.h +++ b/sys/dev/usb/if_urndisreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_urndisreg.h,v 1.1 2011/07/20 19:59:49 jakllsch Exp $ */ +/* $NetBSD: if_urndisreg.h,v 1.2 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_urndisreg.h,v 1.14 2010/07/08 18:22:01 ckuethe Exp $ */ /* @@ -26,7 +26,7 @@ struct urndis_chain { struct urndis_softc *sc_softc; - usbd_xfer_handle sc_xfer; + struct usbd_xfer *sc_xfer; char *sc_buf; struct mbuf *sc_mbuf; int sc_idx; @@ -51,16 +51,16 @@ struct urndis_softc { uint32_t sc_filter; /* USB goo */ - usbd_device_handle sc_udev; + struct usbd_device * sc_udev; int sc_ifaceno_ctl; - usbd_interface_handle sc_iface_ctl; - usbd_interface_handle sc_iface_data; + struct usbd_interface * sc_iface_ctl; + struct usbd_interface * sc_iface_data; struct timeval sc_rx_notice; int sc_bulkin_no; - usbd_pipe_handle sc_bulkin_pipe; + struct usbd_pipe * sc_bulkin_pipe; int sc_bulkout_no; - usbd_pipe_handle sc_bulkout_pipe; + struct usbd_pipe * sc_bulkout_pipe; struct urndis_cdata sc_data; }; diff --git a/sys/dev/usb/if_urtw.c b/sys/dev/usb/if_urtw.c index e6b1136eab6..45f13d8d735 100644 --- a/sys/dev/usb/if_urtw.c +++ b/sys/dev/usb/if_urtw.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_urtw.c,v 1.6 2013/10/16 18:55:31 christos Exp $ */ +/* $NetBSD: if_urtw.c,v 1.7 2016/04/23 10:15:31 skrll Exp $ */ /* $OpenBSD: if_urtw.c,v 1.39 2011/07/03 15:47:17 matthew Exp $ */ /*- @@ -19,7 +19,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_urtw.c,v 1.6 2013/10/16 18:55:31 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_urtw.c,v 1.7 2016/04/23 10:15:31 skrll Exp $"); #include <sys/param.h> #include <sys/sockio.h> @@ -28,7 +28,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_urtw.c,v 1.6 2013/10/16 18:55:31 christos Exp $") #include <sys/kernel.h> #include <sys/socket.h> #include <sys/systm.h> -#include <sys/malloc.h> #include <sys/callout.h> #include <sys/conf.h> #include <sys/device.h> @@ -483,13 +482,13 @@ int urtw_alloc_rx_data_list(struct urtw_softc *); void urtw_free_rx_data_list(struct urtw_softc *); int urtw_alloc_tx_data_list(struct urtw_softc *); void urtw_free_tx_data_list(struct urtw_softc *); -void urtw_rxeof(usbd_xfer_handle, usbd_private_handle, +void urtw_rxeof(struct usbd_xfer *, void *, usbd_status); int urtw_tx_start(struct urtw_softc *, struct ieee80211_node *, struct mbuf *, int); -void urtw_txeof_low(usbd_xfer_handle, usbd_private_handle, +void urtw_txeof_low(struct usbd_xfer *, void *, usbd_status); -void urtw_txeof_normal(usbd_xfer_handle, usbd_private_handle, +void urtw_txeof_normal(struct usbd_xfer *, void *, usbd_status); void urtw_next_scan(void *); void urtw_task(void *); @@ -500,7 +499,7 @@ int urtw_newstate(struct ieee80211com *, enum ieee80211_state, int); void urtw_watchdog(struct ifnet *); void urtw_set_chan(struct urtw_softc *, struct ieee80211_channel *); int urtw_isbmode(uint16_t); -uint16_t urtw_rate2rtl(int rate); +uint16_t urtw_rate2rtl(int); uint16_t urtw_rtl2rate(int); usbd_status urtw_set_rate(struct urtw_softc *); usbd_status urtw_update_msr(struct urtw_softc *); @@ -592,8 +591,8 @@ urtw_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return ((urtw_lookup(uaa->vendor, uaa->product) != NULL) ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return urtw_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } void @@ -609,8 +608,8 @@ urtw_attach(device_t parent, device_t self, void *aux) int i; sc->sc_dev = self; - sc->sc_udev = uaa->device; - sc->sc_hwrev = urtw_lookup(uaa->vendor, uaa->product)->rev; + sc->sc_udev = uaa->uaa_device; + sc->sc_hwrev = urtw_lookup(uaa->uaa_vendor, uaa->uaa_product)->rev; printf(": "); @@ -741,11 +740,11 @@ urtw_attach(device_t parent, device_t self, void *aux) sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN, &sc->sc_drvbpf); - sc->sc_rxtap_len = sizeof sc->sc_rxtapu; + sc->sc_rxtap_len = sizeof(sc->sc_rxtapu); sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); sc->sc_rxtap.wr_ihdr.it_present = htole32(URTW_RX_RADIOTAP_PRESENT); - sc->sc_txtap_len = sizeof sc->sc_txtapu; + sc->sc_txtap_len = sizeof(sc->sc_txtapu); sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); sc->sc_txtap.wt_ihdr.it_present = htole32(URTW_TX_RADIOTAP_PRESENT); @@ -789,7 +788,7 @@ urtw_detach(device_t self, int flags) splx(s); - return (0); + return 0; } int @@ -803,7 +802,7 @@ urtw_activate(device_t self, enum devact act) break; } - return (0); + return 0; } usbd_status @@ -830,7 +829,7 @@ urtw_close_pipes(struct urtw_softc *sc) sc->sc_txpipe_normal = NULL; } fail: - return (error); + return error; } usbd_status @@ -880,10 +879,10 @@ urtw_open_pipes(struct urtw_softc *sc) goto fail; } - return (0); + return 0; fail: (void)urtw_close_pipes(sc); - return (error); + return error; } int @@ -896,16 +895,11 @@ urtw_alloc_rx_data_list(struct urtw_softc *sc) data->sc = sc; - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { - printf("%s: could not allocate rx xfer\n", - device_xname(sc->sc_dev)); - error = ENOMEM; - goto fail; - } + error = usbd_create_xfer(sc->sc_rxpipe, MCLBYTES, + USBD_SHORT_XFER_OK, 0, &data->xfer); + if (error) { - if (usbd_alloc_buffer(data->xfer, URTW_RX_MAXSIZE) == NULL) { - printf("%s: could not allocate rx buffer\n", + printf("%s: could not allocate rx xfer\n", device_xname(sc->sc_dev)); error = ENOMEM; goto fail; @@ -928,11 +922,11 @@ urtw_alloc_rx_data_list(struct urtw_softc *sc) data->buf = mtod(data->m, uint8_t *); } - return (0); + return 0; fail: urtw_free_rx_data_list(sc); - return (error); + return error; } void @@ -948,7 +942,7 @@ urtw_free_rx_data_list(struct urtw_softc *sc) struct urtw_rx_data *data = &sc->sc_rx_data[i]; if (data->xfer != NULL) { - usbd_free_xfer(data->xfer); + usbd_destroy_xfer(data->xfer); data->xfer = NULL; } if (data->m != NULL) { @@ -963,38 +957,36 @@ urtw_alloc_tx_data_list(struct urtw_softc *sc) { int i, error; - for (i = 0; i < URTW_TX_DATA_LIST_COUNT; i++) { - struct urtw_tx_data *data = &sc->sc_tx_data[i]; + for (size_t j = 0; j < URTW_PRIORITY_MAX; j++) { + for (i = 0; i < URTW_TX_DATA_LIST_COUNT; i++) { + struct urtw_tx_data *data = &sc->sc_tx_data[j][i]; - data->sc = sc; - data->ni = NULL; + data->sc = sc; + data->ni = NULL; - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { - printf("%s: could not allocate tx xfer\n", - device_xname(sc->sc_dev)); - error = ENOMEM; - goto fail; - } + error = usbd_create_xfer((j == URTW_PRIORITY_LOW) ? + sc->sc_txpipe_low : sc->sc_txpipe_normal, + URTW_TX_MAXSIZE, USBD_FORCE_SHORT_XFER, 0, + &data->xfer); + if (error) { + printf("%s: could not allocate tx xfer\n", + device_xname(sc->sc_dev)); + goto fail; + } - data->buf = usbd_alloc_buffer(data->xfer, URTW_TX_MAXSIZE); - if (data->buf == NULL) { - printf("%s: could not allocate tx buffer\n", - device_xname(sc->sc_dev)); - error = ENOMEM; - goto fail; - } + data->buf = usbd_get_buffer(data->xfer); - if (((unsigned long)data->buf) % 4) - printf("%s: warn: unaligned buffer %p\n", - device_xname(sc->sc_dev), data->buf); + if (((unsigned long)data->buf) % 4) + printf("%s: warn: unaligned buffer %p\n", + device_xname(sc->sc_dev), data->buf); + } } - return (0); + return 0; fail: urtw_free_tx_data_list(sc); - return (error); + return error; } void @@ -1008,16 +1000,18 @@ urtw_free_tx_data_list(struct urtw_softc *sc) if (sc->sc_txpipe_normal != NULL) usbd_abort_pipe(sc->sc_txpipe_normal); - for (i = 0; i < URTW_TX_DATA_LIST_COUNT; i++) { - struct urtw_tx_data *data = &sc->sc_tx_data[i]; + for (size_t j = 0; j < URTW_PRIORITY_MAX; j++) { + for (i = 0; i < URTW_TX_DATA_LIST_COUNT; i++) { + struct urtw_tx_data *data = &sc->sc_tx_data[j][i]; - if (data->xfer != NULL) { - usbd_free_xfer(data->xfer); - data->xfer = NULL; - } - if (data->ni != NULL) { - ieee80211_free_node(data->ni); - data->ni = NULL; + if (data->xfer != NULL) { + usbd_destroy_xfer(data->xfer); + data->xfer = NULL; + } + if (data->ni != NULL) { + ieee80211_free_node(data->ni); + data->ni = NULL; + } } } } @@ -1029,13 +1023,13 @@ urtw_media_change(struct ifnet *ifp) error = ieee80211_media_change(ifp); if (error != ENETRESET) - return (error); + return error; if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) ifp->if_init(ifp); - return (0); + return 0; } int @@ -1051,7 +1045,7 @@ urtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) sc->sc_arg = arg; usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); - return (0); + return 0; } usbd_status @@ -1085,7 +1079,7 @@ urtw_led_init(struct urtw_softc *sc) sc->sc_gpio_ledpin = URTW_LED_PIN_GPIO0; fail: - return (error); + return error; } usbd_status @@ -1100,7 +1094,7 @@ urtw_8225_write_s16(struct urtw_softc *sc, uint8_t addr, int index, USETW(req.wIndex, index); USETW(req.wLength, sizeof(uint16_t)); - return (usbd_do_request(sc->sc_udev, &req, &data)); + return usbd_do_request(sc->sc_udev, &req, &data); } usbd_status @@ -1190,7 +1184,7 @@ urtw_8225_read(struct urtw_softc *sc, uint8_t addr, uint32_t *data) if (data != NULL) *data = value; fail: - return (error); + return error; } usbd_status @@ -1223,7 +1217,7 @@ urtw_8225_write_c(struct urtw_softc *sc, uint8_t addr, uint16_t data) urtw_write16_m(sc, URTW_RF_PINS_SELECT, d84); usbd_delay_ms(sc->sc_udev, 2); fail: - return (error); + return error; } usbd_status @@ -1256,7 +1250,7 @@ urtw_8225_isv2(struct urtw_softc *sc, int *ret) urtw_8225_write(sc, 0x0, 0xb7); fail: - return (error); + return error; } usbd_status @@ -1303,7 +1297,7 @@ urtw_get_rfchip(struct urtw_softc *sc) rf->max_sens = URTW_8225_RF_MAX_SENS; rf->sens = URTW_8225_RF_DEF_SENS; - return (0); + return 0; fail: panic("unsupported RF chip %d", data & 0xff); @@ -1378,7 +1372,7 @@ urtw_get_txpwr(struct urtw_softc *sc) sc->sc_txpwr_ofdm[14] = (data & 0xf000) >> 12; } fail: - return (error); + return error; } usbd_status @@ -1404,7 +1398,7 @@ urtw_get_macaddr(struct urtw_softc *sc) ic->ic_myaddr[4] = data & 0xff; ic->ic_myaddr[5] = (data & 0xff00) >> 8; fail: - return (error); + return error; } usbd_status @@ -1479,7 +1473,7 @@ urtw_eprom_read32(struct urtw_softc *sc, uint32_t addr, uint32_t *data) /* now disable EPROM programming */ urtw_write8_m(sc, URTW_EPROM_CMD, URTW_EPROM_CMD_NORMAL_MODE); fail: - return (error); + return error; #undef URTW_READCMD_LEN } @@ -1494,7 +1488,7 @@ urtw_eprom_readbit(struct urtw_softc *sc, int16_t *data) DELAY(URTW_EPROM_DELAY); fail: - return (error); + return error; } usbd_status @@ -1512,7 +1506,7 @@ urtw_eprom_sendbits(struct urtw_softc *sc, int16_t *buf, int buflen) goto fail; } fail: - return (error); + return error; } usbd_status @@ -1528,7 +1522,7 @@ urtw_eprom_writebit(struct urtw_softc *sc, int16_t bit) urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_WRITEBIT); DELAY(URTW_EPROM_DELAY); fail: - return (error); + return error; } usbd_status @@ -1546,7 +1540,7 @@ urtw_eprom_ck(struct urtw_softc *sc) urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CK); DELAY(URTW_EPROM_DELAY); fail: - return (error); + return error; } usbd_status @@ -1562,7 +1556,7 @@ urtw_eprom_cs(struct urtw_softc *sc, int able) urtw_write8_m(sc, URTW_EPROM_CMD, data & ~URTW_EPROM_CS); DELAY(URTW_EPROM_DELAY); fail: - return (error); + return error; } usbd_status @@ -1578,7 +1572,7 @@ urtw_read8_c(struct urtw_softc *sc, int val, uint8_t *data, uint8_t idx) USETW(req.wLength, sizeof(uint8_t)); error = usbd_do_request(sc->sc_udev, &req, data); - return (error); + return error; } usbd_status @@ -1594,7 +1588,7 @@ urtw_read8e(struct urtw_softc *sc, int val, uint8_t *data) USETW(req.wLength, sizeof(uint8_t)); error = usbd_do_request(sc->sc_udev, &req, data); - return (error); + return error; } usbd_status @@ -1610,7 +1604,7 @@ urtw_read16_c(struct urtw_softc *sc, int val, uint16_t *data, uint8_t idx) USETW(req.wLength, sizeof(uint16_t)); error = usbd_do_request(sc->sc_udev, &req, data); - return (error); + return error; } usbd_status @@ -1626,7 +1620,7 @@ urtw_read32_c(struct urtw_softc *sc, int val, uint32_t *data, uint8_t idx) USETW(req.wLength, sizeof(uint32_t)); error = usbd_do_request(sc->sc_udev, &req, data); - return (error); + return error; } usbd_status @@ -1640,7 +1634,7 @@ urtw_write8_c(struct urtw_softc *sc, int val, uint8_t data, uint8_t idx) USETW(req.wIndex, idx & 0x03); USETW(req.wLength, sizeof(uint8_t)); - return (usbd_do_request(sc->sc_udev, &req, &data)); + return usbd_do_request(sc->sc_udev, &req, &data); } usbd_status @@ -1654,7 +1648,7 @@ urtw_write8e(struct urtw_softc *sc, int val, uint8_t data) USETW(req.wIndex, 0); USETW(req.wLength, sizeof(uint8_t)); - return (usbd_do_request(sc->sc_udev, &req, &data)); + return usbd_do_request(sc->sc_udev, &req, &data); } usbd_status @@ -1668,7 +1662,7 @@ urtw_write16_c(struct urtw_softc *sc, int val, uint16_t data, uint8_t idx) USETW(req.wIndex, idx & 0x03); USETW(req.wLength, sizeof(uint16_t)); - return (usbd_do_request(sc->sc_udev, &req, &data)); + return usbd_do_request(sc->sc_udev, &req, &data); } usbd_status @@ -1682,7 +1676,7 @@ urtw_write32_c(struct urtw_softc *sc, int val, uint32_t data, uint8_t idx) USETW(req.wIndex, idx & 0x03); USETW(req.wLength, sizeof(uint32_t)); - return (usbd_do_request(sc->sc_udev, &req, &data)); + return usbd_do_request(sc->sc_udev, &req, &data); } static usbd_status @@ -1696,7 +1690,7 @@ urtw_set_mode(struct urtw_softc *sc, uint32_t mode) data = data & ~(URTW_EPROM_CS | URTW_EPROM_CK); urtw_write8_m(sc, URTW_EPROM_CMD, data); fail: - return (error); + return error; } usbd_status @@ -1719,7 +1713,7 @@ urtw_8180_set_anaparam(struct urtw_softc *sc, uint32_t val) if (error) goto fail; fail: - return (error); + return error; } usbd_status @@ -1742,7 +1736,7 @@ urtw_8185_set_anaparam2(struct urtw_softc *sc, uint32_t val) if (error) goto fail; fail: - return (error); + return error; } usbd_status @@ -1753,7 +1747,7 @@ urtw_intr_disable(struct urtw_softc *sc) urtw_write16_m(sc, URTW_INTR_MASK, 0); fail: - return (error); + return error; } usbd_status @@ -1808,7 +1802,7 @@ urtw_reset(struct urtw_softc *sc) if (error) goto fail; fail: - return (error); + return error; } usbd_status @@ -1834,7 +1828,7 @@ urtw_led_on(struct urtw_softc *sc, int type) sc->sc_gpio_ledon = 1; fail: - return (error); + return error; } static usbd_status @@ -1861,7 +1855,7 @@ urtw_led_off(struct urtw_softc *sc, int type) sc->sc_gpio_ledon = 0; fail: - return (error); + return error; } usbd_status @@ -1873,7 +1867,7 @@ urtw_led_mode0(struct urtw_softc *sc, int mode) break; case URTW_LED_CTL_TX: if (sc->sc_gpio_ledinprogress == 1) - return (0); + return 0; sc->sc_gpio_ledstate = URTW_LED_BLINK_NORMAL; sc->sc_gpio_blinktime = 2; @@ -1910,25 +1904,25 @@ urtw_led_mode0(struct urtw_softc *sc, int mode) panic("unknown LED status 0x%x", sc->sc_gpio_ledstate); /* NOTREACHED */ } - return (0); + return 0; } usbd_status urtw_led_mode1(struct urtw_softc *sc, int mode) { - return (USBD_INVAL); + return USBD_INVAL; } usbd_status urtw_led_mode2(struct urtw_softc *sc, int mode) { - return (USBD_INVAL); + return USBD_INVAL; } usbd_status urtw_led_mode3(struct urtw_softc *sc, int mode) { - return (USBD_INVAL); + return USBD_INVAL; } void @@ -1977,7 +1971,7 @@ urtw_led_ctl(struct urtw_softc *sc, int mode) /* NOTREACHED */ } - return (error); + return error; } usbd_status @@ -2008,7 +2002,7 @@ urtw_led_blink(struct urtw_softc *sc) sc->sc_gpio_blinktime = 0; sc->sc_gpio_ledinprogress = 0; - return (0); + return 0; } sc->sc_gpio_blinkstate = (sc->sc_gpio_blinkstate != URTW_LED_ON) ? @@ -2023,7 +2017,7 @@ urtw_led_blink(struct urtw_softc *sc) panic("unknown LED status 0x%x", sc->sc_gpio_ledstate); /* NOTREACHED */ } - return (0); + return 0; } usbd_status @@ -2056,7 +2050,7 @@ urtw_update_msr(struct urtw_softc *sc) urtw_write8_m(sc, URTW_MSR, data); fail: - return (error); + return error; } uint16_t @@ -2066,10 +2060,10 @@ urtw_rate2rtl(int rate) for (i = 0; i < __arraycount(urtw_ratetable); i++) { if (rate == urtw_ratetable[i].reg) - return (urtw_ratetable[i].val); + return urtw_ratetable[i].val; } - return (3); + return 3; } uint16_t @@ -2079,10 +2073,10 @@ urtw_rtl2rate(int rate) for (i = 0; i < __arraycount(urtw_ratetable); i++) { if (rate == urtw_ratetable[i].val) - return (urtw_ratetable[i].reg); + return urtw_ratetable[i].reg; } - return (0); + return 0; } usbd_status @@ -2108,7 +2102,7 @@ urtw_set_rate(struct urtw_softc *sc) urtw_write16_m(sc, URTW_8187_BRSR, data); fail: - return (error); + return error; } usbd_status @@ -2118,7 +2112,7 @@ urtw_intr_enable(struct urtw_softc *sc) urtw_write16_m(sc, URTW_INTR_MASK, 0xffff); fail: - return (error); + return error; } usbd_status @@ -2159,7 +2153,7 @@ urtw_rx_setconf(struct urtw_softc *sc) urtw_write32_m(sc, URTW_RX, data); fail: - return (error); + return error; } usbd_status @@ -2176,9 +2170,8 @@ urtw_rx_enable(struct urtw_softc *sc) for (i = 0; i < URTW_RX_DATA_LIST_COUNT; i++) { rx_data = &sc->sc_rx_data[i]; - usbd_setup_xfer(rx_data->xfer, sc->sc_rxpipe, rx_data, - rx_data->buf, MCLBYTES, USBD_SHORT_XFER_OK, - USBD_NO_TIMEOUT, urtw_rxeof); + usbd_setup_xfer(rx_data->xfer, rx_data, rx_data->buf, MCLBYTES, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urtw_rxeof); error = usbd_transfer(rx_data->xfer); if (error != USBD_IN_PROGRESS && error != 0) { printf("%s: could not queue Rx transfer\n", @@ -2194,7 +2187,7 @@ urtw_rx_enable(struct urtw_softc *sc) urtw_read8_m(sc, URTW_CMD, &data); urtw_write8_m(sc, URTW_CMD, data | URTW_CMD_RX_ENABLE); fail: - return (error); + return error; } usbd_status @@ -2237,7 +2230,7 @@ urtw_tx_enable(struct urtw_softc *sc) urtw_read8_m(sc, URTW_CMD, &data8); urtw_write8_m(sc, URTW_CMD, data8 | URTW_CMD_TX_ENABLE); fail: - return (error); + return error; } int @@ -2305,7 +2298,9 @@ urtw_init(struct ifnet *ifp) goto fail; /* reset softc variables */ - sc->sc_txidx = sc->sc_tx_low_queued = sc->sc_tx_normal_queued = 0; + for (size_t j = 0; j < URTW_PRIORITY_MAX; j++) { + sc->sc_txidx[j] = sc->sc_tx_queued[j] = 0; + } sc->sc_txtimer = 0; if (!(sc->sc_flags & URTW_INIT_ONCE)) { @@ -2350,9 +2345,9 @@ urtw_init(struct ifnet *ifp) else ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); - return (0); + return 0; fail: - return (error); + return error; } int @@ -2366,7 +2361,7 @@ urtw_ioctl(struct ifnet *ifp, u_long cmd, void *data) int s, error = 0; if (sc->sc_dying) - return (ENXIO); + return ENXIO; s = splnet(); @@ -2408,7 +2403,7 @@ urtw_ioctl(struct ifnet *ifp, u_long cmd, void *data) splx(s); - return (error); + return error; #undef IS_RUNNING } @@ -2431,8 +2426,8 @@ urtw_start(struct ifnet *ifp) for (;;) { IF_POLL(&ic->ic_mgtq, m0); if (m0 != NULL) { - if (sc->sc_tx_low_queued >= URTW_TX_DATA_LIST_COUNT || - sc->sc_tx_normal_queued >= + + if (sc->sc_tx_queued[URTW_PRIORITY_NORMAL] >= URTW_TX_DATA_LIST_COUNT) { ifp->if_flags |= IFF_OACTIVE; break; @@ -2450,8 +2445,7 @@ urtw_start(struct ifnet *ifp) IFQ_POLL(&ifp->if_snd, m0); if (m0 == NULL) break; - if (sc->sc_tx_low_queued >= URTW_TX_DATA_LIST_COUNT || - sc->sc_tx_normal_queued >= + if (sc->sc_tx_queued[URTW_PRIORITY_NORMAL] >= URTW_TX_DATA_LIST_COUNT) { ifp->if_flags |= IFF_OACTIVE; break; @@ -2506,7 +2500,7 @@ urtw_watchdog(struct ifnet *ifp) } void -urtw_txeof_low(usbd_xfer_handle xfer, usbd_private_handle priv, +urtw_txeof_low(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct urtw_tx_data *data = priv; @@ -2537,7 +2531,7 @@ urtw_txeof_low(usbd_xfer_handle xfer, usbd_private_handle priv, sc->sc_txtimer = 0; ifp->if_opackets++; - sc->sc_tx_low_queued--; + sc->sc_tx_queued[URTW_PRIORITY_LOW]--; ifp->if_flags &= ~IFF_OACTIVE; urtw_start(ifp); @@ -2545,7 +2539,7 @@ urtw_txeof_low(usbd_xfer_handle xfer, usbd_private_handle priv, } void -urtw_txeof_normal(usbd_xfer_handle xfer, usbd_private_handle priv, +urtw_txeof_normal(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct urtw_tx_data *data = priv; @@ -2576,7 +2570,7 @@ urtw_txeof_normal(usbd_xfer_handle xfer, usbd_private_handle priv, sc->sc_txtimer = 0; ifp->if_opackets++; - sc->sc_tx_normal_queued--; + sc->sc_tx_queued[URTW_PRIORITY_NORMAL]--; ifp->if_flags &= ~IFF_OACTIVE; urtw_start(ifp); @@ -2600,7 +2594,7 @@ urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, k = ieee80211_crypto_encap(ic, ni, m0); if (k == NULL) { m_freem(m0); - return (ENOBUFS); + return ENOBUFS; } /* packet header may have moved, reset our local pointer */ wh = mtod(m0, struct ieee80211_frame *); @@ -2625,10 +2619,11 @@ urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, if ((0 == xferlen % 64) || (0 == xferlen % 512)) xferlen += 1; - data = &sc->sc_tx_data[sc->sc_txidx]; - sc->sc_txidx = (sc->sc_txidx + 1) % URTW_TX_DATA_LIST_COUNT; + data = &sc->sc_tx_data[prior][sc->sc_txidx[prior]]; + sc->sc_txidx[prior] = + (sc->sc_txidx[prior] + 1) % URTW_TX_DATA_LIST_COUNT; - bzero(data->buf, URTW_TX_MAXSIZE); + memset(data->buf, 0, URTW_TX_MAXSIZE); data->buf[0] = m0->m_pkthdr.len & 0xff; data->buf[1] = (m0->m_pkthdr.len & 0x0f00) >> 8; data->buf[1] |= (1 << 7); @@ -2673,16 +2668,14 @@ urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, /* mbuf is no longer needed. */ m_freem(m0); - usbd_setup_xfer(data->xfer, - (prior == URTW_PRIORITY_LOW) ? sc->sc_txpipe_low : - sc->sc_txpipe_normal, data, data->buf, xferlen, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, URTW_DATA_TIMEOUT, + usbd_setup_xfer(data->xfer, data, data->buf, xferlen, + USBD_FORCE_SHORT_XFER, URTW_DATA_TIMEOUT, (prior == URTW_PRIORITY_LOW) ? urtw_txeof_low : urtw_txeof_normal); error = usbd_transfer(data->xfer); if (error != USBD_IN_PROGRESS && error != USBD_NORMAL_COMPLETION) { printf("%s: could not send frame: %s\n", device_xname(sc->sc_dev), usbd_errstr(error)); - return (EIO); + return EIO; } error = urtw_led_ctl(sc, URTW_LED_CTL_TX); @@ -2690,12 +2683,9 @@ urtw_tx_start(struct urtw_softc *sc, struct ieee80211_node *ni, struct mbuf *m0, printf("%s: could not control LED (%d)\n", device_xname(sc->sc_dev), error); - if (prior == URTW_PRIORITY_LOW) - sc->sc_tx_low_queued++; - else - sc->sc_tx_normal_queued++; + sc->sc_tx_queued[prior]++; - return (0); + return 0; } usbd_status @@ -2722,7 +2712,7 @@ urtw_8225_usb_init(struct urtw_softc *sc) usbd_delay_ms(sc->sc_udev, 500); fail: - return (error); + return error; } usbd_status @@ -2732,7 +2722,7 @@ urtw_8185_rf_pins_enable(struct urtw_softc *sc) urtw_write16_m(sc, URTW_RF_PINS_ENABLE, 0x1ff7); fail: - return (error); + return error; } usbd_status @@ -2751,21 +2741,21 @@ urtw_8187_write_phy(struct urtw_softc *sc, uint8_t addr, uint32_t data) * usbd_delay_ms(sc->sc_udev, 1); */ fail: - return (error); + return error; } usbd_status urtw_8187_write_phy_ofdm_c(struct urtw_softc *sc, uint8_t addr, uint32_t data) { data = data & 0xff; - return (urtw_8187_write_phy(sc, addr, data)); + return urtw_8187_write_phy(sc, addr, data); } usbd_status urtw_8187_write_phy_cck_c(struct urtw_softc *sc, uint8_t addr, uint32_t data) { data = data & 0xff; - return (urtw_8187_write_phy(sc, addr, data | 0x10000)); + return urtw_8187_write_phy(sc, addr, data | 0x10000); } usbd_status @@ -2778,7 +2768,7 @@ urtw_8225_setgain(struct urtw_softc *sc, int16_t gain) urtw_8187_write_phy_ofdm(sc, 0x1d, urtw_8225_gain[gain * 4 + 3]); urtw_8187_write_phy_ofdm(sc, 0x23, urtw_8225_gain[gain * 4 + 1]); fail: - return (error); + return error; } usbd_status @@ -2831,7 +2821,7 @@ urtw_8225_set_txpwrlvl(struct urtw_softc *sc, int chan) urtw_8187_write_phy_ofdm(sc, 0x7, urtw_8225_txpwr_ofdm[idx]); usbd_delay_ms(sc->sc_udev, 1); fail: - return (error); + return error; } usbd_status @@ -2842,7 +2832,7 @@ urtw_8185_tx_antenna(struct urtw_softc *sc, uint8_t ant) urtw_write8_m(sc, URTW_TX_ANTENNA, ant); usbd_delay_ms(sc->sc_udev, 1); fail: - return (error); + return error; } usbd_status @@ -2939,7 +2929,7 @@ urtw_8225_rf_init(struct urtw_rf *rf) error = urtw_8225_rf_set_chan(rf, 1); fail: - return (error); + return error; } usbd_status @@ -2975,7 +2965,7 @@ urtw_8225_rf_set_chan(struct urtw_rf *rf, int chan) } fail: - return (error); + return error; } usbd_status @@ -2985,7 +2975,7 @@ urtw_8225_rf_set_sens(struct urtw_rf *rf) usbd_status error; if (rf->sens > 6) - return (-1); + return -1; if (rf->sens > 4) urtw_8225_write(sc, 0x0c, 0x850); @@ -3000,7 +2990,7 @@ urtw_8225_rf_set_sens(struct urtw_rf *rf) urtw_8187_write_phy_cck(sc, 0x41, urtw_8225_threshold[rf->sens]); fail: - return (error); + return error; } void @@ -3042,12 +3032,12 @@ urtw_isbmode(uint16_t rate) { rate = urtw_rtl2rate(rate); - return (((rate <= 22 && rate != 12 && rate != 18) || - rate == 44) ? (1) : (0)); + return ((rate <= 22 && rate != 12 && rate != 18) || + rate == 44) ? 1 : 0; } void -urtw_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +urtw_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct urtw_rx_data *data = priv; struct urtw_softc *sc = data->sc; @@ -3168,7 +3158,7 @@ urtw_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) splx(s); skip: /* setup a new transfer */ - usbd_setup_xfer(xfer, sc->sc_rxpipe, data, data->buf, MCLBYTES, + usbd_setup_xfer(xfer, data, data->buf, MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urtw_rxeof); (void)usbd_transfer(xfer); } @@ -3190,7 +3180,7 @@ urtw_8225v2_setgain(struct urtw_softc *sc, int16_t gain) urtw_8187_write_phy_ofdm(sc, 0x21, 0x17); usbd_delay_ms(sc->sc_udev, 1); fail: - return (error); + return error; } usbd_status @@ -3237,7 +3227,7 @@ urtw_8225v2_set_txpwrlvl(struct urtw_softc *sc, int chan) urtw_8225v2_tx_gain_cck_ofdm[ofdm_pwrlvl]); usbd_delay_ms(sc->sc_udev, 1); fail: - return (error); + return error; } usbd_status @@ -3355,7 +3345,7 @@ urtw_8225v2_rf_init(struct urtw_rf *rf) error = urtw_8225_rf_set_chan(rf, 1); fail: - return (error); + return error; } usbd_status @@ -3392,7 +3382,7 @@ urtw_8225v2_rf_set_chan(struct urtw_rf *rf, int chan) } fail: - return (error); + return error; } void @@ -3536,7 +3526,7 @@ urtw_8187b_update_wmm(struct urtw_softc *sc) urtw_write32_m(sc, URTW_AC_BK, data); fail: - return (error); + return error; } usbd_status @@ -3581,7 +3571,7 @@ urtw_8187b_reset(struct urtw_softc *sc) } fail: - return (error); + return error; } int @@ -3671,7 +3661,9 @@ urtw_8187b_init(struct ifnet *ifp) urtw_write8_m(sc, URTW_ACM_CONTROL, 0); /* Reset softc variables. */ - sc->sc_txidx = sc->sc_tx_low_queued = sc->sc_tx_normal_queued = 0; + for (size_t j = 0; j < URTW_PRIORITY_MAX; j++) { + sc->sc_txidx[j] = sc->sc_tx_queued[j] = 0; + } sc->sc_txtimer = 0; if (!(sc->sc_flags & URTW_INIT_ONCE)) { @@ -3718,7 +3710,7 @@ urtw_8187b_init(struct ifnet *ifp) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); fail: - return (error); + return error; } usbd_status @@ -3742,7 +3734,7 @@ urtw_8225v2_b_config_mac(struct urtw_softc *sc) urtw_write32_m(sc, URTW_RF_TIMING, 0x00004001); fail: - return (error); + return error; } usbd_status @@ -3756,7 +3748,7 @@ urtw_8225v2_b_init_rfe(struct urtw_softc *sc) usbd_delay_ms(sc->sc_udev, 100); fail: - return (error); + return error; } usbd_status @@ -3792,7 +3784,7 @@ urtw_8225v2_b_update_chan(struct urtw_softc *sc) urtw_write8_m(sc, URTW_8187B_EIFS, eifs); fail: - return (error); + return error; } usbd_status @@ -3888,7 +3880,7 @@ urtw_8225v2_b_rf_init(struct urtw_rf *rf) error = urtw_8225v2_b_rf_set_chan(rf, 1); fail: - return (error); + return error; } usbd_status @@ -3913,7 +3905,7 @@ urtw_8225v2_b_rf_set_chan(struct urtw_rf *rf, int chan) urtw_write16_m(sc, URTW_AC_BK, 0x5114); fail: - return (error); + return error; } usbd_status @@ -4016,7 +4008,7 @@ urtw_8225v2_b_set_txpwrlvl(struct urtw_softc *sc, int chan) * usbd_delay_ms(sc->sc_udev, 1); */ fail: - return (error); + return error; } int diff --git a/sys/dev/usb/if_urtwn.c b/sys/dev/usb/if_urtwn.c index 2294a923314..d801b08218a 100644 --- a/sys/dev/usb/if_urtwn.c +++ b/sys/dev/usb/if_urtwn.c @@ -1,4 +1,4 @@ -/* $NetBSD: if_urtwn.c,v 1.41 2016/01/18 02:45:05 nonaka Exp $ */ +/* $NetBSD: if_urtwn.c,v 1.42 2016/04/23 10:15:32 skrll Exp $ */ /* $OpenBSD: if_urtwn.c,v 1.42 2015/02/10 23:25:46 mpi Exp $ */ /*- @@ -23,7 +23,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.41 2016/01/18 02:45:05 nonaka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.42 2016/04/23 10:15:32 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -36,7 +36,6 @@ __KERNEL_RCSID(0, "$NetBSD: if_urtwn.c,v 1.41 2016/01/18 02:45:05 nonaka Exp $") #include <sys/kernel.h> #include <sys/socket.h> #include <sys/systm.h> -#include <sys/malloc.h> #include <sys/module.h> #include <sys/conf.h> #include <sys/device.h> @@ -252,10 +251,12 @@ static void urtwn_update_avgrssi(struct urtwn_softc *, int, int8_t); static int8_t urtwn_get_rssi(struct urtwn_softc *, int, void *); static int8_t urtwn_r88e_get_rssi(struct urtwn_softc *, int, void *); static void urtwn_rx_frame(struct urtwn_softc *, uint8_t *, int); -static void urtwn_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void urtwn_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +static void urtwn_rxeof(struct usbd_xfer *, void *, usbd_status); +static void urtwn_txeof(struct usbd_xfer *, void *, usbd_status); static int urtwn_tx(struct urtwn_softc *, struct mbuf *, struct ieee80211_node *, struct urtwn_tx_data *); +static struct urtwn_tx_data * + urtwn_get_tx_data(struct urtwn_softc *, size_t); static void urtwn_start(struct ifnet *); static void urtwn_watchdog(struct ifnet *); static int urtwn_ioctl(struct ifnet *, u_long, void *); @@ -303,8 +304,8 @@ urtwn_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return ((urtwn_lookup(urtwn_devs, uaa->vendor, uaa->product) != NULL) ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return urtwn_lookup(urtwn_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } static void @@ -320,10 +321,10 @@ urtwn_attach(device_t parent, device_t self, void *aux) int error; sc->sc_dev = self; - sc->sc_udev = uaa->device; + sc->sc_udev = uaa->uaa_device; sc->chip = 0; - dev = urtwn_lookup(urtwn_devs, uaa->vendor, uaa->product); + dev = urtwn_lookup(urtwn_devs, uaa->uaa_vendor, uaa->uaa_product); if (dev != NULL && ISSET(dev->flags, FLAG_RTL8188E)) SET(sc->chip, URTWN_CHIP_88E); @@ -506,7 +507,7 @@ urtwn_detach(device_t self, int flags) ieee80211_ifdetach(&sc->sc_ic); if_detach(ifp); - /* Abort and close Tx/Rx pipes. */ + /* Close Tx/Rx pipes. Abort done by urtwn_stop. */ urtwn_close_pipes(sc); } @@ -522,7 +523,7 @@ urtwn_detach(device_t self, int flags) mutex_destroy(&sc->sc_tx_mtx); mutex_destroy(&sc->sc_task_mtx); - return (0); + return 0; } static int @@ -535,9 +536,9 @@ urtwn_activate(device_t self, enum devact act) switch (act) { case DVACT_DEACTIVATE: if_deactivate(sc->sc_ic.ic_ifp); - return (0); + return 0; default: - return (EOPNOTSUPP); + return EOPNOTSUPP; } } @@ -567,7 +568,7 @@ urtwn_open_pipes(struct urtwn_softc *sc) if (ntx == 0 || ntx > R92C_MAX_EPOUT) { aprint_error_dev(sc->sc_dev, "%zd: invalid number of Tx bulk pipes\n", ntx); - return (EIO); + return EIO; } sc->rx_npipe = 1; sc->tx_npipe = ntx; @@ -602,13 +603,13 @@ urtwn_open_pipes(struct urtwn_softc *sc) fail: if (error != 0) urtwn_close_pipes(sc); - return (error); + return error; } static void urtwn_close_pipes(struct urtwn_softc *sc) { - usbd_pipe_handle pipe; + struct usbd_pipe *pipe; size_t i; DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__)); @@ -617,14 +618,12 @@ urtwn_close_pipes(struct urtwn_softc *sc) CTASSERT(sizeof(pipe) == sizeof(void *)); pipe = atomic_swap_ptr(&sc->rx_pipe, NULL); if (pipe != NULL) { - usbd_abort_pipe(pipe); usbd_close_pipe(pipe); } /* Close Tx pipes. */ for (i = 0; i < R92C_MAX_EPOUT; i++) { pipe = atomic_swap_ptr(&sc->tx_pipe[i], NULL); if (pipe != NULL) { - usbd_abort_pipe(pipe); usbd_close_pipe(pipe); } } @@ -644,31 +643,25 @@ urtwn_alloc_rx_list(struct urtwn_softc *sc) data->sc = sc; /* Backpointer for callbacks. */ - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { + error = usbd_create_xfer(sc->rx_pipe, URTWN_RXBUFSZ, + USBD_SHORT_XFER_OK, 0, &data->xfer); + if (error) { aprint_error_dev(sc->sc_dev, "could not allocate xfer\n"); - error = ENOMEM; break; } - data->buf = usbd_alloc_buffer(data->xfer, URTWN_RXBUFSZ); - if (data->buf == NULL) { - aprint_error_dev(sc->sc_dev, - "could not allocate xfer buffer\n"); - error = ENOMEM; - break; - } + data->buf = usbd_get_buffer(data->xfer); } if (error != 0) urtwn_free_rx_list(sc); - return (error); + return error; } static void urtwn_free_rx_list(struct urtwn_softc *sc) { - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; size_t i; DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__)); @@ -678,7 +671,7 @@ urtwn_free_rx_list(struct urtwn_softc *sc) CTASSERT(sizeof(xfer) == sizeof(void *)); xfer = atomic_swap_ptr(&sc->rx_data[i].xfer, NULL); if (xfer != NULL) - usbd_free_xfer(xfer); + usbd_destroy_xfer(xfer); } } @@ -692,54 +685,54 @@ urtwn_alloc_tx_list(struct urtwn_softc *sc) DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__)); mutex_enter(&sc->sc_tx_mtx); - TAILQ_INIT(&sc->tx_free_list); - for (i = 0; i < URTWN_TX_LIST_COUNT; i++) { - data = &sc->tx_data[i]; + for (size_t j = 0; j < sc->tx_npipe; j++) { + TAILQ_INIT(&sc->tx_free_list[j]); + for (i = 0; i < URTWN_TX_LIST_COUNT; i++) { + data = &sc->tx_data[j][i]; + + data->sc = sc; /* Backpointer for callbacks. */ + data->pidx = j; + + error = usbd_create_xfer(sc->tx_pipe[j], + URTWN_TXBUFSZ, USBD_FORCE_SHORT_XFER, 0, + &data->xfer); + if (error) { + aprint_error_dev(sc->sc_dev, + "could not allocate xfer\n"); + goto fail; + } - data->sc = sc; /* Backpointer for callbacks. */ + data->buf = usbd_get_buffer(data->xfer); - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { - aprint_error_dev(sc->sc_dev, - "could not allocate xfer\n"); - error = ENOMEM; - goto fail; + /* Append this Tx buffer to our free list. */ + TAILQ_INSERT_TAIL(&sc->tx_free_list[j], data, next); } - - data->buf = usbd_alloc_buffer(data->xfer, URTWN_TXBUFSZ); - if (data->buf == NULL) { - aprint_error_dev(sc->sc_dev, - "could not allocate xfer buffer\n"); - error = ENOMEM; - goto fail; - } - - /* Append this Tx buffer to our free list. */ - TAILQ_INSERT_TAIL(&sc->tx_free_list, data, next); } mutex_exit(&sc->sc_tx_mtx); - return (0); + return 0; fail: urtwn_free_tx_list(sc); mutex_exit(&sc->sc_tx_mtx); - return (error); + return error; } static void urtwn_free_tx_list(struct urtwn_softc *sc) { - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; size_t i; DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__)); /* NB: Caller must abort pipe first. */ - for (i = 0; i < URTWN_TX_LIST_COUNT; i++) { - CTASSERT(sizeof(xfer) == sizeof(void *)); - xfer = atomic_swap_ptr(&sc->tx_data[i].xfer, NULL); - if (xfer != NULL) - usbd_free_xfer(xfer); + for (size_t j = 0; j < sc->tx_npipe; j++) { + for (i = 0; i < URTWN_TX_LIST_COUNT; i++) { + CTASSERT(sizeof(xfer) == sizeof(void *)); + xfer = atomic_swap_ptr(&sc->tx_data[j][i].xfer, NULL); + if (xfer != NULL) + usbd_destroy_xfer(xfer); + } } } @@ -830,7 +823,7 @@ urtwn_write_region_1(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf, DPRINTFN(DBG_REG, ("%s: %s: error=%d: addr=0x%x, len=%d\n", device_xname(sc->sc_dev), __func__, error, addr, len)); } - return (error); + return error; } static void @@ -898,7 +891,7 @@ urtwn_read_region_1(struct urtwn_softc *sc, uint16_t addr, uint8_t *buf, DPRINTFN(DBG_REG, ("%s: %s: error=%d: addr=0x%x, len=%d\n", device_xname(sc->sc_dev), __func__, error, addr, len)); } - return (error); + return error; } static uint8_t @@ -907,11 +900,11 @@ urtwn_read_1(struct urtwn_softc *sc, uint16_t addr) uint8_t val; if (urtwn_read_region_1(sc, addr, &val, 1) != USBD_NORMAL_COMPLETION) - return (0xff); + return 0xff; DPRINTFN(DBG_REG, ("%s: %s: addr=0x%x, val=0x%x\n", device_xname(sc->sc_dev), __func__, addr, val)); - return (val); + return val; } static uint16_t @@ -921,12 +914,12 @@ urtwn_read_2(struct urtwn_softc *sc, uint16_t addr) uint16_t val; if (urtwn_read_region_1(sc, addr, buf, 2) != USBD_NORMAL_COMPLETION) - return (0xffff); + return 0xffff; val = LE_READ_2(&buf[0]); DPRINTFN(DBG_REG, ("%s: %s: addr=0x%x, val=0x%x\n", device_xname(sc->sc_dev), __func__, addr, val)); - return (val); + return val; } static uint32_t @@ -936,12 +929,12 @@ urtwn_read_4(struct urtwn_softc *sc, uint16_t addr) uint32_t val; if (urtwn_read_region_1(sc, addr, buf, 4) != USBD_NORMAL_COMPLETION) - return (0xffffffff); + return 0xffffffff; val = LE_READ_4(&buf[0]); DPRINTFN(DBG_REG, ("%s: %s: addr=0x%x, val=0x%x\n", device_xname(sc->sc_dev), __func__, addr, val)); - return (val); + return val; } static int @@ -971,7 +964,7 @@ urtwn_fw_cmd(struct urtwn_softc *sc, uint8_t id, const void *buf, int len) if (ntries == 100) { aprint_error_dev(sc->sc_dev, "could not send firmware command %d\n", id); - return (ETIMEDOUT); + return ETIMEDOUT; } memset(&cmd, 0, sizeof(cmd)); @@ -990,7 +983,7 @@ urtwn_fw_cmd(struct urtwn_softc *sc, uint8_t id, const void *buf, int len) urtwn_write_region(sc, R92C_HMEBOX(fwcur), cp, len); } - return (0); + return 0; } static __inline void @@ -1046,7 +1039,7 @@ urtwn_rf_read(struct urtwn_softc *sc, int chain, uint8_t addr) } else { val = urtwn_bb_read(sc, R92C_LSSI_READBACK(chain)); } - return (MS(val, R92C_LSSI_READBACK_DATA)); + return MS(val, R92C_LSSI_READBACK_DATA); } static int @@ -1065,11 +1058,11 @@ urtwn_llt_write(struct urtwn_softc *sc, uint32_t addr, uint32_t data) if (MS(urtwn_read_4(sc, R92C_LLT_INIT), R92C_LLT_INIT_OP) == R92C_LLT_INIT_OP_NO_ACTIVE) { /* Done */ - return (0); + return 0; } DELAY(5); } - return (ETIMEDOUT); + return ETIMEDOUT; } static uint8_t @@ -1090,13 +1083,13 @@ urtwn_efuse_read_1(struct urtwn_softc *sc, uint16_t addr) reg = urtwn_read_4(sc, R92C_EFUSE_CTRL); if (reg & R92C_EFUSE_CTRL_VALID) { /* Done */ - return (MS(reg, R92C_EFUSE_CTRL_DATA)); + return MS(reg, R92C_EFUSE_CTRL_DATA); } DELAY(5); } aprint_error_dev(sc->sc_dev, "could not read efuse byte at address 0x%04x\n", addr); - return (0xff); + return 0xff; } static void @@ -1174,12 +1167,12 @@ urtwn_read_chipid(struct urtwn_softc *sc) DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__)); if (ISSET(sc->chip, URTWN_CHIP_88E)) - return (0); + return 0; reg = urtwn_read_4(sc, R92C_SYS_CFG); if (reg & R92C_SYS_CFG_TRP_VAUX_EN) { /* test chip, not supported */ - return (EIO); + return EIO; } if (reg & R92C_SYS_CFG_TYPE_92C) { sc->chip |= URTWN_CHIP_92C; @@ -1196,7 +1189,7 @@ urtwn_read_chipid(struct urtwn_softc *sc) sc->chip |= URTWN_CHIP_UMC_A_CUT; } } - return (0); + return 0; } #ifdef URTWN_DEBUG @@ -1399,13 +1392,13 @@ urtwn_media_change(struct ifnet *ifp) DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__)); if ((error = ieee80211_media_change(ifp)) != ENETRESET) - return (error); + return error; if ((ifp->if_flags & (IFF_UP | IFF_RUNNING)) == (IFF_UP | IFF_RUNNING)) { urtwn_init(ifp); } - return (0); + return 0; } /* @@ -1482,7 +1475,7 @@ urtwn_ra_init(struct urtwn_softc *sc) if (error != 0) { aprint_error_dev(sc->sc_dev, "could not add broadcast station\n"); - return (error); + return error; } /* Set initial MRR rate. */ DPRINTFN(DBG_INIT, ("%s: %s: maxbasicrate=%zd\n", @@ -1499,7 +1492,7 @@ urtwn_ra_init(struct urtwn_softc *sc) error = urtwn_fw_cmd(sc, R92C_CMD_MACID_CONFIG, &cmd, sizeof(cmd)); if (error != 0) { aprint_error_dev(sc->sc_dev, "could not add BSS station\n"); - return (error); + return error; } /* Set initial MRR rate. */ DPRINTFN(DBG_INIT, ("%s: %s: maxrate=%zd\n", device_xname(sc->sc_dev), @@ -1509,7 +1502,7 @@ urtwn_ra_init(struct urtwn_softc *sc) /* Indicate highest supported rate. */ ni->ni_txrate = rs->rs_nrates - 1; - return (0); + return 0; } static int @@ -1534,7 +1527,7 @@ urtwn_get_nettype(struct urtwn_softc *sc) break; } - return (type); + return type; } static void @@ -1704,7 +1697,7 @@ urtwn_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) cmd.state = nstate; cmd.arg = arg; urtwn_do_async(sc, urtwn_newstate_cb, &cmd, sizeof(cmd)); - return (0); + return 0; } static void @@ -2019,11 +2012,11 @@ urtwn_wme_update(struct ieee80211com *ic) /* don't override default WME values if WME is not actually enabled */ if (!(ic->ic_flags & IEEE80211_F_WME)) - return (0); + return 0; /* Do it in a process context. */ urtwn_do_async(sc, urtwn_wme_update_cb, NULL, 0); - return (0); + return 0; } static void @@ -2129,7 +2122,7 @@ urtwn_get_rssi(struct urtwn_softc *sc, int rate, void *physt) phy = (struct r92c_rx_phystat *)physt; rssi = ((le32toh(phy->phydw1) >> 1) & 0x7f) - 110; } - return (rssi); + return rssi; } static int8_t @@ -2183,7 +2176,7 @@ urtwn_r88e_get_rssi(struct urtwn_softc *sc, int rate, void *physt) phy = (struct r92c_rx_phystat *)physt; rssi = ((le32toh(phy->phydw1) >> 1) & 0x7f) - 110; } - return (rssi); + return rssi; } static void @@ -2322,7 +2315,7 @@ urtwn_rx_frame(struct urtwn_softc *sc, uint8_t *buf, int pktlen) } static void -urtwn_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +urtwn_rxeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct urtwn_rx_data *data = priv; struct urtwn_softc *sc = data->sc; @@ -2396,18 +2389,18 @@ urtwn_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) resubmit: /* Setup a new transfer. */ - usbd_setup_xfer(xfer, sc->rx_pipe, data, data->buf, URTWN_RXBUFSZ, - USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, urtwn_rxeof); + usbd_setup_xfer(xfer, data, data->buf, URTWN_RXBUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urtwn_rxeof); (void)usbd_transfer(xfer); } static void -urtwn_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +urtwn_txeof(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct urtwn_tx_data *data = priv; struct urtwn_softc *sc = data->sc; struct ifnet *ifp = &sc->sc_if; - usbd_pipe_handle pipe = data->pipe; + size_t pidx = data->pidx; int s; DPRINTFN(DBG_FN|DBG_TX, ("%s: %s: status=%d\n", @@ -2415,7 +2408,7 @@ urtwn_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) mutex_enter(&sc->sc_tx_mtx); /* Put this Tx buffer back to our free list. */ - TAILQ_INSERT_TAIL(&sc->tx_free_list, data, next); + TAILQ_INSERT_TAIL(&sc->tx_free_list[pidx], data, next); mutex_exit(&sc->sc_tx_mtx); s = splnet(); @@ -2424,8 +2417,10 @@ urtwn_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) if (__predict_false(status != USBD_NORMAL_COMPLETION)) { if (status != USBD_NOT_STARTED && status != USBD_CANCELLED) { - if (status == USBD_STALLED) + if (status == USBD_STALLED) { + struct usbd_pipe *pipe = sc->tx_pipe[pidx]; usbd_clear_endpoint_stall_async(pipe); + } ifp->if_oerrors++; } splx(s); @@ -2446,10 +2441,9 @@ urtwn_tx(struct urtwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, struct ieee80211_frame *wh; struct ieee80211_key *k = NULL; struct r92c_tx_desc *txd; - usbd_pipe_handle pipe; size_t i, padsize, xferlen; uint16_t seq, sum; - uint8_t raid, type, tid, qid; + uint8_t raid, type, tid; int s, hasqos, error; DPRINTFN(DBG_FN, ("%s: %s\n", device_xname(sc->sc_dev), __func__)); @@ -2480,24 +2474,16 @@ urtwn_tx(struct urtwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m); } + /* non-qos data frames */ + tid = R92C_TXDW1_QSEL_BE; if ((hasqos = ieee80211_has_qos(wh))) { /* data frames in 11n mode */ struct ieee80211_qosframe *qwh = (void *)wh; tid = qwh->i_qos[0] & IEEE80211_QOS_TID; - qid = TID_TO_WME_AC(tid); } else if (type != IEEE80211_FC0_TYPE_DATA) { - /* Use AC_VO for management frames. */ - qid = WME_AC_VO; - tid = 0; /* compiler happy */ - } else { - /* non-qos data frames */ - tid = R92C_TXDW1_QSEL_BE; - qid = WME_AC_BE; + tid = R92C_TXDW1_QSEL_MGNT; } - /* Get the USB pipe to use for this AC. */ - pipe = sc->tx_pipe[sc->ac2idx[qid]]; - if (((sizeof(*txd) + m->m_pkthdr.len) % 64) == 0) /* XXX: 64 */ padsize = 8; else @@ -2614,9 +2600,8 @@ urtwn_tx(struct urtwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, m_copydata(m, 0, m->m_pkthdr.len, (char *)&txd[1] + padsize); s = splnet(); - data->pipe = pipe; - usbd_setup_xfer(data->xfer, pipe, data, data->buf, xferlen, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, URTWN_TX_TIMEOUT, + usbd_setup_xfer(data->xfer, data, data->buf, xferlen, + USBD_FORCE_SHORT_XFER, URTWN_TX_TIMEOUT, urtwn_txeof); error = usbd_transfer(data->xfer); if (__predict_false(error != USBD_NORMAL_COMPLETION && @@ -2630,6 +2615,21 @@ urtwn_tx(struct urtwn_softc *sc, struct mbuf *m, struct ieee80211_node *ni, return 0; } +struct urtwn_tx_data * +urtwn_get_tx_data(struct urtwn_softc *sc, size_t pidx) +{ + struct urtwn_tx_data *data = NULL; + + mutex_enter(&sc->sc_tx_mtx); + if (!TAILQ_EMPTY(&sc->tx_free_list[pidx])) { + data = TAILQ_FIRST(&sc->tx_free_list[pidx]); + TAILQ_REMOVE(&sc->tx_free_list[pidx], data, next); + } + mutex_exit(&sc->sc_tx_mtx); + + return data; +} + static void urtwn_start(struct ifnet *ifp) { @@ -2647,23 +2647,20 @@ urtwn_start(struct ifnet *ifp) data = NULL; for (;;) { - mutex_enter(&sc->sc_tx_mtx); - if (data == NULL && !TAILQ_EMPTY(&sc->tx_free_list)) { - data = TAILQ_FIRST(&sc->tx_free_list); - TAILQ_REMOVE(&sc->tx_free_list, data, next); - } - mutex_exit(&sc->sc_tx_mtx); - - if (data == NULL) { - ifp->if_flags |= IFF_OACTIVE; - DPRINTFN(DBG_TX, ("%s: empty tx_free_list\n", - device_xname(sc->sc_dev))); - return; - } - /* Send pending management frames first. */ - IF_DEQUEUE(&ic->ic_mgtq, m); + IF_POLL(&ic->ic_mgtq, m); if (m != NULL) { + /* Use AC_VO for management frames. */ + + data = urtwn_get_tx_data(sc, sc->ac2idx[WME_AC_VO]); + + if (data == NULL) { + ifp->if_flags |= IFF_OACTIVE; + DPRINTFN(DBG_TX, ("%s: empty tx_free_list\n", + device_xname(sc->sc_dev))); + return; + } + IF_DEQUEUE(&ic->ic_mgtq, m); ni = (void *)m->m_pkthdr.rcvif; m->m_pkthdr.rcvif = NULL; goto sendit; @@ -2672,10 +2669,31 @@ urtwn_start(struct ifnet *ifp) break; /* Encapsulate and send data frames. */ - IFQ_DEQUEUE(&ifp->if_snd, m); + IFQ_POLL(&ifp->if_snd, m); if (m == NULL) break; + struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *); + uint8_t type = wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK; + uint8_t qid = WME_AC_BE; + if (ieee80211_has_qos(wh)) { + /* data frames in 11n mode */ + struct ieee80211_qosframe *qwh = (void *)wh; + uint8_t tid = qwh->i_qos[0] & IEEE80211_QOS_TID; + qid = TID_TO_WME_AC(tid); + } else if (type != IEEE80211_FC0_TYPE_DATA) { + qid = WME_AC_VO; + } + data = urtwn_get_tx_data(sc, sc->ac2idx[qid]); + + if (data == NULL) { + ifp->if_flags |= IFF_OACTIVE; + DPRINTFN(DBG_TX, ("%s: empty tx_free_list\n", + device_xname(sc->sc_dev))); + return; + } + IFQ_DEQUEUE(&ifp->if_snd, m); + if (m->m_len < (int)sizeof(*eh) && (m = m_pullup(m, sizeof(*eh))) == NULL) { ifp->if_oerrors++; @@ -2705,17 +2723,11 @@ urtwn_start(struct ifnet *ifp) ifp->if_oerrors++; continue; } - data = NULL; m_freem(m); ieee80211_free_node(ni); sc->tx_timer = 5; ifp->if_timer = 1; } - - /* Return the Tx buffer to the free list */ - mutex_enter(&sc->sc_tx_mtx); - TAILQ_INSERT_TAIL(&sc->tx_free_list, data, next); - mutex_exit(&sc->sc_tx_mtx); } static void @@ -2792,7 +2804,7 @@ urtwn_ioctl(struct ifnet *ifp, u_long cmd, void *data) splx(s); - return (error); + return error; } static __inline int @@ -2821,7 +2833,7 @@ urtwn_r92c_power_on(struct urtwn_softc *sc) if (ntries == 1000) { aprint_error_dev(sc->sc_dev, "timeout waiting for chip autoload\n"); - return (ETIMEDOUT); + return ETIMEDOUT; } /* Unlock ISO/CLK/Power control register. */ @@ -2852,7 +2864,7 @@ urtwn_r92c_power_on(struct urtwn_softc *sc) if (ntries == 1000) { aprint_error_dev(sc->sc_dev, "timeout waiting for MAC auto ON\n"); - return (ETIMEDOUT); + return ETIMEDOUT; } /* Enable radio, GPIO and LED functions. */ @@ -2879,7 +2891,7 @@ urtwn_r92c_power_on(struct urtwn_softc *sc) if (ntries == 200) { aprint_error_dev(sc->sc_dev, "timeout waiting for MAC initialization\n"); - return (ETIMEDOUT); + return ETIMEDOUT; } /* Enable MAC DMA/WMAC/SCHEDULE/SEC blocks. */ @@ -2891,7 +2903,7 @@ urtwn_r92c_power_on(struct urtwn_softc *sc) urtwn_write_2(sc, R92C_CR, reg); urtwn_write_1(sc, 0xfe10, 0x19); - return (0); + return 0; } static int @@ -2915,7 +2927,7 @@ urtwn_r88e_power_on(struct urtwn_softc *sc) if (ntries == 5000) { aprint_error_dev(sc->sc_dev, "timeout waiting for chip power up\n"); - return (ETIMEDOUT); + return ETIMEDOUT; } /* Reset BB. */ @@ -2938,7 +2950,7 @@ urtwn_r88e_power_on(struct urtwn_softc *sc) DELAY(10); } if (ntries == 5000) - return (ETIMEDOUT); + return ETIMEDOUT; /* Enable LDO normal mode. */ urtwn_write_1(sc, 0x23, urtwn_read_1(sc, 0x23) & ~0x10); @@ -2951,7 +2963,7 @@ urtwn_r88e_power_on(struct urtwn_softc *sc) R92C_CR_SCHEDULE_EN | R92C_CR_ENSEC | R92C_CR_CALTMR_EN; urtwn_write_2(sc, R92C_CR, reg); - return (0); + return 0; } static int @@ -2972,22 +2984,22 @@ urtwn_llt_init(struct urtwn_softc *sc) /* Reserve pages [0; page_count]. */ for (i = 0; i < page_count; i++) { if ((error = urtwn_llt_write(sc, i, i + 1)) != 0) - return (error); + return error; } /* NB: 0xff indicates end-of-list. */ if ((error = urtwn_llt_write(sc, i, 0xff)) != 0) - return (error); + return error; /* * Use pages [page_count + 1; pktbuf_count - 1] * as ring buffer. */ for (++i; i < pktbuf_count - 1; i++) { if ((error = urtwn_llt_write(sc, i, i + 1)) != 0) - return (error); + return error; } /* Make the last page point to the beginning of the ring buffer. */ error = urtwn_llt_write(sc, i, pktbuf_count + 1); - return (error); + return error; } static void @@ -3057,7 +3069,7 @@ urtwn_fw_loadpage(struct urtwn_softc *sc, int page, uint8_t *buf, int len) buf += mlen; len -= mlen; } - return (error); + return error; } static int @@ -3087,7 +3099,7 @@ urtwn_load_firmware(struct urtwn_softc *sc) aprint_error_dev(sc->sc_dev, "failed load firmware of file %s (error %d)\n", name, error); - return (error); + return error; } const size_t fwlen = len = firmware_get_size(fwh); fw = firmware_malloc(len); @@ -3095,7 +3107,7 @@ urtwn_load_firmware(struct urtwn_softc *sc) aprint_error_dev(sc->sc_dev, "failed to allocate firmware memory\n"); firmware_close(fwh); - return (ENOMEM); + return ENOMEM; } error = firmware_read(fwh, 0, fw, len); firmware_close(fwh); @@ -3103,7 +3115,7 @@ urtwn_load_firmware(struct urtwn_softc *sc) aprint_error_dev(sc->sc_dev, "failed to read firmware (error %d)\n", error); firmware_free(fw, fwlen); - return (error); + return error; } ptr = fw; @@ -3193,7 +3205,7 @@ urtwn_load_firmware(struct urtwn_softc *sc) } fail: firmware_free(fw, fwlen); - return (error); + return error; } static __inline int @@ -3217,7 +3229,7 @@ urtwn_r92c_dma_init(struct urtwn_softc *sc) /* Initialize LLT table. */ error = urtwn_llt_init(sc); if (error != 0) - return (error); + return error; /* Get Tx queues to USB endpoints mapping. */ hashq = hasnq = haslq = 0; @@ -3232,7 +3244,7 @@ urtwn_r92c_dma_init(struct urtwn_softc *sc) haslq = 1; nqueues = hashq + hasnq + haslq; if (nqueues == 0) - return (EIO); + return EIO; /* Get the number of pages for each queue. */ nqpages = (R92C_TX_PAGE_COUNT - R92C_PUBQ_NPAGES) / nqueues; /* The remaining pages are assigned to the high priority queue. */ @@ -3270,7 +3282,7 @@ urtwn_r92c_dma_init(struct urtwn_softc *sc) } else if (nqueues == 2) { /* All 2-endpoints configs have a high priority queue. */ if (!hashq) { - return (EIO); + return EIO; } if (hasnq) { reg |= R92C_TRXDMA_CTRL_QMAP_HQ_NQ; @@ -3288,7 +3300,7 @@ urtwn_r92c_dma_init(struct urtwn_softc *sc) /* Set Tx/Rx transfer page size. */ urtwn_write_1(sc, R92C_PBP, SM(R92C_PBP_PSRX, R92C_PBP_128) | SM(R92C_PBP_PSTX, R92C_PBP_128)); - return (0); + return 0; } static int @@ -3306,13 +3318,13 @@ urtwn_r88e_dma_init(struct urtwn_softc *sc) /* Initialize LLT table. */ error = urtwn_llt_init(sc); if (error != 0) - return (error); + return error; /* Get Tx queues to USB endpoints mapping. */ id = usbd_get_interface_descriptor(sc->sc_iface); nqueues = id->bNumEndpoints - 1; if (nqueues == 0) - return (EIO); + return EIO; /* Set number of pages for normal priority queue. */ urtwn_write_2(sc, R92C_RQPN_NPQ, 0); @@ -3343,7 +3355,7 @@ urtwn_r88e_dma_init(struct urtwn_softc *sc) urtwn_write_1(sc, R92C_PBP, SM(R92C_PBP_PSRX, R92C_PBP_128) | SM(R92C_PBP_PSTX, R92C_PBP_128)); - return (0); + return 0; } static void @@ -4402,9 +4414,8 @@ urtwn_init(struct ifnet *ifp) /* Queue Rx xfers. */ for (i = 0; i < URTWN_RX_LIST_COUNT; i++) { data = &sc->rx_data[i]; - usbd_setup_xfer(data->xfer, sc->rx_pipe, data, data->buf, - URTWN_RXBUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, urtwn_rxeof); + usbd_setup_xfer(data->xfer, data, data->buf, URTWN_RXBUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, urtwn_rxeof); error = usbd_transfer(data->xfer); if (__predict_false(error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS)) @@ -4423,13 +4434,13 @@ urtwn_init(struct ifnet *ifp) ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); urtwn_wait_async(sc); - return (0); + return 0; fail: mutex_exit(&sc->sc_write_mtx); urtwn_stop(ifp, 1); - return (error); + return error; } static void @@ -4620,14 +4631,14 @@ if_urtwn_modcmd(modcmd_t cmd, void *aux) error = config_init_component(cfdriver_ioconf_urtwn, cfattach_ioconf_urtwn, cfdata_ioconf_urtwn); #endif - return (error); + return error; case MODULE_CMD_FINI: #ifdef _MODULE error = config_fini_component(cfdriver_ioconf_urtwn, cfattach_ioconf_urtwn, cfdata_ioconf_urtwn); #endif - return (error); + return error; default: - return (ENOTTY); + return ENOTTY; } } diff --git a/sys/dev/usb/if_urtwnreg.h b/sys/dev/usb/if_urtwnreg.h index 9ba58158734..8a0ff176ed3 100644 --- a/sys/dev/usb/if_urtwnreg.h +++ b/sys/dev/usb/if_urtwnreg.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_urtwnreg.h,v 1.7 2014/07/20 13:25:23 nonaka Exp $ */ +/* $NetBSD: if_urtwnreg.h,v 1.8 2016/04/23 10:15:32 skrll Exp $ */ /* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $ */ /*- @@ -530,7 +530,7 @@ /* Bits for R92C_BCNDMATIM */ #define R92C_DMA_ATIME_INT_TIME 0x02 - + /* Bits for R92C_APSD_CTRL. */ #define R92C_APSD_CTRL_OFF 0x40 #define R92C_APSD_CTRL_OFF_STATUS 0x80 diff --git a/sys/dev/usb/if_urtwnvar.h b/sys/dev/usb/if_urtwnvar.h index bf0ff6812bb..b5cf1c80882 100644 --- a/sys/dev/usb/if_urtwnvar.h +++ b/sys/dev/usb/if_urtwnvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: if_urtwnvar.h,v 1.8 2014/07/20 13:25:23 nonaka Exp $ */ +/* $NetBSD: if_urtwnvar.h,v 1.9 2016/04/23 10:15:32 skrll Exp $ */ /* $OpenBSD: if_urtwnreg.h,v 1.3 2010/11/16 18:02:59 damien Exp $ */ /*- @@ -67,14 +67,14 @@ struct urtwn_softc; struct urtwn_rx_data { struct urtwn_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; }; struct urtwn_tx_data { struct urtwn_softc *sc; - usbd_pipe_handle pipe; - usbd_xfer_handle xfer; + size_t pidx; + struct usbd_xfer *xfer; uint8_t *buf; TAILQ_ENTRY(urtwn_tx_data) next; }; @@ -114,8 +114,8 @@ struct urtwn_softc { int (*sc_newstate)(struct ieee80211com *, enum ieee80211_state, int); - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device * sc_udev; + struct usbd_interface * sc_iface; u_int sc_flags; #define URTWN_FLAG_CCK_HIPWR __BIT(0) #define URTWN_FLAG_ATTACHED __BIT(1) @@ -131,9 +131,9 @@ struct urtwn_softc { kmutex_t sc_tx_mtx; kmutex_t sc_write_mtx; - usbd_pipe_handle rx_pipe; + struct usbd_pipe * rx_pipe; int rx_npipe; - usbd_pipe_handle tx_pipe[R92C_MAX_EPOUT]; + struct usbd_pipe * tx_pipe[R92C_MAX_EPOUT]; int tx_npipe; int ac2idx[WME_NUM_AC]; @@ -165,8 +165,8 @@ struct urtwn_softc { struct urtwn_host_cmd_ring cmdq; int fwcur; struct urtwn_rx_data rx_data[URTWN_RX_LIST_COUNT]; - struct urtwn_tx_data tx_data[URTWN_TX_LIST_COUNT]; - TAILQ_HEAD(, urtwn_tx_data) tx_free_list; + struct urtwn_tx_data tx_data[R92C_MAX_EPOUT][URTWN_TX_LIST_COUNT]; + TAILQ_HEAD(, urtwn_tx_data) tx_free_list[R92C_MAX_EPOUT]; struct r92c_rom rom; uint8_t r88e_rom[512]; diff --git a/sys/dev/usb/if_urtwreg.h b/sys/dev/usb/if_urtwreg.h index 4e2105c4c31..ee6ddf96a41 100644 --- a/sys/dev/usb/if_urtwreg.h +++ b/sys/dev/usb/if_urtwreg.h @@ -260,14 +260,14 @@ struct urtw_tx_data { struct urtw_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; struct ieee80211_node *ni; }; struct urtw_rx_data { struct urtw_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; struct mbuf *m; }; @@ -330,8 +330,8 @@ struct urtw_softc { bool sc_dying; struct usb_task sc_task; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device * sc_udev; + struct usbd_interface * sc_iface; enum ieee80211_state sc_state; int sc_arg; @@ -358,17 +358,17 @@ struct urtw_softc { uint8_t sc_gpio_blinktime; uint8_t sc_gpio_blinkstate; /* RX/TX */ - usbd_pipe_handle sc_rxpipe; - usbd_pipe_handle sc_txpipe_low; - usbd_pipe_handle sc_txpipe_normal; + struct usbd_pipe * sc_rxpipe; + struct usbd_pipe * sc_txpipe_low; + struct usbd_pipe * sc_txpipe_normal; #define URTW_PRIORITY_LOW 0 #define URTW_PRIORITY_NORMAL 1 +#define URTW_PRIORITY_MAX 2 #define URTW_DATA_TIMEOUT 10000 /* 10 sec */ struct urtw_rx_data sc_rx_data[URTW_RX_DATA_LIST_COUNT]; - struct urtw_tx_data sc_tx_data[URTW_TX_DATA_LIST_COUNT]; - uint32_t sc_tx_low_queued; - uint32_t sc_tx_normal_queued; - uint32_t sc_txidx; + struct urtw_tx_data sc_tx_data[URTW_PRIORITY_MAX][URTW_TX_DATA_LIST_COUNT]; + uint32_t sc_tx_queued[URTW_PRIORITY_MAX];; + uint32_t sc_txidx[URTW_PRIORITY_MAX]; uint8_t sc_rts_retry; uint8_t sc_tx_retry; uint8_t sc_preamble_mode; diff --git a/sys/dev/usb/if_zyd.c b/sys/dev/usb/if_zyd.c index 913dd4117d7..bebc226902d 100644 --- a/sys/dev/usb/if_zyd.c +++ b/sys/dev/usb/if_zyd.c @@ -1,5 +1,5 @@ /* $OpenBSD: if_zyd.c,v 1.52 2007/02/11 00:08:04 jsg Exp $ */ -/* $NetBSD: if_zyd.c,v 1.37 2015/01/07 07:05:48 ozaki-r Exp $ */ +/* $NetBSD: if_zyd.c,v 1.38 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr> @@ -23,13 +23,14 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: if_zyd.c,v 1.37 2015/01/07 07:05:48 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: if_zyd.c,v 1.38 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/sockio.h> #include <sys/proc.h> #include <sys/mbuf.h> #include <sys/kernel.h> +#include <sys/kmem.h> #include <sys/socket.h> #include <sys/systm.h> #include <sys/malloc.h> @@ -216,10 +217,10 @@ Static int zyd_set_rxfilter(struct zyd_softc *); Static void zyd_set_chan(struct zyd_softc *, struct ieee80211_channel *); Static int zyd_set_beacon_interval(struct zyd_softc *, int); Static uint8_t zyd_plcp_signal(int); -Static void zyd_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void zyd_intr(struct usbd_xfer *, void *, usbd_status); Static void zyd_rx_data(struct zyd_softc *, const uint8_t *, uint16_t); -Static void zyd_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -Static void zyd_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void zyd_rxeof(struct usbd_xfer *, void *, usbd_status); +Static void zyd_txeof(struct usbd_xfer *, void *, usbd_status); Static int zyd_tx_mgt(struct zyd_softc *, struct mbuf *, struct ieee80211_node *); Static int zyd_tx_data(struct zyd_softc *, struct mbuf *, @@ -245,7 +246,7 @@ zyd_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (zyd_lookup(uaa->vendor, uaa->product) != NULL) ? + return (zyd_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL) ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } @@ -309,17 +310,17 @@ zyd_attach(device_t parent, device_t self, void *aux) struct ifnet *ifp = &sc->sc_if; sc->sc_dev = self; - sc->sc_udev = uaa->device; + sc->sc_udev = uaa->uaa_device; sc->sc_flags = 0; aprint_naive("\n"); aprint_normal("\n"); - devinfop = usbd_devinfo_alloc(uaa->device, 0); + devinfop = usbd_devinfo_alloc(uaa->uaa_device, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); - sc->mac_rev = zyd_lookup(uaa->vendor, uaa->product)->rev; + sc->mac_rev = zyd_lookup(uaa->uaa_vendor, uaa->uaa_product)->rev; ddesc = usbd_get_device_descriptor(sc->sc_udev); if (UGETW(ddesc->bcdDevice) < 0x4330) { @@ -437,14 +438,14 @@ zyd_complete_attach(struct zyd_softc *sc) ieee80211_media_init(ic, zyd_media_change, ieee80211_media_status); bpf_attach2(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN, + sizeof(struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN, &sc->sc_drvbpf); - sc->sc_rxtap_len = sizeof sc->sc_rxtapu; + sc->sc_rxtap_len = sizeof(sc->sc_rxtapu); sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); sc->sc_rxtap.wr_ihdr.it_present = htole32(ZYD_RX_RADIOTAP_PRESENT); - sc->sc_txtap_len = sizeof sc->sc_txtapu; + sc->sc_txtap_len = sizeof(sc->sc_txtapu); sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); sc->sc_txtap.wt_ihdr.it_present = htole32(ZYD_TX_RADIOTAP_PRESENT); @@ -473,6 +474,7 @@ zyd_detach(device_t self, int flags) callout_stop(&sc->sc_scan_ch); callout_stop(&sc->sc_amrr_ch); + /* Abort, etc. done by zyd_stop */ zyd_close_pipes(sc); sc->attached = 0; @@ -493,7 +495,6 @@ Static int zyd_open_pipes(struct zyd_softc *sc) { usb_endpoint_descriptor_t *edesc; - int isize; usbd_status error; /* interrupt in */ @@ -501,16 +502,16 @@ zyd_open_pipes(struct zyd_softc *sc) if (edesc == NULL) return EINVAL; - isize = UGETW(edesc->wMaxPacketSize); - if (isize == 0) /* should not happen */ + sc->ibuf_size = UGETW(edesc->wMaxPacketSize); + if (sc->ibuf_size == 0) /* should not happen */ return EINVAL; - sc->ibuf = malloc(isize, M_USBDEV, M_NOWAIT); + sc->ibuf = kmem_alloc(sc->ibuf_size, KM_SLEEP); if (sc->ibuf == NULL) return ENOMEM; error = usbd_open_pipe_intr(sc->sc_iface, 0x83, USBD_SHORT_XFER_OK, - &sc->zyd_ep[ZYD_ENDPT_IIN], sc, sc->ibuf, isize, zyd_intr, + &sc->zyd_ep[ZYD_ENDPT_IIN], sc, sc->ibuf, sc->ibuf_size, zyd_intr, USBD_DEFAULT_INTERVAL); if (error != 0) { printf("%s: open rx intr pipe failed: %s\n", @@ -558,13 +559,12 @@ zyd_close_pipes(struct zyd_softc *sc) for (i = 0; i < ZYD_ENDPT_CNT; i++) { if (sc->zyd_ep[i] != NULL) { - usbd_abort_pipe(sc->zyd_ep[i]); usbd_close_pipe(sc->zyd_ep[i]); sc->zyd_ep[i] = NULL; } } if (sc->ibuf != NULL) { - free(sc->ibuf, M_USBDEV); + kmem_free(sc->ibuf, sc->ibuf_size); sc->ibuf = NULL; } } @@ -581,23 +581,17 @@ zyd_alloc_tx_list(struct zyd_softc *sc) data->sc = sc; /* backpointer for callbacks */ - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { + error = usbd_create_xfer(sc->zyd_ep[ZYD_ENDPT_BOUT], + ZYD_MAX_TXBUFSZ, USBD_FORCE_SHORT_XFER, 0, &data->xfer); + if (error) { printf("%s: could not allocate tx xfer\n", device_xname(sc->sc_dev)); - error = ENOMEM; - goto fail; - } - data->buf = usbd_alloc_buffer(data->xfer, ZYD_MAX_TXBUFSZ); - if (data->buf == NULL) { - printf("%s: could not allocate tx buffer\n", - device_xname(sc->sc_dev)); - error = ENOMEM; goto fail; } + data->buf = usbd_get_buffer(data->xfer); /* clear Tx descriptor */ - memset(data->buf, 0, sizeof (struct zyd_tx_desc)); + memset(data->buf, 0, sizeof(struct zyd_tx_desc)); } return 0; @@ -614,7 +608,7 @@ zyd_free_tx_list(struct zyd_softc *sc) struct zyd_tx_data *data = &sc->tx_data[i]; if (data->xfer != NULL) { - usbd_free_xfer(data->xfer); + usbd_destroy_xfer(data->xfer); data->xfer = NULL; } if (data->ni != NULL) { @@ -634,20 +628,14 @@ zyd_alloc_rx_list(struct zyd_softc *sc) data->sc = sc; /* backpointer for callbacks */ - data->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data->xfer == NULL) { + error = usbd_create_xfer(sc->zyd_ep[ZYD_ENDPT_BIN], + ZYX_MAX_RXBUFSZ, USBD_SHORT_XFER_OK, 0, &data->xfer); + if (error) { printf("%s: could not allocate rx xfer\n", device_xname(sc->sc_dev)); - error = ENOMEM; - goto fail; - } - data->buf = usbd_alloc_buffer(data->xfer, ZYX_MAX_RXBUFSZ); - if (data->buf == NULL) { - printf("%s: could not allocate rx buffer\n", - device_xname(sc->sc_dev)); - error = ENOMEM; goto fail; } + data->buf = usbd_get_buffer(data->xfer); } return 0; @@ -664,7 +652,7 @@ zyd_free_rx_list(struct zyd_softc *sc) struct zyd_rx_data *data = &sc->rx_data[i]; if (data->xfer != NULL) { - usbd_free_xfer(data->xfer); + usbd_destroy_xfer(data->xfer); data->xfer = NULL; } } @@ -676,7 +664,7 @@ zyd_node_alloc(struct ieee80211_node_table *nt __unused) { struct zyd_node *zn; - zn = malloc(sizeof (struct zyd_node), M_80211_NODE, M_NOWAIT | M_ZERO); + zn = malloc(sizeof(struct zyd_node), M_80211_NODE, M_NOWAIT | M_ZERO); return &zn->ni; } @@ -795,7 +783,7 @@ Static int zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen, void *odata, int olen, u_int flags) { - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; struct zyd_cmd cmd; struct rq rq; uint16_t xferflags; @@ -803,11 +791,13 @@ zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen, usbd_status uerror; int s = 0; - if ((xfer = usbd_alloc_xfer(sc->sc_udev)) == NULL) - return ENOMEM; + error = usbd_create_xfer(sc->zyd_ep[ZYD_ENDPT_IOUT], + sizeof(uint16_t) + ilen, USBD_FORCE_SHORT_XFER, 0, &xfer); + if (error) + return error; cmd.code = htole16(code); - bcopy(idata, cmd.data, ilen); + memcpy(cmd.data, idata, ilen); xferflags = USBD_FORCE_SHORT_XFER; if (!(flags & ZYD_CMD_FLAG_READ)) @@ -816,23 +806,23 @@ zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen, s = splusb(); rq.idata = idata; rq.odata = odata; - rq.len = olen / sizeof (struct zyd_pair); + rq.len = olen / sizeof(struct zyd_pair); SIMPLEQ_INSERT_TAIL(&sc->sc_rqh, &rq, rq); } - usbd_setup_xfer(xfer, sc->zyd_ep[ZYD_ENDPT_IOUT], 0, &cmd, - sizeof (uint16_t) + ilen, xferflags, ZYD_INTR_TIMEOUT, NULL); + usbd_setup_xfer(xfer, 0, &cmd, sizeof(uint16_t) + ilen, xferflags, + ZYD_INTR_TIMEOUT, NULL); uerror = usbd_transfer(xfer); if (uerror != USBD_IN_PROGRESS && uerror != 0) { if (flags & ZYD_CMD_FLAG_READ) splx(s); printf("%s: could not send command (error=%s)\n", device_xname(sc->sc_dev), usbd_errstr(uerror)); - (void)usbd_free_xfer(xfer); + (void)usbd_destroy_xfer(xfer); return EIO; } if (!(flags & ZYD_CMD_FLAG_READ)) { - (void)usbd_free_xfer(xfer); + (void)usbd_destroy_xfer(xfer); return 0; /* write: don't wait for reply */ } /* wait at most one second for command reply */ @@ -842,7 +832,7 @@ zyd_cmd(struct zyd_softc *sc, uint16_t code, const void *idata, int ilen, SIMPLEQ_REMOVE(&sc->sc_rqh, &rq, rq, rq); splx(s); - (void)usbd_free_xfer(xfer); + (void)usbd_destroy_xfer(xfer); return error; } @@ -853,7 +843,7 @@ zyd_read16(struct zyd_softc *sc, uint16_t reg, uint16_t *val) int error; reg = htole16(reg); - error = zyd_cmd(sc, ZYD_CMD_IORD, ®, sizeof reg, &tmp, sizeof tmp, + error = zyd_cmd(sc, ZYD_CMD_IORD, ®, sizeof(reg), &tmp, sizeof(tmp), ZYD_CMD_FLAG_READ); if (error == 0) *val = le16toh(tmp.val); @@ -871,7 +861,7 @@ zyd_read32(struct zyd_softc *sc, uint16_t reg, uint32_t *val) regs[0] = htole16(ZYD_REG32_HI(reg)); regs[1] = htole16(ZYD_REG32_LO(reg)); - error = zyd_cmd(sc, ZYD_CMD_IORD, regs, sizeof regs, tmp, sizeof tmp, + error = zyd_cmd(sc, ZYD_CMD_IORD, regs, sizeof(regs), tmp, sizeof(tmp), ZYD_CMD_FLAG_READ); if (error == 0) *val = le16toh(tmp[0].val) << 16 | le16toh(tmp[1].val); @@ -888,7 +878,7 @@ zyd_write16(struct zyd_softc *sc, uint16_t reg, uint16_t val) pair.reg = htole16(reg); pair.val = htole16(val); - return zyd_cmd(sc, ZYD_CMD_IOWR, &pair, sizeof pair, NULL, 0, 0); + return zyd_cmd(sc, ZYD_CMD_IOWR, &pair, sizeof(pair), NULL, 0, 0); } Static int @@ -901,7 +891,7 @@ zyd_write32(struct zyd_softc *sc, uint16_t reg, uint32_t val) pair[1].reg = htole16(ZYD_REG32_LO(reg)); pair[1].val = htole16(val & 0xffff); - return zyd_cmd(sc, ZYD_CMD_IOWR, pair, sizeof pair, NULL, 0, 0); + return zyd_cmd(sc, ZYD_CMD_IOWR, pair, sizeof(pair), NULL, 0, 0); } Static int @@ -1822,7 +1812,7 @@ zyd_plcp_signal(int rate) } Static void -zyd_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +zyd_intr(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct zyd_softc *sc = (struct zyd_softc *)priv; struct zyd_cmd *cmd; @@ -1893,7 +1883,7 @@ zyd_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) continue; /* copy answer into caller-supplied buffer */ - bcopy(cmd->data, rqp->odata, + memcpy(rqp->odata, cmd->data, sizeof(struct zyd_pair) * rqp->len); wakeup(rqp->odata); /* wakeup caller */ @@ -1927,7 +1917,7 @@ zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len) plcp = (const struct zyd_plcphdr *)buf; stat = (const struct zyd_rx_stat *) - (buf + len - sizeof (struct zyd_rx_stat)); + (buf + len - sizeof(struct zyd_rx_stat)); if (stat->flags & ZYD_RX_ERROR) { DPRINTF(("%s: RX status indicated error (%x)\n", @@ -1937,8 +1927,8 @@ zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len) } /* compute actual frame length */ - rlen = len - sizeof (struct zyd_plcphdr) - - sizeof (struct zyd_rx_stat) - IEEE80211_CRC_LEN; + rlen = len - sizeof(struct zyd_plcphdr) - + sizeof(struct zyd_rx_stat) - IEEE80211_CRC_LEN; /* allocate a mbuf to store the frame */ MGETHDR(m, M_DONTWAIT, MT_DATA); @@ -1960,7 +1950,7 @@ zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len) } m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = rlen; - bcopy((const uint8_t *)(plcp + 1), mtod(m, uint8_t *), rlen); + memcpy(mtod(m, uint8_t *), (const uint8_t *)(plcp + 1), rlen); s = splnet(); @@ -1992,7 +1982,7 @@ zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len) } Static void -zyd_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +zyd_rxeof(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct zyd_rx_data *data = priv; struct zyd_softc *sc = data->sc; @@ -2019,7 +2009,7 @@ zyd_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) } desc = (const struct zyd_rx_desc *) - (data->buf + len - sizeof (struct zyd_rx_desc)); + (data->buf + len - sizeof(struct zyd_rx_desc)); if (UGETW(desc->tag) == ZYD_TAG_MULTIFRAME) { const uint8_t *p = data->buf, *end = p + len; @@ -2044,8 +2034,8 @@ zyd_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) } skip: /* setup a new transfer */ - usbd_setup_xfer(xfer, sc->zyd_ep[ZYD_ENDPT_BIN], data, NULL, - ZYX_MAX_RXBUFSZ, USBD_NO_COPY | USBD_SHORT_XFER_OK, + + usbd_setup_xfer(xfer, data, NULL, ZYX_MAX_RXBUFSZ, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, zyd_rxeof); (void)usbd_transfer(xfer); } @@ -2082,7 +2072,7 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) wh = mtod(m0, struct ieee80211_frame *); - xferlen = sizeof (struct zyd_tx_desc) + m0->m_pkthdr.len; + xferlen = sizeof(struct zyd_tx_desc) + m0->m_pkthdr.len; totlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN; /* fill Tx descriptor */ @@ -2117,7 +2107,7 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) desc->phy |= ZYD_TX_PHY_SHPREAMBLE; /* actual transmit length (XXX why +10?) */ - pktlen = sizeof (struct zyd_tx_desc) + 10; + pktlen = sizeof(struct zyd_tx_desc) + 10; if (sc->mac_rev == ZYD_ZD1211) pktlen += totlen; desc->pktlen = htole16(pktlen); @@ -2142,16 +2132,15 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) } m_copydata(m0, 0, m0->m_pkthdr.len, - data->buf + sizeof (struct zyd_tx_desc)); + data->buf + sizeof(struct zyd_tx_desc)); DPRINTFN(10, ("%s: sending mgt frame len=%zu rate=%u xferlen=%u\n", device_xname(sc->sc_dev), (size_t)m0->m_pkthdr.len, rate, xferlen)); m_freem(m0); /* mbuf no longer needed */ - usbd_setup_xfer(data->xfer, sc->zyd_ep[ZYD_ENDPT_BOUT], data, - data->buf, xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - ZYD_TX_TIMEOUT, zyd_txeof); + usbd_setup_xfer(data->xfer, data, data->buf, xferlen, + USBD_FORCE_SHORT_XFER, ZYD_TX_TIMEOUT, zyd_txeof); error = usbd_transfer(data->xfer); if (error != USBD_IN_PROGRESS && error != 0) { ifp->if_oerrors++; @@ -2163,7 +2152,7 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) } Static void -zyd_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +zyd_txeof(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct zyd_tx_data *data = priv; struct zyd_softc *sc = data->sc; @@ -2240,7 +2229,7 @@ zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) data->ni = ni; - xferlen = sizeof (struct zyd_tx_desc) + m0->m_pkthdr.len; + xferlen = sizeof(struct zyd_tx_desc) + m0->m_pkthdr.len; totlen = m0->m_pkthdr.len + IEEE80211_CRC_LEN; /* fill Tx descriptor */ @@ -2275,7 +2264,7 @@ zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) desc->phy |= ZYD_TX_PHY_SHPREAMBLE; /* actual transmit length (XXX why +10?) */ - pktlen = sizeof (struct zyd_tx_desc) + 10; + pktlen = sizeof(struct zyd_tx_desc) + 10; if (sc->mac_rev == ZYD_ZD1211) pktlen += totlen; desc->pktlen = htole16(pktlen); @@ -2300,16 +2289,15 @@ zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) } m_copydata(m0, 0, m0->m_pkthdr.len, - data->buf + sizeof (struct zyd_tx_desc)); + data->buf + sizeof(struct zyd_tx_desc)); DPRINTFN(10, ("%s: sending data frame len=%zu rate=%u xferlen=%u\n", device_xname(sc->sc_dev), (size_t)m0->m_pkthdr.len, rate, xferlen)); m_freem(m0); /* mbuf no longer needed */ - usbd_setup_xfer(data->xfer, sc->zyd_ep[ZYD_ENDPT_BOUT], data, - data->buf, xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - ZYD_TX_TIMEOUT, zyd_txeof); + usbd_setup_xfer(data->xfer, data, data->buf, xferlen, + USBD_FORCE_SHORT_XFER, ZYD_TX_TIMEOUT, zyd_txeof); error = usbd_transfer(data->xfer); if (error != USBD_IN_PROGRESS && error != 0) { ifp->if_oerrors++; @@ -2520,9 +2508,8 @@ zyd_init(struct ifnet *ifp) for (i = 0; i < ZYD_RX_LIST_CNT; i++) { struct zyd_rx_data *data = &sc->rx_data[i]; - usbd_setup_xfer(data->xfer, sc->zyd_ep[ZYD_ENDPT_BIN], data, - NULL, ZYX_MAX_RXBUFSZ, USBD_NO_COPY | USBD_SHORT_XFER_OK, - USBD_NO_TIMEOUT, zyd_rxeof); + usbd_setup_xfer(data->xfer, data, NULL, ZYX_MAX_RXBUFSZ, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, zyd_rxeof); error = usbd_transfer(data->xfer); if (error != USBD_IN_PROGRESS && error != 0) { printf("%s: could not queue Rx transfer\n", @@ -2617,7 +2604,7 @@ zyd_loadfirmware(struct zyd_softc *sc, u_char *fw, size_t size) req.bRequest = ZYD_DOWNLOADSTS; USETW(req.wValue, 0); USETW(req.wIndex, 0); - USETW(req.wLength, sizeof stat); + USETW(req.wLength, sizeof(stat)); if (usbd_do_request(sc->sc_udev, &req, &stat) != 0) return EIO; diff --git a/sys/dev/usb/if_zydreg.h b/sys/dev/usb/if_zydreg.h index b08d1435188..af6f6c80cd6 100644 --- a/sys/dev/usb/if_zydreg.h +++ b/sys/dev/usb/if_zydreg.h @@ -1,5 +1,5 @@ /* $OpenBSD: if_zydreg.h,v 1.19 2006/11/30 19:28:07 damien Exp $ */ -/* $NetBSD: if_zydreg.h,v 1.7 2012/08/24 09:01:23 msaitoh Exp $ */ +/* $NetBSD: if_zydreg.h,v 1.8 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2006 by Damien Bergamini <damien.bergamini@free.fr> @@ -1084,14 +1084,14 @@ struct zyd_notif_retry { #define ZYD_TX_TIMEOUT 10000 #define ZYD_MAX_TXBUFSZ \ - (sizeof (struct zyd_tx_desc) + MCLBYTES) + (sizeof(struct zyd_tx_desc) + MCLBYTES) #define ZYD_MIN_FRAGSZ \ - (sizeof (struct zyd_plcphdr) + IEEE80211_MIN_LEN + \ - sizeof (struct zyd_rx_stat)) + (sizeof(struct zyd_plcphdr) + IEEE80211_MIN_LEN + \ + sizeof(struct zyd_rx_stat)) #define ZYD_MIN_RXBUFSZ ZYD_MIN_FRAGSZ #define ZYX_MAX_RXBUFSZ \ - (sizeof (struct zyd_plcphdr) + MCLBYTES + sizeof (struct zyd_rx_desc)) + (sizeof(struct zyd_plcphdr) + MCLBYTES + sizeof(struct zyd_rx_desc)) #define ZYD_CMD_FLAG_READ (1 << 0) @@ -1110,14 +1110,14 @@ struct zyd_mac_pair { struct zyd_tx_data { struct zyd_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; struct ieee80211_node *ni; }; struct zyd_rx_data { struct zyd_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; const uint8_t *buf; }; @@ -1183,8 +1183,8 @@ struct zyd_softc { struct zyd_rf sc_rf; struct usb_task sc_task; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device * sc_udev; + struct usbd_interface * sc_iface; int sc_flags; #define ZD1211_FWLOADED (1 << 0) @@ -1217,8 +1217,9 @@ struct zyd_softc { #define ZYD_ENDPT_IIN 2 #define ZYD_ENDPT_IOUT 3 #define ZYD_ENDPT_CNT 4 - usbd_pipe_handle zyd_ep[ZYD_ENDPT_CNT]; + struct usbd_pipe * zyd_ep[ZYD_ENDPT_CNT]; uint8_t *ibuf; + size_t ibuf_size; struct zyd_rx_data rx_data[ZYD_RX_LIST_CNT]; struct zyd_tx_data tx_data[ZYD_TX_LIST_CNT]; diff --git a/sys/dev/usb/irmce.c b/sys/dev/usb/irmce.c index 396bb3c9e44..b250ac20383 100644 --- a/sys/dev/usb/irmce.c +++ b/sys/dev/usb/irmce.c @@ -1,4 +1,4 @@ -/* $NetBSD: irmce.c,v 1.1 2011/07/19 12:23:04 jmcneill Exp $ */ +/* $NetBSD: irmce.c,v 1.2 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: irmce.c,v 1.1 2011/07/19 12:23:04 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: irmce.c,v 1.2 2016/04/23 10:15:32 skrll Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -62,19 +62,19 @@ struct irmce_softc { device_t sc_dev; device_t sc_cirdev; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device * sc_udev; + struct usbd_interface * sc_iface; int sc_bulkin_ep; uint16_t sc_bulkin_maxpktsize; - usbd_pipe_handle sc_bulkin_pipe; - usbd_xfer_handle sc_bulkin_xfer; + struct usbd_pipe * sc_bulkin_pipe; + struct usbd_xfer * sc_bulkin_xfer; uint8_t * sc_bulkin_buffer; int sc_bulkout_ep; uint16_t sc_bulkout_maxpktsize; - usbd_pipe_handle sc_bulkout_pipe; - usbd_xfer_handle sc_bulkout_xfer; + struct usbd_pipe * sc_bulkout_pipe; + struct usbd_xfer * sc_bulkout_xfer; uint8_t * sc_bulkout_buffer; bool sc_raw; @@ -132,8 +132,8 @@ irmce_match(device_t parent, cfdata_t match, void *opaque) unsigned int i; for (i = 0; i < __arraycount(irmce_devices); i++) { - if (irmce_devices[i].vendor == uiaa->vendor && - irmce_devices[i].product == uiaa->product) + if (irmce_devices[i].vendor == uiaa->uiaa_vendor && + irmce_devices[i].product == uiaa->uiaa_product) return UMATCH_VENDOR_PRODUCT; } @@ -154,13 +154,13 @@ irmce_attach(device_t parent, device_t self, void *opaque) aprint_naive("\n"); - devinfop = usbd_devinfo_alloc(uiaa->device, 0); + devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0); aprint_normal(": %s\n", devinfop); usbd_devinfo_free(devinfop); sc->sc_dev = self; - sc->sc_udev = uiaa->device; - sc->sc_iface = uiaa->iface; + sc->sc_udev = uiaa->uiaa_device; + sc->sc_iface = uiaa->uiaa_iface; nep = 0; usbd_endpoint_count(sc->sc_iface, &nep); @@ -203,23 +203,49 @@ irmce_attach(device_t parent, device_t self, void *opaque) aprint_error_dev(self, "bad maxpktsize\n"); return; } + usbd_status err; - sc->sc_bulkin_xfer = usbd_alloc_xfer(sc->sc_udev); - sc->sc_bulkout_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_bulkin_xfer == NULL || sc->sc_bulkout_xfer == NULL) { - aprint_error_dev(self, "couldn't alloc xfer\n"); + err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_ep, + USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe); + if (err) { + aprint_error_dev(sc->sc_dev, + "couldn't open bulk-in pipe: %s\n", usbd_errstr(err)); return; } - sc->sc_bulkin_buffer = usbd_alloc_buffer(sc->sc_bulkin_xfer, - sc->sc_bulkin_maxpktsize); - sc->sc_bulkout_buffer = usbd_alloc_buffer(sc->sc_bulkout_xfer, - sc->sc_bulkout_maxpktsize); - if (sc->sc_bulkin_buffer == NULL || sc->sc_bulkout_buffer == NULL) { - aprint_error_dev(self, "couldn't alloc xfer buffer\n"); + err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_ep, + USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe); + if (err) { + aprint_error_dev(sc->sc_dev, + "couldn't open bulk-out pipe: %s\n", usbd_errstr(err)); + usbd_close_pipe(sc->sc_bulkin_pipe); + sc->sc_bulkin_pipe = NULL; return; } + int error; + error = usbd_create_xfer(sc->sc_bulkin_pipe, sc->sc_bulkin_maxpktsize, + USBD_SHORT_XFER_OK, 0, &sc->sc_bulkin_xfer); + if (error) { + goto fail; + } + + error = usbd_create_xfer(sc->sc_bulkout_pipe, + sc->sc_bulkout_maxpktsize, USBD_FORCE_SHORT_XFER, 0, + &sc->sc_bulkout_xfer); + if (error) { + goto fail; + } + sc->sc_bulkin_buffer = usbd_get_buffer(sc->sc_bulkin_xfer); + sc->sc_bulkout_buffer = usbd_get_buffer(sc->sc_bulkout_xfer); + irmce_rescan(self, NULL, NULL); + return; + +fail: + if (sc->sc_bulkin_xfer) + usbd_destroy_xfer(sc->sc_bulkin_xfer); + if (sc->sc_bulkout_xfer) + usbd_destroy_xfer(sc->sc_bulkout_xfer); } static int @@ -234,16 +260,30 @@ irmce_detach(device_t self, int flags) return error; } + if (sc->sc_bulkin_pipe) { + usbd_abort_pipe(sc->sc_bulkin_pipe); + } + if (sc->sc_bulkout_pipe) { + usbd_abort_pipe(sc->sc_bulkout_pipe); + } if (sc->sc_bulkin_xfer) { - usbd_free_xfer(sc->sc_bulkin_xfer); + usbd_destroy_xfer(sc->sc_bulkin_xfer); sc->sc_bulkin_buffer = NULL; sc->sc_bulkin_xfer = NULL; } if (sc->sc_bulkout_xfer) { - usbd_free_xfer(sc->sc_bulkout_xfer); + usbd_destroy_xfer(sc->sc_bulkout_xfer); sc->sc_bulkout_buffer = NULL; sc->sc_bulkout_xfer = NULL; } + if (sc->sc_bulkin_pipe) { + usbd_close_pipe(sc->sc_bulkin_pipe); + sc->sc_bulkin_pipe = NULL; + } + if (sc->sc_bulkout_pipe) { + usbd_close_pipe(sc->sc_bulkout_pipe); + sc->sc_bulkout_pipe = NULL; + } pmf_device_deregister(self); @@ -304,10 +344,9 @@ irmce_reset(struct irmce_softc *sc) *p++ = reset_cmd[n]; wlen = sizeof(reset_cmd); - err = usbd_bulk_transfer(sc->sc_bulkin_xfer, - sc->sc_bulkout_pipe, USBD_NO_COPY|USBD_FORCE_SHORT_XFER, - USBD_DEFAULT_TIMEOUT, sc->sc_bulkout_buffer, &wlen, - "irmcereset"); + err = usbd_bulk_transfer(sc->sc_bulkout_xfer, sc->sc_bulkout_pipe, + USBD_FORCE_SHORT_XFER, USBD_DEFAULT_TIMEOUT, + sc->sc_bulkout_buffer, &wlen); if (err != USBD_NORMAL_COMPLETION) { if (err == USBD_INTERRUPTED) return EINTR; @@ -324,33 +363,10 @@ static int irmce_open(void *priv, int flag, int mode, struct proc *p) { struct irmce_softc *sc = priv; - usbd_status err; - - err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_ep, - USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe); - if (err) { - aprint_error_dev(sc->sc_dev, - "couldn't open bulk-in pipe: %s\n", usbd_errstr(err)); - return ENXIO; - } - err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_ep, - USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe); - if (err) { - aprint_error_dev(sc->sc_dev, - "couldn't open bulk-out pipe: %s\n", usbd_errstr(err)); - usbd_close_pipe(sc->sc_bulkin_pipe); - sc->sc_bulkin_pipe = NULL; - return ENXIO; - } - - err = irmce_reset(sc); + int err = irmce_reset(sc); if (err) { aprint_error_dev(sc->sc_dev, "couldn't reset device: %s\n", usbd_errstr(err)); - usbd_close_pipe(sc->sc_bulkin_pipe); - sc->sc_bulkin_pipe = NULL; - usbd_close_pipe(sc->sc_bulkout_pipe); - sc->sc_bulkout_pipe = NULL; } sc->sc_ir_state = IRMCE_STATE_HEADER; sc->sc_rc6_nhb = 0; @@ -365,13 +381,9 @@ irmce_close(void *priv, int flag, int mode, struct proc *p) if (sc->sc_bulkin_pipe) { usbd_abort_pipe(sc->sc_bulkin_pipe); - usbd_close_pipe(sc->sc_bulkin_pipe); - sc->sc_bulkin_pipe = NULL; } if (sc->sc_bulkout_pipe) { usbd_abort_pipe(sc->sc_bulkout_pipe); - usbd_close_pipe(sc->sc_bulkout_pipe); - sc->sc_bulkout_pipe = NULL; } return 0; @@ -552,9 +564,8 @@ irmce_read(void *priv, struct uio *uio, int flag) while (uio->uio_resid > 0) { rlen = sc->sc_bulkin_maxpktsize; err = usbd_bulk_transfer(sc->sc_bulkin_xfer, - sc->sc_bulkin_pipe, USBD_NO_COPY|USBD_SHORT_XFER_OK, - USBD_DEFAULT_TIMEOUT, sc->sc_bulkin_buffer, &rlen, - "irmcerd"); + sc->sc_bulkin_pipe, USBD_SHORT_XFER_OK, + USBD_DEFAULT_TIMEOUT, sc->sc_bulkin_buffer, &rlen); if (err != USBD_NORMAL_COMPLETION) { if (err == USBD_INTERRUPTED) return EINTR; diff --git a/sys/dev/usb/moscom.c b/sys/dev/usb/moscom.c index 1c0a453868d..72bdbe40150 100644 --- a/sys/dev/usb/moscom.c +++ b/sys/dev/usb/moscom.c @@ -1,4 +1,4 @@ -/* $NetBSD: moscom.c,v 1.8 2012/09/23 01:08:17 chs Exp $ */ +/* $NetBSD: moscom.c,v 1.9 2016/04/23 10:15:32 skrll Exp $ */ /* $OpenBSD: moscom.c,v 1.11 2007/10/11 18:33:14 deraadt Exp $ */ /* @@ -18,7 +18,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: moscom.c,v 1.8 2012/09/23 01:08:17 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: moscom.c,v 1.9 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -67,11 +67,11 @@ __KERNEL_RCSID(0, "$NetBSD: moscom.c,v 1.8 2012/09/23 01:08:17 chs Exp $"); #define MOSCOM_INT_RXEN 0x01 #define MOSCOM_INT_TXEN 0x02 -#define MOSCOM_INT_RSEN 0x04 +#define MOSCOM_INT_RSEN 0x04 #define MOSCOM_INT_MDMEM 0x08 #define MOSCOM_INT_SLEEP 0x10 #define MOSCOM_INT_XOFF 0x20 -#define MOSCOM_INT_RTS 0x40 +#define MOSCOM_INT_RTS 0x40 #define MOSCOM_FIFO_EN 0x01 #define MOSCOM_FIFO_RXCLR 0x02 @@ -138,8 +138,8 @@ __KERNEL_RCSID(0, "$NetBSD: moscom.c,v 1.8 2012/09/23 01:08:17 chs Exp $"); struct moscom_softc { device_t sc_dev; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device * sc_udev; + struct usbd_interface * sc_iface; device_t sc_subdev; u_char sc_msr; @@ -153,17 +153,17 @@ void moscom_get_status(void *, int, u_char *, u_char *); void moscom_set(void *, int, int, int); int moscom_param(void *, int, struct termios *); int moscom_open(void *, int); -int moscom_cmd(struct moscom_softc *, int, int); +int moscom_cmd(struct moscom_softc *, int, int); struct ucom_methods moscom_methods = { - NULL, - moscom_set, - moscom_param, - NULL, - moscom_open, - NULL, - NULL, - NULL, + .ucom_get_status = NULL, + .ucom_set = moscom_set, + .ucom_param = moscom_param, + .ucom_ioctl = NULL, + .ucom_open = moscom_open, + .ucom_close = NULL, + .ucom_read = NULL, + .ucom_write = NULL, }; static const struct usb_devno moscom_devs[] = { @@ -173,31 +173,31 @@ static const struct usb_devno moscom_devs[] = { }; #define moscom_lookup(v, p) usb_lookup(moscom_devs, v, p) -int moscom_match(device_t, cfdata_t, void *); -void moscom_attach(device_t, device_t, void *); +int moscom_match(device_t, cfdata_t, void *); +void moscom_attach(device_t, device_t, void *); void moscom_childdet(device_t, device_t); -int moscom_detach(device_t, int); -int moscom_activate(device_t, enum devact); +int moscom_detach(device_t, int); +int moscom_activate(device_t, enum devact); CFATTACH_DECL2_NEW(moscom, sizeof(struct moscom_softc), moscom_match, moscom_attach, moscom_detach, moscom_activate, NULL, moscom_childdet); -int +int moscom_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (moscom_lookup(uaa->vendor, uaa->product) != NULL ? + return (moscom_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE); } -void +void moscom_attach(device_t parent, device_t self, void *aux) { struct moscom_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; - struct ucom_attach_args uca; + struct usbd_device *dev = uaa->uaa_device; + struct ucom_attach_args ucaa; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devinfop; @@ -213,8 +213,8 @@ moscom_attach(device_t parent, device_t self, void *aux) sc->sc_dev = self; - bzero(&uca, sizeof(uca)); - sc->sc_udev = uaa->device; + memset(&ucaa, 0, sizeof(ucaa)); + sc->sc_udev = uaa->uaa_device; if (usbd_set_config_index(sc->sc_udev, MOSCOM_CONFIG_NO, 1) != 0) { aprint_error_dev(self, "could not set configuration no\n"); @@ -233,7 +233,7 @@ moscom_attach(device_t parent, device_t self, void *aux) id = usbd_get_interface_descriptor(sc->sc_iface); - uca.bulkin = uca.bulkout = -1; + ucaa.ucaa_bulkin = ucaa.ucaa_bulkout = -1; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { @@ -245,32 +245,32 @@ moscom_attach(device_t parent, device_t self, void *aux) if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) - uca.bulkin = ed->bEndpointAddress; + ucaa.ucaa_bulkin = ed->bEndpointAddress; else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) - uca.bulkout = ed->bEndpointAddress; + ucaa.ucaa_bulkout = ed->bEndpointAddress; } - if (uca.bulkin == -1 || uca.bulkout == -1) { + if (ucaa.ucaa_bulkin == -1 || ucaa.ucaa_bulkout == -1) { aprint_error_dev(self, "missing endpoint\n"); sc->sc_dying = 1; return; } - uca.ibufsize = MOSCOMBUFSZ; - uca.obufsize = MOSCOMBUFSZ; - uca.ibufsizepad = MOSCOMBUFSZ; - uca.opkthdrlen = 0; - uca.device = sc->sc_udev; - uca.iface = sc->sc_iface; - uca.methods = &moscom_methods; - uca.arg = sc; - uca.info = NULL; + ucaa.ucaa_ibufsize = MOSCOMBUFSZ; + ucaa.ucaa_obufsize = MOSCOMBUFSZ; + ucaa.ucaa_ibufsizepad = MOSCOMBUFSZ; + ucaa.ucaa_opkthdrlen = 0; + ucaa.ucaa_device = sc->sc_udev; + ucaa.ucaa_iface = sc->sc_iface; + ucaa.ucaa_methods = &moscom_methods; + ucaa.ucaa_arg = sc; + ucaa.ucaa_info = NULL; usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); - - sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &uca, + + sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &ucaa, ucomprint, ucomsubmatch); return; @@ -285,7 +285,7 @@ moscom_childdet(device_t self, device_t child) sc->sc_subdev = NULL; } -int +int moscom_detach(device_t self, int flags) { struct moscom_softc *sc = device_private(self); @@ -298,7 +298,7 @@ moscom_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - return (rv); + return rv; } int @@ -322,16 +322,16 @@ moscom_open(void *vsc, int portno) usb_device_request_t req; if (sc->sc_dying) - return (EIO); + return EIO; /* Purge FIFOs or odd things happen */ if (moscom_cmd(sc, MOSCOM_FIFO, 0x00) != 0) - return (EIO); - + return EIO; + if (moscom_cmd(sc, MOSCOM_FIFO, MOSCOM_FIFO_EN | MOSCOM_FIFO_RXCLR | MOSCOM_FIFO_TXCLR | - MOSCOM_FIFO_DMA_BLK | MOSCOM_FIFO_RXLVL_MASK) != 0) - return (EIO); + MOSCOM_FIFO_DMA_BLK | MOSCOM_FIFO_RXLVL_MASK) != 0) + return EIO; /* Magic tell device we're ready for data command */ req.bmRequestType = UT_WRITE_VENDOR_DEVICE; @@ -340,9 +340,9 @@ moscom_open(void *vsc, int portno) USETW(req.wIndex, MOSCOM_INT); USETW(req.wLength, 0); if (usbd_do_request(sc->sc_udev, &req, NULL) != 0) - return (EIO); + return EIO; - return (0); + return 0; } void @@ -378,12 +378,12 @@ moscom_param(void *vsc, int portno, struct termios *t) int data; if (t->c_ospeed <= 0 || t->c_ospeed > 115200) - return (EINVAL); + return EINVAL; data = MOSCOM_BAUD_REF / t->c_ospeed; if (data == 0 || data > 0xffff) - return (EINVAL); + return EINVAL; moscom_cmd(sc, MOSCOM_LCR, MOSCOM_LCR_DIVLATCH_EN); moscom_cmd(sc, MOSCOM_BAUDLO, data & 0xFF); @@ -429,14 +429,14 @@ moscom_param(void *vsc, int portno, struct termios *t) } #endif - return (0); + return 0; } void moscom_get_status(void *vsc, int portno, u_char *lsr, u_char *msr) { struct moscom_softc *sc = vsc; - + if (msr != NULL) *msr = sc->sc_msr; if (lsr != NULL) @@ -448,7 +448,7 @@ moscom_cmd(struct moscom_softc *sc, int reg, int val) { usb_device_request_t req; usbd_status err; - + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = MOSCOM_WRITE; USETW(req.wValue, val + MOSCOM_UART_REG); @@ -456,7 +456,7 @@ moscom_cmd(struct moscom_softc *sc, int reg, int val) USETW(req.wLength, 0); err = usbd_do_request(sc->sc_udev, &req, NULL); if (err) - return (EIO); + return EIO; else - return (0); + return 0; } diff --git a/sys/dev/usb/motg.c b/sys/dev/usb/motg.c index eb6d3c9504e..e94d470e010 100644 --- a/sys/dev/usb/motg.c +++ b/sys/dev/usb/motg.c @@ -1,4 +1,4 @@ -/* $NetBSD: motg.c,v 1.13 2015/08/19 06:23:35 skrll Exp $ */ +/* $NetBSD: motg.c,v 1.14 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998, 2004, 2011, 2012, 2014 The NetBSD Foundation, Inc. @@ -39,22 +39,26 @@ * NOTE: The current implementation only supports Device Side Mode! */ -#include "opt_motg.h" - #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.13 2015/08/19 06:23:35 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.14 2016/04/23 10:15:32 skrll Exp $"); + +#ifdef _KERNEL_OPT +#include "opt_motg.h" +#include "opt_usb.h" +#endif #include <sys/param.h> -#include <sys/systm.h> + +#include <sys/bus.h> +#include <sys/cpu.h> +#include <sys/device.h> #include <sys/kernel.h> #include <sys/kmem.h> -#include <sys/device.h> -#include <sys/select.h> -#include <sys/extent.h> #include <sys/proc.h> #include <sys/queue.h> -#include <sys/bus.h> -#include <sys/cpu.h> +#include <sys/select.h> +#include <sys/sysctl.h> +#include <sys/systm.h> #include <machine/endian.h> @@ -62,7 +66,7 @@ __KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.13 2015/08/19 06:23:35 skrll Exp $"); #include <dev/usb/usbdi.h> #include <dev/usb/usbdivar.h> #include <dev/usb/usb_mem.h> -#include <dev/usb/usb_quirks.h> +#include <dev/usb/usbhist.h> #ifdef MOTG_ALLWINNER #include <arch/arm/allwinner/awin_otgreg.h> @@ -71,21 +75,53 @@ __KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.13 2015/08/19 06:23:35 skrll Exp $"); #endif #include <dev/usb/motgvar.h> -#include <dev/usb/usbroothub_subr.h> +#include <dev/usb/usbroothub.h> + +#ifdef USB_DEBUG +#ifndef MOTG_DEBUG +#define motgdebug 0 +#else +int motgdebug = 0; + +SYSCTL_SETUP(sysctl_hw_motg_setup, "sysctl hw.motg setup") +{ + int err; + const struct sysctlnode *rnode; + const struct sysctlnode *cnode; + + err = sysctl_createv(clog, 0, NULL, &rnode, + CTLFLAG_PERMANENT, CTLTYPE_NODE, "motg", + SYSCTL_DESCR("motg global controls"), + NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); + + if (err) + goto fail; + + /* control debugging printfs */ + err = sysctl_createv(clog, 0, &rnode, &cnode, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, + "debug", SYSCTL_DESCR("Enable debugging output"), + NULL, 0, &motgdebug, sizeof(motgdebug), CTL_CREATE, CTL_EOL); + if (err) + goto fail; + + return; +fail: + aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); +} + +#endif /* MOTG_DEBUG */ +#endif /* USB_DEBUG */ -#define MOTG_DEBUG -#ifdef MOTG_DEBUG -#define DPRINTF(x) if (motgdebug) printf x -#define DPRINTFN(n,x) if (motgdebug & (n)) printf x #define MD_ROOT 0x0002 #define MD_CTRL 0x0004 #define MD_BULK 0x0008 -// int motgdebug = MD_ROOT | MD_CTRL | MD_BULK; -int motgdebug = 0; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif + +#define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(motgdebug,1,FMT,A,B,C,D) +#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGM(motgdebug,N,FMT,A,B,C,D) +#define MOTGHIST_FUNC() USBHIST_FUNC() +#define MOTGHIST_CALLED(name) USBHIST_CALLED(motgdebug) + /* various timeouts, for various speeds */ /* control NAK timeouts */ @@ -101,56 +137,52 @@ int motgdebug = 0; #define NAK_TO_BULK_HIGH 0 static void motg_hub_change(struct motg_softc *); -static usbd_status motg_root_ctrl_transfer(usbd_xfer_handle); -static usbd_status motg_root_ctrl_start(usbd_xfer_handle); -static void motg_root_ctrl_abort(usbd_xfer_handle); -static void motg_root_ctrl_close(usbd_pipe_handle); -static void motg_root_ctrl_done(usbd_xfer_handle); - -static usbd_status motg_root_intr_transfer(usbd_xfer_handle); -static usbd_status motg_root_intr_start(usbd_xfer_handle); -static void motg_root_intr_abort(usbd_xfer_handle); -static void motg_root_intr_close(usbd_pipe_handle); -static void motg_root_intr_done(usbd_xfer_handle); - -static usbd_status motg_open(usbd_pipe_handle); + +static usbd_status motg_root_intr_transfer(struct usbd_xfer *); +static usbd_status motg_root_intr_start(struct usbd_xfer *); +static void motg_root_intr_abort(struct usbd_xfer *); +static void motg_root_intr_close(struct usbd_pipe *); +static void motg_root_intr_done(struct usbd_xfer *); + +static usbd_status motg_open(struct usbd_pipe *); static void motg_poll(struct usbd_bus *); static void motg_softintr(void *); -static usbd_status motg_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t); -static void motg_freem(struct usbd_bus *, usb_dma_t *); -static usbd_xfer_handle motg_allocx(struct usbd_bus *); -static void motg_freex(struct usbd_bus *, usbd_xfer_handle); +static struct usbd_xfer * + motg_allocx(struct usbd_bus *, unsigned int); +static void motg_freex(struct usbd_bus *, struct usbd_xfer *); static void motg_get_lock(struct usbd_bus *, kmutex_t **); -static void motg_noop(usbd_pipe_handle pipe); +static int motg_roothub_ctrl(struct usbd_bus *, usb_device_request_t *, + void *, int); + +static void motg_noop(struct usbd_pipe *pipe); static usbd_status motg_portreset(struct motg_softc*); -static usbd_status motg_device_ctrl_transfer(usbd_xfer_handle); -static usbd_status motg_device_ctrl_start(usbd_xfer_handle); -static void motg_device_ctrl_abort(usbd_xfer_handle); -static void motg_device_ctrl_close(usbd_pipe_handle); -static void motg_device_ctrl_done(usbd_xfer_handle); +static usbd_status motg_device_ctrl_transfer(struct usbd_xfer *); +static usbd_status motg_device_ctrl_start(struct usbd_xfer *); +static void motg_device_ctrl_abort(struct usbd_xfer *); +static void motg_device_ctrl_close(struct usbd_pipe *); +static void motg_device_ctrl_done(struct usbd_xfer *); static usbd_status motg_device_ctrl_start1(struct motg_softc *); -static void motg_device_ctrl_read(usbd_xfer_handle); +static void motg_device_ctrl_read(struct usbd_xfer *); static void motg_device_ctrl_intr_rx(struct motg_softc *); static void motg_device_ctrl_intr_tx(struct motg_softc *); -static usbd_status motg_device_data_transfer(usbd_xfer_handle); -static usbd_status motg_device_data_start(usbd_xfer_handle); +static usbd_status motg_device_data_transfer(struct usbd_xfer *); +static usbd_status motg_device_data_start(struct usbd_xfer *); static usbd_status motg_device_data_start1(struct motg_softc *, struct motg_hw_ep *); -static void motg_device_data_abort(usbd_xfer_handle); -static void motg_device_data_close(usbd_pipe_handle); -static void motg_device_data_done(usbd_xfer_handle); +static void motg_device_data_abort(struct usbd_xfer *); +static void motg_device_data_close(struct usbd_pipe *); +static void motg_device_data_done(struct usbd_xfer *); static void motg_device_intr_rx(struct motg_softc *, int); static void motg_device_intr_tx(struct motg_softc *, int); -static void motg_device_data_read(usbd_xfer_handle); -static void motg_device_data_write(usbd_xfer_handle); +static void motg_device_data_read(struct usbd_xfer *); +static void motg_device_data_write(struct usbd_xfer *); -static void motg_waitintr(struct motg_softc *, usbd_xfer_handle); -static void motg_device_clear_toggle(usbd_pipe_handle); -static void motg_device_xfer_abort(usbd_xfer_handle); +static void motg_waitintr(struct motg_softc *, struct usbd_xfer *); +static void motg_device_clear_toggle(struct usbd_pipe *); +static void motg_device_xfer_abort(struct usbd_xfer *); -#define MOTG_INTR_ENDPT 1 #define UBARR(sc) bus_space_barrier((sc)->sc_iot, (sc)->sc_ioh, 0, (sc)->sc_size, \ BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE) #define UWRITE1(sc, r, x) \ @@ -191,74 +223,65 @@ UREAD4(struct motg_softc *sc, bus_size_t r) static void musbotg_pull_common(struct motg_softc *sc, uint8_t on) { - uint8_t val; + uint8_t val; - val = UREAD1(sc, MUSB2_REG_POWER); - if (on) - val |= MUSB2_MASK_SOFTC; - else - val &= ~MUSB2_MASK_SOFTC; + val = UREAD1(sc, MUSB2_REG_POWER); + if (on) + val |= MUSB2_MASK_SOFTC; + else + val &= ~MUSB2_MASK_SOFTC; - UWRITE1(sc, MUSB2_REG_POWER, val); + UWRITE1(sc, MUSB2_REG_POWER, val); } const struct usbd_bus_methods motg_bus_methods = { - .open_pipe = motg_open, - .soft_intr = motg_softintr, - .do_poll = motg_poll, - .allocm = motg_allocm, - .freem = motg_freem, - .allocx = motg_allocx, - .freex = motg_freex, - .get_lock = motg_get_lock, - .new_device = NULL, -}; - -const struct usbd_pipe_methods motg_root_ctrl_methods = { - .transfer = motg_root_ctrl_transfer, - .start = motg_root_ctrl_start, - .abort = motg_root_ctrl_abort, - .close = motg_root_ctrl_close, - .cleartoggle = motg_noop, - .done = motg_root_ctrl_done, + .ubm_open = motg_open, + .ubm_softint = motg_softintr, + .ubm_dopoll = motg_poll, + .ubm_allocx = motg_allocx, + .ubm_freex = motg_freex, + .ubm_getlock = motg_get_lock, + .ubm_rhctrl = motg_roothub_ctrl, }; const struct usbd_pipe_methods motg_root_intr_methods = { - .transfer = motg_root_intr_transfer, - .start = motg_root_intr_start, - .abort = motg_root_intr_abort, - .close = motg_root_intr_close, - .cleartoggle = motg_noop, - .done = motg_root_intr_done, + .upm_transfer = motg_root_intr_transfer, + .upm_start = motg_root_intr_start, + .upm_abort = motg_root_intr_abort, + .upm_close = motg_root_intr_close, + .upm_cleartoggle = motg_noop, + .upm_done = motg_root_intr_done, }; const struct usbd_pipe_methods motg_device_ctrl_methods = { - .transfer = motg_device_ctrl_transfer, - .start = motg_device_ctrl_start, - .abort = motg_device_ctrl_abort, - .close = motg_device_ctrl_close, - .cleartoggle = motg_noop, - .done = motg_device_ctrl_done, + .upm_transfer = motg_device_ctrl_transfer, + .upm_start = motg_device_ctrl_start, + .upm_abort = motg_device_ctrl_abort, + .upm_close = motg_device_ctrl_close, + .upm_cleartoggle = motg_noop, + .upm_done = motg_device_ctrl_done, }; const struct usbd_pipe_methods motg_device_data_methods = { - .transfer = motg_device_data_transfer, - .start = motg_device_data_start, - .abort = motg_device_data_abort, - .close = motg_device_data_close, - .cleartoggle = motg_device_clear_toggle, - .done = motg_device_data_done, + .upm_transfer = motg_device_data_transfer, + .upm_start = motg_device_data_start, + .upm_abort = motg_device_data_abort, + .upm_close = motg_device_data_close, + .upm_cleartoggle = motg_device_clear_toggle, + .upm_done = motg_device_data_done, }; -usbd_status +int motg_init(struct motg_softc *sc) { uint32_t nrx, ntx, val; int dynfifo; int offset, i; + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + if (sc->sc_mode == MOTG_MODE_DEVICE) - return USBD_NORMAL_COMPLETION; /* not supported */ + return ENOTSUP; /* not supported */ /* disable all interrupts */ UWRITE1(sc, MUSB2_REG_INTUSBE, 0); @@ -291,7 +314,7 @@ motg_init(struct motg_softc *sc) UWRITE1(sc, MUSB2_REG_DEVCTL, val); } delay(1000); - DPRINTF(("DEVCTL 0x%x\n", UREAD1(sc, MUSB2_REG_DEVCTL))); + DPRINTF("DEVCTL 0x%x", UREAD1(sc, MUSB2_REG_DEVCTL), 0, 0, 0); /* disable testmode */ @@ -315,7 +338,7 @@ motg_init(struct motg_softc *sc) /* these numbers exclude the control endpoint */ - DPRINTF(("RX/TX endpoints: %u/%u\n", nrx, ntx)); + DPRINTFN(1,"RX/TX endpoints: %u/%u", nrx, ntx, 0, 0); sc->sc_ep_max = MAX(nrx, ntx); } else { @@ -323,13 +346,13 @@ motg_init(struct motg_softc *sc) } if (sc->sc_ep_max == 0) { aprint_error_dev(sc->sc_dev, " no endpoints\n"); - return USBD_INVAL; + return -1; } KASSERT(sc->sc_ep_max <= MOTG_MAX_HW_EP); /* read out configuration data */ val = UREAD1(sc, MUSB2_REG_CONFDATA); - DPRINTF(("Config Data: 0x%02x\n", val)); + DPRINTF("Config Data: 0x%02x", val, 0, 0, 0); dynfifo = (val & MUSB2_MASK_CD_DYNFIFOSZ) ? 1 : 0; @@ -338,7 +361,7 @@ motg_init(struct motg_softc *sc) "assuming 16Kbytes of FIFO RAM\n"); } - DPRINTF(("HW version: 0x%04x\n", UREAD1(sc, MUSB2_REG_HWVERS))); + DPRINTF("HW version: 0x%04x\n", UREAD1(sc, MUSB2_REG_HWVERS), 0, 0, 0); /* initialise endpoint profiles */ sc->sc_in_ep[0].ep_fifo_size = 64; @@ -361,8 +384,8 @@ motg_init(struct motg_softc *sc) fifotx_size = (val & MUSB2_MASK_TX_FSIZE); } - DPRINTF(("Endpoint %u FIFO size: IN=%u, OUT=%u, DYN=%d\n", - i, fifotx_size, fiforx_size, dynfifo)); + DPRINTF("Endpoint %u FIFO size: IN=%u, OUT=%u, DYN=%d", + i, fifotx_size, fiforx_size, dynfifo); if (dynfifo) { if (sc->sc_ep_fifosize) { @@ -429,7 +452,7 @@ motg_init(struct motg_softc *sc) } - DPRINTF(("Dynamic FIFO size = %d bytes\n", offset)); + DPRINTF("Dynamic FIFO size = %d bytes", offset, 0, 0, 0); /* turn on default interrupts */ @@ -447,32 +470,36 @@ motg_init(struct motg_softc *sc) mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB); /* Set up the bus struct. */ - sc->sc_bus.methods = &motg_bus_methods; - sc->sc_bus.pipe_size = sizeof(struct motg_pipe); - sc->sc_bus.usbrev = USBREV_2_0; - sc->sc_bus.hci_private = sc; + sc->sc_bus.ub_methods = &motg_bus_methods; + sc->sc_bus.ub_pipesize= sizeof(struct motg_pipe); + sc->sc_bus.ub_revision = USBREV_2_0; + sc->sc_bus.ub_usedma = false; + sc->sc_bus.ub_hcpriv = sc; snprintf(sc->sc_vendor, sizeof(sc->sc_vendor), "Mentor Graphics"); sc->sc_child = config_found(sc->sc_dev, &sc->sc_bus, usbctlprint); - return USBD_NORMAL_COMPLETION; + return 0; } static int -motg_select_ep(struct motg_softc *sc, usbd_pipe_handle pipe) +motg_select_ep(struct motg_softc *sc, struct usbd_pipe *pipe) { - struct motg_pipe *otgpipe = (struct motg_pipe *)pipe; - usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc; + struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(pipe); + usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc; struct motg_hw_ep *ep; int i, size; + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + ep = (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) ? sc->sc_in_ep : sc->sc_out_ep; - size = UE_GET_SIZE(UGETW(pipe->endpoint->edesc->wMaxPacketSize)); + size = UE_GET_SIZE(UGETW(pipe->up_endpoint->ue_edesc->wMaxPacketSize)); for (i = sc->sc_ep_max; i >= 1; i--) { - DPRINTF(("%s_ep[%d].ep_fifo_size %d size %d ref %d\n", - (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) ? - "in" : "out", i, ep[i].ep_fifo_size, size, ep[i].refcount)); + DPRINTF(UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN ? + "in_ep[%d].ep_fifo_size %d size %d ref %d" : + "out_ep[%d].ep_fifo_size %d size %d ref %d", i, + ep[i].ep_fifo_size, size, ep[i].refcount); if (ep[i].ep_fifo_size >= size) { /* found a suitable endpoint */ otgpipe->hw_ep = &ep[i]; @@ -495,37 +522,39 @@ motg_select_ep(struct motg_softc *sc, usbd_pipe_handle pipe) /* Open a new pipe. */ usbd_status -motg_open(usbd_pipe_handle pipe) +motg_open(struct usbd_pipe *pipe) { - struct motg_softc *sc = pipe->device->bus->hci_private; - struct motg_pipe *otgpipe = (struct motg_pipe *)pipe; - usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc; + struct motg_softc *sc = MOTG_PIPE2SC(pipe); + struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(pipe); + usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc; + uint8_t rhaddr = pipe->up_dev->ud_bus->ub_rhaddr; + + MOTGHIST_FUNC(); MOTGHIST_CALLED(); - DPRINTF(("motg_open: pipe=%p, addr=%d, endpt=%d (%d)\n", - pipe, pipe->device->address, - ed->bEndpointAddress, sc->sc_root_addr)); + DPRINTF("pipe=%p, addr=%d, endpt=%d (%d)", pipe, + pipe->up_dev->ud_addr, ed->bEndpointAddress, rhaddr); if (sc->sc_dying) return USBD_IOERROR; /* toggle state needed for bulk endpoints */ - otgpipe->nexttoggle = pipe->endpoint->datatoggle; + otgpipe->nexttoggle = pipe->up_endpoint->ue_toggle; - if (pipe->device->address == sc->sc_root_addr) { + if (pipe->up_dev->ud_addr == rhaddr) { switch (ed->bEndpointAddress) { case USB_CONTROL_ENDPOINT: - pipe->methods = &motg_root_ctrl_methods; + pipe->up_methods = &roothub_ctrl_methods; break; - case UE_DIR_IN | MOTG_INTR_ENDPT: - pipe->methods = &motg_root_intr_methods; + case UE_DIR_IN | USBROOTHUB_INTR_ENDPT: + pipe->up_methods = &motg_root_intr_methods; break; default: - return (USBD_INVAL); + return USBD_INVAL; } } else { switch (ed->bmAttributes & UE_XFERTYPE) { case UE_CONTROL: - pipe->methods = &motg_device_ctrl_methods; + pipe->up_methods = &motg_device_ctrl_methods; /* always use sc_in_ep[0] for in and out */ otgpipe->hw_ep = &sc->sc_in_ep[0]; mutex_enter(&sc->sc_lock); @@ -537,16 +566,15 @@ motg_open(usbd_pipe_handle pipe) case UE_BULK: case UE_INTERRUPT: DPRINTFN(MD_BULK, - ("new %s %s pipe wMaxPacketSize %d\n", - (ed->bmAttributes & UE_XFERTYPE) == UE_BULK ? - "bulk" : "interrupt", - (UE_GET_DIR(pipe->endpoint->edesc->bEndpointAddress) == UE_DIR_IN) ? "read" : "write", - UGETW(pipe->endpoint->edesc->wMaxPacketSize))); + "type %d dir %d pipe wMaxPacketSize %d", + UE_GET_XFERTYPE(ed->bmAttributes), + UE_GET_DIR(pipe->up_endpoint->ue_edesc->bEndpointAddress), + UGETW(pipe->up_endpoint->ue_edesc->wMaxPacketSize), 0); if (motg_select_ep(sc, pipe) != 0) goto bad; KASSERT(otgpipe->hw_ep != NULL); - pipe->methods = &motg_device_data_methods; - otgpipe->nexttoggle = pipe->endpoint->datatoggle; + pipe->up_methods = &motg_device_data_methods; + otgpipe->nexttoggle = pipe->up_endpoint->ue_toggle; break; default: goto bad; @@ -557,26 +585,27 @@ motg_open(usbd_pipe_handle pipe) #endif /* notyet */ } } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; bad: - return (USBD_NOMEM); + return USBD_NOMEM; } void motg_softintr(void *v) { struct usbd_bus *bus = v; - struct motg_softc *sc = bus->hci_private; + struct motg_softc *sc = MOTG_BUS2SC(bus); uint16_t rx_status, tx_status; uint8_t ctrl_status; uint32_t val; int i; - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); - DPRINTFN(MD_ROOT | MD_CTRL, - ("%s: motg_softintr\n", device_xname(sc->sc_dev))); + DPRINTFN(MD_ROOT | MD_CTRL, "sc %p", sc, 0 ,0 ,0); mutex_spin_enter(&sc->sc_intr_lock); rx_status = sc->sc_intr_rx_ep; @@ -592,8 +621,7 @@ motg_softintr(void *v) if (ctrl_status & (MUSB2_MASK_IRESET | MUSB2_MASK_IRESUME | MUSB2_MASK_ISUSP | MUSB2_MASK_ICONN | MUSB2_MASK_IDISC)) { - DPRINTFN(MD_ROOT | MD_CTRL, ("motg_softintr bus 0x%x\n", - ctrl_status)); + DPRINTFN(MD_ROOT | MD_CTRL, "bus 0x%x", ctrl_status, 0, 0, 0); if (ctrl_status & MUSB2_MASK_IRESET) { sc->sc_isreset = 1; @@ -607,8 +635,8 @@ motg_softintr(void *v) sc->sc_high_speed = 1; else sc->sc_high_speed = 0; - DPRINTFN(MD_ROOT | MD_CTRL, ("motg_softintr speed %d\n", - sc->sc_high_speed)); + DPRINTFN(MD_ROOT | MD_CTRL, "speed %d", sc->sc_high_speed, + 0, 0, 0); /* turn off interrupts */ val = MUSB2_MASK_IRESET; @@ -665,8 +693,7 @@ motg_softintr(void *v) rx_status |= UREAD2(sc, MUSB2_REG_INTRX); tx_status |= UREAD2(sc, MUSB2_REG_INTTX); - if (rx_status & 0x01) - panic("ctrl_rx %08x", rx_status); + KASSERTMSG((rx_status & 0x01) == 0, "ctrl_rx %08x", rx_status); if (tx_status & 0x01) motg_device_ctrl_intr_tx(sc); for (i = 1; i <= sc->sc_ep_max; i++) { @@ -681,7 +708,7 @@ motg_softintr(void *v) void motg_poll(struct usbd_bus *bus) { - struct motg_softc *sc = bus->hci_private; + struct motg_softc *sc = MOTG_BUS2SC(bus); sc->sc_intr_poll(sc->sc_intr_poll_arg); mutex_enter(&sc->sc_lock); @@ -698,8 +725,7 @@ motg_intr(struct motg_softc *sc, uint16_t rx_ep, uint16_t tx_ep, sc->sc_intr_rx_ep = rx_ep; sc->sc_intr_ctrl = ctrl; - if (!sc->sc_bus.use_polling) { - sc->sc_bus.no_intrs++; + if (!sc->sc_bus.ub_usepolling) { usb_schedsoftintr(&sc->sc_bus); } return 1; @@ -709,8 +735,10 @@ int motg_intr_vbus(struct motg_softc *sc, int vbus) { uint8_t val; + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + if (sc->sc_mode == MOTG_MODE_HOST && vbus == 0) { - DPRINTF(("motg_intr_vbus: vbus down, try to re-enable\n")); + DPRINTF("vbus down, try to re-enable", 0, 0, 0, 0); /* try to re-enter session for Host mode */ val = UREAD1(sc, MUSB2_REG_DEVCTL); val |= MUSB2_MASK_SESS; @@ -719,58 +747,33 @@ motg_intr_vbus(struct motg_softc *sc, int vbus) return 1; } -usbd_status -motg_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size) +struct usbd_xfer * +motg_allocx(struct usbd_bus *bus, unsigned int nframes) { - struct motg_softc *sc = bus->hci_private; - usbd_status status; - - status = usb_allocmem(&sc->sc_bus, size, 0, dma); - if (status == USBD_NOMEM) - status = usb_reserve_allocm(&sc->sc_dma_reserve, dma, size); - return status; -} - -void -motg_freem(struct usbd_bus *bus, usb_dma_t *dma) -{ - if (dma->block->flags & USB_DMA_RESERVE) { - usb_reserve_freem(&((struct motg_softc *)bus)->sc_dma_reserve, - dma); - return; - } - usb_freemem(&((struct motg_softc *)bus)->sc_bus, dma); -} - -usbd_xfer_handle -motg_allocx(struct usbd_bus *bus) -{ - struct motg_softc *sc = bus->hci_private; - usbd_xfer_handle xfer; + struct motg_softc *sc = MOTG_BUS2SC(bus); + struct usbd_xfer *xfer; xfer = pool_cache_get(sc->sc_xferpool, PR_NOWAIT); if (xfer != NULL) { memset(xfer, 0, sizeof(struct motg_xfer)); - UXFER(xfer)->sc = sc; #ifdef DIAGNOSTIC - // XXX UXFER(xfer)->iinfo.isdone = 1; - xfer->busy_free = XFER_BUSY; + xfer->ux_state = XFER_BUSY; #endif } - return (xfer); + return xfer; } void -motg_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) +motg_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) { - struct motg_softc *sc = bus->hci_private; + struct motg_softc *sc = MOTG_BUS2SC(bus); #ifdef DIAGNOSTIC - if (xfer->busy_free != XFER_BUSY) { + if (xfer->ux_state != XFER_BUSY) { printf("motg_freex: xfer=%p not busy, 0x%08x\n", xfer, - xfer->busy_free); + xfer->ux_state); } - xfer->busy_free = XFER_FREE; + xfer->ux_state = XFER_FREE; #endif pool_cache_put(sc->sc_xferpool, xfer); } @@ -778,252 +781,77 @@ motg_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) static void motg_get_lock(struct usbd_bus *bus, kmutex_t **lock) { - struct motg_softc *sc = bus->hci_private; + struct motg_softc *sc = MOTG_BUS2SC(bus); *lock = &sc->sc_lock; } /* - * Data structures and routines to emulate the root hub. - */ -usb_device_descriptor_t motg_devd = { - USB_DEVICE_DESCRIPTOR_SIZE, - UDESC_DEVICE, /* type */ - {0x00, 0x01}, /* USB version */ - UDCLASS_HUB, /* class */ - UDSUBCLASS_HUB, /* subclass */ - UDPROTO_FSHUB, /* protocol */ - 64, /* max packet */ - {0},{0},{0x00,0x01}, /* device id */ - 1,2,0, /* string indicies */ - 1 /* # of configurations */ -}; - -const usb_config_descriptor_t motg_confd = { - USB_CONFIG_DESCRIPTOR_SIZE, - UDESC_CONFIG, - {USB_CONFIG_DESCRIPTOR_SIZE + - USB_INTERFACE_DESCRIPTOR_SIZE + - USB_ENDPOINT_DESCRIPTOR_SIZE}, - 1, - 1, - 0, - UC_ATTR_MBO | UC_SELF_POWERED, - 0 /* max power */ -}; - -const usb_interface_descriptor_t motg_ifcd = { - USB_INTERFACE_DESCRIPTOR_SIZE, - UDESC_INTERFACE, - 0, - 0, - 1, - UICLASS_HUB, - UISUBCLASS_HUB, - UIPROTO_FSHUB, - 0 -}; - -const usb_endpoint_descriptor_t motg_endpd = { - USB_ENDPOINT_DESCRIPTOR_SIZE, - UDESC_ENDPOINT, - UE_DIR_IN | MOTG_INTR_ENDPT, - UE_INTERRUPT, - {8}, - 255 -}; - -const usb_hub_descriptor_t motg_hubd = { - USB_HUB_DESCRIPTOR_SIZE, - UDESC_HUB, - 1, - { UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0 }, - 50, /* power on to power good */ - 0, - { 0x00 }, /* port is removable */ - { 0 }, -}; - -/* - * Simulate a hardware hub by handling all the necessary requests. + * Routines to emulate the root hub. */ -usbd_status -motg_root_ctrl_transfer(usbd_xfer_handle xfer) -{ - struct motg_softc *sc = xfer->pipe->device->bus->hci_private; - usbd_status err; - - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return (err); - - /* - * Pipe isn't running (otherwise err would be USBD_INPROG), - * so start it first. - */ - return (motg_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); -} - -usbd_status -motg_root_ctrl_start(usbd_xfer_handle xfer) +Static int +motg_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, + void *buf, int buflen) { - struct motg_softc *sc = xfer->pipe->device->bus->hci_private; - usb_device_request_t *req; - void *buf = NULL; - int len, value, index, status, change, l, totlen = 0; + struct motg_softc *sc = MOTG_BUS2SC(bus); + int status, change, totlen = 0; + uint16_t len, value, index; usb_port_status_t ps; usbd_status err; uint32_t val; - if (sc->sc_dying) - return (USBD_IOERROR); + MOTGHIST_FUNC(); MOTGHIST_CALLED(); -#ifdef DIAGNOSTIC - if (!(xfer->rqflags & URQ_REQUEST)) - panic("motg_root_ctrl_start: not a request"); -#endif - req = &xfer->request; + if (sc->sc_dying) + return -1; - DPRINTFN(MD_ROOT,("motg_root_ctrl_control type=0x%02x request=%02x\n", - req->bmRequestType, req->bRequest)); + DPRINTFN(MD_ROOT, "type=0x%02x request=%02x", req->bmRequestType, + req->bRequest, 0, 0); len = UGETW(req->wLength); value = UGETW(req->wValue); index = UGETW(req->wIndex); - if (len != 0) - buf = KERNADDR(&xfer->dmabuf, 0); - #define C(x,y) ((x) | ((y) << 8)) - switch(C(req->bRequest, req->bmRequestType)) { - case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE): - case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE): - case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT): - /* - * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops - * for the integrated root hub. - */ - break; - case C(UR_GET_CONFIG, UT_READ_DEVICE): - if (len > 0) { - *(u_int8_t *)buf = sc->sc_root_conf; - totlen = 1; - } - break; + switch (C(req->bRequest, req->bmRequestType)) { case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): - DPRINTFN(MD_ROOT,("motg_root_ctrl_control wValue=0x%04x\n", value)); - if (len == 0) + DPRINTFN(MD_ROOT, "wValue=0x%04x", value, 0, 0, 0); + switch (value) { + case C(0, UDESC_DEVICE): { + usb_device_descriptor_t devd; + + totlen = min(buflen, sizeof(devd)); + memcpy(&devd, buf, totlen); + USETW(devd.idVendor, sc->sc_id_vendor); + memcpy(buf, &devd, totlen); break; - switch(value >> 8) { - case UDESC_DEVICE: - if ((value & 0xff) != 0) { - err = USBD_IOERROR; - goto ret; - } - totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE); - USETW(motg_devd.idVendor, sc->sc_id_vendor); - memcpy(buf, &motg_devd, l); + } + case C(1, UDESC_STRING): +#define sd ((usb_string_descriptor_t *)buf) + /* Vendor */ + totlen = usb_makestrdesc(sd, len, sc->sc_vendor); break; - case UDESC_CONFIG: - if ((value & 0xff) != 0) { - err = USBD_IOERROR; - goto ret; - } - totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE); - memcpy(buf, &motg_confd, l); - buf = (char *)buf + l; - len -= l; - l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE); - totlen += l; - memcpy(buf, &motg_ifcd, l); - buf = (char *)buf + l; - len -= l; - l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE); - totlen += l; - memcpy(buf, &motg_endpd, l); + case C(2, UDESC_STRING): + /* Product */ + totlen = usb_makestrdesc(sd, len, "MOTG root hub"); break; - case UDESC_STRING: -#define sd ((usb_string_descriptor_t *)buf) - switch (value & 0xff) { - case 0: /* Language table */ - totlen = usb_makelangtbl(sd, len); - break; - case 1: /* Vendor */ - totlen = usb_makestrdesc(sd, len, - sc->sc_vendor); - break; - case 2: /* Product */ - totlen = usb_makestrdesc(sd, len, - "MOTG root hub"); - break; - } #undef sd - break; default: - err = USBD_IOERROR; - goto ret; - } - break; - case C(UR_GET_INTERFACE, UT_READ_INTERFACE): - if (len > 0) { - *(u_int8_t *)buf = 0; - totlen = 1; - } - break; - case C(UR_GET_STATUS, UT_READ_DEVICE): - if (len > 1) { - USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED); - totlen = 2; - } - break; - case C(UR_GET_STATUS, UT_READ_INTERFACE): - case C(UR_GET_STATUS, UT_READ_ENDPOINT): - if (len > 1) { - USETW(((usb_status_t *)buf)->wStatus, 0); - totlen = 2; - } - break; - case C(UR_SET_ADDRESS, UT_WRITE_DEVICE): - if (value >= USB_MAX_DEVICES) { - err = USBD_IOERROR; - goto ret; + /* default from usbroothub */ + return buflen; } - sc->sc_root_addr = value; - break; - case C(UR_SET_CONFIG, UT_WRITE_DEVICE): - if (value != 0 && value != 1) { - err = USBD_IOERROR; - goto ret; - } - sc->sc_root_conf = value; - break; - case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE): - break; - case C(UR_SET_FEATURE, UT_WRITE_DEVICE): - case C(UR_SET_FEATURE, UT_WRITE_INTERFACE): - case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT): - err = USBD_IOERROR; - goto ret; - case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE): - break; - case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT): break; /* Hub requests */ case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE): break; case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): DPRINTFN(MD_ROOT, - ("motg_root_ctrl_control: UR_CLEAR_PORT_FEATURE " - "port=%d feature=%d\n", - index, value)); + "UR_CLEAR_PORT_FEATURE port=%d feature=%d", index, value, + 0, 0); if (index != 1) { - err = USBD_IOERROR; - goto ret; + return -1; } - switch(value) { + switch (value) { case UHF_PORT_ENABLE: sc->sc_port_enabled = 0; break; @@ -1052,8 +880,7 @@ motg_root_ctrl_start(usbd_xfer_handle xfer) break; case UHF_C_PORT_RESET: sc->sc_isreset = 0; - err = USBD_NORMAL_COMPLETION; - goto ret; + break; case UHF_PORT_POWER: /* XXX todo */ break; @@ -1062,40 +889,32 @@ motg_root_ctrl_start(usbd_xfer_handle xfer) case UHF_PORT_LOW_SPEED: case UHF_C_PORT_SUSPEND: default: - err = USBD_IOERROR; - goto ret; + return -1; } break; case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER): - err = USBD_IOERROR; - goto ret; + return -1; case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE): if (len == 0) break; if ((value & 0xff) != 0) { - err = USBD_IOERROR; - goto ret; + return -1; } - l = min(len, USB_HUB_DESCRIPTOR_SIZE); - totlen = l; - memcpy(buf, &motg_hubd, l); + totlen = buflen; break; case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): if (len != 4) { - err = USBD_IOERROR; - goto ret; + return -1; } memset(buf, 0, len); totlen = len; break; case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): if (index != 1) { - err = USBD_IOERROR; - goto ret; + return -1; } if (len != 4) { - err = USBD_IOERROR; - goto ret; + return -1; } status = change = 0; if (sc->sc_connected) @@ -1119,19 +938,16 @@ motg_root_ctrl_start(usbd_xfer_handle xfer) change |= UPS_C_PORT_RESET; USETW(ps.wPortStatus, status); USETW(ps.wPortChange, change); - l = min(len, sizeof ps); - memcpy(buf, &ps, l); - totlen = l; + totlen = min(len, sizeof(ps)); + memcpy(buf, &ps, totlen); break; case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE): - err = USBD_IOERROR; - goto ret; + return -1; case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE): break; case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER): if (index != 1) { - err = USBD_IOERROR; - goto ret; + return -1; } switch(value) { case UHF_PORT_ENABLE: @@ -1150,11 +966,12 @@ motg_root_ctrl_start(usbd_xfer_handle xfer) break; case UHF_PORT_RESET: err = motg_portreset(sc); - goto ret; + if (err != USBD_NORMAL_COMPLETION) + return -1; + return 0; case UHF_PORT_POWER: /* XXX todo */ - err = USBD_NORMAL_COMPLETION; - goto ret; + return 0; case UHF_C_PORT_CONNECTION: case UHF_C_PORT_ENABLE: case UHF_C_PORT_OVER_CURRENT: @@ -1164,65 +981,36 @@ motg_root_ctrl_start(usbd_xfer_handle xfer) case UHF_C_PORT_SUSPEND: case UHF_C_PORT_RESET: default: - err = USBD_IOERROR; - goto ret; + return -1; } break; default: - err = USBD_IOERROR; - goto ret; + /* default from usbroothub */ + return buflen; } - xfer->actlen = totlen; - err = USBD_NORMAL_COMPLETION; - ret: - xfer->status = err; - mutex_enter(&sc->sc_lock); - usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); - return (USBD_IN_PROGRESS); -} -/* Abort a root control request. */ -void -motg_root_ctrl_abort(usbd_xfer_handle xfer) -{ - /* Nothing to do, all transfers are synchronous. */ -} - -/* Close the root pipe. */ -void -motg_root_ctrl_close(usbd_pipe_handle pipe) -{ - DPRINTFN(MD_ROOT, ("motg_root_ctrl_close\n")); -} - -void -motg_root_ctrl_done(usbd_xfer_handle xfer) -{ + return totlen; } /* Abort a root interrupt request. */ void -motg_root_intr_abort(usbd_xfer_handle xfer) +motg_root_intr_abort(struct usbd_xfer *xfer) { - struct motg_softc *sc = xfer->pipe->device->bus->hci_private; + struct motg_softc *sc = MOTG_XFER2SC(xfer); KASSERT(mutex_owned(&sc->sc_lock)); - KASSERT(xfer->pipe->intrxfer == xfer); + KASSERT(xfer->ux_pipe->up_intrxfer == xfer); sc->sc_intr_xfer = NULL; -#ifdef DIAGNOSTIC - // XXX UXFER(xfer)->iinfo.isdone = 1; -#endif - xfer->status = USBD_CANCELLED; + xfer->ux_status = USBD_CANCELLED; usb_transfer_complete(xfer); } usbd_status -motg_root_intr_transfer(usbd_xfer_handle xfer) +motg_root_intr_transfer(struct usbd_xfer *xfer) { - struct motg_softc *sc = xfer->pipe->device->bus->hci_private; + struct motg_softc *sc = MOTG_XFER2SC(xfer); usbd_status err; /* Insert last in queue. */ @@ -1230,51 +1018,53 @@ motg_root_intr_transfer(usbd_xfer_handle xfer) err = usb_insert_transfer(xfer); mutex_exit(&sc->sc_lock); if (err) - return (err); + return err; /* * Pipe isn't running (otherwise err would be USBD_INPROG), * start first */ - return (motg_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return motg_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } /* Start a transfer on the root interrupt pipe */ usbd_status -motg_root_intr_start(usbd_xfer_handle xfer) +motg_root_intr_start(struct usbd_xfer *xfer) { - usbd_pipe_handle pipe = xfer->pipe; - struct motg_softc *sc = pipe->device->bus->hci_private; + struct usbd_pipe *pipe = xfer->ux_pipe; + struct motg_softc *sc = MOTG_PIPE2SC(pipe); + + MOTGHIST_FUNC(); MOTGHIST_CALLED(); - DPRINTFN(MD_ROOT, ("motg_root_intr_start: xfer=%p len=%d flags=%d\n", - xfer, xfer->length, xfer->flags)); + DPRINTFN(MD_ROOT, "xfer=%p len=%d flags=%d", xfer, xfer->ux_length, + xfer->ux_flags, 0); if (sc->sc_dying) - return (USBD_IOERROR); + return USBD_IOERROR; sc->sc_intr_xfer = xfer; - return (USBD_IN_PROGRESS); + return USBD_IN_PROGRESS; } /* Close the root interrupt pipe. */ void -motg_root_intr_close(usbd_pipe_handle pipe) +motg_root_intr_close(struct usbd_pipe *pipe) { - struct motg_softc *sc = pipe->device->bus->hci_private; + struct motg_softc *sc = MOTG_PIPE2SC(pipe); + MOTGHIST_FUNC(); MOTGHIST_CALLED(); KASSERT(mutex_owned(&sc->sc_lock)); sc->sc_intr_xfer = NULL; - DPRINTFN(MD_ROOT, ("motg_root_intr_close\n")); } void -motg_root_intr_done(usbd_xfer_handle xfer) +motg_root_intr_done(struct usbd_xfer *xfer) { } void -motg_noop(usbd_pipe_handle pipe) +motg_noop(struct usbd_pipe *pipe) { } @@ -1282,6 +1072,7 @@ static usbd_status motg_portreset(struct motg_softc *sc) { uint32_t val; + MOTGHIST_FUNC(); MOTGHIST_CALLED(); val = UREAD1(sc, MUSB2_REG_POWER); val |= MUSB2_MASK_RESET; @@ -1299,12 +1090,11 @@ motg_portreset(struct motg_softc *sc) sc->sc_high_speed = 1; else sc->sc_high_speed = 0; - DPRINTFN(MD_ROOT | MD_CTRL, ("motg_portreset speed %d\n", - sc->sc_high_speed)); + DPRINTFN(MD_ROOT | MD_CTRL, "speed %d", sc->sc_high_speed, 0, 0, 0); sc->sc_isreset = 1; sc->sc_port_enabled = 1; - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } /* @@ -1313,28 +1103,28 @@ motg_portreset(struct motg_softc *sc) static void motg_hub_change(struct motg_softc *sc) { - usbd_xfer_handle xfer = sc->sc_intr_xfer; - usbd_pipe_handle pipe; + struct usbd_xfer *xfer = sc->sc_intr_xfer; + struct usbd_pipe *pipe; u_char *p; - DPRINTFN(MD_ROOT, ("motg_hub_change\n")); + MOTGHIST_FUNC(); MOTGHIST_CALLED(); if (xfer == NULL) return; /* the interrupt pipe is not open */ - pipe = xfer->pipe; - if (pipe->device == NULL || pipe->device->bus == NULL) + pipe = xfer->ux_pipe; + if (pipe->up_dev == NULL || pipe->up_dev->ud_bus == NULL) return; /* device has detached */ - p = KERNADDR(&xfer->dmabuf, 0); + p = xfer->ux_buf; p[0] = 1<<1; - xfer->actlen = 1; - xfer->status = USBD_NORMAL_COMPLETION; + xfer->ux_actlen = 1; + xfer->ux_status = USBD_NORMAL_COMPLETION; usb_transfer_complete(xfer); } static uint8_t -motg_speed(u_int8_t speed) +motg_speed(uint8_t speed) { switch(speed) { case USB_SPEED_LOW: @@ -1350,7 +1140,7 @@ motg_speed(u_int8_t speed) } static uint8_t -motg_type(u_int8_t type) +motg_type(uint8_t type) { switch(type) { case UE_CONTROL: @@ -1368,27 +1158,27 @@ motg_type(u_int8_t type) } static void -motg_setup_endpoint_tx(usbd_xfer_handle xfer) +motg_setup_endpoint_tx(struct usbd_xfer *xfer) { - struct motg_softc *sc = xfer->pipe->device->bus->hci_private; - struct motg_pipe *otgpipe = (struct motg_pipe *)xfer->pipe; - usbd_device_handle dev = otgpipe->pipe.device; + struct motg_softc *sc = MOTG_XFER2SC(xfer); + struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); + struct usbd_device *dev = otgpipe->pipe.up_dev; int epnumber = otgpipe->hw_ep->ep_number; - UWRITE1(sc, MUSB2_REG_TXFADDR(epnumber), dev->address); - if (dev->myhsport) { + UWRITE1(sc, MUSB2_REG_TXFADDR(epnumber), dev->ud_addr); + if (dev->ud_myhsport) { UWRITE1(sc, MUSB2_REG_TXHADDR(epnumber), - dev->myhsport->parent->address); + dev->ud_myhsport->up_parent->ud_addr); UWRITE1(sc, MUSB2_REG_TXHUBPORT(epnumber), - dev->myhsport->portno); + dev->ud_myhsport->up_portno); } else { UWRITE1(sc, MUSB2_REG_TXHADDR(epnumber), 0); UWRITE1(sc, MUSB2_REG_TXHUBPORT(epnumber), 0); } UWRITE1(sc, MUSB2_REG_TXTI, - motg_speed(dev->speed) | - UE_GET_ADDR(xfer->pipe->endpoint->edesc->bEndpointAddress) | - motg_type(UE_GET_XFERTYPE(xfer->pipe->endpoint->edesc->bmAttributes)) + motg_speed(dev->ud_speed) | + UE_GET_ADDR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) | + motg_type(UE_GET_XFERTYPE(xfer->ux_pipe->up_endpoint->ue_edesc->bmAttributes)) ); if (epnumber == 0) { if (sc->sc_high_speed) { @@ -1398,7 +1188,7 @@ motg_setup_endpoint_tx(usbd_xfer_handle xfer) UWRITE1(sc, MUSB2_REG_TXNAKLIMIT, NAK_TO_CTRL); } } else { - if ((xfer->pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE) + if ((xfer->ux_pipe->up_endpoint->ue_edesc->bmAttributes & UE_XFERTYPE) == UE_BULK) { if (sc->sc_high_speed) { UWRITE1(sc, MUSB2_REG_TXNAKLIMIT, @@ -1417,27 +1207,27 @@ motg_setup_endpoint_tx(usbd_xfer_handle xfer) } static void -motg_setup_endpoint_rx(usbd_xfer_handle xfer) +motg_setup_endpoint_rx(struct usbd_xfer *xfer) { - struct motg_softc *sc = xfer->pipe->device->bus->hci_private; - usbd_device_handle dev = xfer->pipe->device; - struct motg_pipe *otgpipe = (struct motg_pipe *)xfer->pipe; + struct motg_softc *sc = MOTG_XFER2SC(xfer); + struct usbd_device *dev = xfer->ux_pipe->up_dev; + struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); int epnumber = otgpipe->hw_ep->ep_number; - UWRITE1(sc, MUSB2_REG_RXFADDR(epnumber), dev->address); - if (dev->myhsport) { + UWRITE1(sc, MUSB2_REG_RXFADDR(epnumber), dev->ud_addr); + if (dev->ud_myhsport) { UWRITE1(sc, MUSB2_REG_RXHADDR(epnumber), - dev->myhsport->parent->address); + dev->ud_myhsport->up_parent->ud_addr); UWRITE1(sc, MUSB2_REG_RXHUBPORT(epnumber), - dev->myhsport->portno); + dev->ud_myhsport->up_portno); } else { UWRITE1(sc, MUSB2_REG_RXHADDR(epnumber), 0); UWRITE1(sc, MUSB2_REG_RXHUBPORT(epnumber), 0); } UWRITE1(sc, MUSB2_REG_RXTI, - motg_speed(dev->speed) | - UE_GET_ADDR(xfer->pipe->endpoint->edesc->bEndpointAddress) | - motg_type(UE_GET_XFERTYPE(xfer->pipe->endpoint->edesc->bmAttributes)) + motg_speed(dev->ud_speed) | + UE_GET_ADDR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) | + motg_type(UE_GET_XFERTYPE(xfer->ux_pipe->up_endpoint->ue_edesc->bmAttributes)) ); if (epnumber == 0) { if (sc->sc_high_speed) { @@ -1447,7 +1237,7 @@ motg_setup_endpoint_rx(usbd_xfer_handle xfer) UWRITE1(sc, MUSB2_REG_TXNAKLIMIT, NAK_TO_CTRL); } } else { - if ((xfer->pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE) + if ((xfer->ux_pipe->up_endpoint->ue_edesc->bmAttributes & UE_XFERTYPE) == UE_BULK) { if (sc->sc_high_speed) { UWRITE1(sc, MUSB2_REG_RXNAKLIMIT, @@ -1466,37 +1256,37 @@ motg_setup_endpoint_rx(usbd_xfer_handle xfer) } static usbd_status -motg_device_ctrl_transfer(usbd_xfer_handle xfer) +motg_device_ctrl_transfer(struct usbd_xfer *xfer) { - struct motg_softc *sc = xfer->pipe->device->bus->hci_private; + struct motg_softc *sc = MOTG_XFER2SC(xfer); usbd_status err; /* Insert last in queue. */ mutex_enter(&sc->sc_lock); err = usb_insert_transfer(xfer); - xfer->status = USBD_NOT_STARTED; + xfer->ux_status = USBD_NOT_STARTED; mutex_exit(&sc->sc_lock); if (err) - return (err); + return err; /* * Pipe isn't running (otherwise err would be USBD_INPROG), * so start it first. */ - return (motg_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return motg_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } static usbd_status -motg_device_ctrl_start(usbd_xfer_handle xfer) +motg_device_ctrl_start(struct usbd_xfer *xfer) { - struct motg_softc *sc = xfer->pipe->device->bus->hci_private; + struct motg_softc *sc = MOTG_XFER2SC(xfer); usbd_status err; mutex_enter(&sc->sc_lock); err = motg_device_ctrl_start1(sc); mutex_exit(&sc->sc_lock); if (err != USBD_IN_PROGRESS) return err; - if (sc->sc_bus.use_polling) + if (sc->sc_bus.ub_usepolling) motg_waitintr(sc, xfer); return USBD_IN_PROGRESS; } @@ -1505,16 +1295,18 @@ static usbd_status motg_device_ctrl_start1(struct motg_softc *sc) { struct motg_hw_ep *ep = &sc->sc_in_ep[0]; - usbd_xfer_handle xfer = NULL; + struct usbd_xfer *xfer = NULL; struct motg_pipe *otgpipe; usbd_status err = 0; + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + KASSERT(mutex_owned(&sc->sc_lock)); if (sc->sc_dying) - return (USBD_IOERROR); + return USBD_IOERROR; if (!sc->sc_connected) - return (USBD_IOERROR); + return USBD_IOERROR; if (ep->xfer != NULL) { err = USBD_IN_PROGRESS; @@ -1522,10 +1314,9 @@ motg_device_ctrl_start1(struct motg_softc *sc) } /* locate the first pipe with work to do */ SIMPLEQ_FOREACH(otgpipe, &ep->ep_pipes, ep_pipe_list) { - xfer = SIMPLEQ_FIRST(&otgpipe->pipe.queue); - DPRINTFN(MD_CTRL, - ("motg_device_ctrl_start1 pipe %p xfer %p status %d\n", - otgpipe, xfer, (xfer != NULL) ? xfer->status : 0)); + xfer = SIMPLEQ_FIRST(&otgpipe->pipe.up_queue); + DPRINTFN(MD_CTRL, "pipe %p xfer %p status %d", + otgpipe, xfer, (xfer != NULL) ? xfer->ux_status : 0, 0); if (xfer != NULL) { /* move this pipe to the end of the list */ @@ -1540,32 +1331,31 @@ motg_device_ctrl_start1(struct motg_softc *sc) err = USBD_NOT_STARTED; goto end; } - xfer->status = USBD_IN_PROGRESS; - KASSERT(otgpipe == (struct motg_pipe *)xfer->pipe); + xfer->ux_status = USBD_IN_PROGRESS; + KASSERT(otgpipe == MOTG_PIPE2MPIPE(xfer->ux_pipe)); KASSERT(otgpipe->hw_ep == ep); -#ifdef DIAGNOSTIC - if (!(xfer->rqflags & URQ_REQUEST)) - panic("motg_device_ctrl_transfer: not a request"); -#endif - // KASSERT(xfer->actlen == 0); - xfer->actlen = 0; + KASSERT(xfer->ux_rqflags & URQ_REQUEST); + // KASSERT(xfer->ux_actlen == 0); + xfer->ux_actlen = 0; ep->xfer = xfer; - ep->datalen = xfer->length; + ep->datalen = xfer->ux_length; if (ep->datalen > 0) - ep->data = KERNADDR(&xfer->dmabuf, 0); + ep->data = xfer->ux_buf; else ep->data = NULL; - if ((xfer->flags & USBD_FORCE_SHORT_XFER) && + if ((xfer->ux_flags & USBD_FORCE_SHORT_XFER) && (ep->datalen % 64) == 0) ep->need_short_xfer = 1; else ep->need_short_xfer = 0; /* now we need send this request */ DPRINTFN(MD_CTRL, - ("motg_device_ctrl_start1(%p) send data %p len %d short %d speed %d to %d\n", - xfer, ep->data, ep->datalen, ep->need_short_xfer, xfer->pipe->device->speed, - xfer->pipe->device->address)); + "xfer %p send data %p len %d short %d", + xfer, ep->data, ep->datalen, ep->need_short_xfer); + DPRINTFN(MD_CTRL, + "xfer %p ... speed %d to %d", xfer->ux_pipe->up_dev->ud_speed, + xfer->ux_pipe->up_dev->ud_addr, 0, 0); KASSERT(ep->phase == IDLE); ep->phase = SETUP; /* select endpoint 0 */ @@ -1573,10 +1363,10 @@ motg_device_ctrl_start1(struct motg_softc *sc) /* fifo should be empty at this point */ KASSERT((UREAD1(sc, MUSB2_REG_TXCSRL) & MUSB2_MASK_CSR0L_TXPKTRDY) == 0); /* send data */ - // KASSERT(((vaddr_t)(&xfer->request) & 3) == 0); - KASSERT(sizeof(xfer->request) == 8); + // KASSERT(((vaddr_t)(&xfer->ux_request) & 3) == 0); + KASSERT(sizeof(xfer->ux_request) == 8); bus_space_write_multi_1(sc->sc_iot, sc->sc_ioh, MUSB2_REG_EPFIFO(0), - (void *)&xfer->request, sizeof(xfer->request)); + (void *)&xfer->ux_request, sizeof(xfer->ux_request)); motg_setup_endpoint_tx(xfer); /* start transaction */ @@ -1585,16 +1375,16 @@ motg_device_ctrl_start1(struct motg_softc *sc) end: if (err) - return (err); + return err; - return (USBD_IN_PROGRESS); + return USBD_IN_PROGRESS; } static void -motg_device_ctrl_read(usbd_xfer_handle xfer) +motg_device_ctrl_read(struct usbd_xfer *xfer) { - struct motg_softc *sc = xfer->pipe->device->bus->hci_private; - struct motg_pipe *otgpipe = (struct motg_pipe *)xfer->pipe; + struct motg_softc *sc = MOTG_XFER2SC(xfer); + struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); /* assume endpoint already selected */ motg_setup_endpoint_rx(xfer); /* start transaction */ @@ -1606,28 +1396,25 @@ static void motg_device_ctrl_intr_rx(struct motg_softc *sc) { struct motg_hw_ep *ep = &sc->sc_in_ep[0]; - usbd_xfer_handle xfer = ep->xfer; + struct usbd_xfer *xfer = ep->xfer; uint8_t csr; int datalen, max_datalen; char *data; bool got_short; usbd_status new_status = USBD_IN_PROGRESS; + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + KASSERT(mutex_owned(&sc->sc_lock)); -#ifdef DIAGNOSTIC - if (ep->phase != DATA_IN && - ep->phase != STATUS_IN) - panic("motg_device_ctrl_intr_rx: bad phase %d", ep->phase); -#endif - /* select endpoint 0 */ + KASSERT(ep->phase == DATA_IN || ep->phase != STATUS_IN); + /* select endpoint 0 */ UWRITE1(sc, MUSB2_REG_EPINDEX, 0); /* read out FIFO status */ csr = UREAD1(sc, MUSB2_REG_TXCSRL); - DPRINTFN(MD_CTRL, - ("motg_device_ctrl_intr_rx phase %d csr 0x%x xfer %p status %d\n", - ep->phase, csr, xfer, (xfer != NULL) ? xfer->status : 0)); + DPRINTFN(MD_CTRL, "phase %d csr 0x%x xfer %p status %d", + ep->phase, csr, xfer, (xfer != NULL) ? xfer->ux_status : 0); if (csr & MUSB2_MASK_CSR0L_NAKTIMO) { csr &= ~MUSB2_MASK_CSR0L_REQPKT; @@ -1650,7 +1437,7 @@ motg_device_ctrl_intr_rx(struct motg_softc *sc) if ((csr & MUSB2_MASK_CSR0L_RXPKTRDY) == 0) return; /* no data yet */ - if (xfer == NULL || xfer->status != USBD_IN_PROGRESS) + if (xfer == NULL || xfer->ux_status != USBD_IN_PROGRESS) goto complete; if (ep->phase == STATUS_IN) { @@ -1659,11 +1446,9 @@ motg_device_ctrl_intr_rx(struct motg_softc *sc) goto complete; } datalen = UREAD2(sc, MUSB2_REG_RXCOUNT); - DPRINTFN(MD_CTRL, - ("motg_device_ctrl_intr_rx phase %d datalen %d\n", - ep->phase, datalen)); - KASSERT(UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize) > 0); - max_datalen = min(UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize), + DPRINTFN(MD_CTRL, "phase %d datalen %d", ep->phase, datalen, 0, 0); + KASSERT(UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize) > 0); + max_datalen = min(UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize), ep->datalen); if (datalen > max_datalen) { new_status = USBD_IOERROR; @@ -1676,20 +1461,17 @@ motg_device_ctrl_intr_rx(struct motg_softc *sc) data = ep->data; ep->data += datalen; ep->datalen -= datalen; - xfer->actlen += datalen; + xfer->ux_actlen += datalen; if (((vaddr_t)data & 0x3) == 0 && (datalen >> 2) > 0) { - DPRINTFN(MD_CTRL, - ("motg_device_ctrl_intr_rx r4 data %p len %d\n", - data, datalen)); + DPRINTFN(MD_CTRL, "r4 data %p len %d", data, datalen, + 0, 0); bus_space_read_multi_4(sc->sc_iot, sc->sc_ioh, MUSB2_REG_EPFIFO(0), (void *)data, datalen >> 2); data += (datalen & ~0x3); datalen -= (datalen & ~0x3); } - DPRINTFN(MD_CTRL, - ("motg_device_ctrl_intr_rx r1 data %p len %d\n", - data, datalen)); + DPRINTFN(MD_CTRL, "r1 data %p len %d", data, datalen, 0, 0); if (datalen) { bus_space_read_multi_1(sc->sc_iot, sc->sc_ioh, MUSB2_REG_EPFIFO(0), data, datalen); @@ -1716,9 +1498,9 @@ motg_device_ctrl_intr_rx(struct motg_softc *sc) complete: ep->phase = IDLE; ep->xfer = NULL; - if (xfer && xfer->status == USBD_IN_PROGRESS) { + if (xfer && xfer->ux_status == USBD_IN_PROGRESS) { KASSERT(new_status != USBD_IN_PROGRESS); - xfer->status = new_status; + xfer->ux_status = new_status; usb_transfer_complete(xfer); } motg_device_ctrl_start1(sc); @@ -1728,30 +1510,29 @@ static void motg_device_ctrl_intr_tx(struct motg_softc *sc) { struct motg_hw_ep *ep = &sc->sc_in_ep[0]; - usbd_xfer_handle xfer = ep->xfer; + struct usbd_xfer *xfer = ep->xfer; uint8_t csr; int datalen; char *data; usbd_status new_status = USBD_IN_PROGRESS; + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + KASSERT(mutex_owned(&sc->sc_lock)); if (ep->phase == DATA_IN || ep->phase == STATUS_IN) { motg_device_ctrl_intr_rx(sc); return; } -#ifdef DIAGNOSTIC - if (ep->phase != SETUP && ep->phase != DATA_OUT && - ep->phase != STATUS_OUT) - panic("motg_device_ctrl_intr_tx: bad phase %d", ep->phase); -#endif - /* select endpoint 0 */ + KASSERT(ep->phase == SETUP || ep->phase == DATA_OUT || + ep->phase == STATUS_OUT); + + /* select endpoint 0 */ UWRITE1(sc, MUSB2_REG_EPINDEX, 0); csr = UREAD1(sc, MUSB2_REG_TXCSRL); - DPRINTFN(MD_CTRL, - ("motg_device_ctrl_intr_tx phase %d csr 0x%x xfer %p status %d\n", - ep->phase, csr, xfer, (xfer != NULL) ? xfer->status : 0)); + DPRINTFN(MD_CTRL, "phase %d csr 0x%x xfer %p status %d", + ep->phase, csr, xfer, (xfer != NULL) ? xfer->ux_status : 0); if (csr & MUSB2_MASK_CSR0L_RXSTALL) { /* command not accepted */ @@ -1790,9 +1571,8 @@ motg_device_ctrl_intr_tx(struct motg_softc *sc) * we have sent status and got no error; * declare transfer complete */ - DPRINTFN(MD_CTRL, - ("motg_device_ctrl_intr_tx %p status %d complete\n", - xfer, xfer->status)); + DPRINTFN(MD_CTRL, "xfer %p status %d complete", xfer, + xfer->ux_status, 0, 0); new_status = USBD_NORMAL_COMPLETION; goto complete; } @@ -1800,16 +1580,15 @@ motg_device_ctrl_intr_tx(struct motg_softc *sc) if (ep->need_short_xfer) { ep->need_short_xfer = 0; /* one more data phase */ - if (xfer->request.bmRequestType & UT_READ) { - DPRINTFN(MD_CTRL, - ("motg_device_ctrl_intr_tx %p to DATA_IN\n", xfer)); + if (xfer->ux_request.bmRequestType & UT_READ) { + DPRINTFN(MD_CTRL, "xfer %p to DATA_IN", xfer, + 0, 0, 0); motg_device_ctrl_read(xfer); return; } /* else fall back to DATA_OUT */ } else { - DPRINTFN(MD_CTRL, - ("motg_device_ctrl_intr_tx %p to STATUS_IN, csrh 0x%x\n", - xfer, UREAD1(sc, MUSB2_REG_TXCSRH))); + DPRINTFN(MD_CTRL, "xfer %p to STATUS_IN, csrh 0x%x", + xfer, UREAD1(sc, MUSB2_REG_TXCSRH), 0, 0); ep->phase = STATUS_IN; UWRITE1(sc, MUSB2_REG_RXCSRH, UREAD1(sc, MUSB2_REG_RXCSRH) | @@ -1821,22 +1600,21 @@ motg_device_ctrl_intr_tx(struct motg_softc *sc) return; } } - if (xfer->request.bmRequestType & UT_READ) { + if (xfer->ux_request.bmRequestType & UT_READ) { motg_device_ctrl_read(xfer); return; } /* setup a dataout phase */ datalen = min(ep->datalen, - UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize)); + UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize)); ep->phase = DATA_OUT; - DPRINTFN(MD_CTRL, - ("motg_device_ctrl_intr_tx %p to DATA_OUT, csrh 0x%x\n", xfer, - UREAD1(sc, MUSB2_REG_TXCSRH))); + DPRINTFN(MD_CTRL, "xfer %p to DATA_OUT, csrh 0x%x", xfer, + UREAD1(sc, MUSB2_REG_TXCSRH), 0, 0); if (datalen) { data = ep->data; ep->data += datalen; ep->datalen -= datalen; - xfer->actlen += datalen; + xfer->ux_actlen += datalen; if (((vaddr_t)data & 0x3) == 0 && (datalen >> 2) > 0) { bus_space_write_multi_4(sc->sc_iot, sc->sc_ioh, @@ -1857,9 +1635,9 @@ motg_device_ctrl_intr_tx(struct motg_softc *sc) complete: ep->phase = IDLE; ep->xfer = NULL; - if (xfer && xfer->status == USBD_IN_PROGRESS) { + if (xfer && xfer->ux_status == USBD_IN_PROGRESS) { KASSERT(new_status != USBD_IN_PROGRESS); - xfer->status = new_status; + xfer->ux_status = new_status; usb_transfer_complete(xfer); } motg_device_ctrl_start1(sc); @@ -1867,24 +1645,26 @@ complete: /* Abort a device control request. */ void -motg_device_ctrl_abort(usbd_xfer_handle xfer) +motg_device_ctrl_abort(struct usbd_xfer *xfer) { - DPRINTFN(MD_CTRL, ("motg_device_ctrl_abort:\n")); + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + motg_device_xfer_abort(xfer); } /* Close a device control pipe */ void -motg_device_ctrl_close(usbd_pipe_handle pipe) +motg_device_ctrl_close(struct usbd_pipe *pipe) { - struct motg_softc *sc __diagused = pipe->device->bus->hci_private; - struct motg_pipe *otgpipe = (struct motg_pipe *)pipe; + struct motg_softc *sc __diagused = MOTG_PIPE2SC(pipe); + struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(pipe); struct motg_pipe *otgpipeiter; - DPRINTFN(MD_CTRL, ("motg_device_ctrl_close:\n")); + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + KASSERT(mutex_owned(&sc->sc_lock)); KASSERT(otgpipe->hw_ep->xfer == NULL || - otgpipe->hw_ep->xfer->pipe != pipe); + otgpipe->hw_ep->xfer->ux_pipe != pipe); SIMPLEQ_FOREACH(otgpipeiter, &otgpipe->hw_ep->ep_pipes, ep_pipe_list) { if (otgpipeiter == otgpipe) { @@ -1900,50 +1680,54 @@ motg_device_ctrl_close(usbd_pipe_handle pipe) } void -motg_device_ctrl_done(usbd_xfer_handle xfer) +motg_device_ctrl_done(struct usbd_xfer *xfer) { - struct motg_pipe *otgpipe __diagused = (struct motg_pipe *)xfer->pipe; - DPRINTFN(MD_CTRL, ("motg_device_ctrl_done:\n")); + struct motg_pipe *otgpipe __diagused = MOTG_PIPE2MPIPE(xfer->ux_pipe); + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + KASSERT(otgpipe->hw_ep->xfer != xfer); } static usbd_status -motg_device_data_transfer(usbd_xfer_handle xfer) +motg_device_data_transfer(struct usbd_xfer *xfer) { - struct motg_softc *sc = xfer->pipe->device->bus->hci_private; + struct motg_softc *sc = MOTG_XFER2SC(xfer); usbd_status err; + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + /* Insert last in queue. */ mutex_enter(&sc->sc_lock); - DPRINTF(("motg_device_data_transfer(%p) status %d\n", - xfer, xfer->status)); + DPRINTF("xfer %p status %d", xfer, xfer->ux_status, 0, 0); err = usb_insert_transfer(xfer); - xfer->status = USBD_NOT_STARTED; + xfer->ux_status = USBD_NOT_STARTED; mutex_exit(&sc->sc_lock); if (err) - return (err); + return err; /* * Pipe isn't running (otherwise err would be USBD_INPROG), * so start it first. */ - return (motg_device_data_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return motg_device_data_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } static usbd_status -motg_device_data_start(usbd_xfer_handle xfer) +motg_device_data_start(struct usbd_xfer *xfer) { - struct motg_softc *sc = xfer->pipe->device->bus->hci_private; - struct motg_pipe *otgpipe = (struct motg_pipe *)xfer->pipe; + struct motg_softc *sc = MOTG_XFER2SC(xfer); + struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); usbd_status err; + + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + mutex_enter(&sc->sc_lock); - DPRINTF(("motg_device_data_start(%p) status %d\n", - xfer, xfer->status)); + DPRINTF("xfer %p status %d", xfer, xfer->ux_status, 0, 0); err = motg_device_data_start1(sc, otgpipe->hw_ep); mutex_exit(&sc->sc_lock); if (err != USBD_IN_PROGRESS) return err; - if (sc->sc_bus.use_polling) + if (sc->sc_bus.ub_usepolling) motg_waitintr(sc, xfer); return USBD_IN_PROGRESS; } @@ -1951,17 +1735,19 @@ motg_device_data_start(usbd_xfer_handle xfer) static usbd_status motg_device_data_start1(struct motg_softc *sc, struct motg_hw_ep *ep) { - usbd_xfer_handle xfer = NULL; + struct usbd_xfer *xfer = NULL; struct motg_pipe *otgpipe; usbd_status err = 0; uint32_t val __diagused; + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + KASSERT(mutex_owned(&sc->sc_lock)); if (sc->sc_dying) - return (USBD_IOERROR); + return USBD_IOERROR; if (!sc->sc_connected) - return (USBD_IOERROR); + return USBD_IOERROR; if (ep->xfer != NULL) { err = USBD_IN_PROGRESS; @@ -1969,10 +1755,9 @@ motg_device_data_start1(struct motg_softc *sc, struct motg_hw_ep *ep) } /* locate the first pipe with work to do */ SIMPLEQ_FOREACH(otgpipe, &ep->ep_pipes, ep_pipe_list) { - xfer = SIMPLEQ_FIRST(&otgpipe->pipe.queue); - DPRINTFN(MD_BULK, - ("motg_device_data_start1 pipe %p xfer %p status %d\n", - otgpipe, xfer, (xfer != NULL) ? xfer->status : 0)); + xfer = SIMPLEQ_FIRST(&otgpipe->pipe.up_queue); + DPRINTFN(MD_BULK, "pipe %p xfer %p status %d", otgpipe, xfer, + (xfer != NULL) ? xfer->ux_status : 0, 0); if (xfer != NULL) { /* move this pipe to the end of the list */ SIMPLEQ_REMOVE(&ep->ep_pipes, otgpipe, @@ -1986,36 +1771,34 @@ motg_device_data_start1(struct motg_softc *sc, struct motg_hw_ep *ep) err = USBD_NOT_STARTED; goto end; } - xfer->status = USBD_IN_PROGRESS; - KASSERT(otgpipe == (struct motg_pipe *)xfer->pipe); + xfer->ux_status = USBD_IN_PROGRESS; + KASSERT(otgpipe == MOTG_PIPE2MPIPE(xfer->ux_pipe)); KASSERT(otgpipe->hw_ep == ep); -#ifdef DIAGNOSTIC - if (xfer->rqflags & URQ_REQUEST) - panic("motg_device_data_transfer: a request"); -#endif - // KASSERT(xfer->actlen == 0); - xfer->actlen = 0; + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); + // KASSERT(xfer->ux_actlen == 0); + xfer->ux_actlen = 0; ep->xfer = xfer; - ep->datalen = xfer->length; + ep->datalen = xfer->ux_length; KASSERT(ep->datalen > 0); - ep->data = KERNADDR(&xfer->dmabuf, 0); - if ((xfer->flags & USBD_FORCE_SHORT_XFER) && + ep->data = xfer->ux_buf; + if ((xfer->ux_flags & USBD_FORCE_SHORT_XFER) && (ep->datalen % 64) == 0) ep->need_short_xfer = 1; else ep->need_short_xfer = 0; /* now we need send this request */ DPRINTFN(MD_BULK, - ("motg_device_data_start1(%p) %s data %p len %d short %d speed %d to %d\n", - xfer, - UE_GET_DIR(xfer->pipe->endpoint->edesc->bEndpointAddress) == UE_DIR_IN ? "read" : "write", - ep->data, ep->datalen, ep->need_short_xfer, xfer->pipe->device->speed, - xfer->pipe->device->address)); + UE_GET_DIR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN ? + "xfer %p in data %p len %d short %d" : + "xfer %p out data %p len %d short %d", + xfer, ep->data, ep->datalen, ep->need_short_xfer); + DPRINTFN(MD_BULK, "... speed %d to %d", xfer->ux_pipe->up_dev->ud_speed, + xfer->ux_pipe->up_dev->ud_addr, 0, 0); KASSERT(ep->phase == IDLE); /* select endpoint */ UWRITE1(sc, MUSB2_REG_EPINDEX, ep->ep_number); - if (UE_GET_DIR(xfer->pipe->endpoint->edesc->bEndpointAddress) + if (UE_GET_DIR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN) { val = UREAD1(sc, MUSB2_REG_RXCSRL); KASSERT((val & MUSB2_MASK_CSRL_RXPKTRDY) == 0); @@ -2028,24 +1811,26 @@ motg_device_data_start1(struct motg_softc *sc, struct motg_hw_ep *ep) } end: if (err) - return (err); + return err; - return (USBD_IN_PROGRESS); + return USBD_IN_PROGRESS; } static void -motg_device_data_read(usbd_xfer_handle xfer) +motg_device_data_read(struct usbd_xfer *xfer) { - struct motg_softc *sc = xfer->pipe->device->bus->hci_private; - struct motg_pipe *otgpipe = (struct motg_pipe *)xfer->pipe; + struct motg_softc *sc = MOTG_XFER2SC(xfer); + struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); uint32_t val; + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + KASSERT(mutex_owned(&sc->sc_lock)); /* assume endpoint already selected */ motg_setup_endpoint_rx(xfer); /* Max packet size */ UWRITE2(sc, MUSB2_REG_RXMAXP, - UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize)); + UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize)); /* Data Toggle */ val = UREAD1(sc, MUSB2_REG_RXCSRH); val |= MUSB2_MASK_CSRH_RXDT_WREN; @@ -2055,40 +1840,40 @@ motg_device_data_read(usbd_xfer_handle xfer) val &= ~MUSB2_MASK_CSRH_RXDT_VAL; UWRITE1(sc, MUSB2_REG_RXCSRH, val); - DPRINTFN(MD_BULK, - ("motg_device_data_read %p to DATA_IN on ep %d, csrh 0x%x\n", - xfer, otgpipe->hw_ep->ep_number, UREAD1(sc, MUSB2_REG_RXCSRH))); + DPRINTFN(MD_BULK, "%p to DATA_IN on ep %d, csrh 0x%x", + xfer, otgpipe->hw_ep->ep_number, UREAD1(sc, MUSB2_REG_RXCSRH), 0); /* start transaction */ UWRITE1(sc, MUSB2_REG_RXCSRL, MUSB2_MASK_CSRL_RXREQPKT); otgpipe->hw_ep->phase = DATA_IN; } static void -motg_device_data_write(usbd_xfer_handle xfer) +motg_device_data_write(struct usbd_xfer *xfer) { - struct motg_softc *sc = xfer->pipe->device->bus->hci_private; - struct motg_pipe *otgpipe = (struct motg_pipe *)xfer->pipe; + struct motg_softc *sc = MOTG_XFER2SC(xfer); + struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); struct motg_hw_ep *ep = otgpipe->hw_ep; int datalen; char *data; uint32_t val; + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + KASSERT(xfer!=NULL); KASSERT(mutex_owned(&sc->sc_lock)); datalen = min(ep->datalen, - UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize)); + UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize)); ep->phase = DATA_OUT; - DPRINTFN(MD_BULK, - ("motg_device_data_write %p to DATA_OUT on ep %d, len %d csrh 0x%x\n", - xfer, ep->ep_number, datalen, UREAD1(sc, MUSB2_REG_TXCSRH))); + DPRINTFN(MD_BULK, "%p to DATA_OUT on ep %d, len %d csrh 0x%x", + xfer, ep->ep_number, datalen, UREAD1(sc, MUSB2_REG_TXCSRH)); /* assume endpoint already selected */ /* write data to fifo */ data = ep->data; ep->data += datalen; ep->datalen -= datalen; - xfer->actlen += datalen; + xfer->ux_actlen += datalen; if (((vaddr_t)data & 0x3) == 0 && (datalen >> 2) > 0) { bus_space_write_multi_4(sc->sc_iot, sc->sc_ioh, @@ -2105,7 +1890,7 @@ motg_device_data_write(usbd_xfer_handle xfer) motg_setup_endpoint_tx(xfer); /* Max packet size */ UWRITE2(sc, MUSB2_REG_TXMAXP, - UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize)); + UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize)); /* Data Toggle */ val = UREAD1(sc, MUSB2_REG_TXCSRH); val |= MUSB2_MASK_CSRH_TXDT_WREN; @@ -2123,35 +1908,31 @@ static void motg_device_intr_rx(struct motg_softc *sc, int epnumber) { struct motg_hw_ep *ep = &sc->sc_in_ep[epnumber]; - usbd_xfer_handle xfer = ep->xfer; + struct usbd_xfer *xfer = ep->xfer; uint8_t csr; int datalen, max_datalen; char *data; bool got_short; usbd_status new_status = USBD_IN_PROGRESS; + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + KASSERT(mutex_owned(&sc->sc_lock)); KASSERT(ep->ep_number == epnumber); - DPRINTFN(MD_BULK, - ("motg_device_intr_rx on ep %d\n", epnumber)); - /* select endpoint */ + DPRINTFN(MD_BULK, "on ep %d", epnumber, 0, 0, 0); + /* select endpoint */ UWRITE1(sc, MUSB2_REG_EPINDEX, epnumber); /* read out FIFO status */ csr = UREAD1(sc, MUSB2_REG_RXCSRL); - DPRINTFN(MD_BULK, - ("motg_device_intr_rx phase %d csr 0x%x\n", - ep->phase, csr)); + DPRINTFN(MD_BULK, "phase %d csr 0x%x", ep->phase, csr ,0 ,0); if ((csr & (MUSB2_MASK_CSRL_RXNAKTO | MUSB2_MASK_CSRL_RXSTALL | MUSB2_MASK_CSRL_RXERROR | MUSB2_MASK_CSRL_RXPKTRDY)) == 0) return; -#ifdef DIAGNOSTIC - if (ep->phase != DATA_IN) - panic("motg_device_intr_rx: bad phase %d", ep->phase); -#endif + KASSERTMSG(ep->phase == DATA_IN, "phase %d", ep->phase); if (csr & MUSB2_MASK_CSRL_RXNAKTO) { csr &= ~MUSB2_MASK_CSRL_RXREQPKT; UWRITE1(sc, MUSB2_REG_RXCSRL, csr); @@ -2172,21 +1953,19 @@ motg_device_intr_rx(struct motg_softc *sc, int epnumber) } KASSERT(csr & MUSB2_MASK_CSRL_RXPKTRDY); - if (xfer == NULL || xfer->status != USBD_IN_PROGRESS) { + if (xfer == NULL || xfer->ux_status != USBD_IN_PROGRESS) { UWRITE1(sc, MUSB2_REG_RXCSRL, 0); goto complete; } - struct motg_pipe *otgpipe = (struct motg_pipe *)xfer->pipe; + struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); otgpipe->nexttoggle = otgpipe->nexttoggle ^ 1; datalen = UREAD2(sc, MUSB2_REG_RXCOUNT); - DPRINTFN(MD_BULK, - ("motg_device_intr_rx phase %d datalen %d\n", - ep->phase, datalen)); - KASSERT(UE_GET_SIZE(UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize)) > 0); + DPRINTFN(MD_BULK, "phase %d datalen %d", ep->phase, datalen ,0 ,0); + KASSERT(UE_GET_SIZE(UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize)) > 0); max_datalen = min( - UE_GET_SIZE(UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize)), + UE_GET_SIZE(UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize)), ep->datalen); if (datalen > max_datalen) { new_status = USBD_IOERROR; @@ -2199,21 +1978,18 @@ motg_device_intr_rx(struct motg_softc *sc, int epnumber) data = ep->data; ep->data += datalen; ep->datalen -= datalen; - xfer->actlen += datalen; + xfer->ux_actlen += datalen; if (((vaddr_t)data & 0x3) == 0 && (datalen >> 2) > 0) { - DPRINTFN(MD_BULK, - ("motg_device_intr_rx r4 data %p len %d\n", - data, datalen)); + DPRINTFN(MD_BULK, "r4 data %p len %d", data, datalen, + 0, 0); bus_space_read_multi_4(sc->sc_iot, sc->sc_ioh, MUSB2_REG_EPFIFO(ep->ep_number), (void *)data, datalen >> 2); data += (datalen & ~0x3); datalen -= (datalen & ~0x3); } - DPRINTFN(MD_BULK, - ("motg_device_intr_rx r1 data %p len %d\n", - data, datalen)); + DPRINTFN(MD_BULK, "r1 data %p len %d", data, datalen ,0 ,0); if (datalen) { bus_space_read_multi_1(sc->sc_iot, sc->sc_ioh, MUSB2_REG_EPFIFO(ep->ep_number), data, datalen); @@ -2231,14 +2007,13 @@ motg_device_intr_rx(struct motg_softc *sc, int epnumber) motg_device_data_read(xfer); return; complete: - DPRINTFN(MD_BULK, - ("motg_device_intr_rx xfer %p complete, status %d\n", xfer, - (xfer != NULL) ? xfer->status : 0)); + DPRINTFN(MD_BULK, "xfer %p complete, status %d", xfer, + (xfer != NULL) ? xfer->ux_status : 0, 0, 0); ep->phase = IDLE; ep->xfer = NULL; - if (xfer && xfer->status == USBD_IN_PROGRESS) { + if (xfer && xfer->ux_status == USBD_IN_PROGRESS) { KASSERT(new_status != USBD_IN_PROGRESS); - xfer->status = new_status; + xfer->ux_status = new_status; usb_transfer_complete(xfer); } motg_device_data_start1(sc, ep); @@ -2248,23 +2023,22 @@ static void motg_device_intr_tx(struct motg_softc *sc, int epnumber) { struct motg_hw_ep *ep = &sc->sc_out_ep[epnumber]; - usbd_xfer_handle xfer = ep->xfer; + struct usbd_xfer *xfer = ep->xfer; uint8_t csr; struct motg_pipe *otgpipe; usbd_status new_status = USBD_IN_PROGRESS; + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + KASSERT(mutex_owned(&sc->sc_lock)); KASSERT(ep->ep_number == epnumber); - DPRINTFN(MD_BULK, - ("motg_device_intr_tx on ep %d\n", epnumber)); - /* select endpoint */ + DPRINTFN(MD_BULK, " on ep %d", epnumber, 0, 0, 0); + /* select endpoint */ UWRITE1(sc, MUSB2_REG_EPINDEX, epnumber); csr = UREAD1(sc, MUSB2_REG_TXCSRL); - DPRINTFN(MD_BULK, - ("motg_device_intr_tx phase %d csr 0x%x\n", - ep->phase, csr)); + DPRINTFN(MD_BULK, "phase %d csr 0x%x", ep->phase, csr, 0, 0); if (csr & (MUSB2_MASK_CSRL_TXSTALLED|MUSB2_MASK_CSRL_TXERROR)) { /* command not accepted */ @@ -2287,8 +2061,8 @@ motg_device_intr_tx(struct motg_softc *sc, int epnumber) UWRITE1(sc, MUSB2_REG_TXCSRL, csr); delay(1000); csr = UREAD1(sc, MUSB2_REG_TXCSRL); - DPRINTFN(MD_BULK, ("TX fifo flush ep %d CSR 0x%x\n", - epnumber, csr)); + DPRINTFN(MD_BULK, "TX fifo flush ep %d CSR 0x%x", + epnumber, csr, 0, 0); } goto complete; } @@ -2296,14 +2070,11 @@ motg_device_intr_tx(struct motg_softc *sc, int epnumber) /* data still not sent */ return; } - if (xfer == NULL || xfer->status != USBD_IN_PROGRESS) + if (xfer == NULL || xfer->ux_status != USBD_IN_PROGRESS) goto complete; -#ifdef DIAGNOSTIC - if (ep->phase != DATA_OUT) - panic("motg_device_intr_tx: bad phase %d", ep->phase); -#endif + KASSERT(ep->phase == DATA_OUT); - otgpipe = (struct motg_pipe *)xfer->pipe; + otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); otgpipe->nexttoggle = otgpipe->nexttoggle ^ 1; if (ep->datalen == 0) { @@ -2319,18 +2090,17 @@ motg_device_intr_tx(struct motg_softc *sc, int epnumber) return; complete: - DPRINTFN(MD_BULK, - ("motg_device_intr_tx xfer %p complete, status %d\n", xfer, - (xfer != NULL) ? xfer->status : 0)); + DPRINTFN(MD_BULK, "xfer %p complete, status %d", xfer, + (xfer != NULL) ? xfer->ux_status : 0, 0, 0); #ifdef DIAGNOSTIC - if (xfer && xfer->status == USBD_IN_PROGRESS && ep->phase != DATA_OUT) + if (xfer && xfer->ux_status == USBD_IN_PROGRESS && ep->phase != DATA_OUT) panic("motg_device_intr_tx: bad phase %d", ep->phase); #endif ep->phase = IDLE; ep->xfer = NULL; - if (xfer && xfer->status == USBD_IN_PROGRESS) { + if (xfer && xfer->ux_status == USBD_IN_PROGRESS) { KASSERT(new_status != USBD_IN_PROGRESS); - xfer->status = new_status; + xfer->ux_status = new_status; usb_transfer_complete(xfer); } motg_device_data_start1(sc, ep); @@ -2338,31 +2108,31 @@ complete: /* Abort a device control request. */ void -motg_device_data_abort(usbd_xfer_handle xfer) +motg_device_data_abort(struct usbd_xfer *xfer) { -#ifdef DIAGNOSTIC - struct motg_softc *sc = xfer->pipe->device->bus->hci_private; -#endif + struct motg_softc __diagused *sc = MOTG_XFER2SC(xfer); KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTFN(MD_BULK, ("motg_device_data_abort:\n")); + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + motg_device_xfer_abort(xfer); } /* Close a device control pipe */ void -motg_device_data_close(usbd_pipe_handle pipe) +motg_device_data_close(struct usbd_pipe *pipe) { - struct motg_softc *sc __diagused = pipe->device->bus->hci_private; - struct motg_pipe *otgpipe = (struct motg_pipe *)pipe; + struct motg_softc *sc __diagused = MOTG_PIPE2SC(pipe); + struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(pipe); struct motg_pipe *otgpipeiter; - DPRINTFN(MD_CTRL, ("motg_device_data_close:\n")); + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + KASSERT(mutex_owned(&sc->sc_lock)); KASSERT(otgpipe->hw_ep->xfer == NULL || - otgpipe->hw_ep->xfer->pipe != pipe); + otgpipe->hw_ep->xfer->ux_pipe != pipe); - pipe->endpoint->datatoggle = otgpipe->nexttoggle; + pipe->up_endpoint->ue_toggle = otgpipe->nexttoggle; SIMPLEQ_FOREACH(otgpipeiter, &otgpipe->hw_ep->ep_pipes, ep_pipe_list) { if (otgpipeiter == otgpipe) { /* remove from list */ @@ -2377,10 +2147,11 @@ motg_device_data_close(usbd_pipe_handle pipe) } void -motg_device_data_done(usbd_xfer_handle xfer) +motg_device_data_done(struct usbd_xfer *xfer) { - struct motg_pipe *otgpipe __diagused = (struct motg_pipe *)xfer->pipe; - DPRINTFN(MD_CTRL, ("motg_device_data_done:\n")); + struct motg_pipe *otgpipe __diagused = MOTG_PIPE2MPIPE(xfer->ux_pipe); + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + KASSERT(otgpipe->hw_ep->xfer != xfer); } @@ -2391,13 +2162,14 @@ motg_device_data_done(usbd_xfer_handle xfer) * Only used during boot when interrupts are not enabled yet. */ void -motg_waitintr(struct motg_softc *sc, usbd_xfer_handle xfer) +motg_waitintr(struct motg_softc *sc, struct usbd_xfer *xfer) { - int timo = xfer->timeout; + int timo = xfer->ux_timeout; + MOTGHIST_FUNC(); MOTGHIST_CALLED(); mutex_enter(&sc->sc_lock); - DPRINTF(("motg_waitintr: timeout = %dms\n", timo)); + DPRINTF("timeout = %dms", timo, 0, 0, 0); for (; timo >= 0; timo--) { mutex_exit(&sc->sc_lock); @@ -2406,12 +2178,12 @@ motg_waitintr(struct motg_softc *sc, usbd_xfer_handle xfer) motg_poll(&sc->sc_bus); mutex_spin_exit(&sc->sc_intr_lock); mutex_enter(&sc->sc_lock); - if (xfer->status != USBD_IN_PROGRESS) + if (xfer->ux_status != USBD_IN_PROGRESS) goto done; } /* Timeout */ - DPRINTF(("motg_waitintr: timeout\n")); + DPRINTF("timeout", 0, 0, 0, 0); panic("motg_waitintr: timeout"); /* XXX handle timeout ! */ @@ -2420,33 +2192,34 @@ done: } void -motg_device_clear_toggle(usbd_pipe_handle pipe) +motg_device_clear_toggle(struct usbd_pipe *pipe) { - struct motg_pipe *otgpipe = (struct motg_pipe *)pipe; + struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(pipe); otgpipe->nexttoggle = 0; } /* Abort a device control request. */ static void -motg_device_xfer_abort(usbd_xfer_handle xfer) +motg_device_xfer_abort(struct usbd_xfer *xfer) { int wake; uint8_t csr; - struct motg_softc *sc = xfer->pipe->device->bus->hci_private; - struct motg_pipe *otgpipe = (struct motg_pipe *)xfer->pipe; + struct motg_softc *sc = MOTG_XFER2SC(xfer); + struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTF(("motg_device_xfer_abort:\n")); - if (xfer->hcflags & UXFER_ABORTING) { - DPRINTF(("motg_device_xfer_abort: already aborting\n")); - xfer->hcflags |= UXFER_ABORTWAIT; - while (xfer->hcflags & UXFER_ABORTING) - cv_wait(&xfer->hccv, &sc->sc_lock); + MOTGHIST_FUNC(); MOTGHIST_CALLED(); + + if (xfer->ux_hcflags & UXFER_ABORTING) { + DPRINTF("already aborting", 0, 0, 0, 0); + xfer->ux_hcflags |= UXFER_ABORTWAIT; + while (xfer->ux_hcflags & UXFER_ABORTING) + cv_wait(&xfer->ux_hccv, &sc->sc_lock); return; } - xfer->hcflags |= UXFER_ABORTING; + xfer->ux_hcflags |= UXFER_ABORTING; if (otgpipe->hw_ep->xfer == xfer) { - KASSERT(xfer->status == USBD_IN_PROGRESS); + KASSERT(xfer->ux_status == USBD_IN_PROGRESS); otgpipe->hw_ep->xfer = NULL; if (otgpipe->hw_ep->ep_number > 0) { /* select endpoint */ @@ -2472,10 +2245,10 @@ motg_device_xfer_abort(usbd_xfer_handle xfer) otgpipe->hw_ep->phase = IDLE; } } - xfer->status = USBD_CANCELLED; /* make software ignore it */ - wake = xfer->hcflags & UXFER_ABORTWAIT; - xfer->hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); + xfer->ux_status = USBD_CANCELLED; /* make software ignore it */ + wake = xfer->ux_hcflags & UXFER_ABORTWAIT; + xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); usb_transfer_complete(xfer); if (wake) - cv_broadcast(&xfer->hccv); + cv_broadcast(&xfer->ux_hccv); } diff --git a/sys/dev/usb/motgvar.h b/sys/dev/usb/motgvar.h index 55ad3b28c42..80b7f47cb5c 100644 --- a/sys/dev/usb/motgvar.h +++ b/sys/dev/usb/motgvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: motgvar.h,v 1.4 2014/09/13 18:36:39 jmcneill Exp $ */ +/* $NetBSD: motgvar.h,v 1.5 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ struct motg_pipe { struct usbd_pipe pipe; int nexttoggle; struct motg_hw_ep *hw_ep; /* pointer to the hardware EP used */ - SIMPLEQ_ENTRY(motg_pipe) ep_pipe_list; + SIMPLEQ_ENTRY(motg_pipe) ep_pipe_list; }; /* description of a hardware endpoint */ @@ -54,7 +54,7 @@ SIMPLEQ_HEAD(ep_pipes_head, motg_pipe); struct motg_hw_ep { int ep_number; int ep_fifo_size; - usbd_xfer_handle xfer; /* active xfer on this EP */ + struct usbd_xfer *xfer; /* active xfer on this EP */ char *data; /* pointer to data to be transmitted/received */ int datalen; /* data len to be transmitted */ usb_phase_t phase; /* current phase of the transfer, if any */ @@ -85,8 +85,6 @@ struct motg_softc { struct motg_hw_ep sc_in_ep[MOTG_MAX_HW_EP]; struct motg_hw_ep sc_out_ep[MOTG_MAX_HW_EP]; - struct usb_dma_reserve sc_dma_reserve; - kmutex_t sc_lock; kmutex_t sc_intr_lock; int sc_dying; @@ -94,9 +92,7 @@ struct motg_softc { pool_cache_t sc_xferpool; /* Info for the root hub interrupt "pipe". */ - usbd_xfer_handle sc_intr_xfer; /* root hub interrupt transfer */ - uint8_t sc_root_addr; /* address of the root hub */ - uint8_t sc_root_conf; /* configuration of the root hub */ + struct usbd_xfer *sc_intr_xfer; /* root hub interrupt transfer */ char sc_vendor[32]; /* vendor string for root hub */ int sc_id_vendor; /* vendor ID for root hub */ @@ -115,13 +111,17 @@ struct motg_softc { struct motg_xfer { struct usbd_xfer xfer; - struct motg_softc *sc; }; -#define UXFER(xfer) ((struct motg_xfer *)(xfer)) +#define MOTG_BUS2SC(bus) ((bus)->ub_hcpriv) +#define MOTG_PIPE2SC(pipe) MOTG_BUS2SC((pipe)->up_dev->ud_bus) +#define MOTG_XFER2SC(xfer) MOTG_BUS2SC((xfer)->ux_bus) +#define MOTG_MPIPE2SC(mpipe) MOTG_BUS2SC((mpipe)->pipe.up_dev->ud_bus) +#define MOTG_XFER2MXFER(xfer) ((struct motg_xfer *)(xfer)) +#define MOTG_PIPE2MPIPE(pipe) ((struct motg_pipe *)(pipe)) -usbd_status motg_init(struct motg_softc *); +int motg_init(struct motg_softc *); int motg_intr(struct motg_softc *, uint16_t, uint16_t, uint8_t); int motg_intr_vbus(struct motg_softc *, int); int motg_detach(struct motg_softc *, int); diff --git a/sys/dev/usb/ohci.c b/sys/dev/usb/ohci.c index dc2a3140468..fd5e8e5d269 100644 --- a/sys/dev/usb/ohci.c +++ b/sys/dev/usb/ohci.c @@ -1,4 +1,4 @@ -/* $NetBSD: ohci.c,v 1.259 2016/03/13 07:01:43 skrll Exp $ */ +/* $NetBSD: ohci.c,v 1.260 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998, 2004, 2005, 2012 The NetBSD Foundation, Inc. @@ -41,17 +41,21 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.259 2016/03/13 07:01:43 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.260 2016/04/23 10:15:32 skrll Exp $"); + +#include "opt_usb.h" #include <sys/param.h> -#include <sys/systm.h> -#include <sys/kmem.h> -#include <sys/kernel.h> + +#include <sys/cpu.h> #include <sys/device.h> -#include <sys/select.h> +#include <sys/kernel.h> +#include <sys/kmem.h> #include <sys/proc.h> #include <sys/queue.h> -#include <sys/cpu.h> +#include <sys/select.h> +#include <sys/sysctl.h> +#include <sys/systm.h> #include <machine/endian.h> @@ -63,18 +67,49 @@ __KERNEL_RCSID(0, "$NetBSD: ohci.c,v 1.259 2016/03/13 07:01:43 skrll Exp $"); #include <dev/usb/ohcireg.h> #include <dev/usb/ohcivar.h> -#include <dev/usb/usbroothub_subr.h> +#include <dev/usb/usbroothub.h> +#include <dev/usb/usbhist.h> +#ifdef USB_DEBUG +#ifndef OHCI_DEBUG +#define ohcidebug 0 +#else +static int ohcidebug = 10; +SYSCTL_SETUP(sysctl_hw_ohci_setup, "sysctl hw.ohci setup") +{ + int err; + const struct sysctlnode *rnode; + const struct sysctlnode *cnode; -#ifdef OHCI_DEBUG -#define DPRINTF(x) if (ohcidebug) printf x -#define DPRINTFN(n,x) if (ohcidebug>(n)) printf x -int ohcidebug = 0; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif + err = sysctl_createv(clog, 0, NULL, &rnode, + CTLFLAG_PERMANENT, CTLTYPE_NODE, "ohci", + SYSCTL_DESCR("ohci global controls"), + NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); + + if (err) + goto fail; + + /* control debugging printfs */ + err = sysctl_createv(clog, 0, &rnode, &cnode, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, + "debug", SYSCTL_DESCR("Enable debugging output"), + NULL, 0, &ohcidebug, sizeof(ohcidebug), CTL_CREATE, CTL_EOL); + if (err) + goto fail; + + return; +fail: + aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); +} + +#endif /* OHCI_DEBUG */ +#endif /* USB_DEBUG */ + +#define DPRINTF(FMT,A,B,C,D) USBHIST_LOG(ohcidebug,FMT,A,B,C,D) +#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(ohcidebug,N,FMT,A,B,C,D) +#define OHCIHIST_FUNC() USBHIST_FUNC() +#define OHCIHIST_CALLED(name) USBHIST_CALLED(ohcidebug) #if BYTE_ORDER == BIG_ENDIAN #define SWAP_ENDIAN OHCI_LITTLE_ENDIAN @@ -94,24 +129,27 @@ Static void ohci_free_sed(ohci_softc_t *, ohci_soft_ed_t *); Static ohci_soft_td_t *ohci_alloc_std(ohci_softc_t *); Static void ohci_free_std(ohci_softc_t *, ohci_soft_td_t *); +Static void ohci_free_std_locked(ohci_softc_t *, ohci_soft_td_t *); Static ohci_soft_itd_t *ohci_alloc_sitd(ohci_softc_t *); Static void ohci_free_sitd(ohci_softc_t *,ohci_soft_itd_t *); +Static void ohci_free_sitd_locked(ohci_softc_t *, + ohci_soft_itd_t *); + +Static int ohci_alloc_std_chain(ohci_softc_t *, struct usbd_xfer *, + int, int); +Static void ohci_free_stds(ohci_softc_t *, struct ohci_xfer *); -Static void ohci_free_std_chain(ohci_softc_t *, ohci_soft_td_t *, - ohci_soft_td_t *); -Static usbd_status ohci_alloc_std_chain(struct ohci_pipe *, - ohci_softc_t *, int, int, usbd_xfer_handle, - ohci_soft_td_t *, ohci_soft_td_t **); +Static void ohci_reset_std_chain(ohci_softc_t *, struct usbd_xfer *, + int, int, ohci_soft_td_t *, ohci_soft_td_t **); -Static usbd_status ohci_open(usbd_pipe_handle); +Static usbd_status ohci_open(struct usbd_pipe *); Static void ohci_poll(struct usbd_bus *); Static void ohci_softintr(void *); -Static void ohci_waitintr(ohci_softc_t *, usbd_xfer_handle); -Static void ohci_rhsc(ohci_softc_t *, usbd_xfer_handle); -Static void ohci_rhsc_softint(void *arg); +Static void ohci_waitintr(ohci_softc_t *, struct usbd_xfer *); +Static void ohci_rhsc(ohci_softc_t *, struct usbd_xfer *); +Static void ohci_rhsc_softint(void *); -Static usbd_status ohci_device_request(usbd_xfer_handle xfer); Static void ohci_add_ed(ohci_softc_t *, ohci_soft_ed_t *, ohci_soft_ed_t *); @@ -124,64 +162,65 @@ Static void ohci_hash_add_itd(ohci_softc_t *, ohci_soft_itd_t *); Static void ohci_hash_rem_itd(ohci_softc_t *, ohci_soft_itd_t *); Static ohci_soft_itd_t *ohci_hash_find_itd(ohci_softc_t *, ohci_physaddr_t); -Static usbd_status ohci_setup_isoc(usbd_pipe_handle pipe); -Static void ohci_device_isoc_enter(usbd_xfer_handle); - -Static usbd_status ohci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t); -Static void ohci_freem(struct usbd_bus *, usb_dma_t *); +Static usbd_status ohci_setup_isoc(struct usbd_pipe *); +Static void ohci_device_isoc_enter(struct usbd_xfer *); -Static usbd_xfer_handle ohci_allocx(struct usbd_bus *); -Static void ohci_freex(struct usbd_bus *, usbd_xfer_handle); +Static struct usbd_xfer * + ohci_allocx(struct usbd_bus *, unsigned int); +Static void ohci_freex(struct usbd_bus *, struct usbd_xfer *); Static void ohci_get_lock(struct usbd_bus *, kmutex_t **); - -Static usbd_status ohci_root_ctrl_transfer(usbd_xfer_handle); -Static usbd_status ohci_root_ctrl_start(usbd_xfer_handle); -Static void ohci_root_ctrl_abort(usbd_xfer_handle); -Static void ohci_root_ctrl_close(usbd_pipe_handle); -Static void ohci_root_ctrl_done(usbd_xfer_handle); - -Static usbd_status ohci_root_intr_transfer(usbd_xfer_handle); -Static usbd_status ohci_root_intr_start(usbd_xfer_handle); -Static void ohci_root_intr_abort(usbd_xfer_handle); -Static void ohci_root_intr_close(usbd_pipe_handle); -Static void ohci_root_intr_done(usbd_xfer_handle); - -Static usbd_status ohci_device_ctrl_transfer(usbd_xfer_handle); -Static usbd_status ohci_device_ctrl_start(usbd_xfer_handle); -Static void ohci_device_ctrl_abort(usbd_xfer_handle); -Static void ohci_device_ctrl_close(usbd_pipe_handle); -Static void ohci_device_ctrl_done(usbd_xfer_handle); - -Static usbd_status ohci_device_bulk_transfer(usbd_xfer_handle); -Static usbd_status ohci_device_bulk_start(usbd_xfer_handle); -Static void ohci_device_bulk_abort(usbd_xfer_handle); -Static void ohci_device_bulk_close(usbd_pipe_handle); -Static void ohci_device_bulk_done(usbd_xfer_handle); - -Static usbd_status ohci_device_intr_transfer(usbd_xfer_handle); -Static usbd_status ohci_device_intr_start(usbd_xfer_handle); -Static void ohci_device_intr_abort(usbd_xfer_handle); -Static void ohci_device_intr_close(usbd_pipe_handle); -Static void ohci_device_intr_done(usbd_xfer_handle); - -Static usbd_status ohci_device_isoc_transfer(usbd_xfer_handle); -Static usbd_status ohci_device_isoc_start(usbd_xfer_handle); -Static void ohci_device_isoc_abort(usbd_xfer_handle); -Static void ohci_device_isoc_close(usbd_pipe_handle); -Static void ohci_device_isoc_done(usbd_xfer_handle); - -Static usbd_status ohci_device_setintr(ohci_softc_t *sc, - struct ohci_pipe *pipe, int ival); +Static int ohci_roothub_ctrl(struct usbd_bus *, + usb_device_request_t *, void *, int); + +Static usbd_status ohci_root_intr_transfer(struct usbd_xfer *); +Static usbd_status ohci_root_intr_start(struct usbd_xfer *); +Static void ohci_root_intr_abort(struct usbd_xfer *); +Static void ohci_root_intr_close(struct usbd_pipe *); +Static void ohci_root_intr_done(struct usbd_xfer *); + +Static int ohci_device_ctrl_init(struct usbd_xfer *); +Static void ohci_device_ctrl_fini(struct usbd_xfer *); +Static usbd_status ohci_device_ctrl_transfer(struct usbd_xfer *); +Static usbd_status ohci_device_ctrl_start(struct usbd_xfer *); +Static void ohci_device_ctrl_abort(struct usbd_xfer *); +Static void ohci_device_ctrl_close(struct usbd_pipe *); +Static void ohci_device_ctrl_done(struct usbd_xfer *); + +Static int ohci_device_bulk_init(struct usbd_xfer *); +Static void ohci_device_bulk_fini(struct usbd_xfer *); +Static usbd_status ohci_device_bulk_transfer(struct usbd_xfer *); +Static usbd_status ohci_device_bulk_start(struct usbd_xfer *); +Static void ohci_device_bulk_abort(struct usbd_xfer *); +Static void ohci_device_bulk_close(struct usbd_pipe *); +Static void ohci_device_bulk_done(struct usbd_xfer *); + +Static int ohci_device_intr_init(struct usbd_xfer *); +Static void ohci_device_intr_fini(struct usbd_xfer *); +Static usbd_status ohci_device_intr_transfer(struct usbd_xfer *); +Static usbd_status ohci_device_intr_start(struct usbd_xfer *); +Static void ohci_device_intr_abort(struct usbd_xfer *); +Static void ohci_device_intr_close(struct usbd_pipe *); +Static void ohci_device_intr_done(struct usbd_xfer *); + +Static int ohci_device_isoc_init(struct usbd_xfer *); +Static void ohci_device_isoc_fini(struct usbd_xfer *); +Static usbd_status ohci_device_isoc_transfer(struct usbd_xfer *); +Static void ohci_device_isoc_abort(struct usbd_xfer *); +Static void ohci_device_isoc_close(struct usbd_pipe *); +Static void ohci_device_isoc_done(struct usbd_xfer *); + +Static usbd_status ohci_device_setintr(ohci_softc_t *, + struct ohci_pipe *, int); Static void ohci_timeout(void *); Static void ohci_timeout_task(void *); Static void ohci_rhsc_enable(void *); -Static void ohci_close_pipe(usbd_pipe_handle, ohci_soft_ed_t *); -Static void ohci_abort_xfer(usbd_xfer_handle, usbd_status); +Static void ohci_close_pipe(struct usbd_pipe *, ohci_soft_ed_t *); +Static void ohci_abort_xfer(struct usbd_xfer *, usbd_status); -Static void ohci_device_clear_toggle(usbd_pipe_handle pipe); -Static void ohci_noop(usbd_pipe_handle pipe); +Static void ohci_device_clear_toggle(struct usbd_pipe *); +Static void ohci_noop(struct usbd_pipe *); #ifdef OHCI_DEBUG Static void ohci_dumpregs(ohci_softc_t *); @@ -210,7 +249,7 @@ OREAD4(ohci_softc_t *sc, bus_size_t r) } /* Reverse the bits in a value 0 .. 31 */ -Static u_int8_t revbits[OHCI_NO_INTRS] = +Static uint8_t revbits[OHCI_NO_INTRS] = { 0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0c, 0x1c, 0x02, 0x12, 0x0a, 0x1a, 0x06, 0x16, 0x0e, 0x1e, 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d, @@ -228,92 +267,79 @@ struct ohci_pipe { /* Control pipe */ struct { usb_dma_t reqdma; - u_int length; - ohci_soft_td_t *setup, *data, *stat; - } ctl; + } ctrl; /* Interrupt pipe */ struct { int nslots; int pos; } intr; - /* Bulk pipe */ - struct { - u_int length; - int isread; - } bulk; - /* Iso pipe */ - struct iso { + /* Isochronous pipe */ + struct isoc { int next, inuse; - } iso; - } u; + } isoc; + }; }; -#define OHCI_INTR_ENDPT 1 - Static const struct usbd_bus_methods ohci_bus_methods = { - .open_pipe = ohci_open, - .soft_intr = ohci_softintr, - .do_poll = ohci_poll, - .allocm = ohci_allocm, - .freem = ohci_freem, - .allocx = ohci_allocx, - .freex = ohci_freex, - .get_lock = ohci_get_lock, - .new_device = NULL, -}; - -Static const struct usbd_pipe_methods ohci_root_ctrl_methods = { - .transfer = ohci_root_ctrl_transfer, - .start = ohci_root_ctrl_start, - .abort = ohci_root_ctrl_abort, - .close = ohci_root_ctrl_close, - .cleartoggle = ohci_noop, - .done = ohci_root_ctrl_done, + .ubm_open = ohci_open, + .ubm_softint = ohci_softintr, + .ubm_dopoll = ohci_poll, + .ubm_allocx = ohci_allocx, + .ubm_freex = ohci_freex, + .ubm_getlock = ohci_get_lock, + .ubm_rhctrl = ohci_roothub_ctrl, }; Static const struct usbd_pipe_methods ohci_root_intr_methods = { - .transfer = ohci_root_intr_transfer, - .start = ohci_root_intr_start, - .abort = ohci_root_intr_abort, - .close = ohci_root_intr_close, - .cleartoggle = ohci_noop, - .done = ohci_root_intr_done, + .upm_transfer = ohci_root_intr_transfer, + .upm_start = ohci_root_intr_start, + .upm_abort = ohci_root_intr_abort, + .upm_close = ohci_root_intr_close, + .upm_cleartoggle = ohci_noop, + .upm_done = ohci_root_intr_done, }; Static const struct usbd_pipe_methods ohci_device_ctrl_methods = { - .transfer = ohci_device_ctrl_transfer, - .start = ohci_device_ctrl_start, - .abort = ohci_device_ctrl_abort, - .close = ohci_device_ctrl_close, - .cleartoggle = ohci_noop, - .done = ohci_device_ctrl_done, + .upm_init = ohci_device_ctrl_init, + .upm_fini = ohci_device_ctrl_fini, + .upm_transfer = ohci_device_ctrl_transfer, + .upm_start = ohci_device_ctrl_start, + .upm_abort = ohci_device_ctrl_abort, + .upm_close = ohci_device_ctrl_close, + .upm_cleartoggle = ohci_noop, + .upm_done = ohci_device_ctrl_done, }; Static const struct usbd_pipe_methods ohci_device_intr_methods = { - .transfer = ohci_device_intr_transfer, - .start = ohci_device_intr_start, - .abort = ohci_device_intr_abort, - .close = ohci_device_intr_close, - .cleartoggle = ohci_device_clear_toggle, - .done = ohci_device_intr_done, + .upm_init = ohci_device_intr_init, + .upm_fini = ohci_device_intr_fini, + .upm_transfer = ohci_device_intr_transfer, + .upm_start = ohci_device_intr_start, + .upm_abort = ohci_device_intr_abort, + .upm_close = ohci_device_intr_close, + .upm_cleartoggle = ohci_device_clear_toggle, + .upm_done = ohci_device_intr_done, }; Static const struct usbd_pipe_methods ohci_device_bulk_methods = { - .transfer = ohci_device_bulk_transfer, - .start = ohci_device_bulk_start, - .abort = ohci_device_bulk_abort, - .close = ohci_device_bulk_close, - .cleartoggle = ohci_device_clear_toggle, - .done = ohci_device_bulk_done, + .upm_init = ohci_device_bulk_init, + .upm_fini = ohci_device_bulk_fini, + .upm_transfer = ohci_device_bulk_transfer, + .upm_start = ohci_device_bulk_start, + .upm_abort = ohci_device_bulk_abort, + .upm_close = ohci_device_bulk_close, + .upm_cleartoggle = ohci_device_clear_toggle, + .upm_done = ohci_device_bulk_done, }; Static const struct usbd_pipe_methods ohci_device_isoc_methods = { - .transfer = ohci_device_isoc_transfer, - .start = ohci_device_isoc_start, - .abort = ohci_device_isoc_abort, - .close = ohci_device_isoc_close, - .cleartoggle = ohci_noop, - .done = ohci_device_isoc_done, + .upm_init = ohci_device_isoc_init, + .upm_fini = ohci_device_isoc_fini, + .upm_transfer = ohci_device_isoc_transfer, + .upm_abort = ohci_device_isoc_abort, + .upm_close = ohci_device_isoc_close, + .upm_cleartoggle = ohci_noop, + .upm_done = ohci_device_isoc_done, }; int @@ -348,7 +374,7 @@ ohci_detach(struct ohci_softc *sc, int flags) rv = config_detach(sc->sc_child, flags); if (rv != 0) - return (rv); + return rv; callout_halt(&sc->sc_tmo_rhsc, &sc->sc_lock); @@ -366,7 +392,7 @@ ohci_detach(struct ohci_softc *sc, int flags) usb_freemem(&sc->sc_bus, &sc->sc_hccadma); pool_cache_destroy(sc->sc_xferpool); - return (rv); + return rv; } ohci_soft_ed_t * @@ -377,12 +403,19 @@ ohci_alloc_sed(ohci_softc_t *sc) int i, offs; usb_dma_t dma; + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + + mutex_enter(&sc->sc_lock); if (sc->sc_freeeds == NULL) { - DPRINTFN(2, ("ohci_alloc_sed: allocating chunk\n")); + DPRINTFN(2, "allocating chunk", 0, 0, 0, 0); + mutex_exit(&sc->sc_lock); + err = usb_allocmem(&sc->sc_bus, OHCI_SED_SIZE * OHCI_SED_CHUNK, OHCI_ED_ALIGN, &dma); if (err) - return (0); + return 0; + + mutex_enter(&sc->sc_lock); for (i = 0; i < OHCI_SED_CHUNK; i++) { offs = i * OHCI_SED_SIZE; sed = KERNADDR(&dma, offs); @@ -395,18 +428,32 @@ ohci_alloc_sed(ohci_softc_t *sc) } sed = sc->sc_freeeds; sc->sc_freeeds = sed->next; + mutex_exit(&sc->sc_lock); + memset(&sed->ed, 0, sizeof(ohci_ed_t)); sed->next = 0; - return (sed); + return sed; } -void -ohci_free_sed(ohci_softc_t *sc, ohci_soft_ed_t *sed) +static inline void +ohci_free_sed_locked(ohci_softc_t *sc, ohci_soft_ed_t *sed) { + + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + sed->next = sc->sc_freeeds; sc->sc_freeeds = sed; } +void +ohci_free_sed(ohci_softc_t *sc, ohci_soft_ed_t *sed) +{ + + mutex_enter(&sc->sc_lock); + ohci_free_sed_locked(sc, sed); + mutex_exit(&sc->sc_lock); +} + ohci_soft_td_t * ohci_alloc_std(ohci_softc_t *sc) { @@ -415,14 +462,19 @@ ohci_alloc_std(ohci_softc_t *sc) int i, offs; usb_dma_t dma; - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + mutex_enter(&sc->sc_lock); if (sc->sc_freetds == NULL) { - DPRINTFN(2, ("ohci_alloc_std: allocating chunk\n")); + DPRINTFN(2, "allocating chunk", 0, 0, 0, 0); + mutex_exit(&sc->sc_lock); + err = usb_allocmem(&sc->sc_bus, OHCI_STD_SIZE * OHCI_STD_CHUNK, OHCI_TD_ALIGN, &dma); if (err) - return (NULL); + return NULL; + + mutex_enter(&sc->sc_lock); for (i = 0; i < OHCI_STD_CHUNK; i++) { offs = i * OHCI_STD_SIZE; std = KERNADDR(&dma, offs); @@ -436,139 +488,208 @@ ohci_alloc_std(ohci_softc_t *sc) std = sc->sc_freetds; sc->sc_freetds = std->nexttd; + mutex_exit(&sc->sc_lock); + memset(&std->td, 0, sizeof(ohci_td_t)); std->nexttd = NULL; std->xfer = NULL; - ohci_hash_add_td(sc, std); - return (std); + return std; } void -ohci_free_std(ohci_softc_t *sc, ohci_soft_td_t *std) +ohci_free_std_locked(ohci_softc_t *sc, ohci_soft_td_t *std) { - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); - ohci_hash_rem_td(sc, std); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + std->nexttd = sc->sc_freetds; sc->sc_freetds = std; } -usbd_status -ohci_alloc_std_chain(struct ohci_pipe *opipe, ohci_softc_t *sc, - int alen, int rd, usbd_xfer_handle xfer, - ohci_soft_td_t *sp, ohci_soft_td_t **ep) +void +ohci_free_std(ohci_softc_t *sc, ohci_soft_td_t *std) +{ + + mutex_enter(&sc->sc_lock); + ohci_free_std_locked(sc, std); + mutex_exit(&sc->sc_lock); +} + +Static int +ohci_alloc_std_chain(ohci_softc_t *sc, struct usbd_xfer *xfer, int length, int rd) +{ + struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); + uint16_t flags = xfer->ux_flags; + + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + + DPRINTFN(8, "addr=%d endpt=%d len=%d speed=%d", + xfer->ux_pipe->up_dev->ud_addr, + UE_GET_ADDR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress), + length, xfer->ux_pipe->up_dev->ud_speed); + + ASSERT_SLEEPABLE(); + KASSERT(length != 0 || (!rd && (flags & USBD_FORCE_SHORT_XFER))); + + size_t nstd = (!rd && (flags & USBD_FORCE_SHORT_XFER)) ? 1 : 0; + nstd += ((length + OHCI_PAGE_SIZE - 1) / OHCI_PAGE_SIZE); + ox->ox_stds = kmem_zalloc(sizeof(ohci_soft_td_t *) * nstd, + KM_SLEEP); + ox->ox_nstd = nstd; + + DPRINTFN(8, "xfer %p nstd %d", xfer, nstd, 0, 0); + + for (size_t j = 0; j < ox->ox_nstd;) { + ohci_soft_td_t *cur = ohci_alloc_std(sc); + if (cur == NULL) + goto nomem; + + ox->ox_stds[j++] = cur; + cur->xfer = xfer; + cur->flags = 0; + } + + return 0; + + nomem: + ohci_free_stds(sc, ox); + kmem_free(ox->ox_stds, sizeof(ohci_soft_td_t *) * nstd); + + return ENOMEM; +} + +Static void +ohci_free_stds(ohci_softc_t *sc, struct ohci_xfer *ox) +{ + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTF("ox=%p", ox, 0, 0, 0); + + mutex_enter(&sc->sc_lock); + for (size_t i = 0; i < ox->ox_nstd; i++) { + ohci_soft_td_t *std = ox->ox_stds[i]; + if (std == NULL) + break; + ohci_free_std_locked(sc, std); + } + mutex_exit(&sc->sc_lock); +} + +void +ohci_reset_std_chain(ohci_softc_t *sc, struct usbd_xfer *xfer, + int alen, int rd, ohci_soft_td_t *sp, ohci_soft_td_t **ep) { + struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); ohci_soft_td_t *next, *cur; - ohci_physaddr_t dataphys, dataphysend; - u_int32_t tdflags; int len, curlen; - usb_dma_t *dma = &xfer->dmabuf; - u_int16_t flags = xfer->flags; + usb_dma_t *dma = &xfer->ux_dmabuf; + uint16_t flags = xfer->ux_flags; - DPRINTFN(alen < 4096,("ohci_alloc_std_chain: start len=%d\n", alen)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTF("start len=%d", alen, 0, 0, 0); KASSERT(mutex_owned(&sc->sc_lock)); + DPRINTFN(8, "addr=%d endpt=%d len=%d speed=%d", + xfer->ux_pipe->up_dev->ud_addr, + UE_GET_ADDR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress), + alen, xfer->ux_pipe->up_dev->ud_speed); + + KASSERT(sp); + + int mps = UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize); + + /* + * Assign next for the len == 0 case where we don't go through the + * main loop. + */ len = alen; - cur = sp; - dataphys = DMAADDR(dma, 0); - dataphysend = OHCI_PAGE(dataphys + len - 1); + cur = next = sp; + usb_syncmem(dma, 0, len, rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); - tdflags = HTOO32( + const uint32_t tdflags = HTOO32( (rd ? OHCI_TD_IN : OHCI_TD_OUT) | - (flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0) | OHCI_TD_NOCC | OHCI_TD_TOGGLE_CARRY | OHCI_TD_NOINTR); - for (;;) { - next = ohci_alloc_std(sc); - if (next == NULL) - goto nomem; + size_t curoffs = 0; + for (size_t j = 1; len != 0;) { + if (j == ox->ox_nstd) + next = NULL; + else + next = ox->ox_stds[j++]; + KASSERT(next != cur); - /* 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 { + curlen = 0; + ohci_physaddr_t sdataphys = DMAADDR(dma, curoffs); + ohci_physaddr_t edataphys = DMAADDR(dma, curoffs + len - 1); + + ohci_physaddr_t sphyspg = OHCI_PAGE(sdataphys); + ohci_physaddr_t ephyspg = OHCI_PAGE(edataphys); + /* + * The OHCI hardware can handle at most one page + * crossing per TD + */ + curlen = len; + if (!(sphyspg == ephyspg || sphyspg + 1 == ephyspg)) { /* must use multiple TDs, fill as much as possible. */ curlen = 2 * OHCI_PAGE_SIZE - - (dataphys & (OHCI_PAGE_SIZE-1)); + (sdataphys & (OHCI_PAGE_SIZE - 1)); /* the length must be a multiple of the max size */ - curlen -= curlen % UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize); -#ifdef DIAGNOSTIC - if (curlen == 0) - panic("ohci_alloc_std: curlen == 0"); -#endif + curlen -= curlen % mps; } - DPRINTFN(4,("ohci_alloc_std_chain: dataphys=0x%08x " - "dataphysend=0x%08x len=%d curlen=%d\n", - dataphys, dataphysend, - len, curlen)); - len -= curlen; + KASSERT(curlen != 0); + DPRINTFN(4, "sdataphys=0x%08x edataphys=0x%08x " + "len=%d curlen=%d", sdataphys, edataphys, len, curlen); cur->td.td_flags = tdflags; - cur->td.td_cbp = HTOO32(dataphys); + cur->td.td_cbp = HTOO32(sdataphys); + cur->td.td_be = HTOO32(edataphys); + cur->td.td_nexttd = (next != NULL) ? HTOO32(next->physaddr) : 0; cur->nexttd = next; - cur->td.td_nexttd = HTOO32(next->physaddr); - cur->td.td_be = HTOO32(dataphys + curlen - 1); cur->len = curlen; cur->flags = OHCI_ADD_LEN; cur->xfer = xfer; + ohci_hash_add_td(sc, cur); + usb_syncmem(&cur->dma, cur->offs, sizeof(cur->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - 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; + + curoffs += curlen; + len -= curlen; + + if (len != 0) { + KASSERT(next != NULL); + DPRINTFN(10, "extend chain", 0, 0, 0, 0); + cur = next; + } } - if (!rd && (flags & USBD_FORCE_SHORT_XFER) && - alen % UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize) == 0) { + cur->td.td_flags |= + (xfer->ux_flags & USBD_SHORT_XFER_OK ? OHCI_TD_R : 0); + + if (!rd && + (flags & USBD_FORCE_SHORT_XFER) && + alen % mps == 0) { /* Force a 0 length transfer at the end. */ + KASSERT(next != NULL); cur = next; - next = ohci_alloc_std(sc); - if (next == NULL) - goto nomem; cur->td.td_flags = tdflags; cur->td.td_cbp = 0; /* indicate 0 length packet */ - cur->nexttd = next; - cur->td.td_nexttd = HTOO32(next->physaddr); + cur->td.td_nexttd = 0; cur->td.td_be = ~0; + cur->nexttd = NULL; cur->len = 0; cur->flags = 0; cur->xfer = xfer; + ohci_hash_add_td(sc, cur); + usb_syncmem(&cur->dma, cur->offs, sizeof(cur->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - DPRINTFN(2,("ohci_alloc_std_chain: add 0 xfer\n")); + DPRINTFN(2, "add 0 xfer", 0, 0, 0, 0); } *ep = cur; - - return (USBD_NORMAL_COMPLETION); - - nomem: - - /* Don't free sp - let the caller do that */ - ohci_free_std_chain(sc, sp->nexttd, NULL); - - return (USBD_NOMEM); -} - -Static void -ohci_free_std_chain(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); - } } ohci_soft_itd_t * @@ -579,12 +700,18 @@ ohci_alloc_sitd(ohci_softc_t *sc) int i, offs; usb_dma_t dma; + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + + mutex_enter(&sc->sc_lock); if (sc->sc_freeitds == NULL) { - DPRINTFN(2, ("ohci_alloc_sitd: allocating chunk\n")); + DPRINTFN(2, "allocating chunk", 0, 0, 0, 0); + mutex_exit(&sc->sc_lock); + err = usb_allocmem(&sc->sc_bus, OHCI_SITD_SIZE * OHCI_SITD_CHUNK, OHCI_ITD_ALIGN, &dma); if (err) - return (NULL); + return NULL; + mutex_enter(&sc->sc_lock); for (i = 0; i < OHCI_SITD_CHUNK; i++) { offs = i * OHCI_SITD_SIZE; sitd = KERNADDR(&dma, offs); @@ -598,47 +725,57 @@ ohci_alloc_sitd(ohci_softc_t *sc) sitd = sc->sc_freeitds; sc->sc_freeitds = sitd->nextitd; + mutex_exit(&sc->sc_lock); + memset(&sitd->itd, 0, sizeof(ohci_itd_t)); sitd->nextitd = NULL; sitd->xfer = NULL; - ohci_hash_add_itd(sc, sitd); #ifdef DIAGNOSTIC - sitd->isdone = 0; + sitd->isdone = true; #endif - return (sitd); + return sitd; } -void -ohci_free_sitd(ohci_softc_t *sc, ohci_soft_itd_t *sitd) +Static void +ohci_free_sitd_locked(ohci_softc_t *sc, ohci_soft_itd_t *sitd) { - DPRINTFN(10,("ohci_free_sitd: sitd=%p\n", sitd)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTFN(10, "sitd=%p", sitd, 0, 0, 0); + KASSERT(sitd->isdone); #ifdef DIAGNOSTIC - if (!sitd->isdone) { - panic("ohci_free_sitd: sitd=%p not done", sitd); - return; - } /* Warn double free */ - sitd->isdone = 0; + sitd->isdone = false; #endif - ohci_hash_rem_itd(sc, sitd); sitd->nextitd = sc->sc_freeitds; sc->sc_freeitds = sitd; } -usbd_status +void +ohci_free_sitd(ohci_softc_t *sc, ohci_soft_itd_t *sitd) +{ + + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + + mutex_enter(&sc->sc_lock); + ohci_free_sitd_locked(sc, sitd); + mutex_exit(&sc->sc_lock); +} + +int ohci_init(ohci_softc_t *sc) { ohci_soft_ed_t *sed, *psed; usbd_status err; int i; - u_int32_t s, ctl, rwc, ival, hcr, fm, per, rev, desca /*, descb */; + uint32_t s, ctl, rwc, ival, hcr, fm, per, rev, desca /*, descb */; + + OHCIHIST_FUNC(); OHCIHIST_CALLED(); - DPRINTF(("ohci_init: start\n")); aprint_normal_dev(sc->sc_dev, ""); sc->sc_hcca = NULL; @@ -666,13 +803,11 @@ ohci_init(ohci_softc_t *sc) if (OHCI_REV_HI(rev) != 1 || OHCI_REV_LO(rev) != 0) { aprint_error_dev(sc->sc_dev, "unsupported OHCI revision\n"); - sc->sc_bus.usbrev = USBREV_UNKNOWN; - return (USBD_INVAL); + sc->sc_bus.ub_revision = USBREV_UNKNOWN; + return -1; } - sc->sc_bus.usbrev = USBREV_1_0; - - usb_setup_reserve(sc->sc_dev, &sc->sc_dma_reserve, sc->sc_bus.dmatag, - USB_MEM_RESERVE); + sc->sc_bus.ub_revision = USBREV_1_0; + sc->sc_bus.ub_usedma = true; /* XXX determine alignment by R/W */ /* Allocate the HCCA area. */ @@ -690,7 +825,7 @@ ohci_init(ohci_softc_t *sc) /* Allocate dummy ED that starts the control list. */ sc->sc_ctrl_head = ohci_alloc_sed(sc); if (sc->sc_ctrl_head == NULL) { - err = USBD_NOMEM; + err = ENOMEM; goto bad1; } sc->sc_ctrl_head->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); @@ -698,7 +833,7 @@ ohci_init(ohci_softc_t *sc) /* Allocate dummy ED that starts the bulk list. */ sc->sc_bulk_head = ohci_alloc_sed(sc); if (sc->sc_bulk_head == NULL) { - err = USBD_NOMEM; + err = ENOMEM; goto bad2; } sc->sc_bulk_head->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); @@ -709,7 +844,7 @@ ohci_init(ohci_softc_t *sc) /* Allocate dummy ED that starts the isochronous list. */ sc->sc_isoc_head = ohci_alloc_sed(sc); if (sc->sc_isoc_head == NULL) { - err = USBD_NOMEM; + err = ENOMEM; goto bad3; } sc->sc_isoc_head->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); @@ -723,7 +858,7 @@ ohci_init(ohci_softc_t *sc) if (sed == NULL) { while (--i >= 0) ohci_free_sed(sc, sc->sc_eds[i]); - err = USBD_NOMEM; + err = ENOMEM; goto bad4; } /* All ED fields are set to 0. */ @@ -749,14 +884,16 @@ ohci_init(ohci_softc_t *sc) BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); #ifdef OHCI_DEBUG - if (ohcidebug > 15) { + DPRINTFN(15, "--- dump start ---", 0, 0, 0 ,0); + if (ohcidebug >= 15) { for (i = 0; i < OHCI_NO_EDS; i++) { - printf("ed#%d ", i); + DPRINTFN(15, "ed#%d ", i, 0, 0, 0); ohci_dump_ed(sc, sc->sc_eds[i]); } - printf("iso "); + DPRINTFN(15, "iso", 0, 0, 0 ,0); ohci_dump_ed(sc, sc->sc_isoc_head); } + DPRINTFN(15, "--- dump end ---", 0, 0, 0 ,0); #endif /* Preserve values programmed by SMM/BIOS but lost over reset. */ @@ -769,7 +906,7 @@ ohci_init(ohci_softc_t *sc) /* Determine in what context we are running. */ if (ctl & OHCI_IR) { /* SMM active, request change */ - DPRINTF(("ohci_init: SMM active, request owner change\n")); + DPRINTF("SMM active, request owner change", 0, 0, 0, 0); if ((sc->sc_intre & (OHCI_OC | OHCI_MIE)) == (OHCI_OC | OHCI_MIE)) OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_MIE); @@ -790,14 +927,14 @@ ohci_init(ohci_softc_t *sc) /* Don't bother trying to reuse the BIOS init, we'll reset it anyway. */ } else if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_RESET) { /* BIOS started controller. */ - DPRINTF(("ohci_init: BIOS active\n")); + DPRINTF("BIOS active", 0, 0, 0, 0); if ((ctl & OHCI_HCFS_MASK) != OHCI_HCFS_OPERATIONAL) { OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_OPERATIONAL | rwc); usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY); } #endif } else { - DPRINTF(("ohci_init: cold started\n")); + DPRINTF("cold started", 0 ,0 ,0 ,0); reset: /* Controller was cold started. */ usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY); @@ -807,7 +944,7 @@ ohci_init(ohci_softc_t *sc) * This reset should not be necessary according to the OHCI spec, but * without it some controllers do not start. */ - DPRINTF(("%s: resetting\n", device_xname(sc->sc_dev))); + DPRINTF("sc %p: resetting", sc, 0, 0, 0); OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET | rwc); usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY); @@ -823,11 +960,11 @@ ohci_init(ohci_softc_t *sc) } if (hcr) { aprint_error_dev(sc->sc_dev, "reset timeout\n"); - err = USBD_IOERROR; + err = EIO; goto bad5; } #ifdef OHCI_DEBUG - if (ohcidebug > 15) + if (ohcidebug >= 15) ohci_dumpregs(sc); #endif @@ -888,21 +1025,21 @@ ohci_init(ohci_softc_t *sc) } #ifdef OHCI_DEBUG - if (ohcidebug > 5) + if (ohcidebug >= 5) ohci_dumpregs(sc); #endif /* Set up the bus struct. */ - sc->sc_bus.methods = &ohci_bus_methods; - sc->sc_bus.pipe_size = sizeof(struct ohci_pipe); + sc->sc_bus.ub_methods = &ohci_bus_methods; + sc->sc_bus.ub_pipesize = sizeof(struct ohci_pipe); sc->sc_control = sc->sc_intre = 0; /* Finally, turn on interrupts. */ - DPRINTFN(1,("ohci_init: enabling %#x\n", sc->sc_eintrs | OHCI_MIE)); + DPRINTF("enabling %#x", sc->sc_eintrs | OHCI_MIE, 0, 0, 0); OWRITE4(sc, OHCI_INTERRUPT_ENABLE, sc->sc_eintrs | OHCI_MIE); - return (USBD_NORMAL_COMPLETION); + return 0; bad5: for (i = 0; i < OHCI_NO_EDS; i++) @@ -916,59 +1053,34 @@ ohci_init(ohci_softc_t *sc) bad1: usb_freemem(&sc->sc_bus, &sc->sc_hccadma); sc->sc_hcca = NULL; - return (err); -} - -usbd_status -ohci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size) -{ - struct ohci_softc *sc = bus->hci_private; - usbd_status status; - - status = usb_allocmem(&sc->sc_bus, size, 0, dma); - if (status == USBD_NOMEM) - status = usb_reserve_allocm(&sc->sc_dma_reserve, dma, size); - return status; -} - -void -ohci_freem(struct usbd_bus *bus, usb_dma_t *dma) -{ - struct ohci_softc *sc = bus->hci_private; - if (dma->block->flags & USB_DMA_RESERVE) { - usb_reserve_freem(&sc->sc_dma_reserve, dma); - return; - } - usb_freemem(&sc->sc_bus, dma); + return err; } -usbd_xfer_handle -ohci_allocx(struct usbd_bus *bus) +struct usbd_xfer * +ohci_allocx(struct usbd_bus *bus, unsigned int nframes) { - struct ohci_softc *sc = bus->hci_private; - usbd_xfer_handle xfer; + ohci_softc_t *sc = OHCI_BUS2SC(bus); + struct usbd_xfer *xfer; xfer = pool_cache_get(sc->sc_xferpool, PR_NOWAIT); if (xfer != NULL) { memset(xfer, 0, sizeof(struct ohci_xfer)); #ifdef DIAGNOSTIC - xfer->busy_free = XFER_BUSY; + xfer->ux_state = XFER_BUSY; #endif } - return (xfer); + return xfer; } void -ohci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) +ohci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) { - struct ohci_softc *sc = bus->hci_private; + ohci_softc_t *sc = OHCI_BUS2SC(bus); + KASSERTMSG(xfer->ux_state == XFER_BUSY, + "xfer=%p not busy, 0x%08x\n", xfer, xfer->ux_state); #ifdef DIAGNOSTIC - if (xfer->busy_free != XFER_BUSY) { - printf("ohci_freex: xfer=%p not busy, 0x%08x\n", xfer, - xfer->busy_free); - } - xfer->busy_free = XFER_FREE; + xfer->ux_state = XFER_FREE; #endif pool_cache_put(sc->sc_xferpool, xfer); } @@ -976,7 +1088,7 @@ ohci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) Static void ohci_get_lock(struct usbd_bus *bus, kmutex_t **lock) { - struct ohci_softc *sc = bus->hci_private; + ohci_softc_t *sc = OHCI_BUS2SC(bus); *lock = &sc->sc_lock; } @@ -989,7 +1101,9 @@ ohci_shutdown(device_t self, int flags) { ohci_softc_t *sc = device_private(self); - DPRINTF(("ohci_shutdown: stopping the HC\n")); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + + DPRINTF("stopping the HC", 0, 0, 0, 0); OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET); return true; } @@ -1001,7 +1115,7 @@ ohci_resume(device_t dv, const pmf_qual_t *qual) uint32_t ctl; mutex_spin_enter(&sc->sc_intr_lock); - sc->sc_bus.use_polling++; + sc->sc_bus.ub_usepolling++; mutex_spin_exit(&sc->sc_intr_lock); /* Some broken BIOSes do not recover these values */ @@ -1026,7 +1140,7 @@ ohci_resume(device_t dv, const pmf_qual_t *qual) sc->sc_control = sc->sc_intre = 0; mutex_spin_enter(&sc->sc_intr_lock); - sc->sc_bus.use_polling--; + sc->sc_bus.ub_usepolling--; mutex_spin_exit(&sc->sc_intr_lock); return true; @@ -1039,7 +1153,7 @@ ohci_suspend(device_t dv, const pmf_qual_t *qual) uint32_t ctl; mutex_spin_enter(&sc->sc_intr_lock); - sc->sc_bus.use_polling++; + sc->sc_bus.ub_usepolling++; mutex_spin_exit(&sc->sc_intr_lock); ctl = OREAD4(sc, OHCI_CONTROL) & ~OHCI_HCFS_MASK; @@ -1057,7 +1171,7 @@ ohci_suspend(device_t dv, const pmf_qual_t *qual) usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT); mutex_spin_enter(&sc->sc_intr_lock); - sc->sc_bus.use_polling--; + sc->sc_bus.ub_usepolling--; mutex_spin_exit(&sc->sc_intr_lock); return true; @@ -1067,40 +1181,42 @@ ohci_suspend(device_t dv, const pmf_qual_t *qual) void ohci_dumpregs(ohci_softc_t *sc) { - DPRINTF(("ohci_dumpregs: rev=0x%08x control=0x%08x command=0x%08x\n", + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + + DPRINTF("rev=0x%08x control=0x%08x command=0x%08x", OREAD4(sc, OHCI_REVISION), OREAD4(sc, OHCI_CONTROL), - OREAD4(sc, OHCI_COMMAND_STATUS))); - DPRINTF((" intrstat=0x%08x intre=0x%08x intrd=0x%08x\n", + OREAD4(sc, OHCI_COMMAND_STATUS), 0); + DPRINTF(" intrstat=0x%08x intre=0x%08x intrd=0x%08x", OREAD4(sc, OHCI_INTERRUPT_STATUS), OREAD4(sc, OHCI_INTERRUPT_ENABLE), - OREAD4(sc, OHCI_INTERRUPT_DISABLE))); - DPRINTF((" hcca=0x%08x percur=0x%08x ctrlhd=0x%08x\n", + OREAD4(sc, OHCI_INTERRUPT_DISABLE), 0); + DPRINTF(" hcca=0x%08x percur=0x%08x ctrlhd=0x%08x", OREAD4(sc, OHCI_HCCA), OREAD4(sc, OHCI_PERIOD_CURRENT_ED), - OREAD4(sc, OHCI_CONTROL_HEAD_ED))); - DPRINTF((" ctrlcur=0x%08x bulkhd=0x%08x bulkcur=0x%08x\n", + OREAD4(sc, OHCI_CONTROL_HEAD_ED), 0); + DPRINTF(" ctrlcur=0x%08x bulkhd=0x%08x bulkcur=0x%08x", OREAD4(sc, OHCI_CONTROL_CURRENT_ED), OREAD4(sc, OHCI_BULK_HEAD_ED), - OREAD4(sc, OHCI_BULK_CURRENT_ED))); - DPRINTF((" done=0x%08x fmival=0x%08x fmrem=0x%08x\n", + OREAD4(sc, OHCI_BULK_CURRENT_ED) ,0); + DPRINTF(" done=0x%08x fmival=0x%08x fmrem=0x%08x", OREAD4(sc, OHCI_DONE_HEAD), OREAD4(sc, OHCI_FM_INTERVAL), - OREAD4(sc, OHCI_FM_REMAINING))); - DPRINTF((" fmnum=0x%08x perst=0x%08x lsthrs=0x%08x\n", + OREAD4(sc, OHCI_FM_REMAINING), 0); + DPRINTF(" fmnum=0x%08x perst=0x%08x lsthrs=0x%08x", OREAD4(sc, OHCI_FM_NUMBER), OREAD4(sc, OHCI_PERIODIC_START), - OREAD4(sc, OHCI_LS_THRESHOLD))); - DPRINTF((" desca=0x%08x descb=0x%08x stat=0x%08x\n", + OREAD4(sc, OHCI_LS_THRESHOLD), 0); + DPRINTF(" desca=0x%08x descb=0x%08x stat=0x%08x", OREAD4(sc, OHCI_RH_DESCRIPTOR_A), OREAD4(sc, OHCI_RH_DESCRIPTOR_B), - OREAD4(sc, OHCI_RH_STATUS))); - DPRINTF((" port1=0x%08x port2=0x%08x\n", + OREAD4(sc, OHCI_RH_STATUS), 0); + DPRINTF(" port1=0x%08x port2=0x%08x", OREAD4(sc, OHCI_RH_PORT_STATUS(1)), - OREAD4(sc, OHCI_RH_PORT_STATUS(2)))); - DPRINTF((" HCCA: frame_number=0x%04x done_head=0x%08x\n", + OREAD4(sc, OHCI_RH_PORT_STATUS(2)), 0, 0); + DPRINTF(" HCCA: frame_number=0x%04x done_head=0x%08x", O32TOH(sc->sc_hcca->hcca_frame_number), - O32TOH(sc->sc_hcca->hcca_done_head))); + O32TOH(sc->sc_hcca->hcca_done_head), 0, 0); } #endif @@ -1112,8 +1228,10 @@ ohci_intr(void *p) ohci_softc_t *sc = p; int ret = 0; + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + if (sc == NULL) - return (0); + return 0; mutex_spin_enter(&sc->sc_intr_lock); @@ -1121,10 +1239,8 @@ ohci_intr(void *p) goto done; /* If we get an interrupt while polling, then just ignore it. */ - if (sc->sc_bus.use_polling) { -#ifdef DIAGNOSTIC - DPRINTFN(16, ("ohci_intr: ignored interrupt while polling\n")); -#endif + if (sc->sc_bus.ub_usepolling) { + DPRINTFN(16, "ignored interrupt while polling", 0, 0, 0, 0); /* for level triggered intrs, should do something to ack */ OWRITE4(sc, OHCI_INTERRUPT_STATUS, OREAD4(sc, OHCI_INTERRUPT_STATUS)); @@ -1142,35 +1258,36 @@ done: Static int ohci_intr1(ohci_softc_t *sc) { - u_int32_t intrs, eintrs; + uint32_t intrs, eintrs; - DPRINTFN(14,("ohci_intr1: enter\n")); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); /* In case the interrupt occurs before initialization has completed. */ if (sc == NULL || sc->sc_hcca == NULL) { #ifdef DIAGNOSTIC printf("ohci_intr: sc->sc_hcca == NULL\n"); #endif - return (0); + return 0; } KASSERT(mutex_owned(&sc->sc_intr_lock)); intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS); if (!intrs) - return (0); + return 0; - OWRITE4(sc, OHCI_INTERRUPT_STATUS, intrs & ~(OHCI_MIE|OHCI_WDH)); /* Acknowledge */ + /* Acknowledge */ + OWRITE4(sc, OHCI_INTERRUPT_STATUS, intrs & ~(OHCI_MIE|OHCI_WDH)); eintrs = intrs & sc->sc_eintrs; - DPRINTFN(7, ("ohci_intr: sc=%p intrs=%#x(%#x) eintrs=%#x(%#x)\n", - sc, (u_int)intrs, OREAD4(sc, OHCI_INTERRUPT_STATUS), - (u_int)eintrs, sc->sc_eintrs)); + DPRINTFN(7, "sc=%p", sc, 0, 0, 0); + DPRINTFN(7, "intrs=%#x(%#x) eintrs=%#x(%#x)", + intrs, OREAD4(sc, OHCI_INTERRUPT_STATUS), eintrs, + sc->sc_eintrs); if (!eintrs) { - return (0); + return 0; } - sc->sc_bus.no_intrs++; if (eintrs & OHCI_SO) { sc->sc_overrun_cnt++; if (usbd_ratecheck(&sc->sc_overrun_ntc)) { @@ -1189,10 +1306,12 @@ ohci_intr1(ohci_softc_t *sc) usb_schedsoftintr(&sc->sc_bus); } if (eintrs & OHCI_RD) { + DPRINTFN(5, "resume detect", sc, 0, 0, 0); printf("%s: resume detect\n", device_xname(sc->sc_dev)); /* XXX process resume detect */ } if (eintrs & OHCI_UE) { + DPRINTFN(5, "unrecoverable error", sc, 0, 0, 0); printf("%s: unrecoverable error, controller halted\n", device_xname(sc->sc_dev)); OWRITE4(sc, OHCI_CONTROL, OHCI_HCFS_RESET); @@ -1210,11 +1329,10 @@ ohci_intr1(ohci_softc_t *sc) /* Block unprocessed interrupts. */ OWRITE4(sc, OHCI_INTERRUPT_DISABLE, eintrs); sc->sc_eintrs &= ~eintrs; - DPRINTFN(1, ("%s: blocking intrs 0x%x\n", - device_xname(sc->sc_dev), eintrs)); + DPRINTF("sc %p blocking intrs 0x%x", sc, eintrs, 0, 0); } - return (1); + return 1; } void @@ -1222,7 +1340,8 @@ ohci_rhsc_enable(void *v_sc) { ohci_softc_t *sc = v_sc; - DPRINTFN(1, ("%s: %s\n", __func__, device_xname(sc->sc_dev))); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTF("sc %p", sc, 0, 0, 0); mutex_spin_enter(&sc->sc_intr_lock); sc->sc_eintrs |= OHCI_RHSC; OWRITE4(sc, OHCI_INTERRUPT_ENABLE, OHCI_RHSC); @@ -1254,18 +1373,18 @@ void ohci_softintr(void *v) { struct usbd_bus *bus = v; - ohci_softc_t *sc = bus->hci_private; + ohci_softc_t *sc = OHCI_BUS2SC(bus); ohci_soft_itd_t *sitd, *sidone, *sitdnext; ohci_soft_td_t *std, *sdone, *stdnext; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; struct ohci_pipe *opipe; int len, cc; int i, j, actlen, iframes, uedir; ohci_physaddr_t done; - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); - DPRINTFN(10,("ohci_softintr: enter\n")); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); usb_syncmem(&sc->sc_hccadma, offsetof(struct ohci_hcca, hcca_done_head), sizeof(sc->sc_hcca->hcca_done_head), @@ -1288,7 +1407,7 @@ ohci_softintr(void *v) std->dnext = sdone; done = O32TOH(std->td.td_nexttd); sdone = std; - DPRINTFN(10,("add TD %p\n", std)); + DPRINTFN(10, "add TD %p", std, 0, 0, 0); continue; } sitd = ohci_hash_find_itd(sc, done); @@ -1298,29 +1417,30 @@ ohci_softintr(void *v) sitd->dnext = sidone; done = O32TOH(sitd->itd.itd_nextitd); sidone = sitd; - DPRINTFN(5,("add ITD %p\n", sitd)); + DPRINTFN(5, "add ITD %p", sitd, 0, 0, 0); continue; } + DPRINTFN(10, "addr %p not found", done, 0, 0, 0); device_printf(sc->sc_dev, "WARNING: addr 0x%08lx not found\n", (u_long)done); break; } - DPRINTFN(10,("ohci_softintr: sdone=%p sidone=%p\n", sdone, sidone)); - + DPRINTFN(10, "sdone=%p sidone=%p", sdone, sidone, 0, 0); + DPRINTFN(10, "--- TD dump start ---", 0, 0, 0, 0); #ifdef OHCI_DEBUG - if (ohcidebug > 10) { - DPRINTF(("ohci_process_done: TD done:\n")); + if (ohcidebug >= 10) { for (std = sdone; std; std = std->dnext) ohci_dump_td(sc, std); } #endif + DPRINTFN(10, "--- TD dump end ---", 0, 0, 0, 0); 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 ? xfer->hcpriv : 0)); + DPRINTFN(10, "std=%p xfer=%p hcpriv=%p", std, xfer, + xfer ? xfer->ux_hcpriv : 0, 0); if (xfer == NULL) { /* * xfer == NULL: There seems to be no xfer associated @@ -1330,31 +1450,29 @@ ohci_softintr(void *v) */ continue; } - if (xfer->status == USBD_CANCELLED || - xfer->status == USBD_TIMEOUT) { - DPRINTF(("ohci_process_done: cancel/timeout %p\n", - xfer)); + if (xfer->ux_status == USBD_CANCELLED || + xfer->ux_status == USBD_TIMEOUT) { + DPRINTF("cancel/timeout %p", xfer, 0, 0, 0); /* Handled by abort routine. */ continue; } - callout_stop(&xfer->timeout_handle); + callout_stop(&xfer->ux_callout); len = std->len; if (std->td.td_cbp != 0) len -= O32TOH(std->td.td_be) - O32TOH(std->td.td_cbp) + 1; - DPRINTFN(10, ("ohci_process_done: len=%d, flags=0x%x\n", len, - std->flags)); + DPRINTFN(10, "len=%d, flags=0x%x", len, std->flags, 0, 0); if (std->flags & OHCI_ADD_LEN) - xfer->actlen += len; + xfer->ux_actlen += len; cc = OHCI_TD_GET_CC(O32TOH(std->td.td_flags)); if (cc == OHCI_CC_NO_ERROR) { + ohci_hash_rem_td(sc, std); if (std->flags & OHCI_CALL_DONE) { - xfer->status = USBD_NORMAL_COMPLETION; + xfer->ux_status = USBD_NORMAL_COMPLETION; usb_transfer_complete(xfer); } - ohci_free_std(sc, std); } else { /* * Endpoint is halted. First unlink all the TDs @@ -1362,76 +1480,81 @@ ohci_softintr(void *v) * the endpoint. */ ohci_soft_td_t *p, *n; - opipe = (struct ohci_pipe *)xfer->pipe; + opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); - DPRINTFN(15,("ohci_process_done: error cc=%d (%s)\n", - OHCI_TD_GET_CC(O32TOH(std->td.td_flags)), - ohci_cc_strs[OHCI_TD_GET_CC(O32TOH(std->td.td_flags))])); + DPRINTFN(10, "error cc=%d", cc, 0, 0, 0); - /* remove TDs */ + /* remove xfer's TDs from the hash */ for (p = std; p->xfer == xfer; p = n) { n = p->nexttd; - ohci_free_std(sc, p); + ohci_hash_rem_td(sc, p); } - /* clear halt */ - opipe->sed->ed.ed_headp = HTOO32(p->physaddr); + ohci_soft_ed_t *sed = opipe->sed; + + /* clear halt and TD chain */ + sed->ed.ed_headp = HTOO32(p->physaddr); + usb_syncmem(&sed->dma, + sed->offs + offsetof(ohci_ed_t, ed_headp), + sizeof(sed->ed.ed_headp), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); - if (cc == OHCI_CC_STALL) - xfer->status = USBD_STALLED; + if (cc == OHCI_CC_DATA_UNDERRUN) + xfer->ux_status = USBD_NORMAL_COMPLETION; + else if (cc == OHCI_CC_STALL) + xfer->ux_status = USBD_STALLED; else - xfer->status = USBD_IOERROR; + xfer->ux_status = USBD_IOERROR; usb_transfer_complete(xfer); } } - + DPRINTFN(10, "--- ITD dump start ---", 0, 0, 0, 0); #ifdef OHCI_DEBUG - if (ohcidebug > 10) { - DPRINTF(("ohci_softintr: ITD done:\n")); + if (ohcidebug >= 10) { for (sitd = sidone; sitd; sitd = sitd->dnext) ohci_dump_itd(sc, sitd); } #endif + DPRINTFN(10, "--- ITD dump end ---", 0, 0, 0, 0); for (sitd = sidone; sitd != NULL; sitd = sitdnext) { xfer = sitd->xfer; sitdnext = sitd->dnext; - DPRINTFN(1, ("ohci_process_done: sitd=%p xfer=%p hcpriv=%p\n", - sitd, xfer, xfer ? xfer->hcpriv : 0)); + DPRINTFN(1, "sitd=%p xfer=%p hcpriv=%p", sitd, xfer, + xfer ? xfer->ux_hcpriv : 0, 0); if (xfer == NULL) continue; - if (xfer->status == USBD_CANCELLED || - xfer->status == USBD_TIMEOUT) { - DPRINTF(("ohci_process_done: cancel/timeout %p\n", - xfer)); + if (xfer->ux_status == USBD_CANCELLED || + xfer->ux_status == USBD_TIMEOUT) { + DPRINTF("cancel/timeout %p", xfer, 0, 0, 0); /* Handled by abort routine. */ continue; } + KASSERT(!sitd->isdone); #ifdef DIAGNOSTIC - if (sitd->isdone) - printf("ohci_softintr: sitd=%p is done\n", sitd); - sitd->isdone = 1; + sitd->isdone = true; #endif if (sitd->flags & OHCI_CALL_DONE) { ohci_soft_itd_t *next; - opipe = (struct ohci_pipe *)xfer->pipe; - opipe->u.iso.inuse -= xfer->nframes; - uedir = UE_GET_DIR(xfer->pipe->endpoint->edesc-> + opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); + opipe->isoc.inuse -= xfer->ux_nframes; + uedir = UE_GET_DIR(xfer->ux_pipe->up_endpoint->ue_edesc-> bEndpointAddress); - xfer->status = USBD_NORMAL_COMPLETION; + xfer->ux_status = USBD_NORMAL_COMPLETION; actlen = 0; - for (i = 0, sitd = xfer->hcpriv;; + for (i = 0, sitd = xfer->ux_hcpriv;; sitd = next) { next = sitd->nextitd; if (OHCI_ITD_GET_CC(O32TOH(sitd-> itd.itd_flags)) != OHCI_CC_NO_ERROR) - xfer->status = USBD_IOERROR; + xfer->ux_status = USBD_IOERROR; /* For input, update frlengths with actual */ /* XXX anything necessary for output? */ if (uedir == UE_DIR_IN && - xfer->status == USBD_NORMAL_COMPLETION) { + xfer->ux_status == USBD_NORMAL_COMPLETION) { iframes = OHCI_ITD_GET_FC(O32TOH( sitd->itd.itd_flags)); for (j = 0; j < iframes; i++, j++) { @@ -1443,19 +1566,20 @@ ohci_softintr(void *v) len = 0; else len = OHCI_ITD_PSW_LENGTH(len); - xfer->frlengths[i] = len; + xfer->ux_frlengths[i] = len; actlen += len; } } if (sitd->flags & OHCI_CALL_DONE) break; - ohci_free_sitd(sc, sitd); + ohci_hash_rem_itd(sc, sitd); + } - ohci_free_sitd(sc, sitd); + ohci_hash_rem_itd(sc, sitd); if (uedir == UE_DIR_IN && - xfer->status == USBD_NORMAL_COMPLETION) - xfer->actlen = actlen; - xfer->hcpriv = NULL; + xfer->ux_status == USBD_NORMAL_COMPLETION) + xfer->ux_actlen = actlen; + xfer->ux_hcpriv = NULL; usb_transfer_complete(xfer); } @@ -1466,102 +1590,59 @@ ohci_softintr(void *v) cv_broadcast(&sc->sc_softwake_cv); } - DPRINTFN(10,("ohci_softintr: done:\n")); + DPRINTFN(10, "done", 0, 0, 0, 0); } void -ohci_device_ctrl_done(usbd_xfer_handle xfer) +ohci_device_ctrl_done(struct usbd_xfer *xfer) { - struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; -#ifdef DIAGNOSTIC - ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; -#endif - int len = UGETW(xfer->request.wLength); - int isread = (xfer->request.bmRequestType & UT_READ); + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); + ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer); + int len = UGETW(xfer->ux_request.wLength); + int isread = (xfer->ux_request.bmRequestType & UT_READ); - DPRINTFN(10,("ohci_device_ctrl_done: xfer=%p\n", xfer)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTFN(10, "xfer=%p", xfer, 0, 0, 0); - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + KASSERT(xfer->ux_rqflags & URQ_REQUEST); -#ifdef DIAGNOSTIC - if (!(xfer->rqflags & URQ_REQUEST)) { - panic("ohci_device_ctrl_done: not a request"); - } -#endif if (len) - usb_syncmem(&xfer->dmabuf, 0, len, + usb_syncmem(&xfer->ux_dmabuf, 0, len, isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); - usb_syncmem(&opipe->u.ctl.reqdma, 0, - sizeof(usb_device_request_t), BUS_DMASYNC_POSTWRITE); + usb_syncmem(&opipe->ctrl.reqdma, 0, + sizeof(usb_device_request_t), BUS_DMASYNC_POSTWRITE); } void -ohci_device_intr_done(usbd_xfer_handle xfer) +ohci_device_intr_done(struct usbd_xfer *xfer) { - struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; - ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; - ohci_soft_ed_t *sed = opipe->sed; - ohci_soft_td_t *data, *tail; + ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer); int isread = - (UE_GET_DIR(xfer->pipe->endpoint->edesc->bEndpointAddress) == UE_DIR_IN); + (UE_GET_DIR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN); - DPRINTFN(10,("ohci_device_intr_done: xfer=%p, actlen=%d\n", - xfer, xfer->actlen)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTFN(10, "xfer=%p, actlen=%d", xfer, xfer->ux_actlen, 0, 0); - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); - usb_syncmem(&xfer->dmabuf, 0, xfer->length, + usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); - if (xfer->pipe->repeat) { - data = opipe->tail.td; - tail = ohci_alloc_std(sc); /* XXX should reuse TD */ - if (tail == NULL) { - xfer->status = USBD_NOMEM; - return; - } - tail->xfer = NULL; - - data->td.td_flags = HTOO32( - OHCI_TD_IN | OHCI_TD_NOCC | - OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY); - if (xfer->flags & USBD_SHORT_XFER_OK) - data->td.td_flags |= HTOO32(OHCI_TD_R); - data->td.td_cbp = HTOO32(DMAADDR(&xfer->dmabuf, 0)); - data->nexttd = tail; - data->td.td_nexttd = HTOO32(tail->physaddr); - data->td.td_be = HTOO32(O32TOH(data->td.td_cbp) + - xfer->length - 1); - data->len = xfer->length; - data->xfer = xfer; - data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN; - usb_syncmem(&data->dma, data->offs, sizeof(data->td), - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - xfer->hcpriv = data; - xfer->actlen = 0; - - sed->ed.ed_tailp = HTOO32(tail->physaddr); - usb_syncmem(&sed->dma, - sed->offs + offsetof(ohci_ed_t, ed_tailp), - sizeof(sed->ed.ed_tailp), - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - opipe->tail.td = tail; - } } void -ohci_device_bulk_done(usbd_xfer_handle xfer) +ohci_device_bulk_done(struct usbd_xfer *xfer) { -#ifdef DIAGNOSTIC - ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; -#endif + ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer); + int isread = - (UE_GET_DIR(xfer->pipe->endpoint->edesc->bEndpointAddress) == UE_DIR_IN); + (UE_GET_DIR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN); KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTFN(10,("ohci_device_bulk_done: xfer=%p, actlen=%d\n", - xfer, xfer->actlen)); - usb_syncmem(&xfer->dmabuf, 0, xfer->length, + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTFN(10, "xfer=%p, actlen=%d", xfer, xfer->ux_actlen, 0, 0); + usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); } @@ -1581,46 +1662,47 @@ ohci_rhsc_softint(void *arg) } void -ohci_rhsc(ohci_softc_t *sc, usbd_xfer_handle xfer) +ohci_rhsc(ohci_softc_t *sc, struct usbd_xfer *xfer) { u_char *p; int i, m; int hstatus __unused; + OHCIHIST_FUNC(); OHCIHIST_CALLED(); KASSERT(mutex_owned(&sc->sc_lock)); hstatus = OREAD4(sc, OHCI_RH_STATUS); - DPRINTF(("ohci_rhsc: sc=%p xfer=%p hstatus=0x%08x\n", - sc, xfer, hstatus)); + DPRINTF("sc=%p xfer=%p hstatus=0x%08x", sc, xfer, hstatus, 0); if (xfer == NULL) { /* Just ignore the change. */ return; } - p = KERNADDR(&xfer->dmabuf, 0); - m = min(sc->sc_noport, xfer->length * 8 - 1); - memset(p, 0, xfer->length); + p = xfer->ux_buf; + m = min(sc->sc_noport, xfer->ux_length * 8 - 1); + memset(p, 0, xfer->ux_length); for (i = 1; i <= m; i++) { /* Pick out CHANGE bits from the status reg. */ if (OREAD4(sc, OHCI_RH_PORT_STATUS(i)) >> 16) p[i/8] |= 1 << (i%8); } - DPRINTF(("ohci_rhsc: change=0x%02x\n", *p)); - xfer->actlen = xfer->length; - xfer->status = USBD_NORMAL_COMPLETION; + DPRINTF("change=0x%02x", *p, 0, 0, 0); + xfer->ux_actlen = xfer->ux_length; + xfer->ux_status = USBD_NORMAL_COMPLETION; usb_transfer_complete(xfer); } void -ohci_root_intr_done(usbd_xfer_handle xfer) +ohci_root_intr_done(struct usbd_xfer *xfer) { -} + ohci_softc_t *sc = OHCI_XFER2SC(xfer); -void -ohci_root_ctrl_done(usbd_xfer_handle xfer) -{ + KASSERT(mutex_owned(&sc->sc_lock)); + + KASSERT(sc->sc_intrxfer == xfer); + sc->sc_intrxfer = NULL; } /* @@ -1629,20 +1711,21 @@ ohci_root_ctrl_done(usbd_xfer_handle xfer) * too long. */ void -ohci_waitintr(ohci_softc_t *sc, usbd_xfer_handle xfer) +ohci_waitintr(ohci_softc_t *sc, struct usbd_xfer *xfer) { int timo; - u_int32_t intrs; + uint32_t intrs; + OHCIHIST_FUNC(); OHCIHIST_CALLED(); mutex_enter(&sc->sc_lock); - xfer->status = USBD_IN_PROGRESS; - for (timo = xfer->timeout; timo >= 0; timo--) { + xfer->ux_status = USBD_IN_PROGRESS; + for (timo = xfer->ux_timeout; timo >= 0; timo--) { usb_delay_ms(&sc->sc_bus, 1); if (sc->sc_dying) break; intrs = OREAD4(sc, OHCI_INTERRUPT_STATUS) & sc->sc_eintrs; - DPRINTFN(15,("ohci_waitintr: 0x%04x\n", intrs)); + DPRINTFN(15, "intrs 0x%04x", intrs, 0, 0, 0); #ifdef OHCI_DEBUG if (ohcidebug > 15) ohci_dumpregs(sc); @@ -1651,18 +1734,16 @@ ohci_waitintr(ohci_softc_t *sc, usbd_xfer_handle xfer) mutex_spin_enter(&sc->sc_intr_lock); ohci_intr1(sc); mutex_spin_exit(&sc->sc_intr_lock); - if (xfer->status != USBD_IN_PROGRESS) + if (xfer->ux_status != USBD_IN_PROGRESS) goto done; } } /* Timeout */ - DPRINTF(("ohci_waitintr: timeout\n")); - xfer->status = USBD_TIMEOUT; + DPRINTF("timeout", 0, 0, 0, 0); + xfer->ux_status = USBD_TIMEOUT; usb_transfer_complete(xfer); - /* XXX should free TD */ - done: mutex_exit(&sc->sc_lock); } @@ -1670,13 +1751,15 @@ done: void ohci_poll(struct usbd_bus *bus) { - ohci_softc_t *sc = bus->hci_private; + ohci_softc_t *sc = OHCI_BUS2SC(bus); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + #ifdef OHCI_DEBUG static int last; int new; new = OREAD4(sc, OHCI_INTERRUPT_STATUS); if (new != last) { - DPRINTFN(10,("ohci_poll: intrs=0x%04x\n", new)); + DPRINTFN(10, "intrs=0x%04x", new, 0, 0, 0); last = new; } #endif @@ -1688,159 +1771,14 @@ ohci_poll(struct usbd_bus *bus) } } -usbd_status -ohci_device_request(usbd_xfer_handle xfer) -{ - 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 = dev->bus->hci_private; - ohci_soft_td_t *setup, *stat, *next, *tail; - ohci_soft_ed_t *sed; - int isread; - int len; - usbd_status err; - - KASSERT(mutex_owned(&sc->sc_lock)); - - isread = req->bmRequestType & UT_READ; - len = UGETW(req->wLength); - - DPRINTFN(3,("ohci_device_control type=0x%02x, request=0x%02x, " - "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n", - req->bmRequestType, req->bRequest, UGETW(req->wValue), - UGETW(req->wIndex), len, dev->address, - opipe->pipe.endpoint->edesc->bEndpointAddress)); - - setup = opipe->tail.td; - stat = ohci_alloc_std(sc); - if (stat == NULL) { - err = USBD_NOMEM; - goto bad1; - } - tail = ohci_alloc_std(sc); - if (tail == NULL) { - err = USBD_NOMEM; - goto bad2; - } - tail->xfer = NULL; - - sed = opipe->sed; - opipe->u.ctl.length = len; - - KASSERTMSG(OHCI_ED_GET_FA(O32TOH(sed->ed.ed_flags)) == dev->address, - "address ED %d pipe %d\n", - OHCI_ED_GET_FA(O32TOH(sed->ed.ed_flags)), dev->address); - KASSERTMSG(OHCI_ED_GET_MAXP(O32TOH(sed->ed.ed_flags)) == - UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize), - "MPL ED %d pipe %d\n", - OHCI_ED_GET_MAXP(O32TOH(sed->ed.ed_flags)), - UGETW(opipe->pipe.endpoint->edesc->wMaxPacketSize)); - - next = stat; - - /* Set up data transaction */ - if (len != 0) { - ohci_soft_td_t *std = stat; - - err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer, - std, &stat); - if (err) { - /* stat is unchanged if error */ - goto bad3; - } - stat = stat->nexttd; /* point at free TD */ - - /* Start toggle at 1 and then use the carried toggle. */ - std->td.td_flags &= HTOO32(~OHCI_TD_TOGGLE_MASK); - std->td.td_flags |= HTOO32(OHCI_TD_TOGGLE_1); - usb_syncmem(&std->dma, - std->offs + offsetof(ohci_td_t, td_flags), - sizeof(std->td.td_flags), - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - } - - memcpy(KERNADDR(&opipe->u.ctl.reqdma, 0), req, sizeof *req); - usb_syncmem(&opipe->u.ctl.reqdma, 0, sizeof *req, BUS_DMASYNC_PREWRITE); - - setup->td.td_flags = HTOO32(OHCI_TD_SETUP | OHCI_TD_NOCC | - OHCI_TD_TOGGLE_0 | OHCI_TD_NOINTR); - setup->td.td_cbp = HTOO32(DMAADDR(&opipe->u.ctl.reqdma, 0)); - setup->nexttd = next; - setup->td.td_nexttd = HTOO32(next->physaddr); - setup->td.td_be = HTOO32(O32TOH(setup->td.td_cbp) + sizeof *req - 1); - setup->len = 0; - setup->xfer = xfer; - setup->flags = 0; - xfer->hcpriv = setup; - usb_syncmem(&setup->dma, setup->offs, sizeof(setup->td), - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - - stat->td.td_flags = HTOO32( - (isread ? OHCI_TD_OUT : OHCI_TD_IN) | - OHCI_TD_NOCC | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DI(1)); - stat->td.td_cbp = 0; - stat->nexttd = tail; - stat->td.td_nexttd = HTOO32(tail->physaddr); - stat->td.td_be = 0; - stat->flags = OHCI_CALL_DONE; - stat->len = 0; - stat->xfer = xfer; - usb_syncmem(&stat->dma, stat->offs, sizeof(stat->td), - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - -#ifdef OHCI_DEBUG - if (ohcidebug > 5) { - DPRINTF(("ohci_device_request:\n")); - ohci_dump_ed(sc, sed); - ohci_dump_tds(sc, setup); - } -#endif - - /* Insert ED in schedule */ - sed->ed.ed_tailp = HTOO32(tail->physaddr); - usb_syncmem(&sed->dma, - sed->offs + offsetof(ohci_ed_t, ed_tailp), - sizeof(sed->ed.ed_tailp), - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - opipe->tail.td = tail; - OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); - if (xfer->timeout && !sc->sc_bus.use_polling) { - callout_reset(&xfer->timeout_handle, mstohz(xfer->timeout), - ohci_timeout, xfer); - } - -#ifdef OHCI_DEBUG - if (ohcidebug > 20) { - delay(10000); - DPRINTF(("ohci_device_request: status=%x\n", - OREAD4(sc, OHCI_COMMAND_STATUS))); - ohci_dumpregs(sc); - printf("ctrl head:\n"); - ohci_dump_ed(sc, sc->sc_ctrl_head); - printf("sed:\n"); - ohci_dump_ed(sc, sed); - ohci_dump_tds(sc, setup); - } -#endif - - return (USBD_NORMAL_COMPLETION); - - bad3: - ohci_free_std(sc, tail); - bad2: - ohci_free_std(sc, stat); - bad1: - return (err); -} - /* * Add an ED to the schedule. Called with USB lock held. */ Static void ohci_add_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed, ohci_soft_ed_t *head) { - DPRINTFN(8,("ohci_add_ed: sed=%p head=%p\n", sed, head)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTFN(8, "sed=%p head=%p", sed, head, 0, 0); KASSERT(mutex_owned(&sc->sc_lock)); @@ -1901,7 +1839,7 @@ ohci_hash_add_td(ohci_softc_t *sc, ohci_soft_td_t *std) { int h = HASH(std->physaddr); - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); LIST_INSERT_HEAD(&sc->sc_hash_tds[h], std, hnext); } @@ -1911,7 +1849,7 @@ void ohci_hash_rem_td(ohci_softc_t *sc, ohci_soft_td_t *std) { - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); LIST_REMOVE(std, hnext); } @@ -1926,8 +1864,8 @@ ohci_hash_find_td(ohci_softc_t *sc, ohci_physaddr_t a) std != NULL; std = LIST_NEXT(std, hnext)) if (std->physaddr == a) - return (std); - return (NULL); + return std; + return NULL; } /* Called with USB lock held. */ @@ -1936,10 +1874,12 @@ ohci_hash_add_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd) { int h = HASH(sitd->physaddr); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTFN(10,("ohci_hash_add_itd: sitd=%p physaddr=0x%08lx\n", - sitd, (u_long)sitd->physaddr)); + DPRINTFN(10, "sitd=%p physaddr=0x%08lx", sitd, (u_long)sitd->physaddr, + 0, 0); LIST_INSERT_HEAD(&sc->sc_hash_itds[h], sitd, hnext); } @@ -1949,10 +1889,12 @@ void ohci_hash_rem_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd) { + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTFN(10,("ohci_hash_rem_itd: sitd=%p physaddr=0x%08lx\n", - sitd, (u_long)sitd->physaddr)); + DPRINTFN(10, "sitd=%p physaddr=0x%08lx", sitd, (u_long)sitd->physaddr, + 0, 0); LIST_REMOVE(sitd, hnext); } @@ -1967,22 +1909,23 @@ ohci_hash_find_itd(ohci_softc_t *sc, ohci_physaddr_t a) sitd != NULL; sitd = LIST_NEXT(sitd, hnext)) if (sitd->physaddr == a) - return (sitd); - return (NULL); + return sitd; + return NULL; } void ohci_timeout(void *addr) { - struct ohci_xfer *oxfer = addr; - struct ohci_pipe *opipe = (struct ohci_pipe *)oxfer->xfer.pipe; - ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; + struct usbd_xfer *xfer = addr; + struct ohci_xfer *oxfer = OHCI_XFER2OXFER(xfer); + ohci_softc_t *sc = OHCI_XFER2SC(xfer); - DPRINTF(("ohci_timeout: oxfer=%p\n", oxfer)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTF("oxfer=%p", oxfer, 0, 0, 0); if (sc->sc_dying) { mutex_enter(&sc->sc_lock); - ohci_abort_xfer(&oxfer->xfer, USBD_TIMEOUT); + ohci_abort_xfer(xfer, USBD_TIMEOUT); mutex_exit(&sc->sc_lock); return; } @@ -1990,17 +1933,19 @@ ohci_timeout(void *addr) /* Execute the abort in a process context. */ usb_init_task(&oxfer->abort_task, ohci_timeout_task, addr, USB_TASKQ_MPSAFE); - usb_add_task(oxfer->xfer.pipe->device, &oxfer->abort_task, + usb_add_task(xfer->ux_pipe->up_dev, &oxfer->abort_task, USB_TASKQ_HC); } void ohci_timeout_task(void *addr) { - usbd_xfer_handle xfer = addr; - ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; + struct usbd_xfer *xfer = addr; + ohci_softc_t *sc = OHCI_XFER2SC(xfer); - DPRINTF(("ohci_timeout_task: xfer=%p\n", xfer)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + + DPRINTF("xfer=%p", xfer, 0, 0, 0); mutex_enter(&sc->sc_lock); ohci_abort_xfer(xfer, USBD_TIMEOUT); @@ -2011,63 +1956,66 @@ ohci_timeout_task(void *addr) void ohci_dump_tds(ohci_softc_t *sc, ohci_soft_td_t *std) { - for (; std; std = std->nexttd) + for (; std; std = std->nexttd) { ohci_dump_td(sc, std); + KASSERTMSG(std->nexttd == NULL || std != std->nexttd, + "std %p next %p", std, std->nexttd); + } } void ohci_dump_td(ohci_softc_t *sc, ohci_soft_td_t *std) { - char sbuf[128]; + OHCIHIST_FUNC(); OHCIHIST_CALLED(); usb_syncmem(&std->dma, std->offs, sizeof(std->td), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - snprintb(sbuf, sizeof(sbuf), - "\177\20" - "b\22R\0" - "f\23\02DP\0" - "=\x0" "setup\0" - "=\x1" "out\0" - "=\x2" "in\0" - "=\x3" "reserved\0" - "f\25\03DI\0" - "=\x07" "none\0" - "f\30\02T\0" - "=\x0" "carry\0" - "=\x1" "carry\0" - "=\x2" "0\0" - "=\x3" "1\0" - "f\32\02EC\0" - "f\34\04CC\0", - (u_int32_t)O32TOH(std->td.td_flags)); - printf("TD(%p) at %08lx:\n\tflags=%s\n\tcbp=0x%08lx nexttd=0x%08lx be=0x%08lx\n", - std, (u_long)std->physaddr, sbuf, + + uint32_t flags = O32TOH(std->td.td_flags); + DPRINTF("TD(%p) at 0x%08lx:", std, (u_long)std->physaddr, 0, 0); + DPRINTF(" round=%d DP=%x DI=%x T=%x", + !!(flags & OHCI_TD_R), + __SHIFTOUT(flags, OHCI_TD_DP_MASK), + OHCI_TD_GET_DI(flags), + __SHIFTOUT(flags, OHCI_TD_TOGGLE_MASK)); + DPRINTF(" EC=%d CC=%d", OHCI_TD_GET_EC(flags), OHCI_TD_GET_CC(flags), + 0, 0); + DPRINTF(" td_cbp=0x%08lx td_nexttd=0x%08lx td_be=0x%08lx", (u_long)O32TOH(std->td.td_cbp), (u_long)O32TOH(std->td.td_nexttd), - (u_long)O32TOH(std->td.td_be)); + (u_long)O32TOH(std->td.td_be), 0); } void ohci_dump_itd(ohci_softc_t *sc, ohci_soft_itd_t *sitd) { - int i; + OHCIHIST_FUNC(); OHCIHIST_CALLED(); usb_syncmem(&sitd->dma, sitd->offs, sizeof(sitd->itd), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - printf("ITD(%p) at %08lx: sf=%d di=%d fc=%d cc=%d\n" - "bp0=0x%08lx next=0x%08lx be=0x%08lx\n", - sitd, (u_long)sitd->physaddr, - OHCI_ITD_GET_SF(O32TOH(sitd->itd.itd_flags)), - OHCI_ITD_GET_DI(O32TOH(sitd->itd.itd_flags)), - OHCI_ITD_GET_FC(O32TOH(sitd->itd.itd_flags)), - OHCI_ITD_GET_CC(O32TOH(sitd->itd.itd_flags)), - (u_long)O32TOH(sitd->itd.itd_bp0), - (u_long)O32TOH(sitd->itd.itd_nextitd), - (u_long)O32TOH(sitd->itd.itd_be)); - for (i = 0; i < OHCI_ITD_NOFFSET; i++) - printf("offs[%d]=0x%04x ", i, - (u_int)O16TOH(sitd->itd.itd_offset[i])); - printf("\n"); + + uint32_t flags = O32TOH(sitd->itd.itd_flags); + DPRINTF("ITD(%p) at 0x%08lx", sitd, (u_long)sitd->physaddr, 0, 0); + DPRINTF(" sf=%d di=%d fc=%d cc=%d", + OHCI_ITD_GET_SF(flags), OHCI_ITD_GET_DI(flags), + OHCI_ITD_GET_FC(flags), OHCI_ITD_GET_CC(flags)); + DPRINTF(" bp0=0x%08x next=0x%08x be=0x%08x", + O32TOH(sitd->itd.itd_bp0), + O32TOH(sitd->itd.itd_nextitd), + O32TOH(sitd->itd.itd_be), 0); + CTASSERT(OHCI_ITD_NOFFSET == 8); + DPRINTF(" offs[0] = 0x%04x offs[1] = 0x%04x " + "offs[2] = 0x%04x offs[3] = 0x%04x", + O16TOH(sitd->itd.itd_offset[0]), + O16TOH(sitd->itd.itd_offset[1]), + O16TOH(sitd->itd.itd_offset[2]), + O16TOH(sitd->itd.itd_offset[3])); + DPRINTF(" offs[4] = 0x%04x offs[5] = 0x%04x " + "offs[6] = 0x%04x offs[7] = 0x%04x", + O16TOH(sitd->itd.itd_offset[4]), + O16TOH(sitd->itd.itd_offset[5]), + O16TOH(sitd->itd.itd_offset[6]), + O16TOH(sitd->itd.itd_offset[7])); } void @@ -2080,47 +2028,53 @@ ohci_dump_itds(ohci_softc_t *sc, ohci_soft_itd_t *sitd) void ohci_dump_ed(ohci_softc_t *sc, ohci_soft_ed_t *sed) { - char sbuf[128], sbuf2[128]; + OHCIHIST_FUNC(); OHCIHIST_CALLED(); usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - snprintb(sbuf, sizeof(sbuf), - "\20\14OUT\15IN\16LOWSPEED\17SKIP\20ISO", - (u_int32_t)O32TOH(sed->ed.ed_flags)); - snprintb(sbuf2, sizeof(sbuf2), "\20\1HALT\2CARRY", - (u_int32_t)O32TOH(sed->ed.ed_headp)); - - printf("ED(%p) at 0x%08lx: addr=%d endpt=%d maxp=%d flags=%s\ntailp=0x%08lx " - "headflags=%s headp=0x%08lx nexted=0x%08lx\n", - sed, (u_long)sed->physaddr, - OHCI_ED_GET_FA(O32TOH(sed->ed.ed_flags)), - OHCI_ED_GET_EN(O32TOH(sed->ed.ed_flags)), - OHCI_ED_GET_MAXP(O32TOH(sed->ed.ed_flags)), sbuf, - (u_long)O32TOH(sed->ed.ed_tailp), sbuf2, - (u_long)O32TOH(sed->ed.ed_headp), - (u_long)O32TOH(sed->ed.ed_nexted)); + + uint32_t flags = O32TOH(sed->ed.ed_flags); + DPRINTF("ED(%p) at 0x%08lx:", sed, sed->physaddr, 0, 0); + DPRINTF(" addr=%d endpt=%d maxp=%d", + OHCI_ED_GET_FA(flags), + OHCI_ED_GET_EN(flags), + OHCI_ED_GET_MAXP(flags), + 0); + DPRINTF(" dir=%d speed=%d skip=%d iso=%d", + __SHIFTOUT(flags, OHCI_ED_DIR_MASK), + !!(flags & OHCI_ED_SPEED), + !!(flags & OHCI_ED_SKIP), + !!(flags & OHCI_ED_FORMAT_ISO)); + DPRINTF(" tailp=0x%08lx", (u_long)O32TOH(sed->ed.ed_tailp), + 0, 0, 0); + DPRINTF(" headp=0x%08lx nexted=0x%08lx halted=%d carry=%d", + O32TOH(sed->ed.ed_headp), O32TOH(sed->ed.ed_nexted), + !!(O32TOH(sed->ed.ed_headp) & OHCI_HALTED), + !!(O32TOH(sed->ed.ed_headp) & OHCI_TOGGLECARRY)); } #endif usbd_status -ohci_open(usbd_pipe_handle pipe) -{ - usbd_device_handle dev = pipe->device; - ohci_softc_t *sc = dev->bus->hci_private; - usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc; - struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; - u_int8_t addr = dev->address; - u_int8_t xfertype = ed->bmAttributes & UE_XFERTYPE; +ohci_open(struct usbd_pipe *pipe) +{ + struct usbd_device *dev = pipe->up_dev; + struct usbd_bus *bus = dev->ud_bus; + ohci_softc_t *sc = OHCI_PIPE2SC(pipe); + usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc; + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(pipe); + uint8_t addr = dev->ud_addr; + uint8_t xfertype = ed->bmAttributes & UE_XFERTYPE; ohci_soft_ed_t *sed; ohci_soft_td_t *std; ohci_soft_itd_t *sitd; ohci_physaddr_t tdphys; - u_int32_t fmt; + uint32_t fmt; usbd_status err = USBD_NOMEM; int ival; - DPRINTFN(1, ("ohci_open: pipe=%p, addr=%d, endpt=%d (%d)\n", - pipe, addr, ed->bEndpointAddress, sc->sc_addr)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTFN(1, "pipe=%p, addr=%d, endpt=%d (%d)", pipe, addr, + ed->bEndpointAddress, bus->ub_rhaddr); if (sc->sc_dying) { return USBD_IOERROR; @@ -2129,13 +2083,13 @@ ohci_open(usbd_pipe_handle pipe) std = NULL; sed = NULL; - if (addr == sc->sc_addr) { + if (addr == bus->ub_rhaddr) { switch (ed->bEndpointAddress) { case USB_CONTROL_ENDPOINT: - pipe->methods = &ohci_root_ctrl_methods; + pipe->up_methods = &roothub_ctrl_methods; break; - case UE_DIR_IN | OHCI_INTR_ENDPT: - pipe->methods = &ohci_root_intr_methods; + case UE_DIR_IN | USBROOTHUB_INTR_ENDPT: + pipe->up_methods = &ohci_root_intr_methods; break; default: err = USBD_INVAL; @@ -2147,9 +2101,7 @@ ohci_open(usbd_pipe_handle pipe) goto bad; opipe->sed = sed; if (xfertype == UE_ISOCHRONOUS) { - mutex_enter(&sc->sc_lock); sitd = ohci_alloc_sitd(sc); - mutex_exit(&sc->sc_lock); if (sitd == NULL) goto bad; @@ -2161,9 +2113,7 @@ ohci_open(usbd_pipe_handle pipe) else fmt |= OHCI_ED_DIR_OUT; } else { - mutex_enter(&sc->sc_lock); std = ohci_alloc_std(sc); - mutex_exit(&sc->sc_lock); if (std == NULL) goto bad; @@ -2174,21 +2124,21 @@ ohci_open(usbd_pipe_handle pipe) sed->ed.ed_flags = HTOO32( OHCI_ED_SET_FA(addr) | OHCI_ED_SET_EN(UE_GET_ADDR(ed->bEndpointAddress)) | - (dev->speed == USB_SPEED_LOW ? OHCI_ED_SPEED : 0) | + (dev->ud_speed == USB_SPEED_LOW ? OHCI_ED_SPEED : 0) | fmt | OHCI_ED_SET_MAXP(UGETW(ed->wMaxPacketSize))); sed->ed.ed_headp = HTOO32(tdphys | - (pipe->endpoint->datatoggle ? OHCI_TOGGLECARRY : 0)); + (pipe->up_endpoint->ue_toggle ? OHCI_TOGGLECARRY : 0)); sed->ed.ed_tailp = HTOO32(tdphys); usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); switch (xfertype) { case UE_CONTROL: - pipe->methods = &ohci_device_ctrl_methods; + pipe->up_methods = &ohci_device_ctrl_methods; err = usb_allocmem(&sc->sc_bus, sizeof(usb_device_request_t), - 0, &opipe->u.ctl.reqdma); + 0, &opipe->ctrl.reqdma); if (err) goto bad; mutex_enter(&sc->sc_lock); @@ -2196,8 +2146,8 @@ ohci_open(usbd_pipe_handle pipe) mutex_exit(&sc->sc_lock); break; case UE_INTERRUPT: - pipe->methods = &ohci_device_intr_methods; - ival = pipe->interval; + pipe->up_methods = &ohci_device_intr_methods; + ival = pipe->up_interval; if (ival == USBD_DEFAULT_INTERVAL) ival = ed->bInterval; err = ohci_device_setintr(sc, opipe, ival); @@ -2205,10 +2155,11 @@ ohci_open(usbd_pipe_handle pipe) goto bad; break; case UE_ISOCHRONOUS: - pipe->methods = &ohci_device_isoc_methods; - return (ohci_setup_isoc(pipe)); + pipe->up_serialise = false; + pipe->up_methods = &ohci_device_isoc_methods; + return ohci_setup_isoc(pipe); case UE_BULK: - pipe->methods = &ohci_device_bulk_methods; + pipe->up_methods = &ohci_device_bulk_methods; mutex_enter(&sc->sc_lock); ohci_add_ed(sc, sed, sc->sc_bulk_head); mutex_exit(&sc->sc_lock); @@ -2220,9 +2171,7 @@ ohci_open(usbd_pipe_handle pipe) bad: if (std != NULL) { - mutex_enter(&sc->sc_lock); ohci_free_std(sc, std); - mutex_exit(&sc->sc_lock); } if (sed != NULL) ohci_free_sed(sc, sed); @@ -2235,10 +2184,10 @@ ohci_open(usbd_pipe_handle pipe) * Assumes that there are no pending transactions. */ void -ohci_close_pipe(usbd_pipe_handle pipe, ohci_soft_ed_t *head) +ohci_close_pipe(struct usbd_pipe *pipe, ohci_soft_ed_t *head) { - struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; - ohci_softc_t *sc = pipe->device->bus->hci_private; + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(pipe); + ohci_softc_t *sc = OHCI_PIPE2SC(pipe); ohci_soft_ed_t *sed = opipe->sed; KASSERT(mutex_owned(&sc->sc_lock)); @@ -2269,9 +2218,9 @@ ohci_close_pipe(usbd_pipe_handle pipe, ohci_soft_ed_t *head) ohci_rem_ed(sc, sed, head); /* Make sure the host controller is not touching this ED */ usb_delay_ms(&sc->sc_bus, 1); - pipe->endpoint->datatoggle = + pipe->up_endpoint->ue_toggle = (O32TOH(sed->ed.ed_headp) & OHCI_TOGGLECARRY) ? 1 : 0; - ohci_free_sed(sc, opipe->sed); + ohci_free_sed_locked(sc, opipe->sed); } /* @@ -2287,57 +2236,56 @@ ohci_close_pipe(usbd_pipe_handle pipe, ohci_soft_ed_t *head) * XXXMRG this doesn't make sense anymore. */ void -ohci_abort_xfer(usbd_xfer_handle xfer, usbd_status status) +ohci_abort_xfer(struct usbd_xfer *xfer, usbd_status status) { - struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; - ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); + ohci_softc_t *sc = OHCI_XFER2SC(xfer); ohci_soft_ed_t *sed = opipe->sed; ohci_soft_td_t *p, *n; ohci_physaddr_t headp; int hit; int wake; - DPRINTF(("ohci_abort_xfer: xfer=%p pipe=%p sed=%p\n", xfer, opipe,sed)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTF("xfer=%p pipe=%p sed=%p", xfer, opipe,sed, 0); KASSERT(mutex_owned(&sc->sc_lock)); + ASSERT_SLEEPABLE(); if (sc->sc_dying) { /* If we're dying, just do the software part. */ - xfer->status = status; /* make software ignore it */ - callout_halt(&xfer->timeout_handle, &sc->sc_lock); + xfer->ux_status = status; /* make software ignore it */ + callout_halt(&xfer->ux_callout, &sc->sc_lock); usb_transfer_complete(xfer); return; } - if (cpu_intr_p() || cpu_softintr_p()) - panic("ohci_abort_xfer: not in process context"); - /* * If an abort is already in progress then just wait for it to * complete and return. */ - if (xfer->hcflags & UXFER_ABORTING) { - DPRINTFN(2, ("ohci_abort_xfer: already aborting\n")); + if (xfer->ux_hcflags & UXFER_ABORTING) { + DPRINTFN(2, "already aborting", 0, 0, 0, 0); #ifdef DIAGNOSTIC if (status == USBD_TIMEOUT) printf("%s: TIMEOUT while aborting\n", __func__); #endif /* Override the status which might be USBD_TIMEOUT. */ - xfer->status = status; - DPRINTFN(2, ("ohci_abort_xfer: waiting for abort to finish\n")); - xfer->hcflags |= UXFER_ABORTWAIT; - while (xfer->hcflags & UXFER_ABORTING) - cv_wait(&xfer->hccv, &sc->sc_lock); + xfer->ux_status = status; + DPRINTFN(2, "waiting for abort to finish", 0, 0, 0, 0); + xfer->ux_hcflags |= UXFER_ABORTWAIT; + while (xfer->ux_hcflags & UXFER_ABORTING) + cv_wait(&xfer->ux_hccv, &sc->sc_lock); goto done; } - xfer->hcflags |= UXFER_ABORTING; + xfer->ux_hcflags |= UXFER_ABORTING; /* * Step 1: Make interrupt routine and hardware ignore xfer. */ - xfer->status = status; /* make software ignore it */ - callout_stop(&xfer->timeout_handle); - DPRINTFN(1,("ohci_abort_xfer: stop ed=%p\n", sed)); + xfer->ux_status = status; /* make software ignore it */ + callout_stop(&xfer->ux_callout); + DPRINTFN(1, "stop ed=%p", sed, 0, 0, 0); usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), sizeof(sed->ed.ed_flags), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); @@ -2352,7 +2300,7 @@ ohci_abort_xfer(usbd_xfer_handle xfer, usbd_status status) * has run. */ /* Hardware finishes in 1ms */ - usb_delay_ms_locked(opipe->pipe.device->bus, 20, &sc->sc_lock); + usb_delay_ms_locked(opipe->pipe.up_dev->ud_bus, 20, &sc->sc_lock); sc->sc_softwake = 1; usb_schedsoftintr(&sc->sc_bus); cv_wait(&sc->sc_softwake_cv, &sc->sc_lock); @@ -2364,39 +2312,37 @@ ohci_abort_xfer(usbd_xfer_handle xfer, usbd_status status) * the TDs of this xfer we check if the hardware points to * any of them. */ - p = xfer->hcpriv; -#ifdef DIAGNOSTIC - if (p == NULL) { - xfer->hcflags &= ~UXFER_ABORTING; /* XXX */ - printf("ohci_abort_xfer: hcpriv is NULL\n"); - goto done; - } -#endif + p = xfer->ux_hcpriv; + KASSERT(p); + #ifdef OHCI_DEBUG - if (ohcidebug > 1) { - DPRINTF(("ohci_abort_xfer: sed=\n")); + DPRINTF("--- dump start ---", 0, 0, 0, 0); + + if (ohcidebug >= 2) { + DPRINTF("sed:", 0, 0, 0, 0); ohci_dump_ed(sc, sed); ohci_dump_tds(sc, p); } + DPRINTF("--- dump end ---", 0, 0, 0, 0); #endif headp = O32TOH(sed->ed.ed_headp) & OHCI_HEADMASK; hit = 0; for (; p->xfer == xfer; p = n) { hit |= headp == p->physaddr; n = p->nexttd; - ohci_free_std(sc, p); + ohci_hash_rem_td(sc, p); } /* Zap headp register if hardware pointed inside the xfer. */ if (hit) { - DPRINTFN(1,("ohci_abort_xfer: set hd=0x%08x, tl=0x%08x\n", - (int)p->physaddr, (int)O32TOH(sed->ed.ed_tailp))); + DPRINTFN(1, "set hd=0x%08x, tl=0x%08x", (int)p->physaddr, + (int)O32TOH(sed->ed.ed_tailp), 0, 0); sed->ed.ed_headp = HTOO32(p->physaddr); /* unlink TDs */ usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_headp), sizeof(sed->ed.ed_headp), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } else { - DPRINTFN(1,("ohci_abort_xfer: no hit\n")); + DPRINTFN(1, "no hit", 0, 0, 0, 0); } /* @@ -2413,11 +2359,11 @@ ohci_abort_xfer(usbd_xfer_handle xfer, usbd_status status) /* * Step 5: Execute callback. */ - wake = xfer->hcflags & UXFER_ABORTWAIT; - xfer->hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); + wake = xfer->ux_hcflags & UXFER_ABORTWAIT; + xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); usb_transfer_complete(xfer); if (wake) - cv_broadcast(&xfer->hccv); + cv_broadcast(&xfer->ux_hccv); done: KASSERT(mutex_owned(&sc->sc_lock)); @@ -2426,235 +2372,69 @@ done: /* * Data structures and routines to emulate the root hub. */ -Static usb_device_descriptor_t ohci_devd = { - USB_DEVICE_DESCRIPTOR_SIZE, - UDESC_DEVICE, /* type */ - {0x00, 0x01}, /* USB version */ - UDCLASS_HUB, /* class */ - UDSUBCLASS_HUB, /* subclass */ - UDPROTO_FSHUB, /* protocol */ - 64, /* max packet */ - {0},{0},{0x00,0x01}, /* device id */ - 1,2,0, /* string indicies */ - 1 /* # of configurations */ -}; - -Static const usb_config_descriptor_t ohci_confd = { - USB_CONFIG_DESCRIPTOR_SIZE, - UDESC_CONFIG, - {USB_CONFIG_DESCRIPTOR_SIZE + - USB_INTERFACE_DESCRIPTOR_SIZE + - USB_ENDPOINT_DESCRIPTOR_SIZE}, - 1, - 1, - 0, - UC_ATTR_MBO | UC_SELF_POWERED, - 0 /* max power */ -}; - -Static const usb_interface_descriptor_t ohci_ifcd = { - USB_INTERFACE_DESCRIPTOR_SIZE, - UDESC_INTERFACE, - 0, - 0, - 1, - UICLASS_HUB, - UISUBCLASS_HUB, - UIPROTO_FSHUB, - 0 -}; - -Static const usb_endpoint_descriptor_t ohci_endpd = { - .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE, - .bDescriptorType = UDESC_ENDPOINT, - .bEndpointAddress = UE_DIR_IN | OHCI_INTR_ENDPT, - .bmAttributes = UE_INTERRUPT, - .wMaxPacketSize = {8, 0}, /* max packet */ - .bInterval = 255, -}; - -Static const usb_hub_descriptor_t ohci_hubd = { - .bDescLength = USB_HUB_DESCRIPTOR_SIZE, - .bDescriptorType = UDESC_HUB, -}; - -/* - * Simulate a hardware hub by handling all the necessary requests. - */ -Static usbd_status -ohci_root_ctrl_transfer(usbd_xfer_handle xfer) -{ - ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; - usbd_status err; - - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return (err); - - /* Pipe isn't running, start first */ - return (ohci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); -} - -Static usbd_status -ohci_root_ctrl_start(usbd_xfer_handle xfer) +Static int +ohci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, + void *buf, int buflen) { - ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; - usb_device_request_t *req; - void *buf = NULL; - int port, i; - int len, value, index, l, totlen = 0; + ohci_softc_t *sc = OHCI_BUS2SC(bus); usb_port_status_t ps; - usb_hub_descriptor_t hubd; - usbd_status err; - u_int32_t v; + uint16_t len, value, index; + int l, totlen = 0; + int port, i; + uint32_t v; - if (sc->sc_dying) - return (USBD_IOERROR); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); -#ifdef DIAGNOSTIC - if (!(xfer->rqflags & URQ_REQUEST)) - /* XXX panic */ - return (USBD_INVAL); -#endif - req = &xfer->request; + if (sc->sc_dying) + return -1; - DPRINTFN(4,("ohci_root_ctrl_control type=0x%02x request=%02x\n", - req->bmRequestType, req->bRequest)); + DPRINTFN(4, "type=0x%02x request=%02x", req->bmRequestType, + req->bRequest, 0, 0); len = UGETW(req->wLength); value = UGETW(req->wValue); index = UGETW(req->wIndex); - if (len != 0) - buf = KERNADDR(&xfer->dmabuf, 0); - #define C(x,y) ((x) | ((y) << 8)) - switch(C(req->bRequest, req->bmRequestType)) { - case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE): - case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE): - case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT): - /* - * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops - * for the integrated root hub. - */ - break; - case C(UR_GET_CONFIG, UT_READ_DEVICE): - if (len > 0) { - *(u_int8_t *)buf = sc->sc_conf; - totlen = 1; - } - break; + switch (C(req->bRequest, req->bmRequestType)) { case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): - DPRINTFN(8,("ohci_root_ctrl_control wValue=0x%04x\n", value)); + DPRINTFN(8, "wValue=0x%04x", value, 0, 0, 0); if (len == 0) break; - switch(value >> 8) { - case UDESC_DEVICE: - if ((value & 0xff) != 0) { - err = USBD_IOERROR; - goto ret; - } - totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE); - USETW(ohci_devd.idVendor, sc->sc_id_vendor); - memcpy(buf, &ohci_devd, l); - break; - case UDESC_CONFIG: - if ((value & 0xff) != 0) { - err = USBD_IOERROR; - goto ret; - } - totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE); - memcpy(buf, &ohci_confd, l); - buf = (char *)buf + l; - len -= l; - l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE); - totlen += l; - memcpy(buf, &ohci_ifcd, l); - buf = (char *)buf + l; - len -= l; - l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE); - totlen += l; - memcpy(buf, &ohci_endpd, l); + switch (value) { + case C(0, UDESC_DEVICE): { + usb_device_descriptor_t devd; + + totlen = min(buflen, sizeof(devd)); + memcpy(&devd, buf, totlen); + USETW(devd.idVendor, sc->sc_id_vendor); + memcpy(buf, &devd, totlen); break; - case UDESC_STRING: + } + case C(1, UDESC_STRING): #define sd ((usb_string_descriptor_t *)buf) - switch (value & 0xff) { - case 0: /* Language table */ - totlen = usb_makelangtbl(sd, len); - break; - case 1: /* Vendor */ - totlen = usb_makestrdesc(sd, len, - sc->sc_vendor); - break; - case 2: /* Product */ - totlen = usb_makestrdesc(sd, len, - "OHCI root hub"); - break; - } -#undef sd + /* Vendor */ + totlen = usb_makestrdesc(sd, len, sc->sc_vendor); + break; + case C(2, UDESC_STRING): + /* Product */ + totlen = usb_makestrdesc(sd, len, "OHCI root hub"); break; +#undef sd default: - err = USBD_IOERROR; - goto ret; - } - break; - case C(UR_GET_INTERFACE, UT_READ_INTERFACE): - if (len > 0) { - *(u_int8_t *)buf = 0; - totlen = 1; - } - break; - case C(UR_GET_STATUS, UT_READ_DEVICE): - if (len > 1) { - USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED); - totlen = 2; - } - break; - case C(UR_GET_STATUS, UT_READ_INTERFACE): - case C(UR_GET_STATUS, UT_READ_ENDPOINT): - if (len > 1) { - USETW(((usb_status_t *)buf)->wStatus, 0); - totlen = 2; + /* default from usbroothub */ + return buflen; } break; - case C(UR_SET_ADDRESS, UT_WRITE_DEVICE): - if (value >= USB_MAX_DEVICES) { - err = USBD_IOERROR; - goto ret; - } - sc->sc_addr = value; - break; - case C(UR_SET_CONFIG, UT_WRITE_DEVICE): - if (value != 0 && value != 1) { - err = USBD_IOERROR; - goto ret; - } - sc->sc_conf = value; - break; - case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE): - break; - case C(UR_SET_FEATURE, UT_WRITE_DEVICE): - case C(UR_SET_FEATURE, UT_WRITE_INTERFACE): - case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT): - err = USBD_IOERROR; - goto ret; - case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE): - break; - case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT): - break; + /* Hub requests */ case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE): break; case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): - DPRINTFN(8, ("ohci_root_ctrl_control: UR_CLEAR_PORT_FEATURE " - "port=%d feature=%d\n", - index, value)); + DPRINTFN(8, "UR_CLEAR_PORT_FEATURE port=%d feature=%d", + index, value, 0, 0); if (index < 1 || index > sc->sc_noport) { - err = USBD_IOERROR; - goto ret; + return -1; } port = OHCI_RH_PORT_STATUS(index); switch(value) { @@ -2684,8 +2464,7 @@ ohci_root_ctrl_start(usbd_xfer_handle xfer) OWRITE4(sc, port, UPS_C_PORT_RESET << 16); break; default: - err = USBD_IOERROR; - goto ret; + return -1; } switch(value) { case UHF_C_PORT_CONNECTION: @@ -2705,11 +2484,14 @@ ohci_root_ctrl_start(usbd_xfer_handle xfer) if (len == 0) break; if ((value & 0xff) != 0) { - err = USBD_IOERROR; - goto ret; + return -1; } + usb_hub_descriptor_t hubd; + + totlen = min(buflen, sizeof(hubd)); + memcpy(&hubd, buf, totlen); + v = OREAD4(sc, OHCI_RH_DESCRIPTOR_A); - hubd = ohci_hubd; hubd.bNbrPorts = sc->sc_noport; USETW(hubd.wHubCharacteristics, (v & OHCI_NPS ? UHD_PWR_NO_SWITCH : @@ -2719,49 +2501,40 @@ ohci_root_ctrl_start(usbd_xfer_handle xfer) hubd.bPwrOn2PwrGood = OHCI_GET_POTPGT(v); v = OREAD4(sc, OHCI_RH_DESCRIPTOR_B); for (i = 0, l = sc->sc_noport; l > 0; i++, l -= 8, v >>= 8) - hubd.DeviceRemovable[i++] = (u_int8_t)v; + hubd.DeviceRemovable[i++] = (uint8_t)v; hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i; - l = min(len, hubd.bDescLength); - totlen = l; - memcpy(buf, &hubd, l); + totlen = min(totlen, hubd.bDescLength); + memcpy(buf, &hubd, totlen); break; case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): if (len != 4) { - err = USBD_IOERROR; - goto ret; + return -1; } memset(buf, 0, len); /* ? XXX */ totlen = len; break; case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): - DPRINTFN(8,("ohci_root_ctrl_transfer: get port status i=%d\n", - index)); + DPRINTFN(8, "get port status i=%d", index, 0, 0, 0); if (index < 1 || index > sc->sc_noport) { - err = USBD_IOERROR; - goto ret; + return -1; } if (len != 4) { - err = USBD_IOERROR; - goto ret; + return -1; } v = OREAD4(sc, OHCI_RH_PORT_STATUS(index)); - DPRINTFN(8,("ohci_root_ctrl_transfer: port status=0x%04x\n", - v)); + DPRINTFN(8, "port status=0x%04x", v, 0, 0, 0); USETW(ps.wPortStatus, v); USETW(ps.wPortChange, v >> 16); - l = min(len, sizeof ps); - memcpy(buf, &ps, l); - totlen = l; + totlen = min(len, sizeof(ps)); + memcpy(buf, &ps, totlen); break; case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE): - err = USBD_IOERROR; - goto ret; + return -1; 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) { - err = USBD_IOERROR; - goto ret; + return -1; } port = OHCI_RH_PORT_STATUS(index); switch(value) { @@ -2772,65 +2545,40 @@ ohci_root_ctrl_start(usbd_xfer_handle xfer) OWRITE4(sc, port, UPS_SUSPEND); break; case UHF_PORT_RESET: - DPRINTFN(5,("ohci_root_ctrl_transfer: reset port %d\n", - index)); + DPRINTFN(5, "reset port %d", index, 0, 0, 0); OWRITE4(sc, port, UPS_RESET); for (i = 0; i < 5; i++) { usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY); if (sc->sc_dying) { - err = USBD_IOERROR; - goto ret; + return -1; } if ((OREAD4(sc, port) & UPS_RESET) == 0) break; } - DPRINTFN(8,("ohci port %d reset, status = 0x%04x\n", - index, OREAD4(sc, port))); + DPRINTFN(8, "port %d reset, status = 0x%04x", index, + OREAD4(sc, port), 0, 0); break; case UHF_PORT_POWER: - DPRINTFN(2,("ohci_root_ctrl_transfer: set port power " - "%d\n", index)); + DPRINTFN(2, "set port power %d", index, 0, 0, 0); OWRITE4(sc, port, UPS_PORT_POWER); break; default: - err = USBD_IOERROR; - goto ret; + return -1; } break; default: - err = USBD_IOERROR; - goto ret; + /* default from usbroothub */ + return buflen; } - xfer->actlen = totlen; - err = USBD_NORMAL_COMPLETION; - ret: - xfer->status = err; - mutex_enter(&sc->sc_lock); - usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); - return (USBD_IN_PROGRESS); -} - -/* Abort a root control request. */ -Static void -ohci_root_ctrl_abort(usbd_xfer_handle xfer) -{ - /* Nothing to do, all transfers are synchronous. */ -} -/* Close the root pipe. */ -Static void -ohci_root_ctrl_close(usbd_pipe_handle pipe) -{ - DPRINTF(("ohci_root_ctrl_close\n")); - /* Nothing to do. */ + return totlen; } Static usbd_status -ohci_root_intr_transfer(usbd_xfer_handle xfer) +ohci_root_intr_transfer(struct usbd_xfer *xfer) { - ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; + ohci_softc_t *sc = OHCI_XFER2SC(xfer); usbd_status err; /* Insert last in queue. */ @@ -2838,63 +2586,134 @@ ohci_root_intr_transfer(usbd_xfer_handle xfer) err = usb_insert_transfer(xfer); mutex_exit(&sc->sc_lock); if (err) - return (err); + return err; /* Pipe isn't running, start first */ - return (ohci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return ohci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } Static usbd_status -ohci_root_intr_start(usbd_xfer_handle xfer) +ohci_root_intr_start(struct usbd_xfer *xfer) { - usbd_pipe_handle pipe = xfer->pipe; - ohci_softc_t *sc = pipe->device->bus->hci_private; + ohci_softc_t *sc = OHCI_XFER2SC(xfer); if (sc->sc_dying) - return (USBD_IOERROR); + return USBD_IOERROR; mutex_enter(&sc->sc_lock); KASSERT(sc->sc_intrxfer == NULL); sc->sc_intrxfer = xfer; mutex_exit(&sc->sc_lock); - return (USBD_IN_PROGRESS); + return USBD_IN_PROGRESS; } /* Abort a root interrupt request. */ Static void -ohci_root_intr_abort(usbd_xfer_handle xfer) +ohci_root_intr_abort(struct usbd_xfer *xfer) { - ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; + ohci_softc_t *sc = OHCI_XFER2SC(xfer); KASSERT(mutex_owned(&sc->sc_lock)); - KASSERT(xfer->pipe->intrxfer == xfer); + KASSERT(xfer->ux_pipe->up_intrxfer == xfer); sc->sc_intrxfer = NULL; - xfer->status = USBD_CANCELLED; + xfer->ux_status = USBD_CANCELLED; usb_transfer_complete(xfer); } /* Close the root pipe. */ Static void -ohci_root_intr_close(usbd_pipe_handle pipe) +ohci_root_intr_close(struct usbd_pipe *pipe) { - ohci_softc_t *sc = pipe->device->bus->hci_private; + ohci_softc_t *sc = OHCI_PIPE2SC(pipe); KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTF(("ohci_root_intr_close\n")); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); sc->sc_intrxfer = NULL; } /************************/ +int +ohci_device_ctrl_init(struct usbd_xfer *xfer) +{ + struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); + usb_device_request_t *req = &xfer->ux_request; + ohci_softc_t *sc = OHCI_XFER2SC(xfer); + ohci_soft_td_t *stat, *setup; + int isread = req->bmRequestType & UT_READ; + int len = xfer->ux_bufsize; + int err = ENOMEM; + + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + + setup = ohci_alloc_std(sc); + if (setup == NULL) { + goto bad1; + } + stat = ohci_alloc_std(sc); + if (stat == NULL) { + goto bad2; + } + + ox->ox_setup = setup; + ox->ox_stat = stat; + ox->ox_nstd = 0; + + /* Set up data transaction */ + if (len != 0) { + err = ohci_alloc_std_chain(sc, xfer, len, isread); + if (err) { + goto bad3; + } + } + return 0; + + bad3: + ohci_free_std(sc, stat); + bad2: + ohci_free_std(sc, setup); + bad1: + return err; +} + +void +ohci_device_ctrl_fini(struct usbd_xfer *xfer) +{ + struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); + ohci_softc_t *sc = OHCI_XFER2SC(xfer); + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); + + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTFN(8, "xfer %p nstd %d", xfer, ox->ox_nstd, 0, 0); + + mutex_enter(&sc->sc_lock); + if (ox->ox_setup != opipe->tail.td) { + ohci_free_std_locked(sc, ox->ox_setup); + } + for (size_t i = 0; i < ox->ox_nstd; i++) { + ohci_soft_td_t *std = ox->ox_stds[i]; + if (std == NULL) + break; + ohci_free_std_locked(sc, std); + } + ohci_free_std_locked(sc, ox->ox_stat); + mutex_exit(&sc->sc_lock); + + if (ox->ox_nstd) { + const size_t sz = sizeof(ohci_soft_td_t *) * ox->ox_nstd; + kmem_free(ox->ox_stds, sz); + } +} + Static usbd_status -ohci_device_ctrl_transfer(usbd_xfer_handle xfer) +ohci_device_ctrl_transfer(struct usbd_xfer *xfer) { - ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; + ohci_softc_t *sc = OHCI_XFER2SC(xfer); usbd_status err; /* Insert last in queue. */ @@ -2902,88 +2721,272 @@ ohci_device_ctrl_transfer(usbd_xfer_handle xfer) err = usb_insert_transfer(xfer); mutex_exit(&sc->sc_lock); if (err) - return (err); + return err; /* Pipe isn't running, start first */ - return (ohci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return ohci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } Static usbd_status -ohci_device_ctrl_start(usbd_xfer_handle xfer) +ohci_device_ctrl_start(struct usbd_xfer *xfer) { - ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; - usbd_status err; + ohci_softc_t *sc = OHCI_XFER2SC(xfer); + struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); + usb_device_request_t *req = &xfer->ux_request; + struct usbd_device *dev __diagused = opipe->pipe.up_dev; + ohci_soft_td_t *setup, *stat, *next, *tail; + ohci_soft_ed_t *sed; + int isread; + int len; + + OHCIHIST_FUNC(); OHCIHIST_CALLED(); if (sc->sc_dying) - return (USBD_IOERROR); + return USBD_IOERROR; -#ifdef DIAGNOSTIC - if (!(xfer->rqflags & URQ_REQUEST)) { - /* XXX panic */ - printf("ohci_device_ctrl_transfer: not a request\n"); - return (USBD_INVAL); + KASSERT(xfer->ux_rqflags & URQ_REQUEST); + + isread = req->bmRequestType & UT_READ; + len = UGETW(req->wLength); + + DPRINTF("xfer=%p len=%d, addr=%d, endpt=%d", xfer, len, dev->ud_addr, + opipe->pipe.up_endpoint->ue_edesc->bEndpointAddress); + DPRINTF("type=0x%02x, request=0x%02x, wValue=0x%04x, wIndex=0x%04x", + req->bmRequestType, req->bRequest, UGETW(req->wValue), + UGETW(req->wIndex)); + + /* Need to take lock here for pipe->tail.td */ + mutex_enter(&sc->sc_lock); + + /* + * Use the pipe "tail" TD as our first and loan our first TD to the + * next transfer + */ + setup = opipe->tail.td; + opipe->tail.td = ox->ox_setup; + ox->ox_setup = setup; + + stat = ox->ox_stat; + + /* point at sentinel */ + tail = opipe->tail.td; + sed = opipe->sed; + + KASSERTMSG(OHCI_ED_GET_FA(O32TOH(sed->ed.ed_flags)) == dev->ud_addr, + "address ED %d pipe %d\n", + OHCI_ED_GET_FA(O32TOH(sed->ed.ed_flags)), dev->ud_addr); + KASSERTMSG(OHCI_ED_GET_MAXP(O32TOH(sed->ed.ed_flags)) == + UGETW(opipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize), + "MPL ED %d pipe %d\n", + OHCI_ED_GET_MAXP(O32TOH(sed->ed.ed_flags)), + UGETW(opipe->pipe.up_endpoint->ue_edesc->wMaxPacketSize)); + + /* next will point to data if len != 0 */ + next = stat; + + /* Set up data transaction */ + if (len != 0) { + ohci_soft_td_t *std; + ohci_soft_td_t *end; + + next = ox->ox_stds[0]; + ohci_reset_std_chain(sc, xfer, len, isread, next, &end); + + end->td.td_nexttd = HTOO32(stat->physaddr); + end->nexttd = stat; + + usb_syncmem(&end->dma, + end->offs + offsetof(ohci_td_t, td_nexttd), + sizeof(end->td.td_nexttd), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + + usb_syncmem(&xfer->ux_dmabuf, 0, len, + isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); + std = ox->ox_stds[0]; + /* Start toggle at 1 and then use the carried toggle. */ + std->td.td_flags &= HTOO32(~OHCI_TD_TOGGLE_MASK); + std->td.td_flags |= HTOO32(OHCI_TD_TOGGLE_1); + usb_syncmem(&std->dma, + std->offs + offsetof(ohci_td_t, td_flags), + sizeof(std->td.td_flags), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } + + DPRINTFN(8, "setup %p data %p stat %p tail %p", setup, + (len != 0 ? ox->ox_stds[0] : NULL), stat, tail); + KASSERT(opipe->tail.td == tail); + + memcpy(KERNADDR(&opipe->ctrl.reqdma, 0), req, sizeof(*req)); + usb_syncmem(&opipe->ctrl.reqdma, 0, sizeof(*req), BUS_DMASYNC_PREWRITE); + + setup->td.td_flags = HTOO32(OHCI_TD_SETUP | OHCI_TD_NOCC | + OHCI_TD_TOGGLE_0 | OHCI_TD_NOINTR); + setup->td.td_cbp = HTOO32(DMAADDR(&opipe->ctrl.reqdma, 0)); + setup->td.td_nexttd = HTOO32(next->physaddr); + setup->td.td_be = HTOO32(O32TOH(setup->td.td_cbp) + sizeof(*req) - 1); + setup->nexttd = next; + setup->len = 0; + setup->xfer = xfer; + setup->flags = 0; + ohci_hash_add_td(sc, setup); + + xfer->ux_hcpriv = setup; + usb_syncmem(&setup->dma, setup->offs, sizeof(setup->td), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + + stat->td.td_flags = HTOO32( + (isread ? OHCI_TD_OUT : OHCI_TD_IN) | + OHCI_TD_NOCC | OHCI_TD_TOGGLE_1 | OHCI_TD_SET_DI(1)); + stat->td.td_cbp = 0; + stat->td.td_nexttd = HTOO32(tail->physaddr); + stat->td.td_be = 0; + stat->nexttd = tail; + stat->flags = OHCI_CALL_DONE; + stat->len = 0; + stat->xfer = xfer; + ohci_hash_add_td(sc, stat); + + usb_syncmem(&stat->dma, stat->offs, sizeof(stat->td), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + + memset(&tail->td, 0, sizeof(tail->td)); + tail->nexttd = NULL; + tail->xfer = NULL; + + usb_syncmem(&tail->dma, tail->offs, sizeof(tail->td), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + +#ifdef OHCI_DEBUG + USBHIST_LOGN(ohcidebug, 5, "--- dump start ---", 0, 0, 0, 0); + if (ohcidebug >= 5) { + ohci_dump_ed(sc, sed); + ohci_dump_tds(sc, setup); + } + USBHIST_LOGN(ohcidebug, 5, "--- dump end ---", 0, 0, 0, 0); #endif - mutex_enter(&sc->sc_lock); - err = ohci_device_request(xfer); + /* Insert ED in schedule */ + sed->ed.ed_tailp = HTOO32(tail->physaddr); + usb_syncmem(&sed->dma, + sed->offs + offsetof(ohci_ed_t, ed_tailp), + sizeof(sed->ed.ed_tailp), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_CLF); + if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { + callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), + ohci_timeout, xfer); + } + + DPRINTF("done", 0, 0, 0, 0); + mutex_exit(&sc->sc_lock); - if (err) - return (err); - if (sc->sc_bus.use_polling) + if (sc->sc_bus.ub_usepolling) ohci_waitintr(sc, xfer); - return (USBD_IN_PROGRESS); + + return USBD_IN_PROGRESS; } /* Abort a device control request. */ Static void -ohci_device_ctrl_abort(usbd_xfer_handle xfer) +ohci_device_ctrl_abort(struct usbd_xfer *xfer) { -#ifdef DIAGNOSTIC - ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; -#endif + ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer); KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTF(("ohci_device_ctrl_abort: xfer=%p\n", xfer)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTF("xfer=%p", xfer, 0, 0, 0); ohci_abort_xfer(xfer, USBD_CANCELLED); } /* Close a device control pipe. */ Static void -ohci_device_ctrl_close(usbd_pipe_handle pipe) +ohci_device_ctrl_close(struct usbd_pipe *pipe) { - struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; - ohci_softc_t *sc = pipe->device->bus->hci_private; + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(pipe); + ohci_softc_t *sc = OHCI_PIPE2SC(pipe); KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTF(("ohci_device_ctrl_close: pipe=%p\n", pipe)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTF("pipe=%p", pipe, 0, 0, 0); ohci_close_pipe(pipe, sc->sc_ctrl_head); - ohci_free_std(sc, opipe->tail.td); + ohci_free_std_locked(sc, opipe->tail.td); } /************************/ Static void -ohci_device_clear_toggle(usbd_pipe_handle pipe) +ohci_device_clear_toggle(struct usbd_pipe *pipe) { - struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; - ohci_softc_t *sc = pipe->device->bus->hci_private; + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(pipe); + ohci_softc_t *sc = OHCI_PIPE2SC(pipe); opipe->sed->ed.ed_headp &= HTOO32(~OHCI_TOGGLECARRY); } Static void -ohci_noop(usbd_pipe_handle pipe) +ohci_noop(struct usbd_pipe *pipe) { } +Static int +ohci_device_bulk_init(struct usbd_xfer *xfer) +{ + ohci_softc_t *sc = OHCI_XFER2SC(xfer); + int len = xfer->ux_bufsize; + int endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress;; + int isread = UE_GET_DIR(endpt) == UE_DIR_IN; + int err; + + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); + + DPRINTFN(4, "xfer=%p len=%d isread=%d flags=%d", xfer, len, isread, + xfer->ux_flags); + DPRINTFN(4, "endpt=%d", endpt, 0, 0, 0); + + /* Allocate a chain of new TDs (including a new tail). */ + err = ohci_alloc_std_chain(sc, xfer, len, isread); + if (err) + return err; + + return 0; +} + +Static void +ohci_device_bulk_fini(struct usbd_xfer *xfer) +{ + ohci_softc_t *sc = OHCI_XFER2SC(xfer); + struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); + + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTFN(8, "xfer %p nstd %d", xfer, ox->ox_nstd, 0, 0); + + mutex_enter(&sc->sc_lock); + for (size_t i = 0; i < ox->ox_nstd; i++) { + ohci_soft_td_t *std = ox->ox_stds[i]; + if (std == NULL) + break; + if (std != opipe->tail.td) + ohci_free_std_locked(sc, std); + } + mutex_exit(&sc->sc_lock); + + if (ox->ox_nstd) { + const size_t sz = sizeof(ohci_soft_td_t *) * ox->ox_nstd; + kmem_free(ox->ox_stds, sz); + } +} + Static usbd_status -ohci_device_bulk_transfer(usbd_xfer_handle xfer) +ohci_device_bulk_transfer(struct usbd_xfer *xfer) { - ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; + ohci_softc_t *sc = OHCI_XFER2SC(xfer); usbd_status err; /* Insert last in queue. */ @@ -2991,133 +2994,117 @@ ohci_device_bulk_transfer(usbd_xfer_handle xfer) err = usb_insert_transfer(xfer); mutex_exit(&sc->sc_lock); if (err) - return (err); + return err; /* Pipe isn't running, start first */ - return (ohci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return ohci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } Static usbd_status -ohci_device_bulk_start(usbd_xfer_handle xfer) +ohci_device_bulk_start(struct usbd_xfer *xfer) { - struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; - usbd_device_handle dev = opipe->pipe.device; - ohci_softc_t *sc = dev->bus->hci_private; - int addr = dev->address; + struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); + ohci_softc_t *sc = OHCI_XFER2SC(xfer); + ohci_soft_td_t *last; ohci_soft_td_t *data, *tail, *tdp; ohci_soft_ed_t *sed; int len, isread, endpt; - usbd_status err; - if (sc->sc_dying) - return (USBD_IOERROR); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); -#ifdef DIAGNOSTIC - if (xfer->rqflags & URQ_REQUEST) { - /* XXX panic */ - printf("ohci_device_bulk_start: a request\n"); - return (USBD_INVAL); - } -#endif + if (sc->sc_dying) + return USBD_IOERROR; - mutex_enter(&sc->sc_lock); + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); - len = xfer->length; - endpt = xfer->pipe->endpoint->edesc->bEndpointAddress; + len = xfer->ux_length; + endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress; isread = UE_GET_DIR(endpt) == UE_DIR_IN; sed = opipe->sed; - 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; + DPRINTFN(4, "xfer=%p len=%d isread=%d flags=%d", xfer, len, isread, + xfer->ux_flags); + DPRINTFN(4, "endpt=%d", endpt, 0, 0, 0); - usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), - BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - /* Update device address */ - sed->ed.ed_flags = HTOO32( - (O32TOH(sed->ed.ed_flags) & ~OHCI_ED_ADDRMASK) | - OHCI_ED_SET_FA(addr)); + mutex_enter(&sc->sc_lock); - /* Allocate a chain of new TDs (including a new tail). */ + /* + * Use the pipe "tail" TD as our first and loan our first TD to the + * next transfer + */ data = opipe->tail.td; - err = ohci_alloc_std_chain(opipe, sc, len, isread, xfer, - data, &tail); - if (err) - return err; + opipe->tail.td = ox->ox_stds[0]; + ox->ox_stds[0] = data; + ohci_reset_std_chain(sc, xfer, len, isread, data, &last); + + /* point at sentinel */ + tail = opipe->tail.td; + memset(&tail->td, 0, sizeof(tail->td)); + tail->nexttd = NULL; + tail->xfer = NULL; + usb_syncmem(&tail->dma, tail->offs, sizeof(tail->td), + BUS_DMASYNC_PREWRITE); + xfer->ux_hcpriv = data; + + DPRINTFN(8, "xfer %p data %p tail %p", xfer, ox->ox_stds[0], tail, 0); + KASSERT(opipe->tail.td == tail); /* We want interrupt at the end of the transfer. */ - tail->td.td_flags &= HTOO32(~OHCI_TD_INTR_MASK); - tail->td.td_flags |= HTOO32(OHCI_TD_SET_DI(1)); - tail->flags |= OHCI_CALL_DONE; - tail = tail->nexttd; /* point at sentinel */ - usb_syncmem(&tail->dma, tail->offs + offsetof(ohci_td_t, td_flags), - sizeof(tail->td.td_flags), + last->td.td_flags &= HTOO32(~OHCI_TD_INTR_MASK); + last->td.td_flags |= HTOO32(OHCI_TD_SET_DI(1)); + last->td.td_nexttd = HTOO32(tail->physaddr); + last->nexttd = tail; + last->flags |= OHCI_CALL_DONE; + usb_syncmem(&last->dma, last->offs, sizeof(last->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - if (err) { - mutex_exit(&sc->sc_lock); - 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", + DPRINTFN(4, "ed_flags=0x%08x td_flags=0x%08x " + "td_cbp=0x%08x td_be=0x%08x", (int)O32TOH(sed->ed.ed_flags), (int)O32TOH(data->td.td_flags), (int)O32TOH(data->td.td_cbp), - (int)O32TOH(data->td.td_be))); + (int)O32TOH(data->td.td_be)); #ifdef OHCI_DEBUG - if (ohcidebug > 5) { + DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); + if (ohcidebug >= 5) { ohci_dump_ed(sc, sed); ohci_dump_tds(sc, data); } + DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); #endif /* Insert ED in schedule */ for (tdp = data; tdp != tail; tdp = tdp->nexttd) { - tdp->xfer = xfer; + KASSERT(tdp->xfer == xfer); } + usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); sed->ed.ed_tailp = HTOO32(tail->physaddr); - opipe->tail.td = tail; sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); OWRITE4(sc, OHCI_COMMAND_STATUS, OHCI_BLF); - if (xfer->timeout && !sc->sc_bus.use_polling) { - callout_reset(&xfer->timeout_handle, mstohz(xfer->timeout), + if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { + callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), ohci_timeout, xfer); } mutex_exit(&sc->sc_lock); -#if 0 -/* This goes wrong if we are too slow. */ - if (ohcidebug > 10) { - delay(10000); - DPRINTF(("ohci_device_intr_transfer: status=%x\n", - OREAD4(sc, OHCI_COMMAND_STATUS))); - ohci_dump_ed(sc, sed); - ohci_dump_tds(sc, data); - } -#endif - - return (USBD_IN_PROGRESS); + return USBD_IN_PROGRESS; } Static void -ohci_device_bulk_abort(usbd_xfer_handle xfer) +ohci_device_bulk_abort(struct usbd_xfer *xfer) { -#ifdef DIAGNOSTIC - ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; -#endif + ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer); + + OHCIHIST_FUNC(); OHCIHIST_CALLED(); KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTF(("ohci_device_bulk_abort: xfer=%p\n", xfer)); + DPRINTF("xfer=%p", xfer, 0, 0, 0); ohci_abort_xfer(xfer, USBD_CANCELLED); } @@ -3125,24 +3112,81 @@ ohci_device_bulk_abort(usbd_xfer_handle xfer) * Close a device bulk pipe. */ Static void -ohci_device_bulk_close(usbd_pipe_handle pipe) +ohci_device_bulk_close(struct usbd_pipe *pipe) { - struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; - ohci_softc_t *sc = pipe->device->bus->hci_private; + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(pipe); + ohci_softc_t *sc = OHCI_PIPE2SC(pipe); KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTF(("ohci_device_bulk_close: pipe=%p\n", pipe)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + + DPRINTF("pipe=%p", pipe, 0, 0, 0); ohci_close_pipe(pipe, sc->sc_bulk_head); - ohci_free_std(sc, opipe->tail.td); + ohci_free_std_locked(sc, opipe->tail.td); } /************************/ +Static int +ohci_device_intr_init(struct usbd_xfer *xfer) +{ + struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); + ohci_softc_t *sc = OHCI_XFER2SC(xfer); + int len = xfer->ux_bufsize; + int endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress;; + int isread = UE_GET_DIR(endpt) == UE_DIR_IN; + int err; + + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); + KASSERT(len != 0); + + DPRINTFN(4, "xfer=%p len=%d isread=%d flags=%d", xfer, len, isread, + xfer->ux_flags); + DPRINTFN(4, "endpt=%d", endpt, 0, 0, 0); + + ox->ox_nstd = 0; + + err = ohci_alloc_std_chain(sc, xfer, len, isread); + if (err) { + return err; + } + + return 0; +} + +Static void +ohci_device_intr_fini(struct usbd_xfer *xfer) +{ + ohci_softc_t *sc = OHCI_XFER2SC(xfer); + struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); + + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTFN(8, "xfer %p nstd %d", xfer, ox->ox_nstd, 0, 0); + + mutex_enter(&sc->sc_lock); + for (size_t i = 0; i < ox->ox_nstd; i++) { + ohci_soft_td_t *std = ox->ox_stds[i]; + if (std != NULL) + break; + if (std != opipe->tail.td) + ohci_free_std_locked(sc, std); + } + mutex_exit(&sc->sc_lock); + + if (ox->ox_nstd) { + const size_t sz = sizeof(ohci_soft_td_t *) * ox->ox_nstd; + kmem_free(ox->ox_stds, sz); + } +} + Static usbd_status -ohci_device_intr_transfer(usbd_xfer_handle xfer) +ohci_device_intr_transfer(struct usbd_xfer *xfer) { - ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; + ohci_softc_t *sc = OHCI_XFER2SC(xfer); usbd_status err; /* Insert last in queue. */ @@ -3150,129 +3194,119 @@ ohci_device_intr_transfer(usbd_xfer_handle xfer) err = usb_insert_transfer(xfer); mutex_exit(&sc->sc_lock); if (err) - return (err); + return err; /* Pipe isn't running, start first */ - return (ohci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return ohci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } Static usbd_status -ohci_device_intr_start(usbd_xfer_handle xfer) +ohci_device_intr_start(struct usbd_xfer *xfer) { - struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; - usbd_device_handle dev = opipe->pipe.device; - ohci_softc_t *sc = dev->bus->hci_private; + struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); + ohci_softc_t *sc = OHCI_XFER2SC(xfer); ohci_soft_ed_t *sed = opipe->sed; - ohci_soft_td_t *data, *tail; + ohci_soft_td_t *data, *last, *tail; int len, isread, endpt; + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + if (sc->sc_dying) - return (USBD_IOERROR); + return USBD_IOERROR; - DPRINTFN(3, ("ohci_device_intr_transfer: xfer=%p len=%d " - "flags=%d priv=%p\n", - xfer, xfer->length, xfer->flags, xfer->priv)); + DPRINTFN(3, "xfer=%p len=%d flags=%d priv=%p", xfer, xfer->ux_length, + xfer->ux_flags, xfer->ux_priv); -#ifdef DIAGNOSTIC - if (xfer->rqflags & URQ_REQUEST) - panic("ohci_device_intr_transfer: a request"); -#endif + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); - len = xfer->length; - endpt = xfer->pipe->endpoint->edesc->bEndpointAddress; + len = xfer->ux_length; + endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress; isread = UE_GET_DIR(endpt) == UE_DIR_IN; - data = opipe->tail.td; mutex_enter(&sc->sc_lock); - tail = ohci_alloc_std(sc); - mutex_exit(&sc->sc_lock); - if (tail == NULL) - return (USBD_NOMEM); + + /* + * Use the pipe "tail" TD as our first and loan our first TD to the + * next transfer. + */ + data = opipe->tail.td; + opipe->tail.td = ox->ox_stds[0]; + ox->ox_stds[0] = data; + ohci_reset_std_chain(sc, xfer, len, isread, data, &last); + + /* point at sentinel */ + tail = opipe->tail.td; + memset(&tail->td, 0, sizeof(tail->td)); + tail->nexttd = NULL; tail->xfer = NULL; + usb_syncmem(&tail->dma, tail->offs, sizeof(tail->td), + BUS_DMASYNC_PREWRITE); + xfer->ux_hcpriv = data; + + DPRINTFN(8, "data %p tail %p", ox->ox_stds[0], tail, 0, 0); + KASSERT(opipe->tail.td == tail); - data->td.td_flags = HTOO32( - (isread ? OHCI_TD_IN : OHCI_TD_OUT) | - OHCI_TD_NOCC | - OHCI_TD_SET_DI(1) | OHCI_TD_TOGGLE_CARRY); - if (xfer->flags & USBD_SHORT_XFER_OK) - data->td.td_flags |= HTOO32(OHCI_TD_R); - data->td.td_cbp = HTOO32(DMAADDR(&xfer->dmabuf, 0)); - data->nexttd = tail; - data->td.td_nexttd = HTOO32(tail->physaddr); - data->td.td_be = HTOO32(O32TOH(data->td.td_cbp) + len - 1); - data->len = len; - data->xfer = xfer; - data->flags = OHCI_CALL_DONE | OHCI_ADD_LEN; - usb_syncmem(&data->dma, data->offs, sizeof(data->td), + /* We want interrupt at the end of the transfer. */ + last->td.td_flags &= HTOO32(~OHCI_TD_INTR_MASK); + last->td.td_flags |= HTOO32(OHCI_TD_SET_DI(1)); + + last->td.td_nexttd = HTOO32(tail->physaddr); + last->nexttd = tail; + last->flags |= OHCI_CALL_DONE; + usb_syncmem(&last->dma, last->offs, sizeof(last->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - xfer->hcpriv = data; #ifdef OHCI_DEBUG - if (ohcidebug > 5) { - DPRINTF(("ohci_device_intr_transfer:\n")); + DPRINTFN(5, "--- dump start ---", 0, 0, 0, 0); + if (ohcidebug >= 5) { ohci_dump_ed(sc, sed); ohci_dump_tds(sc, data); } + DPRINTFN(5, "--- dump end ---", 0, 0, 0, 0); #endif /* Insert ED in schedule */ - mutex_enter(&sc->sc_lock); usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); sed->ed.ed_tailp = HTOO32(tail->physaddr); - opipe->tail.td = tail; sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); -#if 0 -/* - * 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) { - usb_delay_ms_locked(&sc->sc_bus, 5, &sc->sc_lock); - DPRINTF(("ohci_device_intr_transfer: status=%x\n", - OREAD4(sc, OHCI_COMMAND_STATUS))); - ohci_dump_ed(sc, sed); - ohci_dump_tds(sc, data); - } -#endif mutex_exit(&sc->sc_lock); - return (USBD_IN_PROGRESS); + return USBD_IN_PROGRESS; } /* Abort a device interrupt request. */ Static void -ohci_device_intr_abort(usbd_xfer_handle xfer) +ohci_device_intr_abort(struct usbd_xfer *xfer) { -#ifdef DIAGNOSTIC - ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; -#endif + ohci_softc_t *sc __diagused = OHCI_XFER2SC(xfer); KASSERT(mutex_owned(&sc->sc_lock)); - KASSERT(xfer->pipe->intrxfer == xfer); + KASSERT(xfer->ux_pipe->up_intrxfer == xfer); ohci_abort_xfer(xfer, USBD_CANCELLED); } /* Close a device interrupt pipe. */ Static void -ohci_device_intr_close(usbd_pipe_handle pipe) +ohci_device_intr_close(struct usbd_pipe *pipe) { - struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; - ohci_softc_t *sc = pipe->device->bus->hci_private; - int nslots = opipe->u.intr.nslots; - int pos = opipe->u.intr.pos; + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(pipe); + ohci_softc_t *sc = OHCI_PIPE2SC(pipe); + int nslots = opipe->intr.nslots; + int pos = opipe->intr.pos; int j; ohci_soft_ed_t *p, *sed = opipe->sed; + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTFN(1,("ohci_device_intr_close: pipe=%p nslots=%d pos=%d\n", - pipe, nslots, pos)); + DPRINTFN(1, "pipe=%p nslots=%d pos=%d", pipe, nslots, pos, 0); usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); sed->ed.ed_flags |= HTOO32(OHCI_ED_SKIP); @@ -3285,10 +3319,7 @@ ohci_device_intr_close(usbd_pipe_handle pipe) for (p = sc->sc_eds[pos]; p && p->next != sed; p = p->next) continue; -#ifdef DIAGNOSTIC - if (p == NULL) - panic("ohci_device_intr_close: ED not found"); -#endif + KASSERT(p); p->next = sed->next; p->ed.ed_nexted = sed->ed.ed_nexted; usb_syncmem(&p->dma, p->offs + offsetof(ohci_ed_t, ed_nexted), @@ -3298,8 +3329,8 @@ ohci_device_intr_close(usbd_pipe_handle pipe) for (j = 0; j < nslots; j++) --sc->sc_bws[(pos * nslots + j) % OHCI_NO_INTRS]; - ohci_free_std(sc, opipe->tail.td); - ohci_free_sed(sc, opipe->sed); + ohci_free_std_locked(sc, opipe->tail.td); + ohci_free_sed_locked(sc, opipe->sed); } Static usbd_status @@ -3310,16 +3341,18 @@ ohci_device_setintr(ohci_softc_t *sc, struct ohci_pipe *opipe, int ival) u_int bestbw, bw; ohci_soft_ed_t *hsed, *sed = opipe->sed; - DPRINTFN(2, ("ohci_setintr: pipe=%p\n", opipe)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + + DPRINTFN(2, "pipe=%p", opipe, 0, 0, 0); if (ival == 0) { printf("ohci_setintr: 0 interval\n"); - return (USBD_INVAL); + return USBD_INVAL; } npoll = OHCI_NO_INTRS; while (npoll > ival) npoll /= 2; - DPRINTFN(2, ("ohci_setintr: ival=%d npoll=%d\n", ival, npoll)); + DPRINTFN(2, "ival=%d npoll=%d", ival, npoll, 0, 0); /* * We now know which level in the tree the ED must go into. @@ -3344,8 +3377,7 @@ ohci_device_setintr(ohci_softc_t *sc, struct ohci_pipe *opipe, int ival) bestbw = bw; } } - DPRINTFN(2, ("ohci_setintr: best=%d(%d..%d) bestbw=%d\n", - best, slow, shigh, bestbw)); + DPRINTFN(2, "best=%d(%d..%d) bestbw=%d", best, slow, shigh, bestbw); mutex_enter(&sc->sc_lock); hsed = sc->sc_eds[best]; @@ -3366,225 +3398,262 @@ ohci_device_setintr(ohci_softc_t *sc, struct ohci_pipe *opipe, int ival) for (j = 0; j < nslots; j++) ++sc->sc_bws[(best * nslots + j) % OHCI_NO_INTRS]; - opipe->u.intr.nslots = nslots; - opipe->u.intr.pos = best; + opipe->intr.nslots = nslots; + opipe->intr.pos = best; - DPRINTFN(5, ("ohci_setintr: returns %p\n", opipe)); - return (USBD_NORMAL_COMPLETION); + DPRINTFN(5, "returns %p", opipe, 0, 0, 0); + return USBD_NORMAL_COMPLETION; } /***********************/ +Static int +ohci_device_isoc_init(struct usbd_xfer *xfer) +{ + struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); + ohci_softc_t *sc = OHCI_XFER2SC(xfer); + ohci_soft_itd_t *sitd; + size_t i; + int err; + + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + + DPRINTFN(1, "xfer %p len %d flags %d", xfer, xfer->ux_length, + xfer->ux_flags, 0); + + const size_t nfsitd = + (xfer->ux_nframes + OHCI_ITD_NOFFSET - 1) / OHCI_ITD_NOFFSET; + const size_t nbsitd = xfer->ux_bufsize / OHCI_PAGE_SIZE; + const size_t nsitd = MAX(nfsitd, nbsitd) + 1; + + ox->ox_sitds = kmem_zalloc(sizeof(ohci_soft_itd_t *) * nsitd, + KM_SLEEP); + ox->ox_nsitd = nsitd; + + for (i = 0; i < nsitd; i++) { + /* Allocate next ITD */ + sitd = ohci_alloc_sitd(sc); + if (sitd == NULL) { + err = ENOMEM; + goto fail; + } + ox->ox_sitds[i] = sitd; + sitd->xfer = xfer; + sitd->flags = 0; + } + + return 0; +fail: + for (; i > 0;) { + ohci_free_sitd(sc, ox->ox_sitds[--i]); + } + return err; +} + +Static void +ohci_device_isoc_fini(struct usbd_xfer *xfer) +{ + struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); + ohci_softc_t *sc = OHCI_XFER2SC(xfer); + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); + + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + + mutex_enter(&sc->sc_lock); + for (size_t i = 0; i < ox->ox_nsitd; i++) { + if (ox->ox_sitds[i] != opipe->tail.itd) { + ohci_free_sitd_locked(sc, ox->ox_sitds[i]); + } + } + mutex_exit(&sc->sc_lock); + + if (ox->ox_nsitd) { + const size_t sz = sizeof(ohci_soft_itd_t *) * ox->ox_nsitd; + kmem_free(ox->ox_sitds, sz); + } +} + + usbd_status -ohci_device_isoc_transfer(usbd_xfer_handle xfer) +ohci_device_isoc_transfer(struct usbd_xfer *xfer) { - ohci_softc_t *sc = xfer->pipe->device->bus->hci_private; - usbd_status err; + ohci_softc_t *sc = OHCI_XFER2SC(xfer); + usbd_status __diagused err; + + OHCIHIST_FUNC(); OHCIHIST_CALLED(); - DPRINTFN(5,("ohci_device_isoc_transfer: xfer=%p\n", xfer)); + DPRINTFN(5, "xfer=%p", xfer, 0, 0, 0); /* Put it on our queue, */ mutex_enter(&sc->sc_lock); err = usb_insert_transfer(xfer); mutex_exit(&sc->sc_lock); - /* bail out on error, */ - if (err && err != USBD_IN_PROGRESS) - return (err); - - /* XXX should check inuse here */ + KASSERT(err == USBD_NORMAL_COMPLETION); /* insert into schedule, */ ohci_device_isoc_enter(xfer); /* and start if the pipe wasn't running */ - if (!err) - ohci_device_isoc_start(SIMPLEQ_FIRST(&xfer->pipe->queue)); - - return (err); + return USBD_IN_PROGRESS; } void -ohci_device_isoc_enter(usbd_xfer_handle xfer) +ohci_device_isoc_enter(struct usbd_xfer *xfer) { - struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; - usbd_device_handle dev = opipe->pipe.device; - ohci_softc_t *sc = dev->bus->hci_private; + struct ohci_xfer *ox = OHCI_XFER2OXFER(xfer); + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); + ohci_softc_t *sc = OHCI_XFER2SC(xfer); ohci_soft_ed_t *sed = opipe->sed; - struct iso *iso = &opipe->u.iso; - ohci_soft_itd_t *sitd, *nsitd; + ohci_soft_itd_t *sitd, *nsitd, *tail; ohci_physaddr_t buf, offs, noffs, bp0; int i, ncur, nframes; - DPRINTFN(1,("ohci_device_isoc_enter: used=%d next=%d xfer=%p " - "nframes=%d\n", - iso->inuse, iso->next, xfer, xfer->nframes)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTFN(5, "xfer=%p", xfer, 0, 0, 0); - if (sc->sc_dying) + mutex_enter(&sc->sc_lock); + + if (sc->sc_dying) { + mutex_exit(&sc->sc_lock); return; + } + + struct isoc *isoc = &opipe->isoc; - if (iso->next == -1) { + DPRINTFN(1, "used=%d next=%d xfer=%p nframes=%d", + isoc->inuse, isoc->next, xfer, xfer->ux_nframes); + + if (isoc->next == -1) { /* Not in use yet, schedule it a few frames ahead. */ - iso->next = O32TOH(sc->sc_hcca->hcca_frame_number) + 5; - DPRINTFN(2,("ohci_device_isoc_enter: start next=%d\n", - iso->next)); + isoc->next = O32TOH(sc->sc_hcca->hcca_frame_number) + 5; + DPRINTFN(2,"start next=%d", isoc->next, 0, 0, 0); } sitd = opipe->tail.itd; - buf = DMAADDR(&xfer->dmabuf, 0); + opipe->tail.itd = ox->ox_sitds[0]; + ox->ox_sitds[0] = sitd; + + buf = DMAADDR(&xfer->ux_dmabuf, 0); bp0 = OHCI_PAGE(buf); offs = OHCI_PAGE_OFFSET(buf); - nframes = xfer->nframes; - xfer->hcpriv = sitd; + nframes = xfer->ux_nframes; + xfer->ux_hcpriv = sitd; + size_t j = 1; for (i = ncur = 0; i < nframes; i++, ncur++) { - noffs = offs + xfer->frlengths[i]; + noffs = offs + xfer->ux_frlengths[i]; if (ncur == OHCI_ITD_NOFFSET || /* all offsets used */ OHCI_PAGE(buf + noffs) > bp0 + OHCI_PAGE_SIZE) { /* too many page crossings */ /* Allocate next ITD */ - mutex_enter(&sc->sc_lock); - nsitd = ohci_alloc_sitd(sc); - mutex_exit(&sc->sc_lock); - if (nsitd == NULL) { - /* XXX what now? */ - printf("%s: isoc TD alloc failed\n", - device_xname(sc->sc_dev)); - return; - } + nsitd = ox->ox_sitds[j++]; + KASSERT(nsitd != NULL); + KASSERT(j < ox->ox_nsitd); /* Fill current ITD */ sitd->itd.itd_flags = HTOO32( OHCI_ITD_NOCC | - OHCI_ITD_SET_SF(iso->next) | + OHCI_ITD_SET_SF(isoc->next) | OHCI_ITD_SET_DI(6) | /* delay intr a little */ OHCI_ITD_SET_FC(ncur)); sitd->itd.itd_bp0 = HTOO32(bp0); - sitd->nextitd = nsitd; sitd->itd.itd_nextitd = HTOO32(nsitd->physaddr); sitd->itd.itd_be = HTOO32(bp0 + offs - 1); + sitd->nextitd = nsitd; sitd->xfer = xfer; sitd->flags = 0; +#ifdef DIAGNOSTIC + sitd->isdone = false; +#endif + ohci_hash_add_itd(sc, sitd); usb_syncmem(&sitd->dma, sitd->offs, sizeof(sitd->itd), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); sitd = nsitd; - iso->next = iso->next + ncur; + isoc->next = isoc->next + ncur; bp0 = OHCI_PAGE(buf + offs); ncur = 0; } sitd->itd.itd_offset[ncur] = HTOO16(OHCI_ITD_MK_OFFS(offs)); offs = noffs; } - mutex_enter(&sc->sc_lock); - nsitd = ohci_alloc_sitd(sc); - mutex_exit(&sc->sc_lock); - if (nsitd == NULL) { - /* XXX what now? */ - printf("%s: isoc TD alloc failed\n", - device_xname(sc->sc_dev)); - return; - } + KASSERT(j <= ox->ox_nsitd); + + /* point at sentinel */ + tail = opipe->tail.itd; + memset(&tail->itd, 0, sizeof(tail->itd)); + tail->nextitd = NULL; + tail->xfer = NULL; + usb_syncmem(&tail->dma, tail->offs, sizeof(tail->itd), + BUS_DMASYNC_PREWRITE); + /* Fixup last used ITD */ sitd->itd.itd_flags = HTOO32( OHCI_ITD_NOCC | - OHCI_ITD_SET_SF(iso->next) | + OHCI_ITD_SET_SF(isoc->next) | OHCI_ITD_SET_DI(0) | OHCI_ITD_SET_FC(ncur)); sitd->itd.itd_bp0 = HTOO32(bp0); - sitd->nextitd = nsitd; - sitd->itd.itd_nextitd = HTOO32(nsitd->physaddr); + sitd->itd.itd_nextitd = HTOO32(tail->physaddr); sitd->itd.itd_be = HTOO32(bp0 + offs - 1); + sitd->nextitd = tail; sitd->xfer = xfer; sitd->flags = OHCI_CALL_DONE; +#ifdef DIAGNOSTIC + sitd->isdone = false; +#endif + ohci_hash_add_itd(sc, sitd); usb_syncmem(&sitd->dma, sitd->offs, sizeof(sitd->itd), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - iso->next = iso->next + ncur; - iso->inuse += nframes; - - xfer->actlen = offs; /* XXX pretend we did it all */ + isoc->next = isoc->next + ncur; + isoc->inuse += nframes; - xfer->status = USBD_IN_PROGRESS; + /* XXX pretend we did it all */ + xfer->ux_actlen = offs; + xfer->ux_status = USBD_IN_PROGRESS; #ifdef OHCI_DEBUG - if (ohcidebug > 5) { - DPRINTF(("ohci_device_isoc_enter: frame=%d\n", - O32TOH(sc->sc_hcca->hcca_frame_number))); - ohci_dump_itds(sc, xfer->hcpriv); + if (ohcidebug >= 5) { + DPRINTF("frame=%d", O32TOH(sc->sc_hcca->hcca_frame_number), + 0, 0, 0); + ohci_dump_itds(sc, xfer->ux_hcpriv); ohci_dump_ed(sc, sed); } #endif - mutex_enter(&sc->sc_lock); usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - sed->ed.ed_tailp = HTOO32(nsitd->physaddr); - opipe->tail.itd = nsitd; + sed->ed.ed_tailp = HTOO32(tail->physaddr); sed->ed.ed_flags &= HTOO32(~OHCI_ED_SKIP); usb_syncmem(&sed->dma, sed->offs + offsetof(ohci_ed_t, ed_flags), sizeof(sed->ed.ed_flags), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); mutex_exit(&sc->sc_lock); - -#ifdef OHCI_DEBUG - if (ohcidebug > 5) { - delay(150000); - DPRINTF(("ohci_device_isoc_enter: after frame=%d\n", - O32TOH(sc->sc_hcca->hcca_frame_number))); - ohci_dump_itds(sc, xfer->hcpriv); - ohci_dump_ed(sc, sed); - } -#endif -} - -usbd_status -ohci_device_isoc_start(usbd_xfer_handle xfer) -{ - struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; - ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; - - DPRINTFN(5,("ohci_device_isoc_start: xfer=%p\n", xfer)); - - mutex_enter(&sc->sc_lock); - - if (sc->sc_dying) { - mutex_exit(&sc->sc_lock); - return (USBD_IOERROR); - } - -#ifdef DIAGNOSTIC - if (xfer->status != USBD_IN_PROGRESS) - printf("ohci_device_isoc_start: not in progress %p\n", xfer); -#endif - - /* XXX anything to do? */ - - mutex_exit(&sc->sc_lock); - - return (USBD_IN_PROGRESS); } void -ohci_device_isoc_abort(usbd_xfer_handle xfer) +ohci_device_isoc_abort(struct usbd_xfer *xfer) { - struct ohci_pipe *opipe = (struct ohci_pipe *)xfer->pipe; - ohci_softc_t *sc = opipe->pipe.device->bus->hci_private; + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(xfer->ux_pipe); + ohci_softc_t *sc = OHCI_XFER2SC(xfer); ohci_soft_ed_t *sed; ohci_soft_itd_t *sitd; - DPRINTFN(1,("ohci_device_isoc_abort: xfer=%p lock=%p\n", xfer, &sc->sc_lock)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTFN(1, "xfer=%p", xfer, 0, 0, 0); KASSERT(mutex_owned(&sc->sc_lock)); /* Transfer is already done. */ - if (xfer->status != USBD_NOT_STARTED && - xfer->status != USBD_IN_PROGRESS) { + if (xfer->ux_status != USBD_NOT_STARTED && + xfer->ux_status != USBD_IN_PROGRESS) { printf("ohci_device_isoc_abort: early return\n"); goto done; } /* Give xfer the requested abort code. */ - xfer->status = USBD_CANCELLED; + xfer->ux_status = USBD_CANCELLED; sed = opipe->sed; usb_syncmem(&sed->dma, sed->offs, sizeof(sed->ed), @@ -3594,22 +3663,19 @@ ohci_device_isoc_abort(usbd_xfer_handle xfer) sizeof(sed->ed.ed_flags), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - sitd = xfer->hcpriv; -#ifdef DIAGNOSTIC - if (sitd == NULL) { - printf("ohci_device_isoc_abort: hcpriv==0\n"); - goto done; - } -#endif + sitd = xfer->ux_hcpriv; + KASSERT(sitd); + + usb_delay_ms_locked(&sc->sc_bus, OHCI_ITD_NOFFSET, &sc->sc_lock); + for (; sitd->xfer == xfer; sitd = sitd->nextitd) { + ohci_hash_rem_itd(sc, sitd); #ifdef DIAGNOSTIC - DPRINTFN(1,("abort sets done sitd=%p\n", sitd)); - sitd->isdone = 1; + DPRINTFN(1, "abort sets done sitd=%p", sitd, 0, 0, 0); + sitd->isdone = true; #endif } - usb_delay_ms_locked(&sc->sc_bus, OHCI_ITD_NOFFSET, &sc->sc_lock); - /* Run callback. */ usb_transfer_complete(xfer); @@ -3623,40 +3689,42 @@ ohci_device_isoc_abort(usbd_xfer_handle xfer) } void -ohci_device_isoc_done(usbd_xfer_handle xfer) +ohci_device_isoc_done(struct usbd_xfer *xfer) { - DPRINTFN(1,("ohci_device_isoc_done: xfer=%p\n", xfer)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTFN(1, "xfer=%p", xfer, 0, 0, 0); } usbd_status -ohci_setup_isoc(usbd_pipe_handle pipe) +ohci_setup_isoc(struct usbd_pipe *pipe) { - struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; - ohci_softc_t *sc = pipe->device->bus->hci_private; - struct iso *iso = &opipe->u.iso; + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(pipe); + ohci_softc_t *sc = OHCI_PIPE2SC(pipe); + struct isoc *isoc = &opipe->isoc; - iso->next = -1; - iso->inuse = 0; + isoc->next = -1; + isoc->inuse = 0; mutex_enter(&sc->sc_lock); ohci_add_ed(sc, opipe->sed, sc->sc_isoc_head); mutex_exit(&sc->sc_lock); - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } void -ohci_device_isoc_close(usbd_pipe_handle pipe) +ohci_device_isoc_close(struct usbd_pipe *pipe) { - struct ohci_pipe *opipe = (struct ohci_pipe *)pipe; - ohci_softc_t *sc = pipe->device->bus->hci_private; + struct ohci_pipe *opipe = OHCI_PIPE2OPIPE(pipe); + ohci_softc_t *sc = OHCI_PIPE2SC(pipe); KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTF(("ohci_device_isoc_close: pipe=%p\n", pipe)); + OHCIHIST_FUNC(); OHCIHIST_CALLED(); + DPRINTF("pipe=%p", pipe, 0, 0, 0); ohci_close_pipe(pipe, sc->sc_isoc_head); #ifdef DIAGNOSTIC - opipe->tail.itd->isdone = 1; + opipe->tail.itd->isdone = true; #endif - ohci_free_sitd(sc, opipe->tail.itd); + ohci_free_sitd_locked(sc, opipe->tail.itd); } diff --git a/sys/dev/usb/ohcireg.h b/sys/dev/usb/ohcireg.h index 9a5d7e2ca0d..34976174367 100644 --- a/sys/dev/usb/ohcireg.h +++ b/sys/dev/usb/ohcireg.h @@ -1,4 +1,4 @@ -/* $NetBSD: ohcireg.h,v 1.26 2015/09/05 06:13:54 skrll Exp $ */ +/* $NetBSD: ohcireg.h,v 1.27 2016/04/23 10:15:32 skrll Exp $ */ /* $FreeBSD: src/sys/dev/usb/ohcireg.h,v 1.8 1999/11/17 22:33:40 n_hibma Exp $ */ /* @@ -119,18 +119,18 @@ #define OHCI_LES (OHCI_PLE | OHCI_IE | OHCI_CLE | OHCI_BLE) #define OHCI_ALL_INTRS (OHCI_SO | OHCI_WDH | OHCI_SF | OHCI_RD | OHCI_UE | \ - OHCI_FNO | OHCI_RHSC | OHCI_OC) + OHCI_FNO | OHCI_RHSC | OHCI_OC) #define OHCI_NORMAL_INTRS (OHCI_SO | OHCI_WDH | OHCI_RD | OHCI_UE | OHCI_RHSC) #define OHCI_FSMPS(i) (((i-210)*6/7) << 16) #define OHCI_PERIODIC(i) ((i)*9/10) -typedef u_int32_t ohci_physaddr_t; +typedef uint32_t ohci_physaddr_t; #define OHCI_NO_INTRS 32 struct ohci_hcca { volatile ohci_physaddr_t hcca_interrupt_table[OHCI_NO_INTRS]; - volatile u_int32_t hcca_frame_number; + volatile uint32_t hcca_frame_number; volatile ohci_physaddr_t hcca_done_head; #define OHCI_DONE_INTRS 1 }; @@ -142,7 +142,7 @@ struct ohci_hcca { #define OHCI_PAGE_OFFSET(x) ((x) & 0xfff) typedef struct { - volatile u_int32_t ed_flags; + volatile uint32_t ed_flags; #define OHCI_ED_GET_FA(s) ((s) & 0x7f) #define OHCI_ED_ADDRMASK 0x0000007f #define OHCI_ED_SET_FA(s) (s) @@ -170,7 +170,7 @@ typedef struct { #define OHCI_ED_ALIGN 16 typedef struct { - volatile u_int32_t td_flags; + volatile uint32_t td_flags; #define OHCI_TD_R 0x00040000 /* Buffer Rounding */ #define OHCI_TD_DP_MASK 0x00180000 /* Direction / PID */ #define OHCI_TD_SETUP 0x00000000 @@ -196,7 +196,7 @@ typedef struct { #define OHCI_ITD_NOFFSET 8 typedef struct { - volatile u_int32_t itd_flags; + volatile uint32_t itd_flags; #define OHCI_ITD_GET_SF(x) ((x) & 0x0000ffff) #define OHCI_ITD_SET_SF(x) ((x) & 0xffff) #define OHCI_ITD_GET_DI(x) (((x) >> 21) & 7) /* Delay Interrupt */ @@ -209,7 +209,7 @@ typedef struct { volatile ohci_physaddr_t itd_bp0; /* Buffer Page 0 */ volatile ohci_physaddr_t itd_nextitd; /* Next ITD */ volatile ohci_physaddr_t itd_be; /* Buffer End */ - volatile u_int16_t itd_offset[OHCI_ITD_NOFFSET];/* Buffer offsets */ + volatile uint16_t itd_offset[OHCI_ITD_NOFFSET];/* Buffer offsets */ #define itd_pswn itd_offset /* Packet Status Word*/ #define OHCI_ITD_PAGE_SELECT 0x00001000 #define OHCI_ITD_MK_OFFS(len) (0xe000 | ((len) & 0x1fff)) diff --git a/sys/dev/usb/ohcivar.h b/sys/dev/usb/ohcivar.h index 23a024889ad..ced9ff681c3 100644 --- a/sys/dev/usb/ohcivar.h +++ b/sys/dev/usb/ohcivar.h @@ -1,4 +1,4 @@ -/* $NetBSD: ohcivar.h,v 1.55 2014/01/28 17:24:42 skrll Exp $ */ +/* $NetBSD: ohcivar.h,v 1.56 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -42,7 +42,7 @@ typedef struct ohci_soft_ed { usb_dma_t dma; int offs; } ohci_soft_ed_t; -#define OHCI_SED_SIZE ((sizeof (struct ohci_soft_ed) + OHCI_ED_ALIGN - 1) / OHCI_ED_ALIGN * OHCI_ED_ALIGN) +#define OHCI_SED_SIZE ((sizeof(struct ohci_soft_ed) + OHCI_ED_ALIGN - 1) / OHCI_ED_ALIGN * OHCI_ED_ALIGN) #define OHCI_SED_CHUNK 128 @@ -54,13 +54,13 @@ typedef struct ohci_soft_td { usb_dma_t dma; int offs; LIST_ENTRY(ohci_soft_td) hnext; - usbd_xfer_handle xfer; - u_int16_t len; - u_int16_t flags; + struct usbd_xfer *xfer; + uint16_t len; + uint16_t flags; #define OHCI_CALL_DONE 0x0001 #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_SIZE ((sizeof(struct ohci_soft_td) + OHCI_TD_ALIGN - 1) / OHCI_TD_ALIGN * OHCI_TD_ALIGN) #define OHCI_STD_CHUNK 128 @@ -72,11 +72,11 @@ typedef struct ohci_soft_itd { usb_dma_t dma; int offs; LIST_ENTRY(ohci_soft_itd) hnext; - usbd_xfer_handle xfer; - u_int16_t flags; - char isdone; /* used only when DIAGNOSTIC is defined */ + struct usbd_xfer *xfer; + uint16_t flags; + bool isdone; /* used only when DIAGNOSTIC is defined */ } ohci_soft_itd_t; -#define OHCI_SITD_SIZE ((sizeof (struct ohci_soft_itd) + OHCI_ITD_ALIGN - 1) / OHCI_ITD_ALIGN * OHCI_ITD_ALIGN) +#define OHCI_SITD_SIZE ((sizeof(struct ohci_soft_itd) + OHCI_ITD_ALIGN - 1) / OHCI_ITD_ALIGN * OHCI_ITD_ALIGN) #define OHCI_SITD_CHUNK 64 @@ -100,7 +100,7 @@ typedef struct ohci_softc { ohci_soft_ed_t *sc_eds[OHCI_NO_EDS]; u_int sc_bws[OHCI_NO_INTRS]; - u_int32_t sc_eintrs; + uint32_t sc_eintrs; ohci_soft_ed_t *sc_isoc_head; ohci_soft_ed_t *sc_ctrl_head; ohci_soft_ed_t *sc_bulk_head; @@ -109,8 +109,6 @@ typedef struct ohci_softc { LIST_HEAD(, ohci_soft_itd) sc_hash_itds[OHCI_HASH_SIZE]; int sc_noport; - u_int8_t sc_addr; /* device address */ - u_int8_t sc_conf; /* device configuration */ int sc_endian; #define OHCI_LITTLE_ENDIAN 0 /* typical (uninitialized default) */ @@ -129,13 +127,13 @@ typedef struct ohci_softc { pool_cache_t sc_xferpool; /* free xfer pool */ - usbd_xfer_handle sc_intrxfer; + struct usbd_xfer *sc_intrxfer; char sc_vendor[32]; int sc_id_vendor; - u_int32_t sc_control; /* Preserved during suspend/standby */ - u_int32_t sc_intre; + uint32_t sc_control; /* Preserved during suspend/standby */ + uint32_t sc_intre; u_int sc_overrun_cnt; struct timeval sc_overrun_ntc; @@ -143,15 +141,36 @@ typedef struct ohci_softc { struct callout sc_tmo_rhsc; device_t sc_child; char sc_dying; - struct usb_dma_reserve sc_dma_reserve; } ohci_softc_t; struct ohci_xfer { struct usbd_xfer xfer; - struct usb_task abort_task; + struct usb_task abort_task; + /* ctrl */ + ohci_soft_td_t *ox_setup; + ohci_soft_td_t *ox_stat; + union { + /* ctrl/bulk/intr */ + struct { + ohci_soft_td_t **ox_stds; + size_t ox_nstd; + }; + /* isoc */ + struct { + ohci_soft_itd_t **ox_sitds; + size_t ox_nsitd; + }; + }; }; -usbd_status ohci_init(ohci_softc_t *); +#define OHCI_BUS2SC(bus) ((bus)->ub_hcpriv) +#define OHCI_PIPE2SC(pipe) OHCI_BUS2SC((pipe)->up_dev->ud_bus) +#define OHCI_XFER2SC(xfer) OHCI_BUS2SC((xfer)->ux_bus) + +#define OHCI_XFER2OXFER(xfer) ((struct ohci_xfer *)(xfer)) +#define OHCI_PIPE2OPIPE(pipe) ((struct ohci_pipe *)(pipe)) + +int ohci_init(ohci_softc_t *); int ohci_intr(void *); int ohci_detach(ohci_softc_t *, int); bool ohci_shutdown(device_t, int); diff --git a/sys/dev/usb/pseye.c b/sys/dev/usb/pseye.c index 010cfe37e8e..0fdd72bd688 100644 --- a/sys/dev/usb/pseye.c +++ b/sys/dev/usb/pseye.c @@ -1,4 +1,4 @@ -/* $NetBSD: pseye.c,v 1.21 2011/05/24 16:42:31 joerg Exp $ */ +/* $NetBSD: pseye.c,v 1.22 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2008 Jared D. McNeill <jmcneill@invisible.ca> @@ -37,12 +37,11 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: pseye.c,v 1.21 2011/05/24 16:42:31 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: pseye.c,v 1.22 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/device.h> -#include <sys/malloc.h> #include <sys/fcntl.h> #include <sys/conf.h> #include <sys/poll.h> @@ -82,8 +81,8 @@ __KERNEL_RCSID(0, "$NetBSD: pseye.c,v 1.21 2011/05/24 16:42:31 joerg Exp $"); struct pseye_softc { device_t sc_dev; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device * sc_udev; + struct usbd_interface * sc_iface; device_t sc_videodev; char sc_running; @@ -91,8 +90,8 @@ struct pseye_softc { kcondvar_t sc_cv; kmutex_t sc_mtx; - usbd_pipe_handle sc_bulkin_pipe; - usbd_xfer_handle sc_bulkin_xfer; + struct usbd_pipe * sc_bulkin_pipe; + struct usbd_xfer * sc_bulkin_xfer; int sc_bulkin; uint8_t *sc_bulkin_buffer; int sc_bulkin_bufferlen; @@ -163,15 +162,15 @@ static const struct video_hw_if pseye_hw_if = { static int pseye_match(device_t parent, cfdata_t match, void *opaque) { - struct usbif_attach_arg *uaa = opaque; + struct usbif_attach_arg *uiaa = opaque; - if (uaa->class != UICLASS_VENDOR) + if (uiaa->uiaa_class != UICLASS_VENDOR) return UMATCH_NONE; - if (uaa->vendor == USB_VENDOR_OMNIVISION2) { - switch (uaa->product) { + if (uiaa->uiaa_vendor == USB_VENDOR_OMNIVISION2) { + switch (uiaa->uiaa_product) { case USB_PRODUCT_OMNIVISION2_PSEYE: - if (uaa->ifaceno != 0) + if (uiaa->uiaa_ifaceno != 0) return UMATCH_NONE; return UMATCH_VENDOR_PRODUCT; } @@ -184,8 +183,8 @@ static void pseye_attach(device_t parent, device_t self, void *opaque) { struct pseye_softc *sc = device_private(self); - struct usbif_attach_arg *uaa = opaque; - usbd_device_handle dev = uaa->device; + struct usbif_attach_arg *uiaa = opaque; + struct usbd_device *dev = uiaa->uiaa_device; usb_interface_descriptor_t *id = NULL; usb_endpoint_descriptor_t *ed = NULL, *ed_bulkin = NULL; char *devinfop; @@ -200,9 +199,9 @@ pseye_attach(device_t parent, device_t self, void *opaque) sc->sc_dev = self; sc->sc_udev = dev; - sc->sc_iface = uaa->iface; + sc->sc_iface = uiaa->uiaa_iface; snprintf(sc->sc_businfo, sizeof(sc->sc_businfo), "usb:%08x", - sc->sc_udev->cookie.cookie); + sc->sc_udev->ud_cookie.cookie); sc->sc_bulkin_bufferlen = PSEYE_BULKIN_BUFLEN; sc->sc_dying = sc->sc_running = 0; @@ -239,20 +238,22 @@ pseye_attach(device_t parent, device_t self, void *opaque) sc->sc_bulkin = ed_bulkin->bEndpointAddress; - sc->sc_bulkin_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_bulkin_xfer == NULL) { - sc->sc_dying = 1; + int error = pseye_init_pipes(sc); + if (error) { + aprint_error_dev(self, "couldn't open pipes\n"); return; } - sc->sc_bulkin_buffer = usbd_alloc_buffer(sc->sc_bulkin_xfer, - sc->sc_bulkin_bufferlen); - if (sc->sc_bulkin_buffer == NULL) { - usbd_free_xfer(sc->sc_bulkin_xfer); - sc->sc_bulkin_xfer = NULL; - sc->sc_dying = 1; + + error = usbd_create_xfer(sc->sc_bulkin_pipe, sc->sc_bulkin_bufferlen, + USBD_SHORT_XFER_OK, 0, &sc->sc_bulkin_xfer); + if (error) { + aprint_error_dev(self, "couldn't create transfer\n"); + pseye_close_pipes(sc); return; } + sc->sc_bulkin_buffer = usbd_get_buffer(sc->sc_bulkin_xfer); + pseye_init(sc); if (!pmf_device_register(self, NULL, NULL)) @@ -284,13 +285,17 @@ pseye_detach(device_t self, int flags) sc->sc_videodev = NULL; } + if (sc->sc_bulkin_pipe != NULL) { + usbd_abort_pipe(sc->sc_bulkin_pipe); + } + if (sc->sc_bulkin_xfer != NULL) { - usbd_free_xfer(sc->sc_bulkin_xfer); + usbd_destroy_xfer(sc->sc_bulkin_xfer); sc->sc_bulkin_xfer = NULL; } if (sc->sc_bulkin_pipe != NULL) { - usbd_abort_pipe(sc->sc_bulkin_pipe); + usbd_close_pipe(sc->sc_bulkin_pipe); sc->sc_bulkin_pipe = NULL; } @@ -622,8 +627,7 @@ pseye_get_frame(struct pseye_softc *sc, uint32_t *plen) return USBD_IOERROR; return usbd_bulk_transfer(sc->sc_bulkin_xfer, sc->sc_bulkin_pipe, - USBD_SHORT_XFER_OK|USBD_NO_COPY, 1000, - sc->sc_bulkin_buffer, plen, "pseyerb"); + USBD_SHORT_XFER_OK, 1000, sc->sc_bulkin_buffer, plen); } static int @@ -642,8 +646,6 @@ pseye_init_pipes(struct pseye_softc *sc) return ENOMEM; } - pseye_start(sc); - return 0; } @@ -656,8 +658,6 @@ pseye_close_pipes(struct pseye_softc *sc) sc->sc_bulkin_pipe = NULL; } - pseye_stop(sc); - return 0; } @@ -731,7 +731,9 @@ pseye_open(void *opaque, int flags) if (sc->sc_dying) return EIO; - return pseye_init_pipes(sc); + pseye_start(sc); + + return 0; } static void @@ -739,7 +741,7 @@ pseye_close(void *opaque) { struct pseye_softc *sc = opaque; - pseye_close_pipes(sc); + pseye_stop(sc); } static const char * diff --git a/sys/dev/usb/slurm.c b/sys/dev/usb/slurm.c index aedbda2b15f..fa20b7013fc 100644 --- a/sys/dev/usb/slurm.c +++ b/sys/dev/usb/slurm.c @@ -1,4 +1,4 @@ -/* $NetBSD: slurm.c,v 1.1 2013/01/13 01:15:02 jakllsch Exp $ */ +/* $NetBSD: slurm.c,v 1.2 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2012 Jonathan A. Kollasch @@ -27,13 +27,12 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: slurm.c,v 1.1 2013/01/13 01:15:02 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: slurm.c,v 1.2 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/proc.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> #include <sys/device.h> #include <sys/conf.h> @@ -60,8 +59,8 @@ int slurmdebug = 0; struct slurm_softc { device_t sc_dev; - usbd_device_handle sc_udev; - usbd_interface_handle sc_uif; + struct usbd_device * sc_udev; + struct usbd_interface * sc_uif; uint32_t sc_band; uint32_t sc_space; }; @@ -103,30 +102,30 @@ static const struct radio_hw_if slurm_radio = { CFATTACH_DECL_NEW(slurm, sizeof(struct slurm_softc), slurm_match, slurm_attach, slurm_detach, NULL); -static int +static int slurm_match(device_t parent, cfdata_t match, void *aux) { - const struct usbif_attach_arg * const uaa = aux; + const struct usbif_attach_arg * const uiaa = aux; - if (uaa->ifaceno != 2) + if (uiaa->uiaa_ifaceno != 2) return UMATCH_NONE; - if (usb_lookup(slurm_devs, uaa->vendor, uaa->product) != NULL) { + if (usb_lookup(slurm_devs, uiaa->uiaa_vendor, uiaa->uiaa_product) != NULL) { return UMATCH_VENDOR_PRODUCT; } return UMATCH_NONE; } -static void +static void slurm_attach(device_t parent, device_t self, void *aux) { struct slurm_softc * const sc = device_private(self); - const struct usbif_attach_arg * const uaa = aux; + const struct usbif_attach_arg * const uiaa = aux; sc->sc_dev = self; - sc->sc_udev = uaa->device; - sc->sc_uif = uaa->iface; + sc->sc_udev = uiaa->uiaa_device; + sc->sc_uif = uiaa->uiaa_iface; aprint_normal("\n"); aprint_naive("\n"); @@ -146,7 +145,7 @@ slurm_attach(device_t parent, device_t self, void *aux) radio_attach_mi(&slurm_radio, sc, self); } -static int +static int slurm_detach(device_t self, int flags) { struct slurm_softc * const sc = device_private(self); @@ -203,7 +202,7 @@ static int slurm_search(void *v, int f) { struct slurm_softc * const sc = v; - + return slurm_si470x_search(sc, f); } diff --git a/sys/dev/usb/stuirda.c b/sys/dev/usb/stuirda.c index 6a9a4bd6220..ec0281ea3ea 100644 --- a/sys/dev/usb/stuirda.c +++ b/sys/dev/usb/stuirda.c @@ -1,4 +1,4 @@ -/* $NetBSD: stuirda.c,v 1.16 2014/09/21 17:02:24 christos Exp $ */ +/* $NetBSD: stuirda.c,v 1.17 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001,2007 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: stuirda.c,v 1.16 2014/09/21 17:02:24 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: stuirda.c,v 1.17 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> @@ -73,7 +73,7 @@ struct stuirda_softc { int stuirda_fwload(struct uirda_softc *sc); -/* +/* * These devices need firmware download. */ Static const struct usb_devno stuirda_devs[] = { @@ -103,22 +103,22 @@ int stuirda_activate(device_t, enum devact); extern struct cfdriver stuirda_cd; CFATTACH_DECL_NEW(stuirda, sizeof(struct stuirda_softc), stuirda_match, stuirda_attach, stuirda_detach, stuirda_activate); -int +int stuirda_match(device_t parent, cfdata_t match, void *aux) { - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; DPRINTFN(50,("stuirda_match\n")); - if (stuirda_lookup(uaa->vendor, uaa->product) != NULL) - return (UMATCH_VENDOR_PRODUCT); + if (stuirda_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product) != NULL) + return UMATCH_VENDOR_PRODUCT; - return (UMATCH_NONE); + return UMATCH_NONE; } void uirda_attach(device_t, device_t, void *); -void +void stuirda_attach(device_t parent, device_t self, void *aux) { struct stuirda_softc *sc = device_private(self); @@ -138,15 +138,15 @@ stuirda_fwload(struct uirda_softc *sc) { firmware_handle_t fh; off_t fwsize; usb_device_descriptor_t usbddsc; - usbd_xfer_handle fwxfer; - usbd_pipe_handle fwpipe; + struct usbd_xfer * fwxfer; + struct usbd_pipe * fwpipe; usbd_status status; usb_device_request_t req; char *buffer; char *p; char fwname[12]; int n; - u_int8_t *usbbuf; + uint8_t *usbbuf; /* size_t bsize; */ printf("%s: needing to download firmware\n", @@ -169,7 +169,7 @@ stuirda_fwload(struct uirda_softc *sc) { printf("%s: Attempting to load firmware %s\n", device_xname(sc->sc_dev), fwname); - + rc = firmware_open("stuirda", fwname, &fh); if (rc) { @@ -230,24 +230,21 @@ stuirda_fwload(struct uirda_softc *sc) { device_xname(sc->sc_dev), rc); goto giveup3; } - fwxfer = usbd_alloc_xfer(sc->sc_udev); - if (fwxfer == NULL) { + + int err = usbd_create_xfer(fwpipe, 1024, USBD_FORCE_SHORT_XFER, 0, + &fwxfer); + if (err) { printf("%s: Cannot alloc xfer\n", device_xname(sc->sc_dev)); goto giveup4; } - usbbuf = usbd_alloc_buffer(fwxfer, 1024); - if (usbbuf == NULL) { - printf("%s: Cannot alloc usb buf\n", device_xname(sc->sc_dev)); - goto giveup5; - } + usbbuf = usbd_get_buffer(fwxfer); n = (buffer + fwsize - p); while (n > 0) { if (n > 1023) n = 1023; memcpy(usbbuf, p, n); - rc = usbd_bulk_transfer(fwxfer, fwpipe, - USBD_SYNCHRONOUS|USBD_FORCE_SHORT_XFER, - 5000, usbbuf, &n, "uirda-fw-wr"); + rc = usbd_bulk_transfer(fwxfer, fwpipe, USBD_FORCE_SHORT_XFER, + 5000, usbbuf, &n); printf("%s: write: rc=%d, %d left\n", device_xname(sc->sc_dev), rc, n); if (rc) { @@ -256,21 +253,20 @@ stuirda_fwload(struct uirda_softc *sc) { goto giveup4; } printf("%s: written %d\n", device_xname(sc->sc_dev), n); - p += n; + p += n; n = (buffer + fwsize - p); } delay(100000); /* TODO: more code here */ rc = 0; - usbd_free_buffer(fwxfer); + usbd_destroy_xfer(fwxfer); - giveup5: usbd_free_xfer(fwxfer); giveup4: usbd_close_pipe(fwpipe); giveup3: firmware_free(buffer, fwsize); giveup2: firmware_close(fh); return rc; - + } int @@ -278,22 +274,22 @@ stuirda_write(void *h, struct uio *uio, int flag) { struct uirda_softc *sc = h; usbd_status err; - u_int32_t n; + uint32_t n; int error = 0; DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); if (sc->sc_dying) - return (EIO); + return EIO; #ifdef DIAGNOSTIC if (sc->sc_wr_buf == NULL) - return (EINVAL); + return EINVAL; #endif n = uio->uio_resid; if (n > sc->sc_params.maxsize) - return (EINVAL); + return EINVAL; sc->sc_refcnt++; mutex_enter(&sc->sc_wr_buf_lk); @@ -307,29 +303,29 @@ stuirda_write(void *h, struct uio *uio, int flag) } error = uiomove(sc->sc_wr_buf + STUIRDA_HEADER_SIZE, n, uio); - if (!error) { - DPRINTFN(1, ("uirdawrite: transfer %d bytes\n", n)); - - n += STUIRDA_HEADER_SIZE + sc->sc_wr_buf[1]; - err = usbd_bulk_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe, - USBD_FORCE_SHORT_XFER|USBD_NO_COPY, - UIRDA_WR_TIMEOUT, - sc->sc_wr_buf, &n, "uirdawr"); - DPRINTFN(2, ("uirdawrite: err=%d\n", err)); - if (err) { - if (err == USBD_INTERRUPTED) - error = EINTR; - else if (err == USBD_TIMEOUT) - error = ETIMEDOUT; - else - error = EIO; - } + if (error) + goto done; + + DPRINTFN(1, ("uirdawrite: transfer %d bytes\n", n)); + + n += STUIRDA_HEADER_SIZE + sc->sc_wr_buf[1]; + + err = usbd_bulk_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe, + USBD_FORCE_SHORT_XFER, UIRDA_WR_TIMEOUT, sc->sc_wr_buf, &n); + DPRINTFN(2, ("uirdawrite: err=%d\n", err)); + if (err) { + if (err == USBD_INTERRUPTED) + error = EINTR; + else if (err == USBD_TIMEOUT) + error = ETIMEDOUT; + else + error = EIO; } - +done: mutex_exit(&sc->sc_wr_buf_lk); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); DPRINTFN(1,("%s: sc=%p done\n", __func__, sc)); - return (error); + return error; } diff --git a/sys/dev/usb/u3g.c b/sys/dev/usb/u3g.c index 2866baba06e..bb53a1b7281 100644 --- a/sys/dev/usb/u3g.c +++ b/sys/dev/usb/u3g.c @@ -1,4 +1,4 @@ -/* $NetBSD: u3g.c,v 1.31 2014/09/24 00:17:13 christos Exp $ */ +/* $NetBSD: u3g.c,v 1.32 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2009 The NetBSD Foundation, Inc. @@ -50,12 +50,12 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: u3g.c,v 1.31 2014/09/24 00:17:13 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: u3g.c,v 1.32 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/bus.h> #include <sys/conf.h> #include <sys/tty.h> @@ -111,7 +111,7 @@ __KERNEL_RCSID(0, "$NetBSD: u3g.c,v 1.31 2014/09/24 00:17:13 christos Exp $"); struct u3g_softc { device_t sc_dev; - usbd_device_handle sc_udev; + struct usbd_device * sc_udev; bool sc_dying; /* We're going away */ int sc_ifaceno; /* Device interface number */ @@ -127,8 +127,9 @@ struct u3g_softc { } sc_com[10]; size_t sc_ncom; - usbd_pipe_handle sc_intr_pipe; /* Interrupt pipe */ + struct usbd_pipe * sc_intr_pipe; /* Interrupt pipe */ u_char *sc_intr_buff; /* Interrupt buffer */ + size_t sc_intr_size; /* buffer size */ }; /* @@ -160,30 +161,30 @@ CFATTACH_DECL2_NEW(u3g, sizeof(struct u3g_softc), u3g_match, u3g_attach, u3g_detach, u3g_activate, NULL, u3g_childdet); -static void u3g_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); +static void u3g_intr(struct usbd_xfer *, void *, usbd_status); static void u3g_get_status(void *, int, u_char *, u_char *); static void u3g_set(void *, int, int, int); static int u3g_open(void *, int); static void u3g_close(void *, int); static void u3g_read(void *, int, u_char **, uint32_t *); -static void u3g_write(void *, int, u_char *, u_char *, u_int32_t *); +static void u3g_write(void *, int, u_char *, u_char *, uint32_t *); struct ucom_methods u3g_methods = { - u3g_get_status, - u3g_set, - NULL, - NULL, - u3g_open, - u3g_close, - u3g_read, - u3g_write, + .ucom_get_status = u3g_get_status, + .ucom_set = u3g_set, + .ucom_param = NULL, + .ucom_ioctl = NULL, + .ucom_open = u3g_open, + .ucom_close = u3g_close, + .ucom_read = u3g_read, + .ucom_write = u3g_write, }; /* * Allegedly supported devices */ static const struct usb_devno u3g_devs[] = { - { USB_VENDOR_DELL, USB_PRODUCT_DELL_W5500 }, + { USB_VENDOR_DELL, USB_PRODUCT_DELL_W5500 }, /* OEM: Huawei */ { USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E1750 }, { USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E1820 }, @@ -265,13 +266,13 @@ static const struct usb_devno u3g_devs[] = { }; static int -send_bulkmsg(usbd_device_handle dev, void *cmd, size_t cmdlen) +send_bulkmsg(struct usbd_device *dev, void *cmd, size_t cmdlen) { - usbd_interface_handle iface; + struct usbd_interface *iface; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; - usbd_pipe_handle pipe; - usbd_xfer_handle xfer; + struct usbd_pipe *pipe; + struct usbd_xfer *xfer; int err, i; /* Move the device into the configured state. */ @@ -310,9 +311,10 @@ send_bulkmsg(usbd_device_handle dev, void *cmd, size_t cmdlen) return UMATCH_NONE; } - xfer = usbd_alloc_xfer(dev); - if (xfer != NULL) { - usbd_setup_xfer(xfer, pipe, NULL, cmd, cmdlen, + int error = usbd_create_xfer(pipe, cmdlen, 0, 0, &xfer); + if (!error) { + + usbd_setup_xfer(xfer, NULL, cmd, cmdlen, USBD_SYNCHRONOUS, USBD_DEFAULT_TIMEOUT, NULL); err = usbd_transfer(xfer); @@ -323,7 +325,7 @@ send_bulkmsg(usbd_device_handle dev, void *cmd, size_t cmdlen) #else err = 0; #endif - usbd_free_xfer(xfer); + usbd_destroy_xfer(xfer); } else { aprint_error("u3ginit: failed to allocate xfer\n"); err = USBD_NOMEM; @@ -332,21 +334,21 @@ send_bulkmsg(usbd_device_handle dev, void *cmd, size_t cmdlen) usbd_abort_pipe(pipe); usbd_close_pipe(pipe); - return (err == USBD_NORMAL_COMPLETION ? UMATCH_HIGHEST : UMATCH_NONE); + return err == USBD_NORMAL_COMPLETION ? UMATCH_HIGHEST : UMATCH_NONE; } /* Byte 0..3: Command Block Wrapper (CBW) signature */ static void set_cbw(unsigned char *cmd) { - cmd[0] = 0x55; + cmd[0] = 0x55; cmd[1] = 0x53; cmd[2] = 0x42; cmd[3] = 0x43; } static int -u3g_bulk_scsi_eject(usbd_device_handle dev) +u3g_bulk_scsi_eject(struct usbd_device *dev) { unsigned char cmd[31]; @@ -374,7 +376,7 @@ u3g_bulk_scsi_eject(usbd_device_handle dev) } static int -u3g_bulk_ata_eject(usbd_device_handle dev) +u3g_bulk_ata_eject(struct usbd_device *dev) { unsigned char cmd[31]; @@ -402,7 +404,7 @@ u3g_bulk_ata_eject(usbd_device_handle dev) } static int -u3g_huawei_reinit(usbd_device_handle dev) +u3g_huawei_reinit(struct usbd_device *dev) { /* * The Huawei device presents itself as a umass device with Windows @@ -418,18 +420,18 @@ u3g_huawei_reinit(usbd_device_handle dev) usb_device_descriptor_t dd; if (usbd_get_device_desc(dev, &dd) != 0) - return (UMATCH_NONE); + return UMATCH_NONE; if (dd.bNumConfigurations != 1) - return (UMATCH_NONE); + return UMATCH_NONE; if (usbd_set_config_index(dev, 0, 1) != 0) - return (UMATCH_NONE); + return UMATCH_NONE; cdesc = usbd_get_config_descriptor(dev); if (cdesc == NULL) - return (UMATCH_NONE); + return UMATCH_NONE; } /* @@ -440,7 +442,7 @@ u3g_huawei_reinit(usbd_device_handle dev) * it needs a mode-switch. */ if (cdesc->bNumInterface > 1) - return (UMATCH_NONE); + return UMATCH_NONE; req.bmRequestType = UT_WRITE_DEVICE; req.bRequest = UR_SET_FEATURE; @@ -450,11 +452,11 @@ u3g_huawei_reinit(usbd_device_handle dev) (void) usbd_do_request(dev, &req, 0); - return (UMATCH_HIGHEST); /* Prevent umass from attaching */ + return UMATCH_HIGHEST; /* Prevent umass from attaching */ } static int -u3g_huawei_k3765_reinit(usbd_device_handle dev) +u3g_huawei_k3765_reinit(struct usbd_device *dev) { unsigned char cmd[31]; @@ -469,7 +471,7 @@ u3g_huawei_k3765_reinit(usbd_device_handle dev) return send_bulkmsg(dev, cmd, sizeof(cmd)); } static int -u3g_huawei_e171_reinit(usbd_device_handle dev) +u3g_huawei_e171_reinit(struct usbd_device *dev) { unsigned char cmd[31]; @@ -487,7 +489,7 @@ u3g_huawei_e171_reinit(usbd_device_handle dev) } static int -u3g_huawei_e353_reinit(usbd_device_handle dev) +u3g_huawei_e353_reinit(struct usbd_device *dev) { unsigned char cmd[31]; @@ -509,7 +511,7 @@ u3g_huawei_e353_reinit(usbd_device_handle dev) } static int -u3g_sierra_reinit(usbd_device_handle dev) +u3g_sierra_reinit(struct usbd_device *dev) { /* Some Sierra devices presents themselves as a umass device with * Windows drivers on it. After installation of the driver, it @@ -525,11 +527,11 @@ u3g_sierra_reinit(usbd_device_handle dev) (void) usbd_do_request(dev, &req, 0); - return (UMATCH_HIGHEST); /* Match to prevent umass from attaching */ + return UMATCH_HIGHEST; /* Match to prevent umass from attaching */ } static int -u3g_4gsystems_reinit(usbd_device_handle dev) +u3g_4gsystems_reinit(struct usbd_device *dev) { /* magic string adapted from usb_modeswitch database */ unsigned char cmd[31]; @@ -569,33 +571,33 @@ u3ginit_match(device_t parent, cfdata_t match, void *aux) /* * Huawei changes product when it is configured as a modem. */ - switch (uaa->vendor) { + switch (uaa->uaa_vendor) { case USB_VENDOR_HUAWEI: - if (uaa->product == USB_PRODUCT_HUAWEI_K3765) + if (uaa->uaa_product == USB_PRODUCT_HUAWEI_K3765) return UMATCH_NONE; - switch (uaa->product) { + switch (uaa->uaa_product) { case USB_PRODUCT_HUAWEI_E1750INIT: case USB_PRODUCT_HUAWEI_K3765INIT: - return u3g_huawei_k3765_reinit(uaa->device); + return u3g_huawei_k3765_reinit(uaa->uaa_device); break; case USB_PRODUCT_HUAWEI_E171INIT: - return u3g_huawei_e171_reinit(uaa->device); + return u3g_huawei_e171_reinit(uaa->uaa_device); break; case USB_PRODUCT_HUAWEI_E353INIT: - return u3g_huawei_e353_reinit(uaa->device); + return u3g_huawei_e353_reinit(uaa->uaa_device); break; default: - return u3g_huawei_reinit(uaa->device); + return u3g_huawei_reinit(uaa->uaa_device); break; } break; case USB_VENDOR_NOVATEL2: - switch (uaa->product){ + switch (uaa->uaa_product){ case USB_PRODUCT_NOVATEL2_MC950D_DRIVER: case USB_PRODUCT_NOVATEL2_U760_DRIVER: - return u3g_bulk_scsi_eject(uaa->device); + return u3g_bulk_scsi_eject(uaa->uaa_device); break; default: break; @@ -603,21 +605,21 @@ u3ginit_match(device_t parent, cfdata_t match, void *aux) break; case USB_VENDOR_SIERRA: - if (uaa->product == USB_PRODUCT_SIERRA_INSTALLER) - return u3g_sierra_reinit(uaa->device); + if (uaa->uaa_product == USB_PRODUCT_SIERRA_INSTALLER) + return u3g_sierra_reinit(uaa->uaa_device); break; case USB_VENDOR_QUALCOMM: - if (uaa->product == USB_PRODUCT_QUALCOMM_NTT_DOCOMO_L02C_STORAGE) - return u3g_bulk_scsi_eject(uaa->device); + if (uaa->uaa_product == USB_PRODUCT_QUALCOMM_NTT_DOCOMO_L02C_STORAGE) + return u3g_bulk_scsi_eject(uaa->uaa_device); break; case USB_VENDOR_ZTE: - switch (uaa->product){ + switch (uaa->uaa_product){ case USB_PRODUCT_ZTE_INSTALLER: case USB_PRODUCT_ZTE_MF820D_INSTALLER: - (void)u3g_bulk_ata_eject(uaa->device); - (void)u3g_bulk_scsi_eject(uaa->device); + (void)u3g_bulk_ata_eject(uaa->uaa_device); + (void)u3g_bulk_scsi_eject(uaa->uaa_device); return UMATCH_HIGHEST; default: break; @@ -625,8 +627,8 @@ u3ginit_match(device_t parent, cfdata_t match, void *aux) break; case USB_VENDOR_4GSYSTEMS: - if (uaa->product == USB_PRODUCT_4GSYSTEMS_XSSTICK_P14_INSTALLER) - return u3g_4gsystems_reinit(uaa->device); + if (uaa->uaa_product == USB_PRODUCT_4GSYSTEMS_XSSTICK_P14_INSTALLER) + return u3g_4gsystems_reinit(uaa->uaa_device); break; default: @@ -644,8 +646,8 @@ u3ginit_attach(device_t parent, device_t self, void *aux) aprint_naive("\n"); aprint_normal(": Switching to 3G mode\n"); - if (uaa->vendor == USB_VENDOR_NOVATEL2) { - switch (uaa->product) { + if (uaa->uaa_vendor == USB_VENDOR_NOVATEL2) { + switch (uaa->uaa_product) { case USB_PRODUCT_NOVATEL2_MC950D_DRIVER: case USB_PRODUCT_NOVATEL2_U760_DRIVER: /* About to disappear... */ @@ -657,14 +659,14 @@ u3ginit_attach(device_t parent, device_t self, void *aux) } /* Move the device into the configured state. */ - (void) usbd_set_config_index(uaa->device, 0, 1); + (void) usbd_set_config_index(uaa->uaa_device, 0, 1); } static int u3ginit_detach(device_t self, int flags) { - return (0); + return 0; } @@ -677,56 +679,58 @@ u3ginit_detach(device_t self, int flags) static int u3g_match(device_t parent, cfdata_t match, void *aux) { - struct usbif_attach_arg *uaa = aux; - usbd_interface_handle iface; + struct usbif_attach_arg *uiaa = aux; + struct usbd_interface *iface; usb_interface_descriptor_t *id; usbd_status error; - if (!usb_lookup(u3g_devs, uaa->vendor, uaa->product)) - return (UMATCH_NONE); + if (!usb_lookup(u3g_devs, uiaa->uiaa_vendor, uiaa->uiaa_product)) + return UMATCH_NONE; - error = usbd_device2interface_handle(uaa->device, uaa->ifaceno, &iface); + error = usbd_device2interface_handle(uiaa->uiaa_device, + uiaa->uiaa_ifaceno, &iface); if (error) { printf("u3g_match: failed to get interface, err=%s\n", usbd_errstr(error)); - return (UMATCH_NONE); + return UMATCH_NONE; } id = usbd_get_interface_descriptor(iface); if (id == NULL) { printf("u3g_match: failed to get interface descriptor\n"); - return (UMATCH_NONE); + return UMATCH_NONE; } /* * Huawei modems use the vendor-specific class for all interfaces, * both tty and CDC NCM, which we should avoid attaching to. */ - if (uaa->vendor == USB_VENDOR_HUAWEI && id->bInterfaceSubClass == 2 && + if (uiaa->uiaa_vendor == USB_VENDOR_HUAWEI && + id->bInterfaceSubClass == 2 && (id->bInterfaceProtocol & 0xf) == 6) /* 0x16, 0x46, 0x76 */ - return (UMATCH_NONE); + return UMATCH_NONE; /* * 3G modems generally report vendor-specific class * * XXX: this may be too generalised. */ - return ((id->bInterfaceClass == UICLASS_VENDOR) ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return id->bInterfaceClass == UICLASS_VENDOR ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } static void u3g_attach(device_t parent, device_t self, void *aux) { struct u3g_softc *sc = device_private(self); - struct usbif_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface; + struct usbif_attach_arg *uiaa = aux; + struct usbd_device *dev = uiaa->uiaa_device; + struct usbd_interface *iface; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; - struct ucom_attach_args uca; + struct ucom_attach_args ucaa; usbd_status error; - int n, intr_address, intr_size; + int n, intr_address, intr_size; aprint_naive("\n"); aprint_normal("\n"); @@ -735,7 +739,7 @@ u3g_attach(device_t parent, device_t self, void *aux) sc->sc_dying = false; sc->sc_udev = dev; - error = usbd_device2interface_handle(dev, uaa->ifaceno, &iface); + error = usbd_device2interface_handle(dev, uiaa->uiaa_ifaceno, &iface); if (error) { aprint_error_dev(self, "failed to get interface, err=%s\n", usbd_errstr(error)); @@ -744,20 +748,20 @@ u3g_attach(device_t parent, device_t self, void *aux) id = usbd_get_interface_descriptor(iface); - uca.info = "3G Modem"; - uca.ibufsize = U3G_BUFF_SIZE; - uca.obufsize = U3G_BUFF_SIZE; - uca.ibufsizepad = U3G_BUFF_SIZE; - uca.opkthdrlen = 0; - uca.device = dev; - uca.iface = iface; - uca.methods = &u3g_methods; - uca.arg = sc; - uca.portno = -1; - uca.bulkin = uca.bulkout = -1; + ucaa.ucaa_info = "3G Modem"; + ucaa.ucaa_ibufsize = U3G_BUFF_SIZE; + ucaa.ucaa_obufsize = U3G_BUFF_SIZE; + ucaa.ucaa_ibufsizepad = U3G_BUFF_SIZE; + ucaa.ucaa_opkthdrlen = 0; + ucaa.ucaa_device = dev; + ucaa.ucaa_iface = iface; + ucaa.ucaa_methods = &u3g_methods; + ucaa.ucaa_arg = sc; + ucaa.ucaa_portno = -1; + ucaa.ucaa_bulkin = ucaa.ucaa_bulkout = -1; - sc->sc_ifaceno = uaa->ifaceno; + sc->sc_ifaceno = uiaa->uiaa_ifaceno; intr_address = -1; intr_size = 0; @@ -777,29 +781,29 @@ u3g_attach(device_t parent, device_t self, void *aux) } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - uca.bulkin = ed->bEndpointAddress; + ucaa.ucaa_bulkin = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - uca.bulkout = ed->bEndpointAddress; + ucaa.ucaa_bulkout = ed->bEndpointAddress; } - if (uca.bulkin != -1 && uca.bulkout != -1) { + if (ucaa.ucaa_bulkin != -1 && ucaa.ucaa_bulkout != -1) { struct u3g_com *com; if (sc->sc_ncom == __arraycount(sc->sc_com)) { aprint_error_dev(self, "Need to configure " "more than %zu ttys", sc->sc_ncom); continue; } - uca.portno = sc->sc_ncom++; - com = &sc->sc_com[uca.portno]; + ucaa.ucaa_portno = sc->sc_ncom++; + com = &sc->sc_com[ucaa.ucaa_portno]; com->c_outpins = 0; com->c_msr = UMSR_DSR | UMSR_CTS | UMSR_DCD; com->c_open = false; com->c_purging = false; com->c_dev = config_found_sm_loc(self, "ucombus", - NULL, &uca, ucomprint, ucomsubmatch); - uca.bulkin = -1; - uca.bulkout = -1; + NULL, &ucaa, ucomprint, ucomsubmatch); + ucaa.ucaa_bulkin = -1; + ucaa.ucaa_bulkout = -1; } } @@ -816,7 +820,8 @@ u3g_attach(device_t parent, device_t self, void *aux) * the tty(4) device is open or not. */ if (intr_address != -1) { - sc->sc_intr_buff = malloc(intr_size, M_USBDEV, M_WAITOK); + sc->sc_intr_size = intr_size; + sc->sc_intr_buff = kmem_alloc(intr_size, KM_SLEEP); error = usbd_open_pipe_intr(iface, intr_address, USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc, sc->sc_intr_buff, intr_size, u3g_intr, 100); @@ -860,11 +865,11 @@ u3g_detach(device_t self, int flags) sc->sc_intr_pipe = NULL; } if (sc->sc_intr_buff != NULL) { - free(sc->sc_intr_buff, M_USBDEV); + kmem_free(sc->sc_intr_buff, sc->sc_intr_size); sc->sc_intr_buff = NULL; } - return (0); + return 0; } static void @@ -901,7 +906,7 @@ u3g_activate(device_t self, enum devact act) } static void -u3g_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +u3g_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct u3g_softc *sc = (struct u3g_softc *)priv; u_char *buf; @@ -994,35 +999,35 @@ u3g_set(void *arg, int portno, int reg, int onoff) err = usbd_do_request(sc->sc_udev, &req, 0); if (err == USBD_STALLED) - usbd_clear_endpoint_stall(sc->sc_udev->default_pipe); + usbd_clear_endpoint_stall(sc->sc_udev->ud_pipe0); } /*ARGSUSED*/ -static int +static int u3g_open(void *arg, int portno) { struct u3g_softc *sc = arg; usb_device_request_t req; usb_endpoint_descriptor_t *ed; usb_interface_descriptor_t *id; - usbd_interface_handle ih; + struct usbd_interface *ih; usbd_status err; struct u3g_com *com = &sc->sc_com[portno]; int i, nin; if (sc->sc_dying) - return (0); + return 0; err = usbd_device2interface_handle(sc->sc_udev, sc->sc_ifaceno, &ih); if (err) - return (EIO); + return EIO; id = usbd_get_interface_descriptor(ih); for (nin = i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(ih, i); - if (ed == NULL) - return (EIO); + if (ed == NULL) + return EIO; if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK && @@ -1035,7 +1040,7 @@ u3g_open(void *arg, int portno) USETW(req.wLength, 0); err = usbd_do_request(sc->sc_udev, &req, 0); if (err) - return (EIO); + return EIO; } } @@ -1043,11 +1048,11 @@ u3g_open(void *arg, int portno) com->c_purging = true; getmicrotime(&com->c_purge_start); - return (0); + return 0; } /*ARGSUSED*/ -static void +static void u3g_close(void *arg, int portno) { struct u3g_softc *sc = arg; @@ -1087,7 +1092,7 @@ u3g_read(void *arg, int portno, u_char **cpp, uint32_t *ccp) /*ARGSUSED*/ static void -u3g_write(void *arg, int portno, u_char *to, u_char *from, u_int32_t *count) +u3g_write(void *arg, int portno, u_char *to, u_char *from, uint32_t *count) { struct u3g_softc *sc = arg; struct u3g_com *com = &sc->sc_com[portno]; diff --git a/sys/dev/usb/uark.c b/sys/dev/usb/uark.c index 968c5253c78..cbf2c2ad446 100644 --- a/sys/dev/usb/uark.c +++ b/sys/dev/usb/uark.c @@ -1,4 +1,4 @@ -/* $NetBSD: uark.c,v 1.6 2012/10/27 17:18:38 chs Exp $ */ +/* $NetBSD: uark.c,v 1.7 2016/04/23 10:15:32 skrll Exp $ */ /* $OpenBSD: uark.c,v 1.13 2009/10/13 19:33:17 pirofti Exp $ */ /* @@ -61,8 +61,8 @@ int uarkebug = 0; struct uark_softc { device_t sc_dev; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device * sc_udev; + struct usbd_interface * sc_iface; device_t sc_subdev; u_char sc_msr; @@ -78,14 +78,14 @@ void uark_break(void *, int, int); int uark_cmd(struct uark_softc *, uint16_t, uint16_t); struct ucom_methods uark_methods = { - uark_get_status, - uark_set, - uark_param, - NULL, - NULL, - NULL, - NULL, - NULL, + .ucom_get_status = uark_get_status, + .ucom_set = uark_set, + .ucom_param = uark_param, + .ucom_ioctl = NULL, + .ucom_open = NULL, + .ucom_close = NULL, + .ucom_read = NULL, + .ucom_write = NULL, }; static const struct usb_devno uark_devs[] = { @@ -99,29 +99,29 @@ int uark_activate(device_t, enum devact); extern struct cfdriver uark_cd; CFATTACH_DECL_NEW(uark, sizeof(struct uark_softc), uark_match, uark_attach, uark_detach, uark_activate); -int +int uark_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (usb_lookup(uark_devs, uaa->vendor, uaa->product) != NULL) ? + return (usb_lookup(uark_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL) ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } -void +void uark_attach(device_t parent, device_t self, void *aux) { struct uark_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; + struct usbd_device *dev = uaa->uaa_device; char *devinfop; - struct ucom_attach_args uca; + struct ucom_attach_args ucaa; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; usbd_status error; int i; - memset(&uca, 0, sizeof(uca)); + memset(&ucaa, 0, sizeof(ucaa)); sc->sc_dev = self; devinfop = usbd_devinfo_alloc(dev, 0); @@ -149,7 +149,7 @@ uark_attach(device_t parent, device_t self, void *aux) id = usbd_get_interface_descriptor(sc->sc_iface); - uca.bulkin = uca.bulkout = -1; + ucaa.ucaa_bulkin = ucaa.ucaa_bulkout = -1; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { @@ -161,32 +161,32 @@ uark_attach(device_t parent, device_t self, void *aux) if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) - uca.bulkin = ed->bEndpointAddress; + ucaa.ucaa_bulkin = ed->bEndpointAddress; else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) - uca.bulkout = ed->bEndpointAddress; + ucaa.ucaa_bulkout = ed->bEndpointAddress; } - if (uca.bulkin == -1 || uca.bulkout == -1) { + if (ucaa.ucaa_bulkin == -1 || ucaa.ucaa_bulkout == -1) { aprint_error_dev(self, "missing endpoint\n"); sc->sc_dying = 1; return; } - uca.ibufsize = UARKBUFSZ; - uca.obufsize = UARKBUFSZ; - uca.ibufsizepad = UARKBUFSZ; - uca.opkthdrlen = 0; - uca.device = sc->sc_udev; - uca.iface = sc->sc_iface; - uca.methods = &uark_methods; - uca.arg = sc; - uca.info = NULL; + ucaa.ucaa_ibufsize = UARKBUFSZ; + ucaa.ucaa_obufsize = UARKBUFSZ; + ucaa.ucaa_ibufsizepad = UARKBUFSZ; + ucaa.ucaa_opkthdrlen = 0; + ucaa.ucaa_device = sc->sc_udev; + ucaa.ucaa_iface = sc->sc_iface; + ucaa.ucaa_methods = &uark_methods; + ucaa.ucaa_arg = sc; + ucaa.ucaa_info = NULL; usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); - - sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &uca, + + sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &ucaa, ucomprint, ucomsubmatch); return; @@ -318,7 +318,7 @@ void uark_get_status(void *vsc, int portno, u_char *lsr, u_char *msr) { struct uark_softc *sc = vsc; - + if (msr != NULL) *msr = sc->sc_msr; if (lsr != NULL) diff --git a/sys/dev/usb/uatp.c b/sys/dev/usb/uatp.c index dd22348ff0e..c79f4538166 100644 --- a/sys/dev/usb/uatp.c +++ b/sys/dev/usb/uatp.c @@ -1,4 +1,4 @@ -/* $NetBSD: uatp.c,v 1.11 2015/03/07 20:20:55 mrg Exp $ */ +/* $NetBSD: uatp.c,v 1.12 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2011-2014 The NetBSD Foundation, Inc. @@ -39,7 +39,7 @@ * Apple's protocol gives more detailed sensor data that lets us detect * multiple fingers to emulate multi-button mice and scroll wheels. */ - + /* * Protocol * @@ -104,7 +104,7 @@ * Should make a struct uatp_motion for all that state. * XXX Add hooks for ignoring trackpad input while typing. */ - + /* * Classifying devices * @@ -144,9 +144,9 @@ * tweak hw.uatp0.x_sensors and hw.uatp0.y_sensors, up to a maximum * of 32 for each value. */ - + #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.11 2015/03/07 20:20:55 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.12 2016/04/23 10:15:32 skrll Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -179,7 +179,7 @@ __KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.11 2015/03/07 20:20:55 mrg Exp $"); fail; \ } \ } while (0) - + #define UATP_DEBUG_ATTACH (1 << 0) #define UATP_DEBUG_MISC (1 << 1) #define UATP_DEBUG_WSMOUSE (1 << 2) @@ -238,7 +238,7 @@ __KERNEL_RCSID(0, "$NetBSD: uatp.c,v 1.11 2015/03/07 20:20:55 mrg Exp $"); #define UATP_STATUS_BUTTON (1 << 0) /* Button pressed */ #define UATP_STATUS_BASE (1 << 2) /* Base sensor data */ #define UATP_STATUS_POST_RESET (1 << 4) /* Post-reset */ - + /* Forward declarations */ struct uatp_softc; /* Device driver state. */ @@ -340,7 +340,7 @@ static bool motion_below_threshold(struct uatp_softc *, unsigned int, int, int); static int accelerate(struct uatp_softc *, unsigned int, unsigned int, unsigned int, unsigned int, bool, int *); - + struct uatp_knobs { /* * Button emulation. What do we do when two or three fingers @@ -408,7 +408,7 @@ struct uatp_knobs { unsigned int three_finger_tap_buttons; unsigned int tap_track_distance_limit; }; - + static const struct uatp_knobs default_knobs = { /* * Button emulation. Fingers on the trackpad don't change it @@ -473,7 +473,7 @@ static const struct uatp_knobs default_knobs = { .three_finger_tap_buttons = 0, .tap_track_distance_limit = 200, }; - + struct uatp_softc { struct uhidev sc_hdev; /* USB parent. */ device_t sc_wsmousedev; /* Attached wsmouse device. */ @@ -522,7 +522,7 @@ struct uatp_softc { uint32_t sc_debug_flags; /* Debugging output enabled. */ #endif }; - + struct uatp_descriptor { uint16_t vendor; uint16_t product; @@ -559,7 +559,7 @@ struct uatp_parameters { /* Called on spurious interrupts to reset. May be null. */ void (*reset)(struct uatp_softc *); }; - + /* Known device parameters */ static const struct uatp_parameters fountain_parameters = { @@ -617,7 +617,7 @@ static const struct uatp_parameters geyser_3_4_parameters = { .accumulate = accumulate_sample_2, .reset = geyser34_deferred_reset, }; - + /* Known device models */ #define APPLE_TRACKPAD(PRODUCT, DESCRIPTION, PARAMETERS) \ @@ -661,7 +661,7 @@ static const struct uatp_descriptor uatp_descriptors[] = #undef MACBOOK_TRACKPAD #undef POWERBOOK_TRACKPAD #undef APPLE_TRACKPAD - + /* Miscellaneous utilities */ static const struct uatp_descriptor * @@ -670,8 +670,8 @@ find_uatp_descriptor(const struct uhidev_attach_arg *uha) unsigned int i; for (i = 0; i < __arraycount(uatp_descriptors); i++) - if ((uha->uaa->vendor == uatp_descriptors[i].vendor) && - (uha->uaa->product == uatp_descriptors[i].product)) + if ((uha->uiaa->uiaa_vendor == uatp_descriptors[i].vendor) && + (uha->uiaa->uiaa_product == uatp_descriptors[i].product)) return &uatp_descriptors[i]; return NULL; @@ -722,7 +722,7 @@ uatp_clear_position(struct uatp_softc *sc) sc->sc_w_remainder = 0; sc->sc_track_distance = 0; } - + static unsigned int uatp_x_sensors(const struct uatp_softc *sc) { @@ -764,7 +764,7 @@ uatp_y_ratio(const struct uatp_softc *sc) else return sc->sc_parameters->y_ratio; } - + static unsigned int uatp_old_raw_weight(const struct uatp_softc *sc) { @@ -795,7 +795,7 @@ uatp_new_raw_weight(const struct uatp_softc *sc) else return 1; } - + static int scale_motion(const struct uatp_softc *sc, int delta, int *remainder, const unsigned int *multiplier, const unsigned int *divisor) @@ -848,7 +848,7 @@ uatp_scale_fast_motion(const struct uatp_softc *sc, int delta, int *remainder) &sc->sc_knobs.fast_motion_multiplier, &sc->sc_knobs.fast_motion_divisor); } - + /* Driver goop */ CFATTACH_DECL2_NEW(uatp, sizeof(struct uatp_softc), uatp_match, uatp_attach, @@ -869,13 +869,13 @@ uatp_match(device_t parent, cfdata_t match, void *aux) const struct uatp_descriptor *uatp_descriptor; aprint_debug("%s: vendor 0x%04x, product 0x%04x\n", __func__, - (unsigned int)uha->uaa->vendor, - (unsigned int)uha->uaa->product); + (unsigned int)uha->uiaa->uiaa_vendor, + (unsigned int)uha->uiaa->uiaa_product); aprint_debug("%s: class 0x%04x, subclass 0x%04x, proto 0x%04x\n", __func__, - (unsigned int)uha->uaa->class, - (unsigned int)uha->uaa->subclass, - (unsigned int)uha->uaa->proto); + (unsigned int)uha->uiaa->uiaa_class, + (unsigned int)uha->uiaa->uiaa_subclass, + (unsigned int)uha->uiaa->uiaa_proto); uhidev_get_report_desc(uha->parent, &report_descriptor, &report_size); input_size = hid_report_size(report_descriptor, report_size, @@ -888,7 +888,7 @@ uatp_match(device_t parent, cfdata_t match, void *aux) * and product ids, but not protocols: only the trackpad * reports a mouse protocol. */ - if (uha->uaa->proto != UIPROTO_MOUSE) + if (uha->uiaa->uiaa_proto != UIPROTO_MOUSE) return UMATCH_NONE; /* Check for a known vendor/product id. */ @@ -909,7 +909,7 @@ uatp_match(device_t parent, cfdata_t match, void *aux) return UMATCH_VENDOR_PRODUCT_CONF_IFACE; } - + static void uatp_attach(device_t parent, device_t self, void *aux) { @@ -933,7 +933,8 @@ uatp_attach(device_t parent, device_t self, void *aux) aprint_naive(": %s\n", uatp_descriptor->description); aprint_verbose_dev(self, "vendor 0x%04x, product 0x%04x, report id %d\n", - (unsigned int)uha->uaa->vendor, (unsigned int)uha->uaa->product, + (unsigned int)uha->uiaa->uiaa_vendor, + (unsigned int)uha->uiaa->uiaa_product, (int)uha->reportid); uhidev_get_report_desc(uha->parent, &report_descriptor, &report_size); @@ -977,7 +978,7 @@ uatp_attach(device_t parent, device_t self, void *aux) sc->sc_wsmousedev = config_found_ia(self, "wsmousedev", &a, wsmousedevprint); } - + /* Sysctl setup */ static void @@ -1032,7 +1033,7 @@ uatp_setup_sysctl(struct uatp_softc *sc) "width of right edge for edge scrolling")) goto err; #endif - + /* * Multifinger tracking. */ @@ -1101,7 +1102,7 @@ uatp_setup_sysctl(struct uatp_softc *sc) if (!uatp_setup_sysctl_knob(sc, &sc->sc_knobs.motion_delay, "motion_delay", "number of packets before motion kicks in")) goto err; - + /* * Tapping. */ @@ -1152,7 +1153,7 @@ uatp_setup_sysctl_knob(struct uatp_softc *sc, int *ptr, const char *name, return true; } - + /* More driver goop */ static void @@ -1210,7 +1211,7 @@ uatp_activate(device_t self, enum devact act) return 0; } - + /* wsmouse routines */ static int @@ -1271,7 +1272,7 @@ uatp_ioctl(void *v, unsigned long cmd, void *data, int flag, struct lwp *p) /* XXX Implement any relevant wsmouse(4) ioctls. */ return EPASSTHROUGH; } - + /* * The Geyser 3 and 4 models talk the generic USB HID mouse protocol by * default. This mode switch makes them give raw sensor data instead @@ -1286,7 +1287,7 @@ uatp_ioctl(void *v, unsigned long cmd, void *data, int flag, struct lwp *p) static void geyser34_enable_raw_mode(struct uatp_softc *sc) { - usbd_device_handle udev = sc->sc_hdev.sc_parent->sc_udev; + struct usbd_device *udev = sc->sc_hdev.sc_parent->sc_udev; usb_device_request_t req; usbd_status status; uint8_t report[GEYSER34_MODE_PACKET_SIZE]; @@ -1304,7 +1305,7 @@ geyser34_enable_raw_mode(struct uatp_softc *sc) "error reading feature report: %s\n", usbd_errstr(status)); return; } - + #if UATP_DEBUG if (sc->sc_debug_flags & UATP_DEBUG_RESET) { unsigned int i; @@ -1338,7 +1339,7 @@ geyser34_enable_raw_mode(struct uatp_softc *sc) return; } } - + /* * The Geyser 3 and 4 need to be reset periodically after we detect a * continual flow of spurious interrupts. We use a USB task for this. @@ -1382,7 +1383,7 @@ geyser34_reset_task(void *arg) /* Reset by putting it into raw mode. Not sure why. */ geyser34_enable_raw_mode(sc); } - + /* Interrupt handler */ static void @@ -1447,7 +1448,7 @@ uatp_intr(struct uhidev *addr, void *ibuf, unsigned int len) memset(uatp_y_sample(sc), 0, UATP_MAX_Y_SENSORS); sc->sc_parameters->read_sample(uatp_x_sample(sc), uatp_y_sample(sc), input); - + #if UATP_DEBUG if (sc->sc_debug_flags & UATP_DEBUG_INTR) { unsigned int i; @@ -1519,7 +1520,7 @@ uatp_intr(struct uhidev *addr, void *ibuf, unsigned int len) uatp_input(sc, buttons, dx, dy, dz, dw); mutex_exit(&sc->sc_tap_mutex); } - + /* * Different ways to discern the base sample initializing the state. * `base_sample_softc_flag' uses a state flag stored in the softc; @@ -1577,7 +1578,7 @@ read_sample_2(uint8_t *x, uint8_t *y, const uint8_t *input) y[i + 1] = input[j + 1]; } } - + static void accumulate_sample_1(struct uatp_softc *sc) { @@ -1624,7 +1625,7 @@ accumulate_sample_2(struct uatp_softc *sc) sc->sc_acc[i] = 0; } } - + /* * Report input to wsmouse, if there is anything interesting to report. * We must take into consideration the current tap-and-drag button @@ -1688,7 +1689,7 @@ uatp_tapped_buttons(struct uatp_softc *sc) return 0; } } - + /* * Interpret the current input state to find a difference in all the * relevant coordinates and buttons to pass on to wsmouse, and update @@ -1755,7 +1756,7 @@ interpret_input(struct uatp_softc *sc, int *dx, int *dy, int *dz, int *dw, return true; } } - + /* * Interpret the accumulated sensor state along one dimension to find * the number, mean position, and pressure of fingers. Returns 0 to @@ -1822,9 +1823,9 @@ interpret_dimension(struct uatp_softc *sc, const int *acc, */ n_fingers = 0; - memset(weighted, 0, sizeof weighted); - memset(total, 0, sizeof total); - + memset(weighted, 0, sizeof(weighted)); + memset(total, 0, sizeof(total)); + for (i = 0; i < n_sensors; i++) { CHECK_(0 <= acc[i]); v = acc[i]; @@ -1901,7 +1902,7 @@ interpret_dimension(struct uatp_softc *sc, const int *acc, #undef CHECK_ } - + /* Tapping */ /* @@ -1959,7 +1960,7 @@ interpret_dimension(struct uatp_softc *sc, const int *acc, * these properties, or globally transform the state machine to avoid * the bad consequences of violating these properties. */ - + static void uatp_tap_limit(const struct uatp_softc *sc, struct timeval *limit) { @@ -1989,7 +1990,7 @@ tap_debug(struct uatp_softc *sc, const char *caller, const char *prefix) case TAP_STATE_DRAGGING_UP: state = "dragging-up"; break; case TAP_STATE_TAPPING_IN_DRAG: state = "tapping-in-drag"; break; default: - snprintf(buffer, sizeof buffer, "unknown (%d)", + snprintf(buffer, sizeof(buffer), "unknown (%d)", sc->sc_tap_state); state = buffer; break; @@ -2007,13 +2008,13 @@ tap_debug(struct uatp_softc *sc, const char *caller, const char *prefix) # define TAP_DEBUG_POST(sc) do {} while (0) #endif - + static void tap_initialize(struct uatp_softc *sc) { callout_init(&sc->sc_untap_callout, 0); callout_setfunc(&sc->sc_untap_callout, untap_callout, sc); - mutex_init(&sc->sc_tap_mutex, MUTEX_DEFAULT, IPL_USB); + mutex_init(&sc->sc_tap_mutex, MUTEX_DEFAULT, IPL_SOFTUSB); cv_init(&sc->sc_tap_cv, "uatptap"); } @@ -2078,7 +2079,7 @@ tap_reset_wait(struct uatp_softc *sc) tap_transition_initial(sc); mutex_exit(&sc->sc_tap_mutex); } - + static const struct timeval zero_timeval; static void @@ -2125,7 +2126,7 @@ tap_transition_double_tapping(struct uatp_softc *sc, tap_transition(sc, TAP_STATE_DOUBLE_TAPPING, start_time, fingers, sc->sc_tapped_fingers); } - + static void tap_transition_dragging_down(struct uatp_softc *sc) { @@ -2172,7 +2173,7 @@ tap_transition_dragging_up(struct uatp_softc *sc) tap_transition(sc, TAP_STATE_DRAGGING_UP, &zero_timeval, 0, sc->sc_tapped_fingers); } - + static void tap_touched(struct uatp_softc *sc, unsigned int fingers) { @@ -2247,7 +2248,7 @@ tap_touched(struct uatp_softc *sc, unsigned int fingers) TAP_DEBUG_POST(sc); mutex_exit(&sc->sc_tap_mutex); } - + static bool tap_released(struct uatp_softc *sc) { @@ -2324,7 +2325,7 @@ tap_released(struct uatp_softc *sc) mutex_exit(&sc->sc_tap_mutex); return ok; } - + /* Untapping: Releasing the button after a tap */ static void @@ -2379,7 +2380,7 @@ untap_callout(void *arg) cv_broadcast(&sc->sc_tap_cv); mutex_exit(&sc->sc_tap_mutex); } - + /* * Emulate different buttons if the user holds down n fingers while * pressing the physical button. (This is unrelated to tapping.) @@ -2405,7 +2406,7 @@ emulated_buttons(struct uatp_softc *sc, unsigned int fingers) return sc->sc_knobs.three_finger_buttons; } } - + /* * Update the position known to the driver based on the position and * number of fingers. dx, dy, dz, and dw are expected to hold zero; @@ -2448,7 +2449,7 @@ scroll_wheel(struct uatp_softc *sc, unsigned int x_raw, unsigned int y_raw, &sc->sc_z_remainder, &sc->sc_w_remainder, dz, dw); } - + static void move(struct uatp_softc *sc, const char *ctx, unsigned int a, unsigned int b, int *a_raw, int *b_raw, @@ -2504,7 +2505,7 @@ move(struct uatp_softc *sc, const char *ctx, unsigned int a, unsigned int b, CHECK_(0 <= *b_smoothed); CHECK_(*a_smoothed <= UATP_MAX_POSITION); CHECK_(*b_smoothed <= UATP_MAX_POSITION); - + if (sc->sc_motion_timer < sc->sc_knobs.motion_delay) { DPRINTF(sc, UATP_DEBUG_MOVE, ("delay motion %u\n", sc->sc_motion_timer)); @@ -2573,7 +2574,7 @@ move(struct uatp_softc *sc, const char *ctx, unsigned int a, unsigned int b, #undef CHECK_ } - + static int smooth(struct uatp_softc *sc, unsigned int old_raw, unsigned int old_smoothed, unsigned int raw) @@ -2646,7 +2647,7 @@ accelerate(struct uatp_softc *sc, unsigned int old_raw, unsigned int raw, #undef CHECK_ } - + MODULE(MODULE_CLASS_DRIVER, uatp, NULL); #ifdef _MODULE diff --git a/sys/dev/usb/uaudio.c b/sys/dev/usb/uaudio.c index 675ba50933e..91173cd6efd 100644 --- a/sys/dev/usb/uaudio.c +++ b/sys/dev/usb/uaudio.c @@ -1,4 +1,4 @@ -/* $NetBSD: uaudio.c,v 1.145 2016/03/13 07:01:43 skrll Exp $ */ +/* $NetBSD: uaudio.c,v 1.146 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1999, 2012 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.145 2016/03/13 07:01:43 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.146 2016/04/23 10:15:32 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -134,7 +134,7 @@ struct as_info { uint8_t attributes; /* Copy of bmAttributes of * usb_audio_streaming_endpoint_descriptor */ - usbd_interface_handle ifaceh; + struct usbd_interface * ifaceh; const usb_interface_descriptor_t *idesc; const usb_endpoint_descriptor_audio_t *edesc; const usb_endpoint_descriptor_audio_t *edesc1; @@ -146,8 +146,8 @@ struct as_info { struct chan { void (*intr)(void *); /* DMA completion intr handler */ void *arg; /* arg for intr() */ - usbd_pipe_handle pipe; - usbd_pipe_handle sync_pipe; + struct usbd_pipe *pipe; + struct usbd_pipe *sync_pipe; u_int sample_size; u_int sample_rate; @@ -166,7 +166,7 @@ struct chan { int curchanbuf; struct chanbuf { struct chan *chan; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; u_char *buffer; uint16_t sizes[UAUDIO_NFRAMES]; uint16_t offsets[UAUDIO_NFRAMES]; @@ -177,20 +177,16 @@ struct chan { }; /* - * XXX Locking notes: - * - * The MI USB audio subsystem is not MP-SAFE. Our strategy here - * is to ensure we have the kernel lock held when calling into - * usbd, and, generally, to have dropped the sc_intr_lock during - * these sections as well since the usb code will sleep. + * The MI USB audio subsystem is now MP-SAFE and expects sc_intr_lock to be + * held on entry the callbacks passed to uaudio_trigger_{in,out}put */ struct uaudio_softc { device_t sc_dev; /* base device */ kmutex_t sc_lock; kmutex_t sc_intr_lock; - usbd_device_handle sc_udev; /* USB device */ + struct usbd_device *sc_udev; /* USB device */ int sc_ac_iface; /* Audio Control interface */ - usbd_interface_handle sc_ac_ifaceh; + struct usbd_interface * sc_ac_ifaceh; struct chan sc_playchan; /* play channel */ struct chan sc_recchan; /* record channel */ int sc_nullalt; @@ -321,6 +317,7 @@ Static void uaudio_ctl_set Static usbd_status uaudio_set_speed(struct uaudio_softc *, int, u_int); Static usbd_status uaudio_chan_open(struct uaudio_softc *, struct chan *); +Static void uaudio_chan_abort(struct uaudio_softc *, struct chan *); Static void uaudio_chan_close(struct uaudio_softc *, struct chan *); Static usbd_status uaudio_chan_alloc_buffers (struct uaudio_softc *, struct chan *); @@ -330,11 +327,11 @@ Static void uaudio_chan_init Static void uaudio_chan_set_param(struct chan *, u_char *, u_char *, int); Static void uaudio_chan_ptransfer(struct chan *); Static void uaudio_chan_pintr - (usbd_xfer_handle, usbd_private_handle, usbd_status); + (struct usbd_xfer *, void *, usbd_status); Static void uaudio_chan_rtransfer(struct chan *); Static void uaudio_chan_rintr - (usbd_xfer_handle, usbd_private_handle, usbd_status); + (struct usbd_xfer *, void *, usbd_status); Static int uaudio_open(void *, int); Static void uaudio_close(void *); @@ -405,12 +402,12 @@ CFATTACH_DECL2_NEW(uaudio, sizeof(struct uaudio_softc), int uaudio_match(device_t parent, cfdata_t match, void *aux) { - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; /* Trigger on the control interface. */ - if (uaa->class != UICLASS_AUDIO || - uaa->subclass != UISUBCLASS_AUDIOCONTROL || - (usbd_get_quirks(uaa->device)->uq_flags & UQ_BAD_AUDIO)) + if (uiaa->uiaa_class != UICLASS_AUDIO || + uiaa->uiaa_subclass != UISUBCLASS_AUDIOCONTROL || + (usbd_get_quirks(uiaa->uiaa_device)->uq_flags & UQ_BAD_AUDIO)) return UMATCH_NONE; return UMATCH_IFACECLASS_IFACESUBCLASS; @@ -420,7 +417,7 @@ void uaudio_attach(device_t parent, device_t self, void *aux) { struct uaudio_softc *sc = device_private(self); - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; usb_interface_descriptor_t *id; usb_config_descriptor_t *cdesc; char *devinfop; @@ -428,19 +425,19 @@ uaudio_attach(device_t parent, device_t self, void *aux) int i, j, found; sc->sc_dev = self; - sc->sc_udev = uaa->device; + sc->sc_udev = uiaa->uiaa_device; mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); - mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SCHED); + mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_SOFTUSB); strlcpy(sc->sc_adev.name, "USB audio", sizeof(sc->sc_adev.name)); strlcpy(sc->sc_adev.version, "", sizeof(sc->sc_adev.version)); snprintf(sc->sc_adev.config, sizeof(sc->sc_adev.config), "usb:%08x", - sc->sc_udev->cookie.cookie); + sc->sc_udev->ud_cookie.cookie); aprint_naive("\n"); aprint_normal("\n"); - devinfop = usbd_devinfo_alloc(uaa->device, 0); + devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); @@ -458,24 +455,24 @@ uaudio_attach(device_t parent, device_t self, void *aux) return; } - sc->sc_ac_ifaceh = uaa->iface; + sc->sc_ac_ifaceh = uiaa->uiaa_iface; /* Pick up the AS interface. */ - for (i = 0; i < uaa->nifaces; i++) { - if (uaa->ifaces[i] == NULL) + for (i = 0; i < uiaa->uiaa_nifaces; i++) { + if (uiaa->uiaa_ifaces[i] == NULL) continue; - id = usbd_get_interface_descriptor(uaa->ifaces[i]); + id = usbd_get_interface_descriptor(uiaa->uiaa_ifaces[i]); if (id == NULL) continue; found = 0; for (j = 0; j < sc->sc_nalts; j++) { if (id->bInterfaceNumber == sc->sc_alts[j].idesc->bInterfaceNumber) { - sc->sc_alts[j].ifaceh = uaa->ifaces[i]; + sc->sc_alts[j].ifaceh = uiaa->uiaa_ifaces[i]; found = 1; } } if (found) - uaa->ifaces[i] = NULL; + uiaa->uiaa_ifaces[i] = NULL; } for (j = 0; j < sc->sc_nalts; j++) { @@ -551,7 +548,8 @@ uaudio_detach(device_t self, int flags) sc->sc_dev); if (sc->sc_formats != NULL) - free(sc->sc_formats, M_USBDEV); + kmem_free(sc->sc_formats, + sizeof(struct audio_format) * sc->sc_nformats); auconv_delete_encodings(sc->sc_encodings); mutex_destroy(&sc->sc_lock); @@ -606,7 +604,7 @@ uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc) DPRINTF("adding %s\n", mc->ctlname); } len = sizeof(*mc) * (sc->sc_nctls + 1); - nmc = malloc(len, M_USBDEV, M_NOWAIT); + nmc = kmem_alloc(len, KM_SLEEP); if (nmc == NULL) { aprint_error("uaudio_mixer_add_ctl: no memory\n"); return; @@ -614,7 +612,7 @@ uaudio_mixer_add_ctl(struct uaudio_softc *sc, struct mixerctl *mc) /* Copy old data, if there was any */ if (sc->sc_nctls != 0) { memcpy(nmc, sc->sc_ctls, sizeof(*mc) * (sc->sc_nctls)); - free(sc->sc_ctls, M_USBDEV); + kmem_free(sc->sc_ctls, sizeof(*mc) * sc->sc_nctls); } sc->sc_ctls = nmc; @@ -743,7 +741,7 @@ uaudio_get_cluster(int id, const struct io_terminal *iot) } bad: aprint_error("uaudio_get_cluster: bad data\n"); - memset(&r, 0, sizeof r); + memset(&r, 0, sizeof(r)); return r; } @@ -1543,7 +1541,7 @@ uaudio_add_alt(struct uaudio_softc *sc, const struct as_info *ai) struct as_info *nai; len = sizeof(*ai) * (sc->sc_nalts + 1); - nai = malloc(len, M_USBDEV, M_NOWAIT); + nai = kmem_alloc(len, KM_SLEEP); if (nai == NULL) { aprint_error("uaudio_add_alt: no memory\n"); return; @@ -1551,7 +1549,7 @@ uaudio_add_alt(struct uaudio_softc *sc, const struct as_info *ai) /* Copy old data, if there was any */ if (sc->sc_nalts != 0) { memcpy(nai, sc->sc_alts, sizeof(*ai) * (sc->sc_nalts)); - free(sc->sc_alts, M_USBDEV); + kmem_free(sc->sc_alts, sizeof(*ai) * sc->sc_nalts); } sc->sc_alts = nai; DPRINTFN(2,"adding alt=%d, enc=%d\n", @@ -1832,8 +1830,8 @@ uaudio_identify_as(struct uaudio_softc *sc, } /* build audio_format array */ - sc->sc_formats = malloc(sizeof(struct audio_format) * sc->sc_nalts, - M_USBDEV, M_NOWAIT); + sc->sc_formats = kmem_alloc(sizeof(struct audio_format) * sc->sc_nalts, + KM_SLEEP); if (sc->sc_formats == NULL) return USBD_NOMEM; sc->sc_nformats = sc->sc_nalts; @@ -1872,7 +1870,8 @@ uaudio_identify_as(struct uaudio_softc *sc, if (0 != auconv_create_encodings(sc->sc_formats, sc->sc_nformats, &sc->sc_encodings)) { - free(sc->sc_formats, M_DEVBUF); + kmem_free(sc->sc_formats, + sizeof(struct audio_format) * sc->sc_nformats); sc->sc_formats = NULL; return ENOMEM; } @@ -1915,7 +1914,7 @@ uaudio_identify_ac(struct uaudio_softc *sc, const usb_config_descriptor_t *cdesc id = uaudio_find_iface(tbuf, size, &offs, UISUBCLASS_AUDIOCONTROL); if (id == NULL) return USBD_INVAL; - if (offs + sizeof *acdp > size) + if (offs + sizeof(*acdp) > size) return USBD_INVAL; sc->sc_ac_iface = id->bInterfaceNumber; DPRINTFN(2,"AC interface is %d\n", sc->sc_ac_iface); @@ -2234,13 +2233,14 @@ uaudio_halt_out_dma(void *addr) DPRINTF("%s", "enter\n"); - mutex_spin_exit(&sc->sc_intr_lock); + mutex_exit(&sc->sc_intr_lock); if (sc->sc_playchan.pipe != NULL) { - uaudio_chan_close(sc, &sc->sc_playchan); + uaudio_chan_abort(sc, &sc->sc_playchan); uaudio_chan_free_buffers(sc, &sc->sc_playchan); + uaudio_chan_close(sc, &sc->sc_playchan); sc->sc_playchan.intr = NULL; } - mutex_spin_enter(&sc->sc_intr_lock); + mutex_enter(&sc->sc_intr_lock); return 0; } @@ -2252,13 +2252,14 @@ uaudio_halt_in_dma(void *addr) DPRINTF("%s", "enter\n"); - mutex_spin_exit(&sc->sc_intr_lock); + mutex_exit(&sc->sc_intr_lock); if (sc->sc_recchan.pipe != NULL) { - uaudio_chan_close(sc, &sc->sc_recchan); + uaudio_chan_abort(sc, &sc->sc_recchan); uaudio_chan_free_buffers(sc, &sc->sc_recchan); + uaudio_chan_close(sc, &sc->sc_recchan); sc->sc_recchan.intr = NULL; } - mutex_spin_enter(&sc->sc_intr_lock); + mutex_enter(&sc->sc_intr_lock); return 0; } @@ -2348,7 +2349,7 @@ uaudio_get(struct uaudio_softc *sc, int which, int type, int wValue, int wIndex, int len) { usb_device_request_t req; - u_int8_t data[4]; + uint8_t data[4]; usbd_status err; int val; @@ -2388,7 +2389,7 @@ uaudio_set(struct uaudio_softc *sc, int which, int type, int wValue, int wIndex, int len, int val) { usb_device_request_t req; - u_int8_t data[4]; + uint8_t data[4]; int err __unused; if (wValue == -1) @@ -2600,26 +2601,30 @@ uaudio_trigger_input(void *addr, void *start, void *end, int blksize, "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame, ch->fraction); - mutex_spin_exit(&sc->sc_intr_lock); - err = uaudio_chan_alloc_buffers(sc, ch); + mutex_exit(&sc->sc_intr_lock); + err = uaudio_chan_open(sc, ch); if (err) { - mutex_spin_enter(&sc->sc_intr_lock); + mutex_enter(&sc->sc_intr_lock); return EIO; } - err = uaudio_chan_open(sc, ch); + err = uaudio_chan_alloc_buffers(sc, ch); if (err) { - uaudio_chan_free_buffers(sc, ch); - mutex_spin_enter(&sc->sc_intr_lock); + uaudio_chan_close(sc, ch); + mutex_enter(&sc->sc_intr_lock); return EIO; } + ch->intr = intr; ch->arg = arg; - for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX -1 shouldn't be needed */ + /* XXX -1 shouldn't be needed */ + for (i = 0; i < UAUDIO_NCHANBUFS - 1; i++) { uaudio_chan_rtransfer(ch); - mutex_spin_enter(&sc->sc_intr_lock); + } + + mutex_enter(&sc->sc_intr_lock); return 0; } @@ -2646,26 +2651,27 @@ uaudio_trigger_output(void *addr, void *start, void *end, int blksize, "fraction=0.%03d\n", ch->sample_size, ch->bytes_per_frame, ch->fraction); - mutex_spin_exit(&sc->sc_intr_lock); - err = uaudio_chan_alloc_buffers(sc, ch); + mutex_exit(&sc->sc_intr_lock); + err = uaudio_chan_open(sc, ch); if (err) { - mutex_spin_enter(&sc->sc_intr_lock); + mutex_enter(&sc->sc_intr_lock); return EIO; } - err = uaudio_chan_open(sc, ch); + err = uaudio_chan_alloc_buffers(sc, ch); if (err) { - uaudio_chan_free_buffers(sc, ch); - mutex_spin_enter(&sc->sc_intr_lock); + uaudio_chan_close(sc, ch); + mutex_enter(&sc->sc_intr_lock); return EIO; } ch->intr = intr; ch->arg = arg; - for (i = 0; i < UAUDIO_NCHANBUFS-1; i++) /* XXX */ + /* XXX -1 shouldn't be needed */ + for (i = 0; i < UAUDIO_NCHANBUFS - 1; i++) uaudio_chan_ptransfer(ch); - mutex_spin_enter(&sc->sc_intr_lock); + mutex_enter(&sc->sc_intr_lock); return 0; } @@ -2715,9 +2721,9 @@ uaudio_chan_open(struct uaudio_softc *sc, struct chan *ch) } Static void -uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch) +uaudio_chan_abort(struct uaudio_softc *sc, struct chan *ch) { - usbd_pipe_handle pipe; + struct usbd_pipe *pipe; struct as_info *as; as = &sc->sc_alts[ch->altidx]; @@ -2727,14 +2733,27 @@ uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch) DPRINTF("set null alt=%d\n", sc->sc_nullalt); usbd_set_interface(as->ifaceh, sc->sc_nullalt); } - pipe = atomic_swap_ptr(&ch->pipe, NULL); + pipe = ch->pipe; if (pipe) { usbd_abort_pipe(pipe); + } + pipe = ch->sync_pipe; + if (pipe) { + usbd_abort_pipe(pipe); + } +} + +Static void +uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch) +{ + struct usbd_pipe *pipe; + + pipe = atomic_swap_ptr(&ch->pipe, NULL); + if (pipe) { usbd_close_pipe(pipe); } pipe = atomic_swap_ptr(&ch->sync_pipe, NULL); if (pipe) { - usbd_abort_pipe(pipe); usbd_close_pipe(pipe); } } @@ -2742,22 +2761,19 @@ uaudio_chan_close(struct uaudio_softc *sc, struct chan *ch) Static usbd_status uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch) { - usbd_xfer_handle xfer; - void *tbuf; int i, size; size = (ch->bytes_per_frame + ch->sample_size) * UAUDIO_NFRAMES; for (i = 0; i < UAUDIO_NCHANBUFS; i++) { - xfer = usbd_alloc_xfer(sc->sc_udev); - if (xfer == 0) + struct usbd_xfer *xfer; + + int err = usbd_create_xfer(ch->pipe, size, 0, UAUDIO_NFRAMES, + &xfer); + if (err) goto bad; + ch->chanbufs[i].xfer = xfer; - tbuf = usbd_alloc_buffer(xfer, size); - if (tbuf == 0) { - i++; - goto bad; - } - ch->chanbufs[i].buffer = tbuf; + ch->chanbufs[i].buffer = usbd_get_buffer(xfer); ch->chanbufs[i].chan = ch; } @@ -2766,7 +2782,7 @@ uaudio_chan_alloc_buffers(struct uaudio_softc *sc, struct chan *ch) bad: while (--i >= 0) /* implicit buffer free */ - usbd_free_xfer(ch->chanbufs[i].xfer); + usbd_destroy_xfer(ch->chanbufs[i].xfer); return USBD_NOMEM; } @@ -2776,10 +2792,9 @@ uaudio_chan_free_buffers(struct uaudio_softc *sc, struct chan *ch) int i; for (i = 0; i < UAUDIO_NCHANBUFS; i++) - usbd_free_xfer(ch->chanbufs[i].xfer); + usbd_destroy_xfer(ch->chanbufs[i].xfer); } -/* Called with USB lock held. */ Static void uaudio_chan_ptransfer(struct chan *ch) { @@ -2837,15 +2852,14 @@ uaudio_chan_ptransfer(struct chan *ch) //DPRINTFN(5, "ptransfer xfer=%p\n", cb->xfer); /* Fill the request */ - usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, - UAUDIO_NFRAMES, USBD_NO_COPY, - uaudio_chan_pintr); + usbd_setup_isoc_xfer(cb->xfer, cb, cb->sizes, UAUDIO_NFRAMES, 0, + uaudio_chan_pintr); (void)usbd_transfer(cb->xfer); } Static void -uaudio_chan_pintr(usbd_xfer_handle xfer, usbd_private_handle priv, +uaudio_chan_pintr(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct chanbuf *cb; @@ -2869,20 +2883,19 @@ uaudio_chan_pintr(usbd_xfer_handle xfer, usbd_private_handle priv, #endif ch->transferred += cb->size; - mutex_spin_enter(&ch->sc->sc_intr_lock); + mutex_enter(&ch->sc->sc_intr_lock); /* Call back to upper layer */ while (ch->transferred >= ch->blksize) { ch->transferred -= ch->blksize; DPRINTFN(5, "call %p(%p)\n", ch->intr, ch->arg); ch->intr(ch->arg); } - mutex_spin_exit(&ch->sc->sc_intr_lock); + mutex_exit(&ch->sc->sc_intr_lock); /* start next transfer */ uaudio_chan_ptransfer(ch); } -/* Called with USB lock held. */ Static void uaudio_chan_rtransfer(struct chan *ch) { @@ -2920,15 +2933,14 @@ uaudio_chan_rtransfer(struct chan *ch) DPRINTFN(5, "transfer xfer=%p\n", cb->xfer); /* Fill the request */ - usbd_setup_isoc_xfer(cb->xfer, ch->pipe, cb, cb->sizes, - UAUDIO_NFRAMES, USBD_NO_COPY, - uaudio_chan_rintr); + usbd_setup_isoc_xfer(cb->xfer, cb, cb->sizes, UAUDIO_NFRAMES, 0, + uaudio_chan_rintr); (void)usbd_transfer(cb->xfer); } Static void -uaudio_chan_rintr(usbd_xfer_handle xfer, usbd_private_handle priv, +uaudio_chan_rintr(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct chanbuf *cb; @@ -2973,13 +2985,13 @@ uaudio_chan_rintr(usbd_xfer_handle xfer, usbd_private_handle priv, /* Call back to upper layer */ ch->transferred += count; - mutex_spin_enter(&ch->sc->sc_intr_lock); + mutex_enter(&ch->sc->sc_intr_lock); while (ch->transferred >= ch->blksize) { ch->transferred -= ch->blksize; DPRINTFN(5, "call %p(%p)\n", ch->intr, ch->arg); ch->intr(ch->arg); } - mutex_spin_exit(&ch->sc->sc_intr_lock); + mutex_exit(&ch->sc->sc_intr_lock); /* start next transfer */ uaudio_chan_rtransfer(ch); diff --git a/sys/dev/usb/uberry.c b/sys/dev/usb/uberry.c index 70d92603ddc..c3014987fc9 100644 --- a/sys/dev/usb/uberry.c +++ b/sys/dev/usb/uberry.c @@ -1,4 +1,4 @@ -/* $NetBSD: uberry.c,v 1.9 2012/12/27 16:42:32 skrll Exp $ */ +/* $NetBSD: uberry.c,v 1.10 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -37,12 +37,11 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uberry.c,v 1.9 2012/12/27 16:42:32 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uberry.c,v 1.10 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> #include <sys/device.h> #include <sys/ioctl.h> #include <sys/conf.h> @@ -71,7 +70,7 @@ int uberrydebug = 0; struct uberry_softc { device_t sc_dev; - usbd_device_handle sc_udev; + struct usbd_device * sc_udev; }; /* @@ -120,7 +119,7 @@ uberry_charge(struct uberry_softc *sc) char dummy[2]; usbd_status err; - if (sc->sc_udev->power != USB_MAX_POWER) { + if (sc->sc_udev->ud_power != USB_MAX_POWER) { uberry_cmd(sc, UT_READ | UT_VENDOR, 0xa5, 0, 1, dummy, 2); uberry_cmd(sc, UT_WRITE | UT_VENDOR, 0xa2, 0, 1, dummy, 0); } @@ -159,7 +158,7 @@ uberry_match(device_t parent, cfdata_t match, void *aux) struct usb_attach_arg *uaa = aux; DPRINTFN(50, ("uberry_match\n")); - return (uberry_lookup(uaa->vendor, uaa->product) != NULL ? + return (uberry_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE); } @@ -168,7 +167,7 @@ uberry_attach(device_t parent, device_t self, void *aux) { struct uberry_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; + struct usbd_device * dev = uaa->uaa_device; char *devinfop; DPRINTFN(10,("uberry_attach: sc=%p\n", sc)); @@ -184,7 +183,7 @@ uberry_attach(device_t parent, device_t self, void *aux) usbd_devinfo_free(devinfop); uberry_charge(sc); - if (uaa->product == USB_PRODUCT_RIM_BLACKBERRY_PEARL) + if (uaa->uaa_product == USB_PRODUCT_RIM_BLACKBERRY_PEARL) uberry_dual_mode(sc); DPRINTFN(10, ("uberry_attach: %p\n", sc->sc_udev)); diff --git a/sys/dev/usb/ubsa.c b/sys/dev/usb/ubsa.c index cee40fda284..dfcea839c7a 100644 --- a/sys/dev/usb/ubsa.c +++ b/sys/dev/usb/ubsa.c @@ -1,4 +1,4 @@ -/* $NetBSD: ubsa.c,v 1.30 2012/02/24 06:48:24 mrg Exp $ */ +/* $NetBSD: ubsa.c,v 1.31 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2002, Alexander Kabaev <kan.FreeBSD.org>. * All rights reserved. @@ -54,12 +54,12 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ubsa.c,v 1.30 2012/02/24 06:48:24 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ubsa.c,v 1.31 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/ioccom.h> #include <sys/fcntl.h> #include <sys/conf.h> @@ -95,14 +95,14 @@ int ubsadebug = 0; #define DPRINTF(x) DPRINTFN(0, x) struct ucom_methods ubsa_methods = { - ubsa_get_status, - ubsa_set, - ubsa_param, - NULL, - ubsa_open, - ubsa_close, - NULL, - NULL + .ucom_get_status = ubsa_get_status, + .ucom_set = ubsa_set, + .ucom_param = ubsa_param, + .ucom_ioctl = NULL, + .ucom_open = ubsa_open, + .ucom_close = ubsa_close, + .ucom_read = NULL, + .ucom_write = NULL }; Static const struct usb_devno ubsa_devs[] = { @@ -136,27 +136,27 @@ extern struct cfdriver ubsa_cd; CFATTACH_DECL2_NEW(ubsa, sizeof(struct ubsa_softc), ubsa_match, ubsa_attach, ubsa_detach, ubsa_activate, NULL, ubsa_childdet); -int +int ubsa_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (ubsa_lookup(uaa->vendor, uaa->product) != NULL ? + return (ubsa_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE); } -void +void ubsa_attach(device_t parent, device_t self, void *aux) { struct ubsa_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; + struct usbd_device *dev = uaa->uaa_device; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devinfop; usbd_status err; - struct ucom_attach_args uca; + struct ucom_attach_args ucaa; int i; sc->sc_dev = self; @@ -184,8 +184,8 @@ ubsa_attach(device_t parent, device_t self, void *aux) * control com settings and only some. */ sc->sc_quadumts = 0; - if (uaa->vendor == USB_VENDOR_OPTIONNV) { - switch (uaa->product) { + if (uaa->uaa_vendor == USB_VENDOR_OPTIONNV) { + switch (uaa->uaa_product) { case USB_PRODUCT_OPTIONNV_QUADUMTS: case USB_PRODUCT_OPTIONNV_QUADUMTS2: sc->sc_quadumts = 1; @@ -232,7 +232,7 @@ ubsa_attach(device_t parent, device_t self, void *aux) sc->sc_iface_number[0] = id->bInterfaceNumber; /* initialize endpoints */ - uca.bulkin = uca.bulkout = -1; + ucaa.ucaa_bulkin = ucaa.ucaa_bulkout = -1; for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface[0], i); @@ -248,12 +248,12 @@ ubsa_attach(device_t parent, device_t self, void *aux) sc->sc_isize = UGETW(ed->wMaxPacketSize); } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - uca.bulkin = ed->bEndpointAddress; - uca.ibufsize = UGETW(ed->wMaxPacketSize); + ucaa.ucaa_bulkin = ed->bEndpointAddress; + ucaa.ucaa_ibufsize = UGETW(ed->wMaxPacketSize); } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - uca.bulkout = ed->bEndpointAddress; - uca.obufsize = UGETW(ed->wMaxPacketSize); + ucaa.ucaa_bulkout = ed->bEndpointAddress; + ucaa.ucaa_obufsize = UGETW(ed->wMaxPacketSize); } } /* end of Endpoint loop */ @@ -263,30 +263,30 @@ ubsa_attach(device_t parent, device_t self, void *aux) goto error; } - if (uca.bulkin == -1) { + if (ucaa.ucaa_bulkin == -1) { aprint_error_dev(self, "Could not find data bulk in\n"); sc->sc_dying = 1; goto error; } - if (uca.bulkout == -1) { + if (ucaa.ucaa_bulkout == -1) { aprint_error_dev(self, "Could not find data bulk out\n"); sc->sc_dying = 1; goto error; } - uca.portno = 0; + ucaa.ucaa_portno = 0; /* bulkin, bulkout set above */ - uca.ibufsizepad = uca.ibufsize; - uca.opkthdrlen = 0; - uca.device = dev; - uca.iface = sc->sc_iface[0]; - uca.methods = &ubsa_methods; - uca.arg = sc; - uca.info = NULL; + ucaa.ucaa_ibufsizepad = ucaa.ucaa_ibufsize; + ucaa.ucaa_opkthdrlen = 0; + ucaa.ucaa_device = dev; + ucaa.ucaa_iface = sc->sc_iface[0]; + ucaa.ucaa_methods = &ubsa_methods; + ucaa.ucaa_arg = sc; + ucaa.ucaa_info = NULL; DPRINTF(("ubsa: int#=%d, in = 0x%x, out = 0x%x, intr = 0x%x\n", - i, uca.bulkin, uca.bulkout, sc->sc_intr_number)); - sc->sc_subdevs[0] = config_found_sm_loc(self, "ucombus", NULL, &uca, + i, ucaa.ucaa_bulkin, ucaa.ucaa_bulkout, sc->sc_intr_number)); + sc->sc_subdevs[0] = config_found_sm_loc(self, "ucombus", NULL, &ucaa, ucomprint, ucomsubmatch); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, @@ -313,7 +313,7 @@ ubsa_childdet(device_t self, device_t child) sc->sc_subdevs[i] = NULL; } -int +int ubsa_detach(device_t self, int flags) { struct ubsa_softc *sc = device_private(self); @@ -326,7 +326,7 @@ ubsa_detach(device_t self, int flags) if (sc->sc_intr_pipe != NULL) { usbd_abort_pipe(sc->sc_intr_pipe); usbd_close_pipe(sc->sc_intr_pipe); - free(sc->sc_intr_buf, M_USBDEV); + kmem_free(sc->sc_intr_buf, sc->sc_isize); sc->sc_intr_pipe = NULL; } diff --git a/sys/dev/usb/ubsa_common.c b/sys/dev/usb/ubsa_common.c index e9ca0708d2c..72c9bfa555c 100644 --- a/sys/dev/usb/ubsa_common.c +++ b/sys/dev/usb/ubsa_common.c @@ -1,4 +1,4 @@ -/* $NetBSD: ubsa_common.c,v 1.9 2012/12/11 09:17:31 msaitoh Exp $ */ +/* $NetBSD: ubsa_common.c,v 1.10 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2002, Alexander Kabaev <kan.FreeBSD.org>. * All rights reserved. @@ -54,12 +54,12 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ubsa_common.c,v 1.9 2012/12/11 09:17:31 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ubsa_common.c,v 1.10 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/ioccom.h> #include <sys/fcntl.h> #include <sys/conf.h> @@ -95,7 +95,7 @@ extern int ubsadebug; #define DPRINTF(x) DPRINTFN(0, x) int -ubsa_request(struct ubsa_softc *sc, int portno, u_int8_t request, u_int16_t value) +ubsa_request(struct ubsa_softc *sc, int portno, uint8_t request, uint16_t value) { usb_device_request_t req; usbd_status err; @@ -108,7 +108,7 @@ ubsa_request(struct ubsa_softc *sc, int portno, u_int8_t request, u_int16_t valu if (portno >= UBSA_MAXCONN) { printf("%s: ubsa_request: invalid port(%d)#\n", device_xname(sc->sc_dev), portno); - return USBD_INVAL; + return USBD_INVAL; } req.bRequest = request; @@ -120,7 +120,7 @@ ubsa_request(struct ubsa_softc *sc, int portno, u_int8_t request, u_int16_t valu if (err) printf("%s: ubsa_request: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); - return (err); + return err; } void @@ -216,7 +216,7 @@ ubsa_set(void *addr, int portno, int reg, int onoff) void ubsa_baudrate(struct ubsa_softc *sc, int portno, speed_t speed) { - u_int16_t value = 0; + uint16_t value = 0; DPRINTF(("ubsa_baudrate: speed = %d\n", speed)); @@ -332,7 +332,7 @@ ubsa_param(void *addr, int portno, struct termios *ti) ubsa_flow(sc, portno, ti->c_cflag, ti->c_iflag); } - return (0); + return 0; } int @@ -342,10 +342,10 @@ ubsa_open(void *addr, int portno) int err; if (sc->sc_dying) - return (ENXIO); + return ENXIO; if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) { - sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK); + sc->sc_intr_buf = kmem_alloc(sc->sc_isize, KM_SLEEP); /* XXX only iface# = 0 has intr line */ /* XXX E220 specific? need to check */ err = usbd_open_pipe_intr(sc->sc_iface[0], @@ -361,11 +361,11 @@ ubsa_open(void *addr, int portno) printf("%s: cannot open interrupt pipe (addr %d)\n", device_xname(sc->sc_dev), sc->sc_intr_number); - return (EIO); + return EIO; } } - return (0); + return 0; } void @@ -390,13 +390,13 @@ ubsa_close(void *addr, int portno) printf("%s: close interrupt pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); - free(sc->sc_intr_buf, M_USBDEV); + kmem_free(sc->sc_intr_buf, sc->sc_isize); sc->sc_intr_pipe = NULL; } } void -ubsa_intr(usbd_xfer_handle xfer, usbd_private_handle priv, +ubsa_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct ubsa_softc *sc = priv; diff --git a/sys/dev/usb/ubsavar.h b/sys/dev/usb/ubsavar.h index 6d14d3c3508..82a0108210f 100644 --- a/sys/dev/usb/ubsavar.h +++ b/sys/dev/usb/ubsavar.h @@ -1,4 +1,4 @@ -/* $NetBSD: ubsavar.h,v 1.9 2011/12/23 00:51:45 jakllsch Exp $ */ +/* $NetBSD: ubsavar.h,v 1.10 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2002, Alexander Kabaev <kan.FreeBSD.org>. * All rights reserved. @@ -113,14 +113,14 @@ struct ubsa_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; /* USB device */ - usbd_interface_handle sc_iface[UBSA_MAXCONN]; /* interface */ + struct usbd_device * sc_udev; /* USB device */ + struct usbd_interface * sc_iface[UBSA_MAXCONN]; /* interface */ int sc_iface_number[UBSA_MAXCONN]; /* interface number */ int sc_config_index; /* USB CONFIG_INDEX */ int sc_intr_number; /* interrupt number */ - usbd_pipe_handle sc_intr_pipe; /* interrupt pipe */ + struct usbd_pipe * sc_intr_pipe; /* interrupt pipe */ u_char *sc_intr_buf; /* interrupt buffer */ int sc_isize; @@ -135,11 +135,11 @@ struct ubsa_softc { u_char sc_dying; /* disconnecting */ u_char sc_quadumts; - u_int16_t sc_devflags; + uint16_t sc_devflags; }; -void ubsa_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); +void ubsa_intr(struct usbd_xfer *, void *, usbd_status); void ubsa_get_status(void *, int, u_char *, u_char *); void ubsa_set(void *, int, int, int); @@ -147,8 +147,8 @@ int ubsa_param(void *, int, struct termios *); int ubsa_open(void *, int); void ubsa_close(void *, int); -void ubsa_break(struct ubsa_softc *sc, int, int onoff); -int ubsa_request(struct ubsa_softc *, int, u_int8_t, u_int16_t); +void ubsa_break(struct ubsa_softc *, int, int); +int ubsa_request(struct ubsa_softc *, int, uint8_t, uint16_t); void ubsa_dtr(struct ubsa_softc *, int, int); void ubsa_quadumts_dtr(struct ubsa_softc *, int, int); void ubsa_rts(struct ubsa_softc *, int, int); diff --git a/sys/dev/usb/ubt.c b/sys/dev/usb/ubt.c index 19c292a37f0..bbfb69f55c1 100644 --- a/sys/dev/usb/ubt.c +++ b/sys/dev/usb/ubt.c @@ -1,4 +1,4 @@ -/* $NetBSD: ubt.c,v 1.53 2016/02/17 10:52:55 plunky Exp $ */ +/* $NetBSD: ubt.c,v 1.54 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2006 Itronix Inc. @@ -67,13 +67,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ubt.c,v 1.53 2016/02/17 10:52:55 plunky Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ubt.c,v 1.54 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/device.h> #include <sys/ioctl.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/mbuf.h> #include <sys/proc.h> #include <sys/sysctl.h> @@ -160,7 +160,7 @@ SYSCTL_SETUP(sysctl_hw_ubt_debug_setup, "sysctl hw.ubt_debug setup") struct ubt_isoc_xfer { struct ubt_softc *softc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; uint8_t *buf; uint16_t size[UBT_NFRAMES]; int busy; @@ -168,56 +168,56 @@ struct ubt_isoc_xfer { struct ubt_softc { device_t sc_dev; - usbd_device_handle sc_udev; + struct usbd_device *sc_udev; int sc_refcnt; int sc_dying; int sc_enabled; /* Control Interface */ - usbd_interface_handle sc_iface0; + struct usbd_interface * sc_iface0; /* Commands (control) */ - usbd_xfer_handle sc_cmd_xfer; + struct usbd_xfer *sc_cmd_xfer; uint8_t *sc_cmd_buf; int sc_cmd_busy; /* write active */ MBUFQ_HEAD() sc_cmd_queue; /* output queue */ /* Events (interrupt) */ int sc_evt_addr; /* endpoint address */ - usbd_pipe_handle sc_evt_pipe; + struct usbd_pipe *sc_evt_pipe; uint8_t *sc_evt_buf; /* ACL data (in) */ int sc_aclrd_addr; /* endpoint address */ - usbd_pipe_handle sc_aclrd_pipe; /* read pipe */ - usbd_xfer_handle sc_aclrd_xfer; /* read xfer */ + struct usbd_pipe *sc_aclrd_pipe; /* read pipe */ + struct usbd_xfer *sc_aclrd_xfer; /* read xfer */ uint8_t *sc_aclrd_buf; /* read buffer */ int sc_aclrd_busy; /* reading */ /* ACL data (out) */ int sc_aclwr_addr; /* endpoint address */ - usbd_pipe_handle sc_aclwr_pipe; /* write pipe */ - usbd_xfer_handle sc_aclwr_xfer; /* write xfer */ + struct usbd_pipe *sc_aclwr_pipe; /* write pipe */ + struct usbd_xfer *sc_aclwr_xfer; /* write xfer */ uint8_t *sc_aclwr_buf; /* write buffer */ int sc_aclwr_busy; /* write active */ MBUFQ_HEAD() sc_aclwr_queue;/* output queue */ /* ISOC interface */ - usbd_interface_handle sc_iface1; /* ISOC interface */ + struct usbd_interface *sc_iface1; /* ISOC interface */ struct sysctllog *sc_log; /* sysctl log */ int sc_config; /* current config no */ int sc_alt_config; /* no of alternates */ /* SCO data (in) */ int sc_scord_addr; /* endpoint address */ - usbd_pipe_handle sc_scord_pipe; /* read pipe */ + struct usbd_pipe *sc_scord_pipe; /* read pipe */ int sc_scord_size; /* frame length */ struct ubt_isoc_xfer sc_scord[UBT_NXFERS]; struct mbuf *sc_scord_mbuf; /* current packet */ /* SCO data (out) */ int sc_scowr_addr; /* endpoint address */ - usbd_pipe_handle sc_scowr_pipe; /* write pipe */ + struct usbd_pipe *sc_scowr_pipe; /* write pipe */ int sc_scowr_size; /* frame length */ struct ubt_isoc_xfer sc_scowr[UBT_NXFERS]; struct mbuf *sc_scowr_mbuf; /* current packet */ @@ -242,30 +242,30 @@ static void ubt_disable(device_t); static void ubt_xmit_cmd(device_t, struct mbuf *); static void ubt_xmit_cmd_start(struct ubt_softc *); -static void ubt_xmit_cmd_complete(usbd_xfer_handle, - usbd_private_handle, usbd_status); +static void ubt_xmit_cmd_complete(struct usbd_xfer *, + void *, usbd_status); static void ubt_xmit_acl(device_t, struct mbuf *); static void ubt_xmit_acl_start(struct ubt_softc *); -static void ubt_xmit_acl_complete(usbd_xfer_handle, - usbd_private_handle, usbd_status); +static void ubt_xmit_acl_complete(struct usbd_xfer *, + void *, usbd_status); static void ubt_xmit_sco(device_t, struct mbuf *); static void ubt_xmit_sco_start(struct ubt_softc *); static void ubt_xmit_sco_start1(struct ubt_softc *, struct ubt_isoc_xfer *); -static void ubt_xmit_sco_complete(usbd_xfer_handle, - usbd_private_handle, usbd_status); +static void ubt_xmit_sco_complete(struct usbd_xfer *, + void *, usbd_status); -static void ubt_recv_event(usbd_xfer_handle, - usbd_private_handle, usbd_status); +static void ubt_recv_event(struct usbd_xfer *, + void *, usbd_status); static void ubt_recv_acl_start(struct ubt_softc *); -static void ubt_recv_acl_complete(usbd_xfer_handle, - usbd_private_handle, usbd_status); +static void ubt_recv_acl_complete(struct usbd_xfer *, + void *, usbd_status); static void ubt_recv_sco_start1(struct ubt_softc *, struct ubt_isoc_xfer *); -static void ubt_recv_sco_complete(usbd_xfer_handle, - usbd_private_handle, usbd_status); +static void ubt_recv_sco_complete(struct usbd_xfer *, + void *, usbd_status); static void ubt_stats(device_t, struct bt_stats *, int); @@ -276,7 +276,7 @@ static const struct hci_if ubt_hci = { .output_acl = ubt_xmit_acl, .output_sco = ubt_xmit_sco, .get_stats = ubt_stats, - .ipl = IPL_USB, /* IPL_SOFTUSB ??? */ + .ipl = IPL_SOFTUSB, }; /******************************************************************************* @@ -431,7 +431,7 @@ const struct ubt_devno { }, }; -int +int ubt_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; @@ -441,19 +441,19 @@ ubt_match(device_t parent, cfdata_t match, void *aux) for (i = 0; i < __arraycount(ubt_dev); i++) { if (ubt_dev[i].vendor != -1 - && ubt_dev[i].vendor != (int)uaa->vendor) + && ubt_dev[i].vendor != (int)uaa->uaa_vendor) continue; if (ubt_dev[i].product != -1 - && ubt_dev[i].product != (int)uaa->product) + && ubt_dev[i].product != (int)uaa->uaa_product) continue; if (ubt_dev[i].class != -1 - && ubt_dev[i].class != uaa->class) + && ubt_dev[i].class != uaa->uaa_class) continue; if (ubt_dev[i].subclass != -1 - && ubt_dev[i].subclass != uaa->subclass) + && ubt_dev[i].subclass != uaa->uaa_subclass) continue; if (ubt_dev[i].proto != -1 - && ubt_dev[i].proto != uaa->proto) + && ubt_dev[i].proto != uaa->uaa_proto) continue; return ubt_dev[i].match; @@ -462,7 +462,7 @@ ubt_match(device_t parent, cfdata_t match, void *aux) return UMATCH_NONE; } -void +void ubt_attach(device_t parent, device_t self, void *aux) { struct ubt_softc *sc = device_private(self); @@ -477,7 +477,7 @@ ubt_attach(device_t parent, device_t self, void *aux) DPRINTFN(50, "ubt_attach: sc=%p\n", sc); sc->sc_dev = self; - sc->sc_udev = uaa->device; + sc->sc_udev = uaa->uaa_device; MBUFQ_INIT(&sc->sc_cmd_queue); MBUFQ_INIT(&sc->sc_aclwr_queue); @@ -660,7 +660,7 @@ ubt_attach(device_t parent, device_t self, void *aux) return; } -int +int ubt_detach(device_t self, int flags) { struct ubt_softc *sc = device_private(self); @@ -735,7 +735,7 @@ ubt_set_isoc_config(struct ubt_softc *sc) err = usbd_set_interface(sc->sc_iface1, sc->sc_config); if (err != USBD_NORMAL_COMPLETION) { - aprint_error_dev(sc->sc_dev, + aprint_error_dev(sc->sc_dev, "Could not set config %d on ISOC interface. %s (%d)\n", sc->sc_config, usbd_errstr(err), err); @@ -867,73 +867,88 @@ ubt_abortdealloc(struct ubt_softc *sc) if (sc->sc_evt_pipe != NULL) { usbd_abort_pipe(sc->sc_evt_pipe); - usbd_close_pipe(sc->sc_evt_pipe); - sc->sc_evt_pipe = NULL; } if (sc->sc_aclrd_pipe != NULL) { usbd_abort_pipe(sc->sc_aclrd_pipe); - usbd_close_pipe(sc->sc_aclrd_pipe); - sc->sc_aclrd_pipe = NULL; } if (sc->sc_aclwr_pipe != NULL) { usbd_abort_pipe(sc->sc_aclwr_pipe); - usbd_close_pipe(sc->sc_aclwr_pipe); - sc->sc_aclwr_pipe = NULL; } if (sc->sc_scord_pipe != NULL) { usbd_abort_pipe(sc->sc_scord_pipe); - usbd_close_pipe(sc->sc_scord_pipe); - sc->sc_scord_pipe = NULL; } if (sc->sc_scowr_pipe != NULL) { usbd_abort_pipe(sc->sc_scowr_pipe); - usbd_close_pipe(sc->sc_scowr_pipe); - sc->sc_scowr_pipe = NULL; } /* Free event buffer */ if (sc->sc_evt_buf != NULL) { - free(sc->sc_evt_buf, M_USBDEV); + kmem_free(sc->sc_evt_buf, UBT_BUFSIZ_EVENT); sc->sc_evt_buf = NULL; } /* Free all xfers and xfer buffers (implicit) */ if (sc->sc_cmd_xfer != NULL) { - usbd_free_xfer(sc->sc_cmd_xfer); + usbd_destroy_xfer(sc->sc_cmd_xfer); sc->sc_cmd_xfer = NULL; sc->sc_cmd_buf = NULL; } if (sc->sc_aclrd_xfer != NULL) { - usbd_free_xfer(sc->sc_aclrd_xfer); + usbd_destroy_xfer(sc->sc_aclrd_xfer); sc->sc_aclrd_xfer = NULL; sc->sc_aclrd_buf = NULL; } if (sc->sc_aclwr_xfer != NULL) { - usbd_free_xfer(sc->sc_aclwr_xfer); + usbd_destroy_xfer(sc->sc_aclwr_xfer); sc->sc_aclwr_xfer = NULL; sc->sc_aclwr_buf = NULL; } for (i = 0 ; i < UBT_NXFERS ; i++) { if (sc->sc_scord[i].xfer != NULL) { - usbd_free_xfer(sc->sc_scord[i].xfer); + usbd_destroy_xfer(sc->sc_scord[i].xfer); sc->sc_scord[i].xfer = NULL; sc->sc_scord[i].buf = NULL; } if (sc->sc_scowr[i].xfer != NULL) { - usbd_free_xfer(sc->sc_scowr[i].xfer); + usbd_destroy_xfer(sc->sc_scowr[i].xfer); sc->sc_scowr[i].xfer = NULL; sc->sc_scowr[i].buf = NULL; } } + if (sc->sc_evt_pipe != NULL) { + usbd_close_pipe(sc->sc_evt_pipe); + sc->sc_evt_pipe = NULL; + } + + if (sc->sc_aclrd_pipe != NULL) { + usbd_close_pipe(sc->sc_aclrd_pipe); + sc->sc_aclrd_pipe = NULL; + } + + if (sc->sc_aclwr_pipe != NULL) { + usbd_close_pipe(sc->sc_aclwr_pipe); + sc->sc_aclwr_pipe = NULL; + } + + if (sc->sc_scord_pipe != NULL) { + usbd_close_pipe(sc->sc_scord_pipe); + sc->sc_scord_pipe = NULL; + } + + if (sc->sc_scowr_pipe != NULL) { + usbd_close_pipe(sc->sc_scowr_pipe); + sc->sc_scowr_pipe = NULL; + } + /* Free partial SCO packets */ if (sc->sc_scord_mbuf != NULL) { m_freem(sc->sc_scord_mbuf); @@ -971,7 +986,7 @@ ubt_enable(device_t self) s = splusb(); /* Events */ - sc->sc_evt_buf = malloc(UBT_BUFSIZ_EVENT, M_USBDEV, M_NOWAIT); + sc->sc_evt_buf = kmem_alloc(UBT_BUFSIZ_EVENT, KM_SLEEP); if (sc->sc_evt_buf == NULL) { error = ENOMEM; goto bad; @@ -991,16 +1006,12 @@ ubt_enable(device_t self) } /* Commands */ - sc->sc_cmd_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_cmd_xfer == NULL) { - error = ENOMEM; - goto bad; - } - sc->sc_cmd_buf = usbd_alloc_buffer(sc->sc_cmd_xfer, UBT_BUFSIZ_CMD); - if (sc->sc_cmd_buf == NULL) { - error = ENOMEM; + struct usbd_pipe *pipe0 = usbd_get_pipe0(sc->sc_udev); + error = usbd_create_xfer(pipe0, UBT_BUFSIZ_CMD, 0, 0, + &sc->sc_cmd_xfer); + if (error) goto bad; - } + sc->sc_cmd_buf = usbd_get_buffer(sc->sc_cmd_xfer); sc->sc_cmd_busy = 0; /* ACL read */ @@ -1010,16 +1021,11 @@ ubt_enable(device_t self) error = EIO; goto bad; } - sc->sc_aclrd_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_aclrd_xfer == NULL) { - error = ENOMEM; + error = usbd_create_xfer(sc->sc_aclrd_pipe, UBT_BUFSIZ_ACL, + USBD_SHORT_XFER_OK, 0, &sc->sc_aclrd_xfer); + if (error) goto bad; - } - sc->sc_aclrd_buf = usbd_alloc_buffer(sc->sc_aclrd_xfer, UBT_BUFSIZ_ACL); - if (sc->sc_aclrd_buf == NULL) { - error = ENOMEM; - goto bad; - } + sc->sc_aclrd_buf = usbd_get_buffer(sc->sc_aclrd_xfer); sc->sc_aclrd_busy = 0; ubt_recv_acl_start(sc); @@ -1030,16 +1036,11 @@ ubt_enable(device_t self) error = EIO; goto bad; } - sc->sc_aclwr_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_aclwr_xfer == NULL) { - error = ENOMEM; - goto bad; - } - sc->sc_aclwr_buf = usbd_alloc_buffer(sc->sc_aclwr_xfer, UBT_BUFSIZ_ACL); - if (sc->sc_aclwr_buf == NULL) { - error = ENOMEM; + error = usbd_create_xfer(sc->sc_aclwr_pipe, UBT_BUFSIZ_ACL, + USBD_FORCE_SHORT_XFER, 0, &sc->sc_aclwr_xfer); + if (error) goto bad; - } + sc->sc_aclwr_buf = usbd_get_buffer(sc->sc_aclwr_xfer); sc->sc_aclwr_busy = 0; /* SCO read */ @@ -1052,17 +1053,15 @@ ubt_enable(device_t self) } for (i = 0 ; i < UBT_NXFERS ; i++) { - sc->sc_scord[i].xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_scord[i].xfer == NULL) { - error = ENOMEM; + error = usbd_create_xfer(sc->sc_scord_pipe, + sc->sc_scord_size * UBT_NFRAMES, + USBD_SHORT_XFER_OK, UBT_NFRAMES, + &sc->sc_scord[i].xfer); + if (error) goto bad; - } - sc->sc_scord[i].buf = usbd_alloc_buffer(sc->sc_scord[i].xfer, - sc->sc_scord_size * UBT_NFRAMES); - if (sc->sc_scord[i].buf == NULL) { - error = ENOMEM; - goto bad; - } + + sc->sc_scord[i].buf = + usbd_get_buffer(sc->sc_scord[i].xfer); sc->sc_scord[i].softc = sc; sc->sc_scord[i].busy = 0; ubt_recv_sco_start1(sc, &sc->sc_scord[i]); @@ -1079,17 +1078,14 @@ ubt_enable(device_t self) } for (i = 0 ; i < UBT_NXFERS ; i++) { - sc->sc_scowr[i].xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_scowr[i].xfer == NULL) { - error = ENOMEM; + error = usbd_create_xfer(sc->sc_scowr_pipe, + sc->sc_scowr_size * UBT_NFRAMES, + USBD_FORCE_SHORT_XFER, UBT_NFRAMES, + &sc->sc_scowr[i].xfer); + if (error) goto bad; - } - sc->sc_scowr[i].buf = usbd_alloc_buffer(sc->sc_scowr[i].xfer, - sc->sc_scowr_size * UBT_NFRAMES); - if (sc->sc_scowr[i].buf == NULL) { - error = ENOMEM; - goto bad; - } + sc->sc_scowr[i].buf = + usbd_get_buffer(sc->sc_scowr[i].xfer); sc->sc_scowr[i].softc = sc; sc->sc_scowr[i].busy = 0; } @@ -1180,7 +1176,7 @@ ubt_xmit_cmd_start(struct ubt_softc *sc) &req, sc->sc_cmd_buf, len, - USBD_NO_COPY | USBD_FORCE_SHORT_XFER, + USBD_FORCE_SHORT_XFER, ubt_xmit_cmd_complete); status = usbd_transfer(sc->sc_cmd_xfer); @@ -1197,8 +1193,8 @@ ubt_xmit_cmd_start(struct ubt_softc *sc) } static void -ubt_xmit_cmd_complete(usbd_xfer_handle xfer, - usbd_private_handle h, usbd_status status) +ubt_xmit_cmd_complete(struct usbd_xfer *xfer, + void * h, usbd_status status) { struct ubt_softc *sc = h; uint32_t count; @@ -1288,11 +1284,10 @@ ubt_xmit_acl_start(struct ubt_softc *sc) sc->sc_stats.byte_tx += len; usbd_setup_xfer(sc->sc_aclwr_xfer, - sc->sc_aclwr_pipe, sc, sc->sc_aclwr_buf, len, - USBD_NO_COPY | USBD_FORCE_SHORT_XFER, + USBD_FORCE_SHORT_XFER, UBT_ACL_TIMEOUT, ubt_xmit_acl_complete); @@ -1310,8 +1305,8 @@ ubt_xmit_acl_start(struct ubt_softc *sc) } static void -ubt_xmit_acl_complete(usbd_xfer_handle xfer, - usbd_private_handle h, usbd_status status) +ubt_xmit_acl_complete(struct usbd_xfer *xfer, + void * h, usbd_status status) { struct ubt_softc *sc = h; @@ -1449,19 +1444,18 @@ ubt_xmit_sco_start1(struct ubt_softc *sc, struct ubt_isoc_xfer *isoc) } usbd_setup_isoc_xfer(isoc->xfer, - sc->sc_scowr_pipe, isoc, isoc->size, num, - USBD_NO_COPY | USBD_FORCE_SHORT_XFER, + USBD_FORCE_SHORT_XFER, ubt_xmit_sco_complete); usbd_transfer(isoc->xfer); } static void -ubt_xmit_sco_complete(usbd_xfer_handle xfer, - usbd_private_handle h, usbd_status status) +ubt_xmit_sco_complete(struct usbd_xfer *xfer, + void * h, usbd_status status) { struct ubt_isoc_xfer *isoc = h; struct ubt_softc *sc; @@ -1536,7 +1530,7 @@ ubt_mbufload(uint8_t *buf, int count, uint8_t type) } static void -ubt_recv_event(usbd_xfer_handle xfer, usbd_private_handle h, usbd_status status) +ubt_recv_event(struct usbd_xfer *xfer, void * h, usbd_status status) { struct ubt_softc *sc = h; struct mbuf *m; @@ -1584,11 +1578,10 @@ ubt_recv_acl_start(struct ubt_softc *sc) sc->sc_aclrd_busy = 1; usbd_setup_xfer(sc->sc_aclrd_xfer, - sc->sc_aclrd_pipe, sc, sc->sc_aclrd_buf, UBT_BUFSIZ_ACL, - USBD_NO_COPY | USBD_SHORT_XFER_OK, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ubt_recv_acl_complete); @@ -1606,8 +1599,8 @@ ubt_recv_acl_start(struct ubt_softc *sc) } static void -ubt_recv_acl_complete(usbd_xfer_handle xfer, - usbd_private_handle h, usbd_status status) +ubt_recv_acl_complete(struct usbd_xfer *xfer, + void * h, usbd_status status) { struct ubt_softc *sc = h; struct mbuf *m; @@ -1683,19 +1676,18 @@ ubt_recv_sco_start1(struct ubt_softc *sc, struct ubt_isoc_xfer *isoc) isoc->size[i] = sc->sc_scord_size; usbd_setup_isoc_xfer(isoc->xfer, - sc->sc_scord_pipe, isoc, isoc->size, UBT_NFRAMES, - USBD_NO_COPY | USBD_SHORT_XFER_OK, + USBD_SHORT_XFER_OK, ubt_recv_sco_complete); usbd_transfer(isoc->xfer); } static void -ubt_recv_sco_complete(usbd_xfer_handle xfer, - usbd_private_handle h, usbd_status status) +ubt_recv_sco_complete(struct usbd_xfer *xfer, + void * h, usbd_status status) { struct ubt_isoc_xfer *isoc = h; struct ubt_softc *sc; @@ -1822,7 +1814,7 @@ ubt_recv_sco_complete(usbd_xfer_handle xfer, sc->sc_stats.sco_rx++; if (!hci_input_sco(sc->sc_unit, m)) sc->sc_stats.err_rx++; - + m = NULL; } } diff --git a/sys/dev/usb/uchcom.c b/sys/dev/usb/uchcom.c index e5f7adc14e9..618937d52da 100644 --- a/sys/dev/usb/uchcom.c +++ b/sys/dev/usb/uchcom.c @@ -1,4 +1,4 @@ -/* $NetBSD: uchcom.c,v 1.13 2014/03/15 19:20:27 martin Exp $ */ +/* $NetBSD: uchcom.c,v 1.14 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2007 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uchcom.c,v 1.13 2014/03/15 19:20:27 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uchcom.c,v 1.14 2016/04/23 10:15:32 skrll Exp $"); /* * driver for WinChipHead CH341/340, the worst USB-serial chip in the world. @@ -39,7 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: uchcom.c,v 1.13 2014/03/15 19:20:27 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/ioctl.h> #include <sys/conf.h> #include <sys/tty.h> @@ -120,14 +120,14 @@ int uchcomdebug = 0; struct uchcom_softc { device_t sc_dev; - usbd_device_handle sc_udev; + struct usbd_device * sc_udev; device_t sc_subdev; - usbd_interface_handle sc_iface; + struct usbd_interface * sc_iface; int sc_dying; /* */ int sc_intr_endpoint; int sc_intr_size; - usbd_pipe_handle sc_intr_pipe; + struct usbd_pipe * sc_intr_pipe; u_char *sc_intr_buf; /* */ uint8_t sc_version; @@ -184,11 +184,11 @@ Static void uchcom_set(void *, int, int, int); Static int uchcom_param(void *, int, struct termios *); Static int uchcom_open(void *, int); Static void uchcom_close(void *, int); -Static void uchcom_intr(usbd_xfer_handle, usbd_private_handle, +Static void uchcom_intr(struct usbd_xfer *, void *, usbd_status); static int set_config(struct uchcom_softc *); -static int find_ifaces(struct uchcom_softc *, usbd_interface_handle *); +static int find_ifaces(struct uchcom_softc *, struct usbd_interface **); static int find_endpoints(struct uchcom_softc *, struct uchcom_endpoints *); static void close_intr_pipe(struct uchcom_softc *); @@ -226,24 +226,24 @@ CFATTACH_DECL2_NEW(uchcom, * driver entry points */ -int +int uchcom_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (uchcom_lookup(uaa->vendor, uaa->product) != NULL ? + return (uchcom_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE); } -void +void uchcom_attach(device_t parent, device_t self, void *aux) { struct uchcom_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; + struct usbd_device *dev = uaa->uaa_device; char *devinfop; struct uchcom_endpoints endpoints; - struct ucom_attach_args uca; + struct ucom_attach_args ucaa; aprint_naive("\n"); aprint_normal("\n"); @@ -263,7 +263,7 @@ uchcom_attach(device_t parent, device_t self, void *aux) if (set_config(sc)) goto failed; - switch (uaa->release) { + switch (uaa->uaa_release) { case UCHCOM_REV_CH340: aprint_normal_dev(self, "CH340 detected\n"); break; @@ -282,23 +282,23 @@ uchcom_attach(device_t parent, device_t self, void *aux) sc->sc_intr_size = endpoints.ep_intr_size; /* setup ucom layer */ - uca.portno = UCOM_UNK_PORTNO; - uca.bulkin = endpoints.ep_bulkin; - uca.bulkout = endpoints.ep_bulkout; - uca.ibufsize = UCHCOMIBUFSIZE; - uca.obufsize = UCHCOMOBUFSIZE; - uca.ibufsizepad = UCHCOMIBUFSIZE; - uca.opkthdrlen = 0; - uca.device = dev; - uca.iface = sc->sc_iface; - uca.methods = &uchcom_methods; - uca.arg = sc; - uca.info = NULL; + ucaa.ucaa_portno = UCOM_UNK_PORTNO; + ucaa.ucaa_bulkin = endpoints.ep_bulkin; + ucaa.ucaa_bulkout = endpoints.ep_bulkout; + ucaa.ucaa_ibufsize = UCHCOMIBUFSIZE; + ucaa.ucaa_obufsize = UCHCOMOBUFSIZE; + ucaa.ucaa_ibufsizepad = UCHCOMIBUFSIZE; + ucaa.ucaa_opkthdrlen = 0; + ucaa.ucaa_device = dev; + ucaa.ucaa_iface = sc->sc_iface; + ucaa.ucaa_methods = &uchcom_methods; + ucaa.ucaa_arg = sc; + ucaa.ucaa_info = NULL; usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); - sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &uca, + sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &ucaa, ucomprint, ucomsubmatch); return; @@ -317,7 +317,7 @@ uchcom_childdet(device_t self, device_t child) sc->sc_subdev = NULL; } -int +int uchcom_detach(device_t self, int flags) { struct uchcom_softc *sc = device_private(self); @@ -369,7 +369,7 @@ set_config(struct uchcom_softc *sc) } static int -find_ifaces(struct uchcom_softc *sc, usbd_interface_handle *riface) +find_ifaces(struct uchcom_softc *sc, struct usbd_interface **riface) { usbd_status err; @@ -505,7 +505,7 @@ read_reg(struct uchcom_softc *sc, err = generic_control_in( sc, UCHCOM_REQ_READ_REG, - reg1|((uint16_t)reg2<<8), 0, buf, sizeof buf, &actin); + reg1|((uint16_t)reg2<<8), 0, buf, sizeof(buf), &actin); if (err) return err; @@ -527,7 +527,7 @@ get_version(struct uchcom_softc *sc, uint8_t *rver) int actin; err = generic_control_in( - sc, UCHCOM_REQ_GET_VERSION, 0, 0, buf, sizeof buf, &actin); + sc, UCHCOM_REQ_GET_VERSION, 0, 0, buf, sizeof(buf), &actin); if (err) return err; @@ -872,7 +872,7 @@ setup_intr_pipe(struct uchcom_softc *sc) usbd_status err; if (sc->sc_intr_endpoint != -1 && sc->sc_intr_pipe == NULL) { - sc->sc_intr_buf = malloc(sc->sc_intr_size, M_USBDEV, M_WAITOK); + sc->sc_intr_buf = kmem_alloc(sc->sc_intr_size, KM_SLEEP); err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_intr_endpoint, USBD_SHORT_XFER_OK, @@ -909,7 +909,7 @@ close_intr_pipe(struct uchcom_softc *sc) aprint_error_dev(sc->sc_dev, "close interrupt pipe failed: %s\n", usbd_errstr(err)); - free(sc->sc_intr_buf, M_USBDEV); + kmem_free(sc->sc_intr_buf, sc->sc_intr_size); sc->sc_intr_pipe = NULL; } } @@ -1009,7 +1009,7 @@ uchcom_close(void *arg, int portno) * callback when the modem status is changed. */ void -uchcom_intr(usbd_xfer_handle xfer, usbd_private_handle priv, +uchcom_intr(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct uchcom_softc *sc = priv; diff --git a/sys/dev/usb/ucom.c b/sys/dev/usb/ucom.c index 8836be99291..07c2134cf22 100644 --- a/sys/dev/usb/ucom.c +++ b/sys/dev/usb/ucom.c @@ -1,4 +1,4 @@ -/* $NetBSD: ucom.c,v 1.110 2015/11/08 21:05:01 joerg Exp $ */ +/* $NetBSD: ucom.c,v 1.111 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.110 2015/11/08 21:05:01 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.111 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -50,6 +50,7 @@ __KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.110 2015/11/08 21:05:01 joerg Exp $"); #include <sys/poll.h> #include <sys/queue.h> #include <sys/kauth.h> +#include <sys/sysctl.h> #include <sys/timepps.h> #include <sys/rndsource.h> @@ -59,6 +60,7 @@ __KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.110 2015/11/08 21:05:01 joerg Exp $"); #include <dev/usb/usbdi_util.h> #include <dev/usb/usbdevs.h> #include <dev/usb/usb_quirks.h> +#include <dev/usb/usbhist.h> #include <dev/usb/ucomvar.h> @@ -68,13 +70,46 @@ __KERNEL_RCSID(0, "$NetBSD: ucom.c,v 1.110 2015/11/08 21:05:01 joerg Exp $"); #if NUCOM > 0 -#ifdef UCOM_DEBUG -#define DPRINTFN(n, x) if (ucomdebug > (n)) printf x -int ucomdebug = 0; +#ifdef USB_DEBUG +#ifndef UCOM_DEBUG +#define ucomdebug 0 #else -#define DPRINTFN(n, x) -#endif -#define DPRINTF(x) DPRINTFN(0, x) +int ucomdebug = 0; + +SYSCTL_SETUP(sysctl_hw_ucom_setup, "sysctl hw.ucom setup") +{ + int err; + const struct sysctlnode *rnode; + const struct sysctlnode *cnode; + + err = sysctl_createv(clog, 0, NULL, &rnode, + CTLFLAG_PERMANENT, CTLTYPE_NODE, "ucom", + SYSCTL_DESCR("ucom global controls"), + NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); + + if (err) + goto fail; + + /* control debugging printfs */ + err = sysctl_createv(clog, 0, &rnode, &cnode, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, + "debug", SYSCTL_DESCR("Enable debugging output"), + NULL, 0, &ucomdebug, sizeof(ucomdebug), CTL_CREATE, CTL_EOL); + if (err) + goto fail; + + return; +fail: + aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); +} + +#endif /* UCOM_DEBUG */ +#endif /* USB_DEBUG */ + +#define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(ucomdebug,1,FMT,A,B,C,D) +#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(ucomdebug,N,FMT,A,B,C,D) +#define UCOMHIST_FUNC() USBHIST_FUNC() +#define UCOMHIST_CALLED(name) USBHIST_CALLED(ucomdebug) #define UCOMCALLUNIT_MASK TTCALLUNIT_MASK #define UCOMUNIT_MASK TTUNIT_MASK @@ -94,7 +129,7 @@ int ucomdebug = 0; struct ucom_buffer { SIMPLEQ_ENTRY(ucom_buffer) ub_link; - usbd_xfer_handle ub_xfer; + struct usbd_xfer *ub_xfer; u_char *ub_data; u_int ub_len; u_int ub_index; @@ -103,12 +138,12 @@ struct ucom_buffer { struct ucom_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; /* USB device */ + struct usbd_device * sc_udev; /* USB device */ - usbd_interface_handle sc_iface; /* data interface */ + struct usbd_interface * sc_iface; /* data interface */ int sc_bulkin_no; /* bulk in endpoint address */ - usbd_pipe_handle sc_bulkin_pipe; /* bulk in pipe */ + struct usbd_pipe * sc_bulkin_pipe; /* bulk in pipe */ u_int sc_ibufsize; /* read buffer size */ u_int sc_ibufsizepad; /* read buffer size padded */ struct ucom_buffer sc_ibuff[UCOM_IN_BUFFS]; @@ -116,7 +151,7 @@ struct ucom_softc { SIMPLEQ_HEAD(, ucom_buffer) sc_ibuff_full; int sc_bulkout_no; /* bulk out endpoint address */ - usbd_pipe_handle sc_bulkout_pipe;/* bulk out pipe */ + struct usbd_pipe * sc_bulkout_pipe;/* bulk out pipe */ u_int sc_obufsize; /* write buffer size */ u_int sc_opkthdrlen; /* header length of */ struct ucom_buffer sc_obuff[UCOM_OUT_BUFFS]; @@ -144,7 +179,11 @@ struct ucom_softc { struct pps_state sc_pps_state; /* pps state */ - krndsource_t sc_rndsource; /* random source */ + krndsource_t sc_rndsource; /* random source */ + + kmutex_t sc_lock; + kcondvar_t sc_opencv; + kcondvar_t sc_detachcv; }; dev_type_open(ucomopen); @@ -168,7 +207,7 @@ const struct cdevsw ucom_cdevsw = { .d_mmap = nommap, .d_kqfilter = ttykqfilter, .d_discard = nodiscard, - .d_flag = D_TTY + .d_flag = D_TTY | D_MPSAFE }; static void ucom_cleanup(struct ucom_softc *); @@ -184,12 +223,12 @@ static void ucom_break(struct ucom_softc *, int); static void tiocm_to_ucom(struct ucom_softc *, u_long, int); static int ucom_to_tiocm(struct ucom_softc *); -static void ucomreadcb(usbd_xfer_handle, usbd_private_handle, usbd_status); +static void ucomreadcb(struct usbd_xfer *, void *, usbd_status); static void ucom_submit_write(struct ucom_softc *, struct ucom_buffer *); static void ucom_write_status(struct ucom_softc *, struct ucom_buffer *, usbd_status); -static void ucomwritecb(usbd_xfer_handle, usbd_private_handle, usbd_status); +static void ucomwritecb(struct usbd_xfer *, void *, usbd_status); static void ucom_read_complete(struct ucom_softc *); static usbd_status ucomsubmitread(struct ucom_softc *, struct ucom_buffer *); static void ucom_softintr(void *); @@ -205,34 +244,37 @@ CFATTACH_DECL_NEW(ucom, sizeof(struct ucom_softc), ucom_match, ucom_attach, int ucom_match(device_t parent, cfdata_t match, void *aux) { - return (1); + return 1; } void ucom_attach(device_t parent, device_t self, void *aux) { struct ucom_softc *sc = device_private(self); - struct ucom_attach_args *uca = aux; + struct ucom_attach_args *ucaa = aux; struct tty *tp; - if (uca->info != NULL) - aprint_normal(": %s", uca->info); + UCOMHIST_FUNC(); UCOMHIST_CALLED(); + + if (ucaa->ucaa_info != NULL) + aprint_normal(": %s", ucaa->ucaa_info); aprint_normal("\n"); - prop_dictionary_set_int32(device_properties(self), "port", uca->portno); + prop_dictionary_set_int32(device_properties(self), "port", + ucaa->ucaa_portno); sc->sc_dev = self; - sc->sc_udev = uca->device; - sc->sc_iface = uca->iface; - sc->sc_bulkout_no = uca->bulkout; - sc->sc_bulkin_no = uca->bulkin; - sc->sc_ibufsize = uca->ibufsize; - sc->sc_ibufsizepad = uca->ibufsizepad; - sc->sc_obufsize = uca->obufsize; - sc->sc_opkthdrlen = uca->opkthdrlen; - sc->sc_methods = uca->methods; - sc->sc_parent = uca->arg; - sc->sc_portno = uca->portno; + sc->sc_udev = ucaa->ucaa_device; + sc->sc_iface = ucaa->ucaa_iface; + sc->sc_bulkout_no = ucaa->ucaa_bulkout; + sc->sc_bulkin_no = ucaa->ucaa_bulkin; + sc->sc_ibufsize = ucaa->ucaa_ibufsize; + sc->sc_ibufsizepad = ucaa->ucaa_ibufsizepad; + sc->sc_obufsize = ucaa->ucaa_obufsize; + sc->sc_opkthdrlen = ucaa->ucaa_opkthdrlen; + sc->sc_methods = ucaa->ucaa_methods; + sc->sc_parent = ucaa->ucaa_arg; + sc->sc_portno = ucaa->ucaa_portno; sc->sc_lsr = 0; sc->sc_msr = 0; @@ -243,7 +285,63 @@ ucom_attach(device_t parent, device_t self, void *aux) sc->sc_refcnt = 0; sc->sc_dying = 0; - sc->sc_si = softint_establish(SOFTINT_NET, ucom_softintr, sc); + sc->sc_si = softint_establish(SOFTINT_USB, ucom_softintr, sc); + mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); + cv_init(&sc->sc_opencv, "ucomopen"); + cv_init(&sc->sc_detachcv, "ucomdtch"); + + SIMPLEQ_INIT(&sc->sc_ibuff_empty); + SIMPLEQ_INIT(&sc->sc_ibuff_full); + SIMPLEQ_INIT(&sc->sc_obuff_free); + SIMPLEQ_INIT(&sc->sc_obuff_full); + + memset(sc->sc_ibuff, 0, sizeof(sc->sc_ibuff)); + memset(sc->sc_obuff, 0, sizeof(sc->sc_obuff)); + + DPRINTF("open pipes in=%d out=%d", sc->sc_bulkin_no, sc->sc_bulkout_no, + 0, 0); + + struct ucom_buffer *ub; + usbd_status err; + int error; + + /* Open the bulk pipes */ + err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no, + USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe); + if (err) { + DPRINTF("open bulk in error (addr %d), err=%d", + sc->sc_bulkin_no, err, 0, 0); + error = EIO; + goto fail_0; + } + err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no, + USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe); + if (err) { + DPRINTF("open bulk out error (addr %d), err=%d", + sc->sc_bulkout_no, err, 0, 0); + error = EIO; + goto fail_1; + } + + /* Allocate input buffers */ + for (ub = &sc->sc_ibuff[0]; ub != &sc->sc_ibuff[UCOM_IN_BUFFS]; + ub++) { + error = usbd_create_xfer(sc->sc_bulkin_pipe, sc->sc_ibufsizepad, + USBD_SHORT_XFER_OK, 0, &ub->ub_xfer); + if (error) + goto fail_2; + ub->ub_data = usbd_get_buffer(ub->ub_xfer); + } + + for (ub = &sc->sc_obuff[0]; ub != &sc->sc_obuff[UCOM_OUT_BUFFS]; + ub++) { + error = usbd_create_xfer(sc->sc_bulkout_pipe, sc->sc_obufsize, + 0, 0, &ub->ub_xfer); + if (error) + goto fail_2; + ub->ub_data = usbd_get_buffer(ub->ub_xfer); + SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_free, ub, ub_link); + } tp = tty_alloc(); tp->t_oproc = ucomstart; @@ -251,7 +349,7 @@ ucom_attach(device_t parent, device_t self, void *aux) tp->t_hwiflow = ucomhwiflow; sc->sc_tty = tp; - DPRINTF(("ucom_attach: tty_attach %p\n", tp)); + DPRINTF("tty_attach %p", tp, 0, 0, 0); tty_attach(tp); rnd_attach_source(&sc->sc_rndsource, device_xname(sc->sc_dev), @@ -260,6 +358,26 @@ ucom_attach(device_t parent, device_t self, void *aux) if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler\n"); return; + +fail_2: + for (ub = &sc->sc_ibuff[0]; ub != &sc->sc_ibuff[UCOM_IN_BUFFS]; + ub++) { + if (ub->ub_xfer) + usbd_destroy_xfer(ub->ub_xfer); + } + for (ub = &sc->sc_obuff[0]; ub != &sc->sc_obuff[UCOM_OUT_BUFFS]; + ub++) { + if (ub->ub_xfer) + usbd_destroy_xfer(ub->ub_xfer); + } + +fail_1: + usbd_close_pipe(sc->sc_bulkin_pipe); + +fail_0: + aprint_error_dev(self, "attach failed, error=%d\n", error); + + return; } int @@ -268,12 +386,17 @@ ucom_detach(device_t self, int flags) struct ucom_softc *sc = device_private(self); struct tty *tp = sc->sc_tty; int maj, mn; - int s, i; + int i; + + UCOMHIST_FUNC(); UCOMHIST_CALLED(); - DPRINTF(("ucom_detach: sc=%p flags=%d tp=%p, pipe=%d,%d\n", - sc, flags, tp, sc->sc_bulkin_no, sc->sc_bulkout_no)); + DPRINTF("sc=%p flags=%d tp=%p", sc, flags, tp, 0); + DPRINTF("... pipe=%d,%d",sc->sc_bulkin_no, sc->sc_bulkout_no, 0, 0); + mutex_enter(&sc->sc_lock); sc->sc_dying = 1; + mutex_exit(&sc->sc_lock); + pmf_device_deregister(self); if (sc->sc_bulkin_pipe != NULL) @@ -281,8 +404,8 @@ ucom_detach(device_t self, int flags) if (sc->sc_bulkout_pipe != NULL) usbd_abort_pipe(sc->sc_bulkout_pipe); - s = splusb(); - if (--sc->sc_refcnt >= 0) { + mutex_enter(&sc->sc_lock); + while (sc->sc_refcnt > 0) { /* Wake up anyone waiting */ if (tp != NULL) { mutex_spin_enter(&tty_lock); @@ -292,18 +415,18 @@ ucom_detach(device_t self, int flags) mutex_spin_exit(&tty_lock); } /* Wait for processes to go away. */ - usb_detach_waitold(sc->sc_dev); + usb_detach_wait(sc->sc_dev, &sc->sc_detachcv, &sc->sc_lock); } softint_disestablish(sc->sc_si); - splx(s); + mutex_exit(&sc->sc_lock); /* locate the major number */ maj = cdevsw_lookup_major(&ucom_cdevsw); /* Nuke the vnodes for any open instances. */ mn = device_unit(self); - DPRINTF(("ucom_detach: maj=%d mn=%d\n", maj, mn)); + DPRINTF("maj=%d mn=%d\n", maj, mn, 0, 0); vdevgone(maj, mn, mn, VCHR); vdevgone(maj, mn | UCOMDIALOUT_MASK, mn | UCOMDIALOUT_MASK, VCHR); vdevgone(maj, mn | UCOMCALLUNIT_MASK, mn | UCOMCALLUNIT_MASK, VCHR); @@ -317,18 +440,32 @@ ucom_detach(device_t self, int flags) for (i = 0; i < UCOM_IN_BUFFS; i++) { if (sc->sc_ibuff[i].ub_xfer != NULL) - usbd_free_xfer(sc->sc_ibuff[i].ub_xfer); + usbd_destroy_xfer(sc->sc_ibuff[i].ub_xfer); } for (i = 0; i < UCOM_OUT_BUFFS; i++) { if (sc->sc_obuff[i].ub_xfer != NULL) - usbd_free_xfer(sc->sc_obuff[i].ub_xfer); + usbd_destroy_xfer(sc->sc_obuff[i].ub_xfer); + } + + if (sc->sc_bulkin_pipe != NULL) { + usbd_close_pipe(sc->sc_bulkin_pipe); + sc->sc_bulkin_pipe = NULL; + } + + if (sc->sc_bulkout_pipe != NULL) { + usbd_close_pipe(sc->sc_bulkout_pipe); + sc->sc_bulkout_pipe = NULL; } /* Detach the random source */ rnd_detach_source(&sc->sc_rndsource); - return (0); + mutex_destroy(&sc->sc_lock); + cv_destroy(&sc->sc_opencv); + cv_destroy(&sc->sc_detachcv); + + return 0; } int @@ -336,11 +473,15 @@ ucom_activate(device_t self, enum devact act) { struct ucom_softc *sc = device_private(self); - DPRINTFN(5,("ucom_activate: %d\n", act)); + UCOMHIST_FUNC(); UCOMHIST_CALLED(); + + DPRINTFN(5, "%d", act, 0, 0, 0); switch (act) { case DVACT_DEACTIVATE: + mutex_enter(&sc->sc_lock); sc->sc_dying = 1; + mutex_exit(&sc->sc_lock); return 0; default: return EOPNOTSUPP; @@ -352,14 +493,17 @@ ucom_shutdown(struct ucom_softc *sc) { struct tty *tp = sc->sc_tty; - DPRINTF(("ucom_shutdown\n")); + UCOMHIST_FUNC(); UCOMHIST_CALLED(); + + KASSERT(mutex_owned(&sc->sc_lock)); /* * Hang up if necessary. Wait a bit, so the other side has time to * notice even if we immediately open the port again. */ if (ISSET(tp->t_cflag, HUPCL)) { ucom_dtr(sc, 0); - (void)tsleep(sc, TTIPRI, ttclos, hz); + /* XXX will only timeout */ + (void) kpause(ttclos, false, hz, &sc->sc_lock); } } @@ -367,41 +511,48 @@ int ucomopen(dev_t dev, int flag, int mode, struct lwp *l) { int unit = UCOMUNIT(dev); - usbd_status err; struct ucom_softc *sc = device_lookup_private(&ucom_cd, unit); struct ucom_buffer *ub; struct tty *tp; - int s, i; int error; + UCOMHIST_FUNC(); UCOMHIST_CALLED(); + if (sc == NULL) - return (ENXIO); + return ENXIO; - if (sc->sc_dying) - return (EIO); + mutex_enter(&sc->sc_lock); + if (sc->sc_dying) { + mutex_exit(&sc->sc_lock); + return EIO; + } - if (!device_is_active(sc->sc_dev)) - return (ENXIO); + if (!device_is_active(sc->sc_dev)) { + mutex_exit(&sc->sc_lock); + return ENXIO; + } tp = sc->sc_tty; - DPRINTF(("ucomopen: unit=%d, tp=%p\n", unit, tp)); - - if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) - return (EBUSY); + DPRINTF("unit=%d, tp=%p\n", unit, tp, 0, 0); - s = spltty(); + if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) { + mutex_exit(&sc->sc_lock); + return EBUSY; + } /* * Do the following iff this is a first open. */ - while (sc->sc_opening) - tsleep(&sc->sc_opening, PRIBIO, "ucomop", 0); + while (sc->sc_opening) { + error = cv_wait_sig(&sc->sc_opencv, &sc->sc_lock); - if (sc->sc_dying) { - splx(s); - return (EIO); + if (error) { + mutex_exit(&sc->sc_lock); + return error; + } } + sc->sc_opening = 1; if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { @@ -415,9 +566,9 @@ ucomopen(dev_t dev, int flag, int mode, struct lwp *l) if (error) { ucom_cleanup(sc); sc->sc_opening = 0; - wakeup(&sc->sc_opening); - splx(s); - return (error); + cv_signal(&sc->sc_opencv); + mutex_exit(&sc->sc_lock); + return error; } } @@ -462,83 +613,21 @@ ucomopen(dev_t dev, int flag, int mode, struct lwp *l) ucom_dtr(sc, 1); ucom_rts(sc, 1); - DPRINTF(("ucomopen: open pipes in=%d out=%d\n", - sc->sc_bulkin_no, sc->sc_bulkout_no)); - - /* Open the bulk pipes */ - err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkin_no, - USBD_EXCLUSIVE_USE, &sc->sc_bulkin_pipe); - if (err) { - DPRINTF(("%s: open bulk in error (addr %d), err=%s\n", - device_xname(sc->sc_dev), sc->sc_bulkin_no, - usbd_errstr(err))); - error = EIO; - goto fail_0; - } - err = usbd_open_pipe(sc->sc_iface, sc->sc_bulkout_no, - USBD_EXCLUSIVE_USE, &sc->sc_bulkout_pipe); - if (err) { - DPRINTF(("%s: open bulk out error (addr %d), err=%s\n", - device_xname(sc->sc_dev), sc->sc_bulkout_no, - usbd_errstr(err))); - error = EIO; - goto fail_1; - } - sc->sc_rx_unblock = 0; sc->sc_rx_stopped = 0; sc->sc_tx_stopped = 0; - memset(sc->sc_ibuff, 0, sizeof(sc->sc_ibuff)); - memset(sc->sc_obuff, 0, sizeof(sc->sc_obuff)); - - SIMPLEQ_INIT(&sc->sc_ibuff_empty); - SIMPLEQ_INIT(&sc->sc_ibuff_full); - SIMPLEQ_INIT(&sc->sc_obuff_free); - SIMPLEQ_INIT(&sc->sc_obuff_full); - - /* Allocate input buffers */ for (ub = &sc->sc_ibuff[0]; ub != &sc->sc_ibuff[UCOM_IN_BUFFS]; ub++) { - ub->ub_xfer = usbd_alloc_xfer(sc->sc_udev); - if (ub->ub_xfer == NULL) { - error = ENOMEM; - goto fail_2; - } - ub->ub_data = usbd_alloc_buffer(ub->ub_xfer, - sc->sc_ibufsizepad); - if (ub->ub_data == NULL) { - error = ENOMEM; - goto fail_2; - } - if (ucomsubmitread(sc, ub) != USBD_NORMAL_COMPLETION) { error = EIO; goto fail_2; } } - - for (ub = &sc->sc_obuff[0]; ub != &sc->sc_obuff[UCOM_OUT_BUFFS]; - ub++) { - ub->ub_xfer = usbd_alloc_xfer(sc->sc_udev); - if (ub->ub_xfer == NULL) { - error = ENOMEM; - goto fail_2; - } - ub->ub_data = usbd_alloc_buffer(ub->ub_xfer, - sc->sc_obufsize); - if (ub->ub_data == NULL) { - error = ENOMEM; - goto fail_2; - } - - SIMPLEQ_INSERT_TAIL(&sc->sc_obuff_free, ub, ub_link); - } - } sc->sc_opening = 0; - wakeup(&sc->sc_opening); - splx(s); + cv_signal(&sc->sc_opencv); + mutex_exit(&sc->sc_lock); error = ttyopen(tp, UCOMDIALOUT(dev), ISSET(flag, O_NONBLOCK)); if (error) @@ -548,39 +637,21 @@ ucomopen(dev_t dev, int flag, int mode, struct lwp *l) if (error) goto bad; - return (0); + return 0; fail_2: usbd_abort_pipe(sc->sc_bulkin_pipe); - for (i = 0; i < UCOM_IN_BUFFS; i++) { - if (sc->sc_ibuff[i].ub_xfer != NULL) { - usbd_free_xfer(sc->sc_ibuff[i].ub_xfer); - sc->sc_ibuff[i].ub_xfer = NULL; - sc->sc_ibuff[i].ub_data = NULL; - } - } usbd_abort_pipe(sc->sc_bulkout_pipe); - for (i = 0; i < UCOM_OUT_BUFFS; i++) { - if (sc->sc_obuff[i].ub_xfer != NULL) { - usbd_free_xfer(sc->sc_obuff[i].ub_xfer); - sc->sc_obuff[i].ub_xfer = NULL; - sc->sc_obuff[i].ub_data = NULL; - } - } - usbd_close_pipe(sc->sc_bulkout_pipe); - sc->sc_bulkout_pipe = NULL; -fail_1: - usbd_close_pipe(sc->sc_bulkin_pipe); - sc->sc_bulkin_pipe = NULL; -fail_0: + mutex_enter(&sc->sc_lock); sc->sc_opening = 0; - wakeup(&sc->sc_opening); - splx(s); - return (error); + cv_signal(&sc->sc_opencv); + mutex_exit(&sc->sc_lock); + + return error; bad: - s = spltty(); + mutex_spin_enter(&tty_lock); CLR(tp->t_state, TS_BUSY); if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { /* @@ -589,9 +660,9 @@ bad: */ ucom_cleanup(sc); } - splx(s); + mutex_spin_exit(&tty_lock); - return (error); + return error; } int @@ -599,19 +670,21 @@ ucomclose(dev_t dev, int flag, int mode, struct lwp *l) { struct ucom_softc *sc = device_lookup_private(&ucom_cd, UCOMUNIT(dev)); struct tty *tp; - int s; - DPRINTF(("ucomclose: unit=%d\n", UCOMUNIT(dev))); + UCOMHIST_FUNC(); UCOMHIST_CALLED(); + + DPRINTF("unit=%d", UCOMUNIT(dev), 0, 0, 0); if (sc == NULL) return 0; + mutex_enter(&sc->sc_lock); tp = sc->sc_tty; - if (!ISSET(tp->t_state, TS_ISOPEN)) - return (0); + if (!ISSET(tp->t_state, TS_ISOPEN)) { + goto out; + } - s = spltty(); sc->sc_refcnt++; (*tp->t_linesw->l_close)(tp, flag); @@ -630,10 +703,12 @@ ucomclose(dev_t dev, int flag, int mode, struct lwp *l) sc->sc_methods->ucom_close(sc->sc_parent, sc->sc_portno); if (--sc->sc_refcnt < 0) - usb_detach_wakeupold(sc->sc_dev); - splx(s); + usb_detach_broadcast(sc->sc_dev, &sc->sc_detachcv); + +out: + mutex_exit(&sc->sc_lock); - return (0); + return 0; } int @@ -643,16 +718,29 @@ ucomread(dev_t dev, struct uio *uio, int flag) struct tty *tp; int error; - if (sc == NULL || sc->sc_dying) - return (EIO); + UCOMHIST_FUNC(); UCOMHIST_CALLED(); + + if (sc == NULL) + return EIO; + + mutex_enter(&sc->sc_lock); + if (sc->sc_dying) { + mutex_exit(&sc->sc_lock); + return EIO; + } tp = sc->sc_tty; sc->sc_refcnt++; + mutex_exit(&sc->sc_lock); error = ((*tp->t_linesw->l_read)(tp, uio, flag)); + mutex_enter(&sc->sc_lock); + if (--sc->sc_refcnt < 0) - usb_detach_wakeupold(sc->sc_dev); - return (error); + usb_detach_broadcast(sc->sc_dev, &sc->sc_detachcv); + mutex_exit(&sc->sc_lock); + + return error; } int @@ -662,16 +750,26 @@ ucomwrite(dev_t dev, struct uio *uio, int flag) struct tty *tp; int error; - if (sc == NULL || sc->sc_dying) - return (EIO); + if (sc == NULL) + return EIO; + + mutex_enter(&sc->sc_lock); + if (sc->sc_dying) { + mutex_exit(&sc->sc_lock); + return EIO; + } tp = sc->sc_tty; sc->sc_refcnt++; + mutex_exit(&sc->sc_lock); error = ((*tp->t_linesw->l_write)(tp, uio, flag)); + mutex_enter(&sc->sc_lock); if (--sc->sc_refcnt < 0) - usb_detach_wakeupold(sc->sc_dev); - return (error); + usb_detach_broadcast(sc->sc_dev, &sc->sc_detachcv); + mutex_exit(&sc->sc_lock); + + return error; } int @@ -682,16 +780,25 @@ ucompoll(dev_t dev, int events, struct lwp *l) int revents; sc = device_lookup_private(&ucom_cd, UCOMUNIT(dev)); - if (sc == NULL || sc->sc_dying) - return (POLLHUP); + if (sc == NULL) + return POLLHUP; + mutex_enter(&sc->sc_lock); + if (sc->sc_dying) { + mutex_exit(&sc->sc_lock); + return POLLHUP; + } tp = sc->sc_tty; sc->sc_refcnt++; + mutex_exit(&sc->sc_lock); revents = ((*tp->t_linesw->l_poll)(tp, events, l)); + mutex_enter(&sc->sc_lock); if (--sc->sc_refcnt < 0) - usb_detach_wakeupold(sc->sc_dev); - return (revents); + usb_detach_broadcast(sc->sc_dev, &sc->sc_detachcv); + mutex_exit(&sc->sc_lock); + + return revents; } struct tty * @@ -699,7 +806,7 @@ ucomtty(dev_t dev) { struct ucom_softc *sc = device_lookup_private(&ucom_cd, UCOMUNIT(dev)); - return ((sc != NULL) ? sc->sc_tty : NULL); + return sc != NULL ? sc->sc_tty : NULL; } int @@ -708,14 +815,21 @@ ucomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) struct ucom_softc *sc = device_lookup_private(&ucom_cd, UCOMUNIT(dev)); int error; - if (sc == NULL || sc->sc_dying) - return (EIO); + if (sc == NULL) + return EIO; + + mutex_enter(&sc->sc_lock); + if (sc->sc_dying) { + mutex_exit(&sc->sc_lock); + return EIO; + } sc->sc_refcnt++; error = ucom_do_ioctl(sc, cmd, data, flag, l); if (--sc->sc_refcnt < 0) - usb_detach_wakeupold(sc->sc_dev); - return (error); + usb_detach_broadcast(sc->sc_dev, &sc->sc_detachcv); + mutex_exit(&sc->sc_lock); + return error; } static int @@ -724,29 +838,30 @@ ucom_do_ioctl(struct ucom_softc *sc, u_long cmd, void *data, { struct tty *tp = sc->sc_tty; int error; - int s; - DPRINTF(("ucomioctl: cmd=0x%08lx\n", cmd)); + UCOMHIST_FUNC(); UCOMHIST_CALLED(); + + DPRINTF("cmd=0x%08lx", cmd, 0, 0, 0); error = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) - return (error); + return error; error = ttioctl(tp, cmd, data, flag, l); if (error != EPASSTHROUGH) - return (error); + return error; if (sc->sc_methods->ucom_ioctl != NULL) { error = sc->sc_methods->ucom_ioctl(sc->sc_parent, sc->sc_portno, cmd, data, flag, l->l_proc); if (error != EPASSTHROUGH) - return (error); + return error; } error = 0; - DPRINTF(("ucomioctl: our cmd=0x%08lx\n", cmd)); - s = spltty(); + DPRINTF("our cmd=0x%08lx", cmd, 0, 0, 0); + //mutex_enter(&tty_lock); switch (cmd) { case TIOCSBRK: @@ -806,9 +921,9 @@ ucom_do_ioctl(struct ucom_softc *sc, u_long cmd, void *data, break; } - splx(s); + //mutex_exit(&tty_lock); - return (error); + return error; } static void @@ -871,13 +986,15 @@ XXX; SET(ttybits, TIOCM_LE); #endif - return (ttybits); + return ttybits; } static void ucom_break(struct ucom_softc *sc, int onoff) { - DPRINTF(("ucom_break: onoff=%d\n", onoff)); + UCOMHIST_FUNC(); UCOMHIST_CALLED(); + + DPRINTF("onoff=%d", onoff, 0, 0, 0); if (sc->sc_methods->ucom_set != NULL) sc->sc_methods->ucom_set(sc->sc_parent, sc->sc_portno, @@ -887,7 +1004,9 @@ ucom_break(struct ucom_softc *sc, int onoff) static void ucom_dtr(struct ucom_softc *sc, int onoff) { - DPRINTF(("ucom_dtr: onoff=%d\n", onoff)); + UCOMHIST_FUNC(); UCOMHIST_CALLED(); + + DPRINTF("onoff=%d", onoff, 0, 0, 0); if (sc->sc_methods->ucom_set != NULL) sc->sc_methods->ucom_set(sc->sc_parent, sc->sc_portno, @@ -897,7 +1016,9 @@ ucom_dtr(struct ucom_softc *sc, int onoff) static void ucom_rts(struct ucom_softc *sc, int onoff) { - DPRINTF(("ucom_rts: onoff=%d\n", onoff)); + UCOMHIST_FUNC(); UCOMHIST_CALLED(); + + DPRINTF("onoff=%d", onoff, 0, 0, 0); if (sc->sc_methods->ucom_set != NULL) sc->sc_methods->ucom_set(sc->sc_parent, sc->sc_portno, @@ -940,12 +1061,14 @@ ucomparam(struct tty *tp, struct termios *t) UCOMUNIT(tp->t_dev)); int error; + UCOMHIST_FUNC(); UCOMHIST_CALLED(); + if (sc == NULL || sc->sc_dying) - return (EIO); + return EIO; /* Check requested parameters. */ if (t->c_ispeed && t->c_ispeed != t->c_ospeed) - return (EINVAL); + return EINVAL; /* * For the console, always force CLOCAL and !HUPCL, so that the port @@ -963,7 +1086,7 @@ ucomparam(struct tty *tp, struct termios *t) */ if (tp->t_ospeed == t->c_ospeed && tp->t_cflag == t->c_cflag) - return (0); + return 0; /* XXX lcr = ISSET(sc->sc_lcr, LCR_SBREAK) | cflag2lcr(t->c_cflag); */ @@ -976,7 +1099,7 @@ ucomparam(struct tty *tp, struct termios *t) error = sc->sc_methods->ucom_param(sc->sc_parent, sc->sc_portno, t); if (error) - return (error); + return error; } /* XXX worry about CHWFLOW */ @@ -986,7 +1109,7 @@ ucomparam(struct tty *tp, struct termios *t) * CLOCAL or MDMBUF. We don't hang up here; we only do that by * explicit request. */ - DPRINTF(("ucomparam: l_modem\n")); + DPRINTF("l_modem", 0, 0, 0, 0); (void) (*tp->t_linesw->l_modem)(tp, ISSET(sc->sc_msr, UMSR_DCD)); #if 0 @@ -999,7 +1122,7 @@ XXX what if the hardware is not open } #endif - return (0); + return 0; } static int @@ -1010,19 +1133,19 @@ ucomhwiflow(struct tty *tp, int block) int old; if (sc == NULL) - return (0); + return 0; + mutex_enter(&sc->sc_lock); old = sc->sc_rx_stopped; sc->sc_rx_stopped = (u_char)block; if (old && !block) { - int s = splusb(); sc->sc_rx_unblock = 1; softint_schedule(sc->sc_si); - splx(s); } + mutex_exit(&sc->sc_lock); - return (1); + return 1; } static void @@ -1031,14 +1154,18 @@ ucomstart(struct tty *tp) struct ucom_softc *sc = device_lookup_private(&ucom_cd, UCOMUNIT(tp->t_dev)); struct ucom_buffer *ub; - int s; u_char *data; int cnt; - if (sc == NULL || sc->sc_dying) + if (sc == NULL) return; - s = spltty(); + KASSERT(&sc->sc_lock); + KASSERT(mutex_owned(&tty_lock)); + if (sc->sc_dying) { + return; + } + if (ISSET(tp->t_state, TS_BUSY | TS_TIMEOUT | TS_TTSTOP)) goto out; if (sc->sc_tx_stopped) @@ -1059,6 +1186,7 @@ ucomstart(struct tty *tp) SET(tp->t_state, TS_BUSY); goto out; } + SIMPLEQ_REMOVE_HEAD(&sc->sc_obuff_free, ub_link); if (SIMPLEQ_FIRST(&sc->sc_obuff_free) == NULL) @@ -1081,24 +1209,26 @@ ucomstart(struct tty *tp) softint_schedule(sc->sc_si); out: - splx(s); + return; } void ucomstop(struct tty *tp, int flag) { #if 0 - /*struct ucom_softc *sc = - device_lookup_private(&ucom_cd, UCOMUNIT(tp->t_dev));*/ - int s; + struct ucom_softc *sc = + device_lookup_private(&ucom_cd, UCOMUNIT(tp->t_dev)); - s = spltty(); + mutex_enter(&sc->sc_lock); + mutex_spin_enter(&tty_lock); if (ISSET(tp->t_state, TS_BUSY)) { + /* obuff_full -> obuff_free? */ /* sc->sc_tx_stopped = 1; */ if (!ISSET(tp->t_state, TS_TTSTOP)) SET(tp->t_state, TS_FLUSH); } - splx(s); + mutex_spin_exit(&tty_lock); + mutex_exit(&sc->sc_lock); #endif } @@ -1109,6 +1239,8 @@ ucom_write_status(struct ucom_softc *sc, struct ucom_buffer *ub, struct tty *tp = sc->sc_tty; uint32_t cc = ub->ub_len; + KASSERT(mutex_owned(&sc->sc_lock)); + switch (err) { case USBD_IN_PROGRESS: ub->ub_index = ub->ub_len; @@ -1139,35 +1271,35 @@ ucom_write_status(struct ucom_softc *sc, struct ucom_buffer *ub, if ((ub = SIMPLEQ_FIRST(&sc->sc_obuff_full)) != NULL) ucom_submit_write(sc, ub); + mutex_spin_enter(&tty_lock); (*tp->t_linesw->l_start)(tp); + mutex_spin_exit(&tty_lock); } break; } } -/* Call at spltty() */ static void ucom_submit_write(struct ucom_softc *sc, struct ucom_buffer *ub) { - usbd_setup_xfer(ub->ub_xfer, sc->sc_bulkout_pipe, - (usbd_private_handle)sc, ub->ub_data, ub->ub_len, - USBD_NO_COPY, USBD_NO_TIMEOUT, ucomwritecb); + KASSERT(mutex_owned(&sc->sc_lock)); + + usbd_setup_xfer(ub->ub_xfer, sc, ub->ub_data, ub->ub_len, + 0, USBD_NO_TIMEOUT, ucomwritecb); ucom_write_status(sc, ub, usbd_transfer(ub->ub_xfer)); } static void -ucomwritecb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) +ucomwritecb(struct usbd_xfer *xfer, void *p, usbd_status status) { struct ucom_softc *sc = (struct ucom_softc *)p; - int s; - - s = spltty(); + mutex_enter(&sc->sc_lock); ucom_write_status(sc, SIMPLEQ_FIRST(&sc->sc_obuff_full), status); + mutex_exit(&sc->sc_lock); - splx(s); } static void @@ -1176,12 +1308,15 @@ ucom_softintr(void *arg) struct ucom_softc *sc = arg; struct tty *tp = sc->sc_tty; struct ucom_buffer *ub; - int s; - if (!ISSET(tp->t_state, TS_ISOPEN)) + mutex_enter(&sc->sc_lock); + mutex_enter(&tty_lock); + if (!ISSET(tp->t_state, TS_ISOPEN)) { + mutex_exit(&tty_lock); + mutex_exit(&sc->sc_lock); return; - - s = spltty(); + } + mutex_exit(&tty_lock); ub = SIMPLEQ_FIRST(&sc->sc_obuff_full); @@ -1191,7 +1326,7 @@ ucom_softintr(void *arg) if (sc->sc_rx_unblock) ucom_read_complete(sc); - splx(s); + mutex_exit(&sc->sc_lock); } static void @@ -1200,7 +1335,8 @@ ucom_read_complete(struct ucom_softc *sc) int (*rint)(int, struct tty *); struct ucom_buffer *ub; struct tty *tp; - int s; + + KASSERT(mutex_owned(&sc->sc_lock)); tp = sc->sc_tty; rint = tp->t_linesw->l_rint; @@ -1208,8 +1344,7 @@ ucom_read_complete(struct ucom_softc *sc) while (ub != NULL && !sc->sc_rx_stopped) { - s = spltty(); - + /* XXX ttyinput takes tty_lock */ while (ub->ub_index < ub->ub_len && !sc->sc_rx_stopped) { /* Give characters to tty layer. */ if ((*rint)(ub->ub_data[ub->ub_index], tp) == -1) { @@ -1219,8 +1354,6 @@ ucom_read_complete(struct ucom_softc *sc) ub->ub_index++; } - splx(s); - if (ub->ub_index == ub->ub_len) { SIMPLEQ_REMOVE_HEAD(&sc->sc_ibuff_full, ub_link); @@ -1238,58 +1371,60 @@ ucomsubmitread(struct ucom_softc *sc, struct ucom_buffer *ub) { usbd_status err; - usbd_setup_xfer(ub->ub_xfer, sc->sc_bulkin_pipe, - (usbd_private_handle)sc, ub->ub_data, sc->sc_ibufsize, - USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, ucomreadcb); + usbd_setup_xfer(ub->ub_xfer, sc, ub->ub_data, sc->sc_ibufsize, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, ucomreadcb); if ((err = usbd_transfer(ub->ub_xfer)) != USBD_IN_PROGRESS) { /* XXX: Recover from this, please! */ printf("ucomsubmitread: err=%s\n", usbd_errstr(err)); - return (err); + return err; } SIMPLEQ_INSERT_TAIL(&sc->sc_ibuff_empty, ub, ub_link); - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } static void -ucomreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) +ucomreadcb(struct usbd_xfer *xfer, void *p, usbd_status status) { struct ucom_softc *sc = (struct ucom_softc *)p; struct tty *tp = sc->sc_tty; struct ucom_buffer *ub; - u_int32_t cc; + uint32_t cc; u_char *cp; - int s; + UCOMHIST_FUNC(); UCOMHIST_CALLED(); + + mutex_enter(&sc->sc_lock); ub = SIMPLEQ_FIRST(&sc->sc_ibuff_empty); SIMPLEQ_REMOVE_HEAD(&sc->sc_ibuff_empty, ub_link); if (status == USBD_CANCELLED || status == USBD_IOERROR || sc->sc_dying) { - DPRINTF(("ucomreadcb: dying\n")); + DPRINTF("dying", 0, 0, 0, 0); ub->ub_index = ub->ub_len = 0; /* Send something to wake upper layer */ - s = spltty(); if (status != USBD_CANCELLED) { (tp->t_linesw->l_rint)('\n', tp); mutex_spin_enter(&tty_lock); /* XXX */ ttwakeup(tp); mutex_spin_exit(&tty_lock); /* XXX */ } - splx(s); + mutex_exit(&sc->sc_lock); return; } if (status == USBD_STALLED) { usbd_clear_endpoint_stall_async(sc->sc_bulkin_pipe); ucomsubmitread(sc, ub); + mutex_exit(&sc->sc_lock); return; } if (status != USBD_NORMAL_COMPLETION) { printf("ucomreadcb: wonky status=%s\n", usbd_errstr(status)); + mutex_exit(&sc->sc_lock); return; } @@ -1308,6 +1443,7 @@ ucomreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) if (sc->sc_opening) { ucomsubmitread(sc, ub); + mutex_exit(&sc->sc_lock); return; } @@ -1323,39 +1459,33 @@ ucomreadcb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) SIMPLEQ_INSERT_TAIL(&sc->sc_ibuff_full, ub, ub_link); ucom_read_complete(sc); + mutex_exit(&sc->sc_lock); } static void ucom_cleanup(struct ucom_softc *sc) { - struct ucom_buffer *ub; - DPRINTF(("ucom_cleanup: closing pipes\n")); + UCOMHIST_FUNC(); UCOMHIST_CALLED(); + + DPRINTF("aborting pipes", 0, 0, 0, 0); + + KASSERT(mutex_owned(&sc->sc_lock)); ucom_shutdown(sc); if (sc->sc_bulkin_pipe != NULL) { - usbd_abort_pipe(sc->sc_bulkin_pipe); - usbd_close_pipe(sc->sc_bulkin_pipe); + struct usbd_pipe *bulkin_pipe = sc->sc_bulkin_pipe; sc->sc_bulkin_pipe = NULL; + mutex_exit(&sc->sc_lock); + usbd_abort_pipe(bulkin_pipe); + mutex_enter(&sc->sc_lock); } if (sc->sc_bulkout_pipe != NULL) { - usbd_abort_pipe(sc->sc_bulkout_pipe); - usbd_close_pipe(sc->sc_bulkout_pipe); + struct usbd_pipe *bulkout_pipe = sc->sc_bulkout_pipe; sc->sc_bulkout_pipe = NULL; - } - for (ub = &sc->sc_ibuff[0]; ub != &sc->sc_ibuff[UCOM_IN_BUFFS]; ub++) { - if (ub->ub_xfer != NULL) { - usbd_free_xfer(ub->ub_xfer); - ub->ub_xfer = NULL; - ub->ub_data = NULL; - } - } - for (ub = &sc->sc_obuff[0]; ub != &sc->sc_obuff[UCOM_OUT_BUFFS]; ub++){ - if (ub->ub_xfer != NULL) { - usbd_free_xfer(ub->ub_xfer); - ub->ub_xfer = NULL; - ub->ub_data = NULL; - } + mutex_exit(&sc->sc_lock); + usbd_abort_pipe(bulkout_pipe); + mutex_enter(&sc->sc_lock); } } @@ -1364,24 +1494,24 @@ ucom_cleanup(struct ucom_softc *sc) int ucomprint(void *aux, const char *pnp) { - struct ucom_attach_args *uca = aux; + struct ucom_attach_args *ucaa = aux; if (pnp) aprint_normal("ucom at %s", pnp); - if (uca->portno != UCOM_UNK_PORTNO) - aprint_normal(" portno %d", uca->portno); - return (UNCONF); + if (ucaa->ucaa_portno != UCOM_UNK_PORTNO) + aprint_normal(" portno %d", ucaa->ucaa_portno); + return UNCONF; } int ucomsubmatch(device_t parent, cfdata_t cf, const int *ldesc, void *aux) { - struct ucom_attach_args *uca = aux; + struct ucom_attach_args *ucaa = aux; - if (uca->portno != UCOM_UNK_PORTNO && + if (ucaa->ucaa_portno != UCOM_UNK_PORTNO && cf->cf_loc[UCOMBUSCF_PORTNO] != UCOMBUSCF_PORTNO_DEFAULT && - cf->cf_loc[UCOMBUSCF_PORTNO] != uca->portno) - return (0); - return (config_match(parent, cf, aux)); + cf->cf_loc[UCOMBUSCF_PORTNO] != ucaa->ucaa_portno) + return 0; + return config_match(parent, cf, aux); } diff --git a/sys/dev/usb/ucomvar.h b/sys/dev/usb/ucomvar.h index 79f529f2a1d..3e1129118d0 100644 --- a/sys/dev/usb/ucomvar.h +++ b/sys/dev/usb/ucomvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: ucomvar.h,v 1.20 2011/12/19 19:34:52 jakllsch Exp $ */ +/* $NetBSD: ucomvar.h,v 1.21 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1999 The NetBSD Foundation, Inc. @@ -37,27 +37,30 @@ struct ucom_softc; struct ucom_methods { - void (*ucom_get_status)(void *sc, int portno, u_char *lsr, u_char *msr); - void (*ucom_set)(void *sc, int portno, int reg, int onoff); + void (*ucom_get_status)(void *, int, u_char *, u_char *); + void (*ucom_set)(void *, int, int, int); #define UCOM_SET_DTR 1 #define UCOM_SET_RTS 2 #define UCOM_SET_BREAK 3 - int (*ucom_param)(void *sc, int portno, struct termios *); - int (*ucom_ioctl)(void *sc, int portno, u_long cmd, - void *data, int flag, proc_t *p); - int (*ucom_open)(void *sc, int portno); - void (*ucom_close)(void *sc, int portno); + int (*ucom_param)(void *, int, struct termios *); + int (*ucom_ioctl)(void *, int, u_long, void *, int, proc_t *); + int (*ucom_open)(void *, int); + void (*ucom_close)(void *, int); /* - * Note: The 'ptr' and 'count' pointers can be adjusted as follows: - * ptr: If consuming characters from the start of the buffer, - * advance '*ptr' to skip the data consumed. - * count: If consuming characters at the end of the buffer, - * decrement '*count' by the number of characters consumed. + * Note: The 'ptr' (2nd arg) and 'count' (3rd arg) pointers can be + * adjusted as follows: + * + * ptr: If consuming characters from the start of the buffer, + * advance '*ptr' to skip the data consumed. + * + * count: If consuming characters at the end of the buffer, + * decrement '*count' by the number of characters + * consumed. + * * If consuming all characters, set '*count' to zero. */ - void (*ucom_read)(void *sc, int portno, u_char **ptr, u_int32_t *count); - void (*ucom_write)(void *sc, int portno, u_char *to, u_char *from, - u_int32_t *count); + void (*ucom_read)(void *, int, u_char **, uint32_t *); + void (*ucom_write)(void *, int, u_char *, u_char *, uint32_t *); }; /* modem control register */ @@ -87,18 +90,18 @@ struct ucom_methods { #define UMSR_DCTS 0x01 /* CTS has changed state */ struct ucom_attach_args { - int portno; - int bulkin; - int bulkout; - u_int ibufsize; - u_int ibufsizepad; - u_int obufsize; - u_int opkthdrlen; - const char *info; /* attach message */ - usbd_device_handle device; - usbd_interface_handle iface; - const struct ucom_methods *methods; - void *arg; + int ucaa_portno; + int ucaa_bulkin; + int ucaa_bulkout; + u_int ucaa_ibufsize; + u_int ucaa_ibufsizepad; + u_int ucaa_obufsize; + u_int ucaa_opkthdrlen; + const char *ucaa_info; /* attach message */ + struct usbd_device *ucaa_device; + struct usbd_interface *ucaa_iface; + const struct ucom_methods *ucaa_methods; + void *ucaa_arg; }; int ucomprint(void *, const char *); diff --git a/sys/dev/usb/ucycom.c b/sys/dev/usb/ucycom.c index 482e98a3f40..02a84782267 100644 --- a/sys/dev/usb/ucycom.c +++ b/sys/dev/usb/ucycom.c @@ -1,4 +1,4 @@ -/* $NetBSD: ucycom.c,v 1.42 2015/03/07 20:20:55 mrg Exp $ */ +/* $NetBSD: ucycom.c,v 1.43 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2005 The NetBSD Foundation, Inc. @@ -38,13 +38,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ucycom.c,v 1.42 2015/03/07 20:20:55 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ucycom.c,v 1.43 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/conf.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/device.h> #include <sys/sysctl.h> #include <sys/tty.h> @@ -164,7 +164,7 @@ const struct cdevsw ucycom_cdevsw = { Static int ucycomparam(struct tty *, struct termios *); Static void ucycomstart(struct tty *); -Static void ucycomwritecb(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void ucycomwritecb(struct usbd_xfer *, void *, usbd_status); Static void ucycom_intr(struct uhidev *, void *, u_int); Static int ucycom_configure(struct ucycom_softc *, uint32_t, uint8_t); Static void tiocm_to_ucycom(struct ucycom_softc *, u_long, int); @@ -174,7 +174,7 @@ Static void ucycom_dtr(struct ucycom_softc *, int); #if 0 Static void ucycom_rts(struct ucycom_softc *, int); #endif -Static void ucycom_cleanup(struct ucycom_softc *sc); +Static void ucycom_cleanup(struct ucycom_softc *); #ifdef UCYCOM_DEBUG Static void ucycom_get_cfg(struct ucycom_softc *); @@ -198,8 +198,8 @@ ucycom_match(device_t parent, cfdata_t match, void *aux) { struct uhidev_attach_arg *uha = aux; - return (ucycom_lookup(uha->uaa->vendor, uha->uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return ucycom_lookup(uha->uiaa->uiaa_vendor, uha->uiaa->uiaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } void @@ -328,20 +328,20 @@ ucycomopen(dev_t dev, int flag, int mode, struct lwp *l) DPRINTF(("ucycomopen: sc=%p\n", sc)); if (sc == NULL) - return (ENXIO); + return ENXIO; if (sc->sc_dying) - return (EIO); + return EIO; if (!device_is_active(sc->sc_hdev.sc_dev)) - return (ENXIO); + return ENXIO; tp = sc->sc_tty; DPRINTF(("ucycomopen: tp=%p\n", tp)); if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp)) - return (EBUSY); + return EBUSY; s = spltty(); @@ -354,7 +354,7 @@ ucycomopen(dev_t dev, int flag, int mode, struct lwp *l) if (err) { /* Any cleanup? */ splx(s); - return (err); + return err; } /* @@ -380,7 +380,7 @@ ucycomopen(dev_t dev, int flag, int mode, struct lwp *l) ttsetwater(tp); /* Allocate an output report buffer */ - sc->sc_obuf = malloc(sc->sc_olen, M_USBDEV, M_WAITOK); + sc->sc_obuf = kmem_alloc(sc->sc_olen, KM_SLEEP); DPRINTF(("ucycomopen: sc->sc_obuf=%p\n", sc->sc_obuf)); @@ -415,7 +415,7 @@ ucycomopen(dev_t dev, int flag, int mode, struct lwp *l) if (err) goto bad; - return (0); + return 0; bad: if (!ISSET(tp->t_state, TS_ISOPEN) && tp->t_wopen == 0) { @@ -426,7 +426,7 @@ bad: ucycom_cleanup(sc); } - return (err); + return err; } @@ -440,7 +440,7 @@ ucycomclose(dev_t dev, int flag, int mode, struct lwp *l) DPRINTF(("ucycomclose: unit=%d\n", UCYCOMUNIT(dev))); if (!ISSET(tp->t_state, TS_ISOPEN)) - return (0); + return 0; (*tp->t_linesw->l_close)(tp, flag); ttyclose(tp); @@ -454,7 +454,7 @@ ucycomclose(dev_t dev, int flag, int mode, struct lwp *l) ucycom_cleanup(sc); } - return (0); + return 0; } Static void @@ -518,8 +518,8 @@ ucycomstart(struct tty *tp) sc->sc_mcr, sc->sc_obuf[0])); #ifdef UCYCOM_DEBUG if (ucycomdebug > 10) { - u_int32_t i; - u_int8_t *d = data; + uint32_t i; + uint8_t *d = data; DPRINTF(("ucycomstart(8): data =")); for (i = 0; i < len; i++) @@ -543,8 +543,8 @@ ucycomstart(struct tty *tp) "sc->sc_obuf[1] = %d\n", sc->sc_obuf[0], sc->sc_obuf[1])); #ifdef UCYCOM_DEBUG if (ucycomdebug > 10) { - u_int32_t i; - u_int8_t *d = data; + uint32_t i; + uint8_t *d = data; DPRINTF(("ucycomstart(32): data =")); for (i = 0; i < len; i++) @@ -576,10 +576,8 @@ ucycomstart(struct tty *tp) } #endif DPRINTFN(4,("ucycomstart: %d chars\n", len)); - usbd_setup_xfer(sc->sc_hdev.sc_parent->sc_oxfer, - sc->sc_hdev.sc_parent->sc_opipe, (usbd_private_handle)sc, - sc->sc_obuf, sc->sc_olen, 0 /* USBD_NO_COPY */, USBD_NO_TIMEOUT, - ucycomwritecb); + usbd_setup_xfer(sc->sc_hdev.sc_parent->sc_oxfer, sc, sc->sc_obuf, + sc->sc_olen, 0, USBD_NO_TIMEOUT, ucycomwritecb); /* What can we do on error? */ err = usbd_transfer(sc->sc_hdev.sc_parent->sc_oxfer); @@ -595,7 +593,7 @@ out: } Static void -ucycomwritecb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) +ucycomwritecb(struct usbd_xfer *xfer, void *p, usbd_status status) { struct ucycom_softc *sc = (struct ucycom_softc *)p; struct tty *tp = sc->sc_tty; @@ -647,12 +645,12 @@ ucycomparam(struct tty *tp, struct termios *t) if (t->c_ospeed < 0) { DPRINTF(("ucycomparam: c_ospeed < 0\n")); - return (EINVAL); + return EINVAL; } /* Check requested parameters. */ if (t->c_ispeed && t->c_ispeed != t->c_ospeed) - return (EINVAL); + return EINVAL; /* * For the console, always force CLOCAL and !HUPCL, so that the port @@ -670,7 +668,7 @@ ucycomparam(struct tty *tp, struct termios *t) */ if (tp->t_ospeed == t->c_ospeed && tp->t_cflag == t->c_cflag) - return (0); + return 0; /* XXX lcr = ISSET(sc->sc_lcr, LCR_SBREAK) | cflag2lcr(t->c_cflag); */ @@ -700,7 +698,7 @@ ucycomparam(struct tty *tp, struct termios *t) cfg |= UCYCOM_DATA_BITS_5; break; default: - return (EINVAL); + return EINVAL; } cfg |= ISSET(t->c_cflag, CSTOPB) ? UCYCOM_STOP_BITS_2 : UCYCOM_STOP_BITS_1; @@ -719,7 +717,7 @@ ucycomparam(struct tty *tp, struct termios *t) (void) (*tp->t_linesw->l_modem)(tp, 1 /* XXX carrier */ ); err = ucycom_configure(sc, baud, cfg); - return (err); + return err; } void @@ -739,10 +737,10 @@ ucycomread(dev_t dev, struct uio *uio, int flag) DPRINTF(("ucycomread: sc=%p, tp=%p, uio=%p, flag=%d\n", sc, tp, uio, flag)); if (sc->sc_dying) - return (EIO); + return EIO; err = ((*tp->t_linesw->l_read)(tp, uio, flag)); - return (err); + return err; } @@ -757,10 +755,10 @@ ucycomwrite(dev_t dev, struct uio *uio, int flag) DPRINTF(("ucycomwrite: sc=%p, tp=%p, uio=%p, flag=%d\n", sc, tp, uio, flag)); if (sc->sc_dying) - return (EIO); + return EIO; err = ((*tp->t_linesw->l_write)(tp, uio, flag)); - return (err); + return err; } struct tty * @@ -772,7 +770,7 @@ ucycomtty(dev_t dev) DPRINTF(("ucycomtty: sc=%p, tp=%p\n", sc, tp)); - return (tp); + return tp; } int @@ -785,17 +783,17 @@ ucycomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) int s; if (sc->sc_dying) - return (EIO); + return EIO; DPRINTF(("ucycomioctl: sc=%p, tp=%p, data=%p\n", sc, tp, data)); err = (*tp->t_linesw->l_ioctl)(tp, cmd, data, flag, l); if (err != EPASSTHROUGH) - return (err); + return err; err = ttioctl(tp, cmd, data, flag, l); if (err != EPASSTHROUGH) - return (err); + return err; err = 0; @@ -848,7 +846,7 @@ ucycomioctl(dev_t dev, u_long cmd, void *data, int flag, struct lwp *l) splx(s); - return (err); + return err; } int @@ -863,10 +861,10 @@ ucycompoll(dev_t dev, int events, struct lwp *l) events, l)); if (sc->sc_dying) - return (EIO); + return EIO; err = ((*tp->t_linesw->l_poll)(tp, events, l)); - return (err); + return err; } Static int @@ -895,7 +893,7 @@ ucycom_configure(struct ucycom_softc *sc, uint32_t baud, uint8_t cfg) #endif break; default: - return (EINVAL); + return EINVAL; } DPRINTF(("ucycom_configure: setting %d baud, %d-%c-%d (%d)\n", baud, @@ -955,7 +953,7 @@ ucycom_intr(struct uhidev *addr, void *ibuf, u_int len) #ifdef UCYCOM_DEBUG if (ucycomdebug > 5) { - u_int32_t i; + uint32_t i; if (n != 0) { DPRINTF(("ucycom_intr: ibuf[0..%d) =", n)); @@ -1040,7 +1038,7 @@ ucycom_to_tiocm(struct ucycom_softc *sc) if (ISSET(combits, UCYCOM_RI)) SET(ttybits, TIOCM_RI); - return (ttybits); + return ttybits; } Static void @@ -1133,5 +1131,5 @@ ucycom_cleanup(struct ucycom_softc *sc) uhidev_close(&sc->sc_hdev); if (obuf != NULL) - free (obuf, M_USBDEV); + kmem_free(obuf, sc->sc_olen); } diff --git a/sys/dev/usb/udl.c b/sys/dev/usb/udl.c index f5f61f597e4..991c24a0484 100644 --- a/sys/dev/usb/udl.c +++ b/sys/dev/usb/udl.c @@ -1,4 +1,4 @@ -/* $NetBSD: udl.c,v 1.13 2016/01/19 03:44:41 msaitoh Exp $ */ +/* $NetBSD: udl.c,v 1.14 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2009 FUKAUMI Naoki. @@ -53,7 +53,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: udl.c,v 1.13 2016/01/19 03:44:41 msaitoh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udl.c,v 1.14 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/device.h> @@ -158,8 +158,8 @@ static inline void udl_draw_line_comp(struct udl_softc *, uint16_t *, int, static int udl_cmd_send(struct udl_softc *); static void udl_cmd_send_async(struct udl_softc *); -static void udl_cmd_send_async_cb(usbd_xfer_handle, - usbd_private_handle, usbd_status); +static void udl_cmd_send_async_cb(struct usbd_xfer *, + void *, usbd_status); static int udl_ctrl_msg(struct udl_softc *, uint8_t, uint8_t, uint16_t, uint16_t, uint8_t *, uint16_t); @@ -338,7 +338,7 @@ udl_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - if (usb_lookup(udl_devs, uaa->vendor, uaa->product) != NULL) + if (usb_lookup(udl_devs, uaa->uaa_vendor, uaa->uaa_product) != NULL) return UMATCH_VENDOR_PRODUCT; return UMATCH_NONE; @@ -358,7 +358,7 @@ udl_attach(device_t parent, device_t self, void *aux) aprint_normal("\n"); sc->sc_dev = self; - sc->sc_udev = uaa->device; + sc->sc_udev = uaa->uaa_device; devinfop = usbd_devinfo_alloc(sc->sc_udev, 0); aprint_normal_dev(sc->sc_dev, "%s\n", devinfop); @@ -478,7 +478,6 @@ udl_detach(device_t self, int flags) */ if (sc->sc_tx_pipeh != NULL) { usbd_abort_pipe(sc->sc_tx_pipeh); - usbd_close_pipe(sc->sc_tx_pipeh); } /* @@ -487,6 +486,10 @@ udl_detach(device_t self, int flags) udl_cmdq_flush(sc); udl_cmdq_free(sc); + if (sc->sc_tx_pipeh != NULL) { + usbd_close_pipe(sc->sc_tx_pipeh); + } + cv_destroy(&sc->sc_cv); mutex_destroy(&sc->sc_mtx); @@ -838,20 +841,15 @@ udl_cmdq_alloc(struct udl_softc *sc) cmdq->cq_sc = sc; - cmdq->cq_xfer = usbd_alloc_xfer(sc->sc_udev); - if (cmdq->cq_xfer == NULL) { + int err = usbd_create_xfer(sc->sc_tx_pipeh, + UDL_CMD_BUFFER_SIZE, 0, 0, &cmdq->cq_xfer); + if (err) { aprint_error_dev(sc->sc_dev, "%s: can't allocate xfer handle!\n", __func__); goto error; } - cmdq->cq_buf = - usbd_alloc_buffer(cmdq->cq_xfer, UDL_CMD_BUFFER_SIZE); - if (cmdq->cq_buf == NULL) { - aprint_error_dev(sc->sc_dev, - "%s: can't allocate xfer buffer!\n", __func__); - goto error; - } + cmdq->cq_buf = usbd_get_buffer(cmdq->cq_xfer); TAILQ_INSERT_TAIL(&sc->sc_freecmd, cmdq, cq_chain); } @@ -873,7 +871,7 @@ udl_cmdq_free(struct udl_softc *sc) cmdq = &sc->sc_cmdq[i]; if (cmdq->cq_xfer != NULL) { - usbd_free_xfer(cmdq->cq_xfer); + usbd_destroy_xfer(cmdq->cq_xfer); cmdq->cq_xfer = NULL; cmdq->cq_buf = NULL; } @@ -1433,8 +1431,8 @@ udl_cmd_send(struct udl_softc *sc) len = UDL_CMD_BUFSIZE(sc); /* do xfer */ - error = usbd_bulk_transfer(cmdq->cq_xfer, sc->sc_tx_pipeh, - USBD_NO_COPY, USBD_NO_TIMEOUT, cmdq->cq_buf, &len, "udlcmds"); + error = usbd_bulk_transfer(cmdq->cq_xfer, sc->sc_tx_pipeh, 0, + USBD_NO_TIMEOUT, cmdq->cq_buf, &len); UDL_CMD_BUFINIT(sc); @@ -1485,8 +1483,8 @@ udl_cmd_send_async(struct udl_softc *sc) /* do xfer */ mutex_enter(&sc->sc_mtx); - usbd_setup_xfer(cmdq->cq_xfer, sc->sc_tx_pipeh, cmdq, cmdq->cq_buf, - len, USBD_NO_COPY, USBD_NO_TIMEOUT, udl_cmd_send_async_cb); + usbd_setup_xfer(cmdq->cq_xfer, cmdq, cmdq->cq_buf, + len, 0, USBD_NO_TIMEOUT, udl_cmd_send_async_cb); error = usbd_transfer(cmdq->cq_xfer); if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { aprint_error_dev(sc->sc_dev, "%s: %s!\n", __func__, @@ -1518,7 +1516,7 @@ udl_cmd_send_async(struct udl_softc *sc) } static void -udl_cmd_send_async_cb(usbd_xfer_handle xfer, usbd_private_handle priv, +udl_cmd_send_async_cb(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct udl_cmdq *cmdq = priv; diff --git a/sys/dev/usb/udl.h b/sys/dev/usb/udl.h index a0d9102bafe..9b4bbe73613 100644 --- a/sys/dev/usb/udl.h +++ b/sys/dev/usb/udl.h @@ -1,4 +1,4 @@ -/* $NetBSD: udl.h,v 1.1 2009/11/30 16:18:34 tsutsui Exp $ */ +/* $NetBSD: udl.h,v 1.2 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2009 FUKAUMI Naoki. @@ -68,7 +68,7 @@ struct udl_cmdq { TAILQ_ENTRY(udl_cmdq) cq_chain; struct udl_softc *cq_sc; - usbd_xfer_handle cq_xfer; + struct usbd_xfer *cq_xfer; uint8_t *cq_buf; }; @@ -77,9 +77,9 @@ struct udl_cmdq { */ struct udl_softc { device_t sc_dev; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; - usbd_pipe_handle sc_tx_pipeh; + struct usbd_device * sc_udev; + struct usbd_interface * sc_iface; + struct usbd_pipe * sc_tx_pipeh; struct udl_cmdq sc_cmdq[UDL_NCMDQ]; TAILQ_HEAD(udl_cmdq_head, udl_cmdq) sc_freecmd, diff --git a/sys/dev/usb/udsbr.c b/sys/dev/usb/udsbr.c index 187b02fbbb0..99b497a04e3 100644 --- a/sys/dev/usb/udsbr.c +++ b/sys/dev/usb/udsbr.c @@ -1,4 +1,4 @@ -/* $NetBSD: udsbr.c,v 1.22 2012/12/27 16:42:32 skrll Exp $ */ +/* $NetBSD: udsbr.c,v 1.23 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: udsbr.c,v 1.22 2012/12/27 16:42:32 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udsbr.c,v 1.23 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -79,23 +79,23 @@ const struct radio_hw_if udsbr_hw_if = { struct udsbr_softc { device_t sc_dev; - usbd_device_handle sc_udev; + struct usbd_device * sc_udev; char sc_mute; char sc_vol; - u_int32_t sc_freq; + uint32_t sc_freq; device_t sc_child; char sc_dying; }; -Static int udsbr_req(struct udsbr_softc *sc, int ureq, int value, - int index); -Static void udsbr_start(struct udsbr_softc *sc); -Static void udsbr_stop(struct udsbr_softc *sc); -Static void udsbr_setfreq(struct udsbr_softc *sc, int freq); -Static int udsbr_status(struct udsbr_softc *sc); +Static int udsbr_req(struct udsbr_softc *, int, int, + int); +Static void udsbr_start(struct udsbr_softc *); +Static void udsbr_stop(struct udsbr_softc *); +Static void udsbr_setfreq(struct udsbr_softc *, int); +Static int udsbr_status(struct udsbr_softc *); int udsbr_match(device_t, cfdata_t, void *); void udsbr_attach(device_t, device_t, void *); @@ -106,25 +106,25 @@ extern struct cfdriver udsbr_cd; CFATTACH_DECL2_NEW(udsbr, sizeof(struct udsbr_softc), udsbr_match, udsbr_attach, udsbr_detach, udsbr_activate, NULL, udsbr_childdet); -int +int udsbr_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; DPRINTFN(50,("udsbr_match\n")); - if (uaa->vendor != USB_VENDOR_CYPRESS || - uaa->product != USB_PRODUCT_CYPRESS_FMRADIO) - return (UMATCH_NONE); - return (UMATCH_VENDOR_PRODUCT); + if (uaa->uaa_vendor != USB_VENDOR_CYPRESS || + uaa->uaa_product != USB_PRODUCT_CYPRESS_FMRADIO) + return UMATCH_NONE; + return UMATCH_VENDOR_PRODUCT; } -void +void udsbr_attach(device_t parent, device_t self, void *aux) { struct udsbr_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; + struct usbd_device * dev = uaa->uaa_device; char *devinfop; usbd_status err; @@ -163,7 +163,7 @@ udsbr_childdet(device_t self, device_t child) { } -int +int udsbr_detach(device_t self, int flags) { struct udsbr_softc *sc = device_private(self); @@ -175,7 +175,7 @@ udsbr_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - return (rv); + return rv; } int @@ -231,14 +231,14 @@ void udsbr_setfreq(struct udsbr_softc *sc, int freq) { DPRINTF(("udsbr_setfreq: setfreq=%d\n", freq)); - /* - * Freq now is in Hz. We need to convert it to the frequency - * that the radio wants. This frequency is 10.7MHz above - * the actual frequency. We then need to convert to - * units of 12.5kHz. We add one to the IFM to make rounding - * easier. - */ - freq = (freq * 1000 + 10700001) / 12500; + /* + * Freq now is in Hz. We need to convert it to the frequency + * that the radio wants. This frequency is 10.7MHz above + * the actual frequency. We then need to convert to + * units of 12.5kHz. We add one to the IFM to make rounding + * easier. + */ + freq = (freq * 1000 + 10700001) / 12500; (void)udsbr_req(sc, 0x01, (freq >> 8) & 0xff, freq & 0xff); (void)udsbr_req(sc, 0x00, 0x0096, 0x00b7); usbd_delay_ms(sc->sc_udev, 240); /* wait for signal to settle */ @@ -247,7 +247,7 @@ udsbr_setfreq(struct udsbr_softc *sc, int freq) int udsbr_status(struct udsbr_softc *sc) { - return (udsbr_req(sc, 0x00, 0x0000, 0x0024)); + return udsbr_req(sc, 0x00, 0x0000, 0x0024); } @@ -264,7 +264,7 @@ udsbr_get_info(void *v, struct radio_info *ri) ri->freq = sc->sc_freq; ri->info = udsbr_status(sc) ? RADIO_INFO_STEREO : 0; - return (0); + return 0; } int @@ -282,5 +282,5 @@ udsbr_set_info(void *v, struct radio_info *ri) else udsbr_start(sc); - return (0); + return 0; } diff --git a/sys/dev/usb/udsir.c b/sys/dev/usb/udsir.c index 7017feef940..6bf6c13f6bd 100644 --- a/sys/dev/usb/udsir.c +++ b/sys/dev/usb/udsir.c @@ -1,4 +1,4 @@ -/* $NetBSD: udsir.c,v 1.1 2013/05/28 12:03:26 kiyohara Exp $ */ +/* $NetBSD: udsir.c,v 1.2 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -30,14 +30,14 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: udsir.c,v 1.1 2013/05/28 12:03:26 kiyohara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: udsir.c,v 1.2 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/device.h> #include <sys/errno.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/conf.h> #include <sys/file.h> #include <sys/poll.h> @@ -67,8 +67,8 @@ int udsirdebug = 0; struct udsir_softc { device_t sc_dev; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device *sc_udev; + struct usbd_interface *sc_iface; uint8_t *sc_ur_buf; /* Unencapsulated frame */ u_int sc_ur_framelen; @@ -77,8 +77,8 @@ struct udsir_softc { int sc_rd_maxpsz; size_t sc_rd_index; int sc_rd_addr; - usbd_pipe_handle sc_rd_pipe; - usbd_xfer_handle sc_rd_xfer; + struct usbd_pipe *sc_rd_pipe; + struct usbd_xfer *sc_rd_xfer; u_int sc_rd_count; int sc_rd_readinprogress; int sc_rd_expectdataticks; @@ -91,8 +91,8 @@ struct udsir_softc { int sc_wr_maxpsz; int sc_wr_addr; int sc_wr_stalewrite; - usbd_xfer_handle sc_wr_xfer; - usbd_pipe_handle sc_wr_pipe; + struct usbd_xfer *sc_wr_xfer; + struct usbd_pipe *sc_wr_pipe; struct selinfo sc_wr_sel; enum { @@ -143,7 +143,7 @@ static void udsir_dumpdata(uint8_t const *, size_t, char const *); #endif static int deframe_rd_ur(struct udsir_softc *); static void udsir_periodic(struct udsir_softc *); -static void udsir_rd_cb(usbd_xfer_handle, usbd_private_handle, usbd_status); +static void udsir_rd_cb(struct usbd_xfer *, void *, usbd_status); static usbd_status udsir_start_read(struct udsir_softc *); CFATTACH_DECL2_NEW(udsir, sizeof(struct udsir_softc), @@ -158,12 +158,12 @@ static struct irframe_methods const udsir_methods = { static int udsir_match(device_t parent, cfdata_t match, void *aux) { - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; DPRINTFN(50, ("udsir_match\n")); - if (uaa->vendor == USB_VENDOR_KINGSUN && - uaa->product == USB_PRODUCT_KINGSUN_IRDA) + if (uiaa->uiaa_vendor == USB_VENDOR_KINGSUN && + uiaa->uiaa_product == USB_PRODUCT_KINGSUN_IRDA) return UMATCH_VENDOR_PRODUCT; return UMATCH_NONE; @@ -173,9 +173,9 @@ static void udsir_attach(device_t parent, device_t self, void *aux) { struct udsir_softc *sc = device_private(self); - struct usbif_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface = uaa->iface; + struct usbif_attach_arg *uiaa = aux; + struct usbd_device *dev = uiaa->uiaa_device; + struct usbd_interface *iface = uiaa->uiaa_iface; char *devinfop; usb_endpoint_descriptor_t *ed; uint8_t epcount; @@ -257,11 +257,26 @@ udsir_detach(device_t self, int flags) /* Abort all pipes. Causes processes waiting for transfer to wake. */ if (sc->sc_rd_pipe != NULL) { usbd_abort_pipe(sc->sc_rd_pipe); + } + if (sc->sc_wr_pipe != NULL) { + usbd_abort_pipe(sc->sc_wr_pipe); + } + if (sc->sc_rd_xfer != NULL) { + usbd_destroy_xfer(sc->sc_rd_xfer); + sc->sc_rd_xfer = NULL; + sc->sc_rd_buf = NULL; + } + if (sc->sc_wr_xfer != NULL) { + usbd_destroy_xfer(sc->sc_wr_xfer); + sc->sc_wr_xfer = NULL; + sc->sc_wr_buf = NULL; + } + /* Close pipes. */ + if (sc->sc_rd_pipe != NULL) { usbd_close_pipe(sc->sc_rd_pipe); sc->sc_rd_pipe = NULL; } if (sc->sc_wr_pipe != NULL) { - usbd_abort_pipe(sc->sc_wr_pipe); usbd_close_pipe(sc->sc_wr_pipe); sc->sc_wr_pipe = NULL; } @@ -329,27 +344,20 @@ udsir_open(void *h, int flag, int mode, struct lwp *l) error = EIO; goto bad2; } - sc->sc_rd_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_rd_xfer == NULL) { - error = ENOMEM; - goto bad3; - } - sc->sc_wr_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_wr_xfer == NULL) { - error = ENOMEM; + error = usbd_create_xfer(sc->sc_rd_pipe, sc->sc_rd_maxpsz, + USBD_SHORT_XFER_OK, 0, &sc->sc_rd_xfer); + if (error) + goto bad3; + + error = usbd_create_xfer(sc->sc_wr_pipe, IRDA_MAX_FRAME_SIZE, + USBD_FORCE_SHORT_XFER, 0, &sc->sc_wr_xfer); + if (error) goto bad4; - } - sc->sc_rd_buf = usbd_alloc_buffer(sc->sc_rd_xfer, sc->sc_rd_maxpsz); - if (sc->sc_rd_buf == NULL) { - error = ENOMEM; - goto bad5; - } - sc->sc_wr_buf = usbd_alloc_buffer(sc->sc_wr_xfer, IRDA_MAX_FRAME_SIZE); - if (sc->sc_wr_buf == NULL) { - error = ENOMEM; - goto bad5; - } - sc->sc_ur_buf = malloc(IRDA_MAX_FRAME_SIZE, M_USBDEV, M_NOWAIT); + + sc->sc_rd_buf = usbd_get_buffer(sc->sc_rd_xfer); + sc->sc_wr_buf = usbd_get_buffer(sc->sc_wr_xfer); + + sc->sc_ur_buf = kmem_alloc(IRDA_MAX_FRAME_SIZE, KM_SLEEP); if (sc->sc_ur_buf == NULL) { error = ENOMEM; goto bad5; @@ -382,10 +390,10 @@ udsir_open(void *h, int flag, int mode, struct lwp *l) return 0; bad5: - usbd_free_xfer(sc->sc_wr_xfer); + usbd_destroy_xfer(sc->sc_wr_xfer); sc->sc_wr_xfer = NULL; bad4: - usbd_free_xfer(sc->sc_rd_xfer); + usbd_destroy_xfer(sc->sc_rd_xfer); sc->sc_rd_xfer = NULL; bad3: usbd_close_pipe(sc->sc_wr_pipe); @@ -417,26 +425,30 @@ udsir_close(void *h, int flag, int mode, struct lwp *l) if (sc->sc_rd_pipe != NULL) { usbd_abort_pipe(sc->sc_rd_pipe); - usbd_close_pipe(sc->sc_rd_pipe); - sc->sc_rd_pipe = NULL; } if (sc->sc_wr_pipe != NULL) { usbd_abort_pipe(sc->sc_wr_pipe); - usbd_close_pipe(sc->sc_wr_pipe); - sc->sc_wr_pipe = NULL; } if (sc->sc_rd_xfer != NULL) { - usbd_free_xfer(sc->sc_rd_xfer); + usbd_destroy_xfer(sc->sc_rd_xfer); sc->sc_rd_xfer = NULL; sc->sc_rd_buf = NULL; } if (sc->sc_wr_xfer != NULL) { - usbd_free_xfer(sc->sc_wr_xfer); + usbd_destroy_xfer(sc->sc_wr_xfer); sc->sc_wr_xfer = NULL; sc->sc_wr_buf = NULL; } + if (sc->sc_rd_pipe != NULL) { + usbd_close_pipe(sc->sc_rd_pipe); + sc->sc_rd_pipe = NULL; + } + if (sc->sc_wr_pipe != NULL) { + usbd_close_pipe(sc->sc_wr_pipe); + sc->sc_wr_pipe = NULL; + } if (sc->sc_ur_buf != NULL) { - free(sc->sc_ur_buf, M_USBDEV); + kmem_free(sc->sc_ur_buf, IRDA_MAX_FRAME_SIZE); sc->sc_ur_buf = NULL; } @@ -604,8 +616,8 @@ udsir_write(void *h, struct uio *uio, int flag) #endif err = usbd_intr_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - UDSIR_WR_TIMEOUT, wrbuf, &btlen, "udsiwr"); + USBD_FORCE_SHORT_XFER, UDSIR_WR_TIMEOUT, + wrbuf, &btlen); DPRINTFN(2, ("%s: err=%d\n", __func__, err)); if (err != USBD_NORMAL_COMPLETION) { if (err == USBD_INTERRUPTED) @@ -936,7 +948,7 @@ udsir_periodic(struct udsir_softc *sc) } static void -udsir_rd_cb(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) +udsir_rd_cb(struct usbd_xfer *xfer, void * priv, usbd_status status) { struct udsir_softc *sc = priv; uint32_t size; @@ -1044,9 +1056,8 @@ udsir_start_read(struct udsir_softc *sc) usbd_clear_endpoint_stall(sc->sc_rd_pipe); } - usbd_setup_xfer(sc->sc_rd_xfer, sc->sc_rd_pipe, sc, sc->sc_rd_buf, - sc->sc_rd_maxpsz, USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, udsir_rd_cb); + usbd_setup_xfer(sc->sc_rd_xfer, sc, sc->sc_rd_buf, sc->sc_rd_maxpsz, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, udsir_rd_cb); err = usbd_transfer(sc->sc_rd_xfer); if (err != USBD_IN_PROGRESS) { DPRINTFN(0, ("%s: err=%d\n", __func__, (int)err)); diff --git a/sys/dev/usb/uep.c b/sys/dev/usb/uep.c index 97d8e3f0dc7..b91db122eca 100644 --- a/sys/dev/usb/uep.c +++ b/sys/dev/usb/uep.c @@ -1,4 +1,4 @@ -/* $NetBSD: uep.c,v 1.19 2013/09/15 15:07:06 martin Exp $ */ +/* $NetBSD: uep.c,v 1.20 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2004 The NetBSD Foundation, Inc. @@ -33,12 +33,12 @@ * eGalax USB touchpanel controller driver. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uep.c,v 1.19 2013/09/15 15:07:06 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uep.c,v 1.20 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/device.h> #include <sys/ioctl.h> #include <sys/vnode.h> @@ -57,12 +57,12 @@ __KERNEL_RCSID(0, "$NetBSD: uep.c,v 1.19 2013/09/15 15:07:06 martin Exp $"); struct uep_softc { device_t sc_dev; - usbd_device_handle sc_udev; /* device */ - usbd_interface_handle sc_iface; /* interface */ + struct usbd_device *sc_udev; /* device */ + struct usbd_interface *sc_iface; /* interface */ int sc_iface_number; int sc_intr_number; /* interrupt number */ - usbd_pipe_handle sc_intr_pipe; /* interrupt pipe */ + struct usbd_pipe * sc_intr_pipe; /* interrupt pipe */ u_char *sc_ibuf; int sc_isize; @@ -81,7 +81,7 @@ static struct wsmouse_calibcoords default_calib = { .samplelen = WSMOUSE_CALIBCOORDS_RESET, }; -Static void uep_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void uep_intr(struct usbd_xfer *, void *, usbd_status); Static int uep_enable(void *); Static void uep_disable(void *); @@ -107,13 +107,13 @@ uep_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - if ((uaa->vendor == USB_VENDOR_EGALAX) && ( - (uaa->product == USB_PRODUCT_EGALAX_TPANEL) - || (uaa->product == USB_PRODUCT_EGALAX_TPANEL2))) + if ((uaa->uaa_vendor == USB_VENDOR_EGALAX) && ( + (uaa->uaa_product == USB_PRODUCT_EGALAX_TPANEL) + || (uaa->uaa_product == USB_PRODUCT_EGALAX_TPANEL2))) return UMATCH_VENDOR_PRODUCT; - if ((uaa->vendor == USB_VENDOR_EGALAX2) - && (uaa->product == USB_PRODUCT_EGALAX2_TPANEL)) + if ((uaa->uaa_vendor == USB_VENDOR_EGALAX2) + && (uaa->uaa_product == USB_PRODUCT_EGALAX2_TPANEL)) return UMATCH_VENDOR_PRODUCT; @@ -125,7 +125,7 @@ uep_attach(device_t parent, device_t self, void *aux) { struct uep_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; + struct usbd_device *dev = uaa->uaa_device; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; @@ -285,12 +285,12 @@ uep_enable(void *v) if (sc->sc_isize == 0) return 0; - sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK); + sc->sc_ibuf = kmem_alloc(sc->sc_isize, KM_SLEEP); err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_intr_number, USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc, sc->sc_ibuf, sc->sc_isize, uep_intr, USBD_DEFAULT_INTERVAL); if (err) { - free(sc->sc_ibuf, M_USBDEV); + kmem_free(sc->sc_ibuf, sc->sc_isize); sc->sc_intr_pipe = NULL; return EIO; } @@ -318,7 +318,7 @@ uep_disable(void *v) } if (sc->sc_ibuf != NULL) { - free(sc->sc_ibuf, M_USBDEV); + kmem_free(sc->sc_ibuf, sc->sc_isize); sc->sc_ibuf = NULL; } @@ -359,12 +359,12 @@ uep_ioctl(void *v, u_long cmd, void *data, int flag, struct lwp *l) } void -uep_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) +uep_intr(struct usbd_xfer *xfer, void *addr, usbd_status status) { struct uep_softc *sc = addr; u_char *p = sc->sc_ibuf; u_char msk; - u_int32_t len; + uint32_t len; int x = 0, y = 0, s; usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); diff --git a/sys/dev/usb/uftdi.c b/sys/dev/usb/uftdi.c index e93ad482aff..eeeebf3d08b 100644 --- a/sys/dev/usb/uftdi.c +++ b/sys/dev/usb/uftdi.c @@ -1,4 +1,4 @@ -/* $NetBSD: uftdi.c,v 1.60 2015/02/20 14:50:53 nonaka Exp $ */ +/* $NetBSD: uftdi.c,v 1.61 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uftdi.c,v 1.60 2015/02/20 14:50:53 nonaka Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uftdi.c,v 1.61 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -78,8 +78,8 @@ int uftdidebug = 0; struct uftdi_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; /* device */ - usbd_interface_handle sc_iface[UFTDI_MAX_PORTS]; /* interface */ + struct usbd_device * sc_udev; /* device */ + struct usbd_interface * sc_iface[UFTDI_MAX_PORTS]; /* interface */ enum uftdi_type sc_type; u_int sc_hdrlen; @@ -97,27 +97,27 @@ struct uftdi_softc { }; -Static void uftdi_get_status(void *, int portno, u_char *lsr, u_char *msr); +Static void uftdi_get_status(void *, int, u_char *, u_char *); Static void uftdi_set(void *, int, int, int); Static int uftdi_param(void *, int, struct termios *); -Static int uftdi_open(void *sc, int portno); -Static void uftdi_read(void *sc, int portno, u_char **ptr,u_int32_t *count); -Static void uftdi_write(void *sc, int portno, u_char *to, u_char *from, - u_int32_t *count); -Static void uftdi_break(void *sc, int portno, int onoff); +Static int uftdi_open(void *, int); +Static void uftdi_read(void *, int, u_char **, uint32_t *); +Static void uftdi_write(void *, int, u_char *, u_char *, + uint32_t *); +Static void uftdi_break(void *, int, int); struct ucom_methods uftdi_methods = { - uftdi_get_status, - uftdi_set, - uftdi_param, - NULL, - uftdi_open, - NULL, - uftdi_read, - uftdi_write, + .ucom_get_status = uftdi_get_status, + .ucom_set = uftdi_set, + .ucom_param = uftdi_param, + .ucom_ioctl = NULL, + .ucom_open = uftdi_open, + .ucom_close = NULL, + .ucom_read = uftdi_read, + .ucom_write = uftdi_write, }; -/* +/* * The devices default to UFTDI_TYPE_8U232AM. * Remember to update uftdi_attach() if it should be UFTDI_TYPE_SIO instead */ @@ -181,25 +181,25 @@ extern struct cfdriver uftdi_cd; CFATTACH_DECL2_NEW(uftdi, sizeof(struct uftdi_softc), uftdi_match, uftdi_attach, uftdi_detach, uftdi_activate, NULL, uftdi_childdet); -int +int uftdi_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; DPRINTFN(20,("uftdi: vendor=0x%x, product=0x%x\n", - uaa->vendor, uaa->product)); + uaa->uaa_vendor, uaa->uaa_product)); - return (uftdi_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return uftdi_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } -void +void uftdi_attach(device_t parent, device_t self, void *aux) { struct uftdi_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface; + struct usbd_device *dev = uaa->uaa_device; + struct usbd_interface *iface; usb_device_descriptor_t *ddesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; @@ -207,7 +207,7 @@ uftdi_attach(device_t parent, device_t self, void *aux) const char *devname = device_xname(self); int i,idx; usbd_status err; - struct ucom_attach_args uca; + struct ucom_attach_args ucaa; DPRINTFN(10,("\nuftdi_attach: sc=%p\n", sc)); @@ -231,8 +231,8 @@ uftdi_attach(device_t parent, device_t self, void *aux) sc->sc_numports = 1; sc->sc_type = UFTDI_TYPE_8U232AM; /* most devices are post-8U232AM */ sc->sc_hdrlen = 0; - if (uaa->vendor == USB_VENDOR_FTDI - && uaa->product == USB_PRODUCT_FTDI_SERIAL_8U100AX) { + if (uaa->uaa_vendor == USB_VENDOR_FTDI + && uaa->uaa_product == USB_PRODUCT_FTDI_SERIAL_8U100AX) { sc->sc_type = UFTDI_TYPE_SIO; sc->sc_hdrlen = 1; } @@ -267,8 +267,8 @@ uftdi_attach(device_t parent, device_t self, void *aux) sc->sc_iface[idx] = iface; - uca.bulkin = uca.bulkout = -1; - uca.ibufsize = uca.obufsize = 0; + ucaa.ucaa_bulkin = ucaa.ucaa_bulkout = -1; + ucaa.ucaa_ibufsize = ucaa.ucaa_obufsize = 0; for (i = 0; i < id->bNumEndpoints; i++) { int addr, dir, attr; ed = usbd_interface2endpoint_descriptor(iface, i); @@ -283,56 +283,56 @@ uftdi_attach(device_t parent, device_t self, void *aux) dir = UE_GET_DIR(ed->bEndpointAddress); attr = ed->bmAttributes & UE_XFERTYPE; if (dir == UE_DIR_IN && attr == UE_BULK) { - uca.bulkin = addr; - uca.ibufsize = UGETW(ed->wMaxPacketSize); - if (uca.ibufsize >= UFTDI_MAX_IBUFSIZE) - uca.ibufsize = UFTDI_MAX_IBUFSIZE; + ucaa.ucaa_bulkin = addr; + ucaa.ucaa_ibufsize = UGETW(ed->wMaxPacketSize); + if (ucaa.ucaa_ibufsize >= UFTDI_MAX_IBUFSIZE) + ucaa.ucaa_ibufsize = UFTDI_MAX_IBUFSIZE; } else if (dir == UE_DIR_OUT && attr == UE_BULK) { - uca.bulkout = addr; - uca.obufsize = UGETW(ed->wMaxPacketSize) + ucaa.ucaa_bulkout = addr; + ucaa.ucaa_obufsize = UGETW(ed->wMaxPacketSize) - sc->sc_hdrlen; - if (uca.obufsize >= UFTDI_MAX_OBUFSIZE) - uca.obufsize = UFTDI_MAX_OBUFSIZE; + if (ucaa.ucaa_obufsize >= UFTDI_MAX_OBUFSIZE) + ucaa.ucaa_obufsize = UFTDI_MAX_OBUFSIZE; /* Limit length if we have a 6-bit header. */ if ((sc->sc_hdrlen > 0) && - (uca.obufsize > UFTDIOBUFSIZE)) - uca.obufsize = UFTDIOBUFSIZE; + (ucaa.ucaa_obufsize > UFTDIOBUFSIZE)) + ucaa.ucaa_obufsize = UFTDIOBUFSIZE; } else { aprint_error_dev(self, "unexpected endpoint\n"); goto bad; } } - if (uca.bulkin == -1) { + if (ucaa.ucaa_bulkin == -1) { aprint_error_dev(self, "Could not find data bulk in\n"); goto bad; } - if (uca.bulkout == -1) { + if (ucaa.ucaa_bulkout == -1) { aprint_error_dev(self, "Could not find data bulk out\n"); goto bad; } - uca.portno = FTDI_PIT_SIOA + idx; - /* bulkin, bulkout set above */ - if (uca.ibufsize == 0) - uca.ibufsize = UFTDIIBUFSIZE; - uca.ibufsizepad = uca.ibufsize; - if (uca.obufsize == 0) - uca.obufsize = UFTDIOBUFSIZE - sc->sc_hdrlen; - uca.opkthdrlen = sc->sc_hdrlen; - uca.device = dev; - uca.iface = iface; - uca.methods = &uftdi_methods; - uca.arg = sc; - uca.info = NULL; + ucaa.ucaa_portno = FTDI_PIT_SIOA + idx; + /* ucaa_bulkin, ucaa_bulkout set above */ + if (ucaa.ucaa_ibufsize == 0) + ucaa.ucaa_ibufsize = UFTDIIBUFSIZE; + ucaa.ucaa_ibufsizepad = ucaa.ucaa_ibufsize; + if (ucaa.ucaa_obufsize == 0) + ucaa.ucaa_obufsize = UFTDIOBUFSIZE - sc->sc_hdrlen; + ucaa.ucaa_opkthdrlen = sc->sc_hdrlen; + ucaa.ucaa_device = dev; + ucaa.ucaa_iface = iface; + ucaa.ucaa_methods = &uftdi_methods; + ucaa.ucaa_arg = sc; + ucaa.ucaa_info = NULL; DPRINTF(("uftdi: in=0x%x out=0x%x isize=0x%x osize=0x%x\n", - uca.bulkin, uca.bulkout, - uca.ibufsize, uca.obufsize)); + ucaa.ucaa_bulkin, ucaa.ucaa_bulkout, + ucaa.ucaa_ibufsize, ucaa.ucaa_obufsize)); sc->sc_subdev[idx] = config_found_sm_loc(self, "ucombus", NULL, - &uca, ucomprint, ucomsubmatch); + &ucaa, ucomprint, ucomsubmatch); } usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, @@ -390,7 +390,7 @@ uftdi_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - return (0); + return 0; } Static int @@ -404,7 +404,7 @@ uftdi_open(void *vsc, int portno) DPRINTF(("uftdi_open: sc=%p\n", sc)); if (sc->sc_dying) - return (EIO); + return EIO; /* Perform a full reset on the device */ req.bmRequestType = UT_WRITE_VENDOR_DEVICE; @@ -414,7 +414,7 @@ uftdi_open(void *vsc, int portno) USETW(req.wLength, 0); err = usbd_do_request(sc->sc_udev, &req, NULL); if (err) - return (EIO); + return EIO; /* Set 9600 baud, 2 stop bits, no parity, 8 bits */ t.c_ospeed = 9600; @@ -429,13 +429,13 @@ uftdi_open(void *vsc, int portno) USETW(req.wLength, 0); err = usbd_do_request(sc->sc_udev, &req, NULL); if (err) - return (EIO); + return EIO; - return (0); + return 0; } Static void -uftdi_read(void *vsc, int portno, u_char **ptr, u_int32_t *count) +uftdi_read(void *vsc, int portno, u_char **ptr, uint32_t *count) { struct uftdi_softc *sc = vsc; u_char msr, lsr; @@ -467,7 +467,7 @@ uftdi_read(void *vsc, int portno, u_char **ptr, u_int32_t *count) } Static void -uftdi_write(void *vsc, int portno, u_char *to, u_char *from, u_int32_t *count) +uftdi_write(void *vsc, int portno, u_char *to, u_char *from, uint32_t *count) { struct uftdi_softc *sc = vsc; @@ -527,7 +527,7 @@ uftdi_param(void *vsc, int portno, struct termios *t) DPRINTF(("uftdi_param: sc=%p\n", sc)); if (sc->sc_dying) - return (EIO); + return EIO; req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = FTDI_SIO_SET_BITMODE; @@ -536,7 +536,7 @@ uftdi_param(void *vsc, int portno, struct termios *t) USETW(req.wLength, 0); err = usbd_do_request(sc->sc_udev, &req, NULL); if (err) - return (EIO); + return EIO; switch (sc->sc_type) { case UFTDI_TYPE_SIO: @@ -552,7 +552,7 @@ uftdi_param(void *vsc, int portno, struct termios *t) case 57600: rate = ftdi_sio_b57600; break; case 115200: rate = ftdi_sio_b115200; break; default: - return (EINVAL); + return EINVAL; } break; @@ -572,12 +572,12 @@ uftdi_param(void *vsc, int portno, struct termios *t) case 460800: rate = ftdi_8u232am_b460800; break; case 921600: rate = ftdi_8u232am_b921600; break; default: - return (EINVAL); + return EINVAL; } break; default: - return (EINVAL); + return EINVAL; } req.bmRequestType = UT_WRITE_VENDOR_DEVICE; req.bRequest = FTDI_SIO_SET_BAUD_RATE; @@ -589,7 +589,7 @@ uftdi_param(void *vsc, int portno, struct termios *t) UGETW(req.wValue), UGETW(req.wIndex), UGETW(req.wLength))); err = usbd_do_request(sc->sc_udev, &req, NULL); if (err) - return (EIO); + return EIO; if (ISSET(t->c_cflag, CSTOPB)) data = FTDI_SIO_SET_DATA_STOP_BITS_2; @@ -628,7 +628,7 @@ uftdi_param(void *vsc, int portno, struct termios *t) UGETW(req.wValue), UGETW(req.wIndex), UGETW(req.wLength))); err = usbd_do_request(sc->sc_udev, &req, NULL); if (err) - return (EIO); + return EIO; if (ISSET(t->c_cflag, CRTSCTS)) { flow = FTDI_SIO_RTS_CTS_HS; @@ -646,9 +646,9 @@ uftdi_param(void *vsc, int portno, struct termios *t) USETW(req.wLength, 0); err = usbd_do_request(sc->sc_udev, &req, NULL); if (err) - return (EIO); + return EIO; - return (0); + return 0; } void diff --git a/sys/dev/usb/uftdireg.h b/sys/dev/usb/uftdireg.h index fbf04a6e66f..d05627509c4 100644 --- a/sys/dev/usb/uftdireg.h +++ b/sys/dev/usb/uftdireg.h @@ -1,4 +1,4 @@ -/* $NetBSD: uftdireg.h,v 1.9 2015/07/28 12:27:55 rjs Exp $ */ +/* $NetBSD: uftdireg.h,v 1.10 2016/04/23 10:15:32 skrll Exp $ */ /* * Definitions for the FTDI USB Single Port Serial Converter - diff --git a/sys/dev/usb/ugen.c b/sys/dev/usb/ugen.c index 6bf3d5580a2..6659191856c 100644 --- a/sys/dev/usb/ugen.c +++ b/sys/dev/usb/ugen.c @@ -1,4 +1,4 @@ -/* $NetBSD: ugen.c,v 1.132 2016/03/13 07:01:43 skrll Exp $ */ +/* $NetBSD: ugen.c,v 1.133 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.132 2016/03/13 07:01:43 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.133 2016/04/23 10:15:32 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -47,7 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: ugen.c,v 1.132 2016/03/13 07:01:43 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/device.h> #include <sys/ioctl.h> #include <sys/conf.h> @@ -84,33 +84,33 @@ int ugendebug = 0; struct isoreq { struct ugen_endpoint *sce; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; void *dmabuf; - u_int16_t sizes[UGEN_NISORFRMS]; + uint16_t sizes[UGEN_NISORFRMS]; }; struct ugen_endpoint { struct ugen_softc *sc; usb_endpoint_descriptor_t *edesc; - usbd_interface_handle iface; + struct usbd_interface *iface; int state; #define UGEN_ASLP 0x02 /* waiting for data */ #define UGEN_SHORT_OK 0x04 /* short xfers are OK */ #define UGEN_BULK_RA 0x08 /* in bulk read-ahead mode */ #define UGEN_BULK_WB 0x10 /* in bulk write-behind mode */ #define UGEN_RA_WB_STOP 0x20 /* RA/WB xfer is stopped (buffer full/empty) */ - usbd_pipe_handle pipeh; + struct usbd_pipe *pipeh; struct clist q; u_char *ibuf; /* start of buffer (circular for isoc) */ u_char *fill; /* location for input (isoc) */ u_char *limit; /* end of circular buffer (isoc) */ u_char *cur; /* current read location (isoc) */ - u_int32_t timeout; - u_int32_t ra_wb_bufsize; /* requested size for RA/WB buffer */ - u_int32_t ra_wb_reqsize; /* requested xfer length for RA/WB */ - u_int32_t ra_wb_used; /* how much is in buffer */ - u_int32_t ra_wb_xferlen; /* current xfer length for RA/WB */ - usbd_xfer_handle ra_wb_xfer; + uint32_t timeout; + uint32_t ra_wb_bufsize; /* requested size for RA/WB buffer */ + uint32_t ra_wb_reqsize; /* requested xfer length for RA/WB */ + uint32_t ra_wb_used; /* how much is in buffer */ + uint32_t ra_wb_xferlen; /* current xfer length for RA/WB */ + struct usbd_xfer *ra_wb_xfer; struct isoreq isoreqs[UGEN_NISOREQS]; /* Keep these last; we don't overwrite them in ugen_set_config() */ #define UGEN_ENDPOINT_NONZERO_CRUFT offsetof(struct ugen_endpoint, rsel) @@ -120,7 +120,7 @@ struct ugen_endpoint { struct ugen_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; + struct usbd_device *sc_udev; kmutex_t sc_lock; kcondvar_t sc_detach_cv; @@ -158,23 +158,23 @@ const struct cdevsw ugen_cdevsw = { .d_flag = D_OTHER, }; -Static void ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, - usbd_status status); -Static void ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr, - usbd_status status); -Static void ugen_bulkra_intr(usbd_xfer_handle xfer, usbd_private_handle addr, - usbd_status status); -Static void ugen_bulkwb_intr(usbd_xfer_handle xfer, usbd_private_handle addr, - usbd_status status); +Static void ugenintr(struct usbd_xfer *, void *, + usbd_status); +Static void ugen_isoc_rintr(struct usbd_xfer *, void *, + usbd_status); +Static void ugen_bulkra_intr(struct usbd_xfer *, void *, + usbd_status); +Static void ugen_bulkwb_intr(struct usbd_xfer *, void *, + usbd_status); Static int ugen_do_read(struct ugen_softc *, int, struct uio *, int); Static int ugen_do_write(struct ugen_softc *, int, struct uio *, int); Static int ugen_do_ioctl(struct ugen_softc *, int, u_long, void *, int, struct lwp *); -Static int ugen_set_config(struct ugen_softc *sc, int configno); -Static usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *sc, - int index, int *lenp); +Static int ugen_set_config(struct ugen_softc *, int); +Static usb_config_descriptor_t *ugen_get_cdesc(struct ugen_softc *, + int, int *); Static usbd_status ugen_set_interface(struct ugen_softc *, int, int); -Static int ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx); +Static int ugen_get_alt_index(struct ugen_softc *, int); Static void ugen_clear_endpoints(struct ugen_softc *); #define UGENUNIT(n) ((minor(n) >> 4) & 0xf) @@ -203,11 +203,11 @@ ugen_match(device_t parent, cfdata_t match, void *aux) override = match->cf_flags & 1; if (override) - return (UMATCH_HIGHEST); - else if (uaa->usegeneric) - return (UMATCH_GENERIC); + return UMATCH_HIGHEST; + else if (uaa->uaa_usegeneric) + return UMATCH_GENERIC; else - return (UMATCH_NONE); + return UMATCH_NONE; } void @@ -215,7 +215,7 @@ ugen_attach(device_t parent, device_t self, void *aux) { struct ugen_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle udev; + struct usbd_device *udev; char *devinfop; usbd_status err; int i, dir, conf; @@ -223,15 +223,15 @@ ugen_attach(device_t parent, device_t self, void *aux) aprint_naive("\n"); aprint_normal("\n"); - mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_USB); + mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); cv_init(&sc->sc_detach_cv, "ugendet"); - devinfop = usbd_devinfo_alloc(uaa->device, 0); + devinfop = usbd_devinfo_alloc(uaa->uaa_device, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); sc->sc_dev = self; - sc->sc_udev = udev = uaa->device; + sc->sc_udev = udev = uaa->uaa_device; for (i = 0; i < USB_MAX_ENDPOINTS; i++) { for (dir = OUT; dir <= IN; dir++) { @@ -287,12 +287,12 @@ ugen_clear_endpoints(struct ugen_softc *sc) Static int ugen_set_config(struct ugen_softc *sc, int configno) { - usbd_device_handle dev = sc->sc_udev; + struct usbd_device *dev = sc->sc_udev; usb_config_descriptor_t *cdesc; - usbd_interface_handle iface; + struct usbd_interface *iface; usb_endpoint_descriptor_t *ed; struct ugen_endpoint *sce; - u_int8_t niface, nendpt; + uint8_t niface, nendpt; int ifaceno, endptno, endpt; usbd_status err; int dir; @@ -309,7 +309,7 @@ ugen_set_config(struct ugen_softc *sc, int configno) DPRINTFN(1, ("ugen_set_config: %s - endpoint %d is open\n", device_xname(sc->sc_dev), endptno)); - return (USBD_IN_USE); + return USBD_IN_USE; } /* Avoid setting the current value. */ @@ -317,12 +317,12 @@ ugen_set_config(struct ugen_softc *sc, int configno) if (!cdesc || cdesc->bConfigurationValue != configno) { err = usbd_set_config_no(dev, configno, 1); if (err) - return (err); + return err; } err = usbd_interface_count(dev, &niface); if (err) - return (err); + return err; ugen_clear_endpoints(sc); @@ -330,10 +330,10 @@ ugen_set_config(struct ugen_softc *sc, int configno) DPRINTFN(1,("ugen_set_config: ifaceno %d\n", ifaceno)); err = usbd_device2interface_handle(dev, ifaceno, &iface); if (err) - return (err); + return err; err = usbd_endpoint_count(iface, &nendpt); if (err) - return (err); + return err; for (endptno = 0; endptno < nendpt; endptno++) { ed = usbd_interface2endpoint_descriptor(iface,endptno); KASSERT(ed != NULL); @@ -349,7 +349,7 @@ ugen_set_config(struct ugen_softc *sc, int configno) sce->iface = iface; } } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } int @@ -362,8 +362,7 @@ ugenopen(dev_t dev, int flag, int mode, struct lwp *l) struct ugen_endpoint *sce; int dir, isize; usbd_status err; - usbd_xfer_handle xfer; - void *tbuf; + struct usbd_xfer *xfer; int i, j; sc = device_lookup_private(&ugen_cd, unit); @@ -374,23 +373,23 @@ ugenopen(dev_t dev, int flag, int mode, struct lwp *l) flag, mode, unit, endpt)); if (sc == NULL || sc->sc_dying) - return (ENXIO); + return ENXIO; /* The control endpoint allows multiple opens. */ if (endpt == USB_CONTROL_ENDPOINT) { sc->sc_is_open[USB_CONTROL_ENDPOINT] = 1; - return (0); + return 0; } if (sc->sc_is_open[endpt]) - return (EBUSY); + return EBUSY; /* Make sure there are pipes for all directions. */ for (dir = OUT; dir <= IN; dir++) { if (flag & (dir == OUT ? FWRITE : FREAD)) { sce = &sc->sc_endpoints[endpt][dir]; if (sce->edesc == NULL) - return (ENXIO); + return ENXIO; } } @@ -411,19 +410,19 @@ ugenopen(dev_t dev, int flag, int mode, struct lwp *l) err = usbd_open_pipe(sce->iface, edesc->bEndpointAddress, 0, &sce->pipeh); if (err) - return (EIO); + return EIO; break; } isize = UGETW(edesc->wMaxPacketSize); if (isize == 0) /* shouldn't happen */ - return (EINVAL); - sce->ibuf = malloc(isize, M_USBDEV, M_WAITOK); + return EINVAL; + sce->ibuf = kmem_alloc(isize, KM_SLEEP); DPRINTFN(5, ("ugenopen: intr endpt=%d,isize=%d\n", endpt, isize)); if (clalloc(&sce->q, UGEN_IBSIZE, 0) == -1) { - free(sce->ibuf, M_USBDEV); + kmem_free(sce->ibuf, isize); sce->ibuf = NULL; - return (ENOMEM); + return ENOMEM; } err = usbd_open_pipe_intr(sce->iface, edesc->bEndpointAddress, @@ -432,9 +431,9 @@ ugenopen(dev_t dev, int flag, int mode, struct lwp *l) USBD_DEFAULT_INTERVAL); if (err) { clfree(&sce->q); - free(sce->ibuf, M_USBDEV); + kmem_free(sce->ibuf, isize); sce->ibuf = NULL; - return (EIO); + return EIO; } DPRINTFN(5, ("ugenopen: interrupt open done\n")); break; @@ -442,7 +441,7 @@ ugenopen(dev_t dev, int flag, int mode, struct lwp *l) err = usbd_open_pipe(sce->iface, edesc->bEndpointAddress, 0, &sce->pipeh); if (err) - return (EIO); + return EIO; sce->ra_wb_bufsize = UGEN_BULK_RA_WB_BUFSIZE; /* * Use request size for non-RA/WB transfers @@ -452,12 +451,12 @@ ugenopen(dev_t dev, int flag, int mode, struct lwp *l) break; case UE_ISOCHRONOUS: if (dir == OUT) - return (EINVAL); + return EINVAL; isize = UGETW(edesc->wMaxPacketSize); if (isize == 0) /* shouldn't happen */ - return (EINVAL); - sce->ibuf = malloc(isize * UGEN_NISOFRAMES, - M_USBDEV, M_WAITOK); + return EINVAL; + sce->ibuf = kmem_alloc(isize * UGEN_NISOFRAMES, + KM_SLEEP); sce->cur = sce->fill = sce->ibuf; sce->limit = sce->ibuf + isize * UGEN_NISOFRAMES; DPRINTFN(5, ("ugenopen: isoc endpt=%d, isize=%d\n", @@ -465,49 +464,43 @@ ugenopen(dev_t dev, int flag, int mode, struct lwp *l) err = usbd_open_pipe(sce->iface, edesc->bEndpointAddress, 0, &sce->pipeh); if (err) { - free(sce->ibuf, M_USBDEV); + kmem_free(sce->ibuf, isize * UGEN_NISOFRAMES); sce->ibuf = NULL; - return (EIO); + return EIO; } for (i = 0; i < UGEN_NISOREQS; ++i) { sce->isoreqs[i].sce = sce; - xfer = usbd_alloc_xfer(sc->sc_udev); - if (xfer == 0) + err = usbd_create_xfer(sce->pipeh, + isize * UGEN_NISORFRMS, 0, UGEN_NISORFRMS, + &xfer); + if (err) goto bad; sce->isoreqs[i].xfer = xfer; - tbuf = usbd_alloc_buffer - (xfer, isize * UGEN_NISORFRMS); - if (tbuf == 0) { - i++; - goto bad; - } - sce->isoreqs[i].dmabuf = tbuf; + sce->isoreqs[i].dmabuf = usbd_get_buffer(xfer); for (j = 0; j < UGEN_NISORFRMS; ++j) sce->isoreqs[i].sizes[j] = isize; - usbd_setup_isoc_xfer - (xfer, sce->pipeh, &sce->isoreqs[i], - sce->isoreqs[i].sizes, - UGEN_NISORFRMS, USBD_NO_COPY, - ugen_isoc_rintr); + usbd_setup_isoc_xfer(xfer, &sce->isoreqs[i], + sce->isoreqs[i].sizes, UGEN_NISORFRMS, 0, + ugen_isoc_rintr); (void)usbd_transfer(xfer); } DPRINTFN(5, ("ugenopen: isoc open done\n")); break; bad: while (--i >= 0) /* implicit buffer free */ - usbd_free_xfer(sce->isoreqs[i].xfer); + usbd_destroy_xfer(sce->isoreqs[i].xfer); usbd_close_pipe(sce->pipeh); sce->pipeh = NULL; - free(sce->ibuf, M_USBDEV); + kmem_free(sce->ibuf, isize * UGEN_NISOFRAMES); sce->ibuf = NULL; - return (ENOMEM); + return ENOMEM; case UE_CONTROL: sce->timeout = USBD_DEFAULT_TIMEOUT; - return (EINVAL); + return EINVAL; } } sc->sc_is_open[endpt] = 1; - return (0); + return 0; } int @@ -529,14 +522,14 @@ ugenclose(dev_t dev, int flag, int mode, struct lwp *l) #ifdef DIAGNOSTIC if (!sc->sc_is_open[endpt]) { printf("ugenclose: not open\n"); - return (EINVAL); + return EINVAL; } #endif if (endpt == USB_CONTROL_ENDPOINT) { DPRINTFN(5, ("ugenclose: close control\n")); sc->sc_is_open[endpt] = 0; - return (0); + return 0; } for (dir = OUT; dir <= IN; dir++) { @@ -549,62 +542,67 @@ ugenclose(dev_t dev, int flag, int mode, struct lwp *l) endpt, dir, sce)); usbd_abort_pipe(sce->pipeh); - usbd_close_pipe(sce->pipeh); - sce->pipeh = NULL; + + int isize = UGETW(sce->edesc->wMaxPacketSize); + int msize = 0; switch (sce->edesc->bmAttributes & UE_XFERTYPE) { case UE_INTERRUPT: ndflush(&sce->q, sce->q.c_cc); clfree(&sce->q); + msize = isize; break; case UE_ISOCHRONOUS: for (i = 0; i < UGEN_NISOREQS; ++i) - usbd_free_xfer(sce->isoreqs[i].xfer); + usbd_destroy_xfer(sce->isoreqs[i].xfer); + msize = isize * UGEN_NISOFRAMES; break; case UE_BULK: - if (sce->state & (UGEN_BULK_RA | UGEN_BULK_WB)) - /* ibuf freed below */ - usbd_free_xfer(sce->ra_wb_xfer); + if (sce->state & (UGEN_BULK_RA | UGEN_BULK_WB)) { + usbd_destroy_xfer(sce->ra_wb_xfer); + msize = sce->ra_wb_bufsize; + } break; default: break; } - + usbd_close_pipe(sce->pipeh); + sce->pipeh = NULL; if (sce->ibuf != NULL) { - free(sce->ibuf, M_USBDEV); + kmem_free(sce->ibuf, msize); sce->ibuf = NULL; } } sc->sc_is_open[endpt] = 0; - return (0); + return 0; } Static int ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) { struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN]; - u_int32_t n, tn; - usbd_xfer_handle xfer; + uint32_t n, tn; + struct usbd_xfer *xfer; usbd_status err; int error = 0; DPRINTFN(5, ("%s: ugenread: %d\n", device_xname(sc->sc_dev), endpt)); if (sc->sc_dying) - return (EIO); + return EIO; if (endpt == USB_CONTROL_ENDPOINT) - return (ENODEV); + return ENODEV; #ifdef DIAGNOSTIC if (sce->edesc == NULL) { printf("ugenread: no edesc\n"); - return (EIO); + return EIO; } if (sce->pipeh == NULL) { printf("ugenread: no pipe\n"); - return (EIO); + return EIO; } #endif @@ -615,7 +613,7 @@ ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) while (sce->q.c_cc == 0) { if (flag & IO_NDELAY) { mutex_exit(&sc->sc_lock); - return (EWOULDBLOCK); + return EWOULDBLOCK; } sce->state |= UGEN_ASLP; DPRINTFN(5, ("ugenread: sleep on %p\n", sce)); @@ -657,7 +655,7 @@ ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) mutex_enter(&sc->sc_lock); if (sce->ra_wb_used == 0 && flag & IO_NDELAY) { mutex_exit(&sc->sc_lock); - return (EWOULDBLOCK); + return EWOULDBLOCK; } while (uio->uio_resid > 0 && !error) { while (sce->ra_wb_used == 0) { @@ -702,10 +700,9 @@ ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) sce->ra_wb_used < sce->limit - sce->ibuf) { n = (sce->limit - sce->ibuf) - sce->ra_wb_used; - usbd_setup_xfer(xfer, - sce->pipeh, sce, NULL, + usbd_setup_xfer(xfer, sce, NULL, min(n, sce->ra_wb_xferlen), - USBD_NO_COPY, USBD_NO_TIMEOUT, + 0, USBD_NO_TIMEOUT, ugen_bulkra_intr); sce->state &= ~UGEN_RA_WB_STOP; err = usbd_transfer(xfer); @@ -722,17 +719,17 @@ ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) mutex_exit(&sc->sc_lock); break; } - xfer = usbd_alloc_xfer(sc->sc_udev); - if (xfer == 0) - return (ENOMEM); + error = usbd_create_xfer(sce->pipeh, UGEN_BBSIZE, + sce->state & UGEN_SHORT_OK ? USBD_SHORT_XFER_OK : 0, + 0, &xfer); + if (error) + return error; while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n)); tn = n; - err = usbd_bulk_transfer( - xfer, sce->pipeh, - sce->state & UGEN_SHORT_OK ? - USBD_SHORT_XFER_OK : 0, - sce->timeout, sc->sc_buffer, &tn, "ugenrb"); + err = usbd_bulk_transfer(xfer, sce->pipeh, + sce->state & UGEN_SHORT_OK ? USBD_SHORT_XFER_OK : 0, + sce->timeout, sc->sc_buffer, &tn); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; @@ -747,14 +744,14 @@ ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) if (error || tn < n) break; } - usbd_free_xfer(xfer); + usbd_destroy_xfer(xfer); break; case UE_ISOCHRONOUS: mutex_enter(&sc->sc_lock); while (sce->cur == sce->fill) { if (flag & IO_NDELAY) { mutex_exit(&sc->sc_lock); - return (EWOULDBLOCK); + return EWOULDBLOCK; } sce->state |= UGEN_ASLP; /* "ugenri" */ @@ -791,9 +788,9 @@ ugen_do_read(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) default: - return (ENXIO); + return ENXIO; } - return (error); + return error; } int @@ -818,7 +815,7 @@ ugenread(dev_t dev, struct uio *uio, int flag) usb_detach_broadcast(sc->sc_dev, &sc->sc_detach_cv); mutex_exit(&sc->sc_lock); - return (error); + return error; } Static int @@ -826,29 +823,29 @@ ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, int flag) { struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT]; - u_int32_t n; + uint32_t n; int error = 0; - u_int32_t tn; + uint32_t tn; char *dbuf; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; usbd_status err; DPRINTFN(5, ("%s: ugenwrite: %d\n", device_xname(sc->sc_dev), endpt)); if (sc->sc_dying) - return (EIO); + return EIO; if (endpt == USB_CONTROL_ENDPOINT) - return (ENODEV); + return ENODEV; #ifdef DIAGNOSTIC if (sce->edesc == NULL) { printf("ugenwrite: no edesc\n"); - return (EIO); + return EIO; } if (sce->pipeh == NULL) { printf("ugenwrite: no pipe\n"); - return (EIO); + return EIO; } #endif @@ -863,7 +860,7 @@ ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, if (sce->ra_wb_used == sce->limit - sce->ibuf && flag & IO_NDELAY) { mutex_exit(&sc->sc_lock); - return (EWOULDBLOCK); + return EWOULDBLOCK; } while (uio->uio_resid > 0 && !error) { while (sce->ra_wb_used == @@ -917,9 +914,8 @@ ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, if (n - tn > 0) memcpy(dbuf, sce->ibuf, n - tn); - usbd_setup_xfer(xfer, - sce->pipeh, sce, NULL, n, - USBD_NO_COPY, USBD_NO_TIMEOUT, + usbd_setup_xfer(xfer, sce, NULL, n, + 0, USBD_NO_TIMEOUT, ugen_bulkwb_intr); sce->state &= ~UGEN_RA_WB_STOP; err = usbd_transfer(xfer); @@ -936,16 +932,18 @@ ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, mutex_exit(&sc->sc_lock); break; } - xfer = usbd_alloc_xfer(sc->sc_udev); - if (xfer == 0) - return (EIO); + error = usbd_create_xfer(sce->pipeh, UGEN_BBSIZE, + sce->state & UGEN_SHORT_OK ? USBD_SHORT_XFER_OK : 0, + 0, &xfer); + if (error) + return error; while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) { error = uiomove(sc->sc_buffer, n, uio); if (error) break; DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n)); - err = usbd_bulk_transfer(xfer, sce->pipeh, 0, - sce->timeout, sc->sc_buffer, &n,"ugenwb"); + err = usbd_bulk_transfer(xfer, sce->pipeh, 0, sce->timeout, + sc->sc_buffer, &n); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; @@ -956,12 +954,13 @@ ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, break; } } - usbd_free_xfer(xfer); + usbd_destroy_xfer(xfer); break; case UE_INTERRUPT: - xfer = usbd_alloc_xfer(sc->sc_udev); - if (xfer == 0) - return (EIO); + error = usbd_create_xfer(sce->pipeh, + UGETW(sce->edesc->wMaxPacketSize), 0, 0, &xfer); + if (error) + return error; while ((n = min(UGETW(sce->edesc->wMaxPacketSize), uio->uio_resid)) != 0) { error = uiomove(sc->sc_buffer, n, uio); @@ -969,7 +968,7 @@ ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, break; DPRINTFN(1, ("ugenwrite: transfer %d bytes\n", n)); err = usbd_intr_transfer(xfer, sce->pipeh, 0, - sce->timeout, sc->sc_buffer, &n, "ugenwi"); + sce->timeout, sc->sc_buffer, &n); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; @@ -980,12 +979,12 @@ ugen_do_write(struct ugen_softc *sc, int endpt, struct uio *uio, break; } } - usbd_free_xfer(xfer); + usbd_destroy_xfer(xfer); break; default: - return (ENXIO); + return ENXIO; } - return (error); + return error; } int @@ -1010,7 +1009,7 @@ ugenwrite(dev_t dev, struct uio *uio, int flag) usb_detach_broadcast(sc->sc_dev, &sc->sc_detach_cv); mutex_exit(&sc->sc_lock); - return (error); + return error; } int @@ -1079,15 +1078,15 @@ ugen_detach(device_t self, int flags) cv_destroy(&sc->sc_detach_cv); mutex_destroy(&sc->sc_lock); - return (0); + return 0; } Static void -ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) +ugenintr(struct usbd_xfer *xfer, void *addr, usbd_status status) { struct ugen_endpoint *sce = addr; struct ugen_softc *sc = sce->sc; - u_int32_t count; + uint32_t count; u_char *ibuf; if (status == USBD_CANCELLED) @@ -1121,13 +1120,13 @@ ugenintr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) } Static void -ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr, +ugen_isoc_rintr(struct usbd_xfer *xfer, void *addr, usbd_status status) { struct isoreq *req = addr; struct ugen_endpoint *sce = req->sce; struct ugen_softc *sc = sce->sc; - u_int32_t count, n; + uint32_t count, n; int i, isize; /* Return if we are aborting. */ @@ -1149,7 +1148,7 @@ ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr, isize = UGETW(sce->edesc->wMaxPacketSize); for (i = 0; i < UGEN_NISORFRMS; i++) { - u_int32_t actlen = req->sizes[i]; + uint32_t actlen = req->sizes[i]; char const *tbuf = (char const *)req->dmabuf + isize * i; /* copy data to buffer */ @@ -1168,8 +1167,8 @@ ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr, req->sizes[i] = isize; } - usbd_setup_isoc_xfer(xfer, sce->pipeh, req, req->sizes, UGEN_NISORFRMS, - USBD_NO_COPY, ugen_isoc_rintr); + usbd_setup_isoc_xfer(xfer, req, req->sizes, UGEN_NISORFRMS, 0, + ugen_isoc_rintr); (void)usbd_transfer(xfer); mutex_enter(&sc->sc_lock); @@ -1183,12 +1182,12 @@ ugen_isoc_rintr(usbd_xfer_handle xfer, usbd_private_handle addr, } Static void -ugen_bulkra_intr(usbd_xfer_handle xfer, usbd_private_handle addr, +ugen_bulkra_intr(struct usbd_xfer *xfer, void *addr, usbd_status status) { struct ugen_endpoint *sce = addr; struct ugen_softc *sc = sce->sc; - u_int32_t count, n; + uint32_t count, n; char const *tbuf; usbd_status err; @@ -1226,8 +1225,7 @@ ugen_bulkra_intr(usbd_xfer_handle xfer, usbd_private_handle addr, /* Set up the next request if necessary. */ n = (sce->limit - sce->ibuf) - sce->ra_wb_used; if (n > 0) { - usbd_setup_xfer(xfer, sce->pipeh, sce, NULL, - min(n, sce->ra_wb_xferlen), USBD_NO_COPY, + usbd_setup_xfer(xfer, sce, NULL, min(n, sce->ra_wb_xferlen), 0, USBD_NO_TIMEOUT, ugen_bulkra_intr); err = usbd_transfer(xfer); if (err != USBD_IN_PROGRESS) { @@ -1253,12 +1251,12 @@ ugen_bulkra_intr(usbd_xfer_handle xfer, usbd_private_handle addr, } Static void -ugen_bulkwb_intr(usbd_xfer_handle xfer, usbd_private_handle addr, +ugen_bulkwb_intr(struct usbd_xfer *xfer, void *addr, usbd_status status) { struct ugen_endpoint *sce = addr; struct ugen_softc *sc = sce->sc; - u_int32_t count, n; + uint32_t count, n; char *tbuf; usbd_status err; @@ -1295,8 +1293,8 @@ ugen_bulkwb_intr(usbd_xfer_handle xfer, usbd_private_handle addr, if (count - n > 0) memcpy(tbuf, sce->ibuf, count - n); - usbd_setup_xfer(xfer, sce->pipeh, sce, NULL, - count, USBD_NO_COPY, USBD_NO_TIMEOUT, ugen_bulkwb_intr); + usbd_setup_xfer(xfer, sce, NULL, count, 0, USBD_NO_TIMEOUT, + ugen_bulkwb_intr); err = usbd_transfer(xfer); if (err != USBD_IN_PROGRESS) { printf("usbd_bulkwb_intr: error=%d\n", err); @@ -1323,36 +1321,36 @@ ugen_bulkwb_intr(usbd_xfer_handle xfer, usbd_private_handle addr, Static usbd_status ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno) { - usbd_interface_handle iface; + struct usbd_interface *iface; usb_endpoint_descriptor_t *ed; usbd_status err; struct ugen_endpoint *sce; - u_int8_t niface, nendpt, endptno, endpt; + uint8_t niface, nendpt, endptno, endpt; int dir; DPRINTFN(15, ("ugen_set_interface %d %d\n", ifaceidx, altno)); err = usbd_interface_count(sc->sc_udev, &niface); if (err) - return (err); + return err; if (ifaceidx < 0 || ifaceidx >= niface) - return (USBD_INVAL); + return USBD_INVAL; err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); if (err) - return (err); + return err; err = usbd_endpoint_count(iface, &nendpt); if (err) - return (err); + return err; /* change setting */ err = usbd_set_interface(iface, altno); if (err) - return (err); + return err; err = usbd_endpoint_count(iface, &nendpt); if (err) - return (err); + return err; ugen_clear_endpoints(sc); @@ -1366,7 +1364,7 @@ ugen_set_interface(struct ugen_softc *sc, int ifaceidx, int altno) sce->edesc = ed; sce->iface = iface; } - return (0); + return 0; } /* Retrieve a complete descriptor for a certain device and index. */ @@ -1382,37 +1380,37 @@ ugen_get_cdesc(struct ugen_softc *sc, int index, int *lenp) len = UGETW(tdesc->wTotalLength); if (lenp) *lenp = len; - cdesc = malloc(len, M_TEMP, M_WAITOK); + cdesc = kmem_alloc(len, KM_SLEEP); memcpy(cdesc, tdesc, len); DPRINTFN(5,("ugen_get_cdesc: current, len=%d\n", len)); } else { err = usbd_get_config_desc(sc->sc_udev, index, &cdescr); if (err) - return (0); + 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); + cdesc = kmem_alloc(len, KM_SLEEP); err = usbd_get_config_desc_full(sc->sc_udev, index, cdesc, len); if (err) { - free(cdesc, M_TEMP); - return (0); + kmem_free(cdesc, len); + return 0; } } - return (cdesc); + return cdesc; } Static int ugen_get_alt_index(struct ugen_softc *sc, int ifaceidx) { - usbd_interface_handle iface; + struct usbd_interface *iface; usbd_status err; err = usbd_device2interface_handle(sc->sc_udev, ifaceidx, &iface); if (err) - return (-1); - return (usbd_get_interface_altindex(iface)); + return -1; + return usbd_get_interface_altindex(iface); } Static int @@ -1421,7 +1419,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, { struct ugen_endpoint *sce; usbd_status err; - usbd_interface_handle iface; + struct usbd_interface *iface; struct usb_config_desc *cd; usb_config_descriptor_t *cdesc; struct usb_interface_desc *id; @@ -1430,28 +1428,30 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, usb_endpoint_descriptor_t *edesc; struct usb_alt_interface *ai; struct usb_string_desc *si; - u_int8_t conf, alt; + uint8_t conf, alt; + int cdesclen; + int error; DPRINTFN(5, ("ugenioctl: cmd=%08lx\n", cmd)); if (sc->sc_dying) - return (EIO); + return EIO; switch (cmd) { case FIONBIO: /* All handled in the upper FS layer. */ - return (0); + return 0; case USB_SET_SHORT_XFER: if (endpt == USB_CONTROL_ENDPOINT) - return (EINVAL); + return EINVAL; /* This flag only affects read */ sce = &sc->sc_endpoints[endpt][IN]; if (sce == NULL || sce->pipeh == NULL) - return (EINVAL); + return EINVAL; if (*(int *)addr) sce->state |= UGEN_SHORT_OK; else sce->state &= ~UGEN_SHORT_OK; - return (0); + return 0; case USB_SET_TIMEOUT: sce = &sc->sc_endpoints[endpt][IN]; if (sce == NULL @@ -1459,111 +1459,89 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, input and output pipes isn't clear enough. || sce->pipeh == NULL */ ) - return (EINVAL); + return EINVAL; sce->timeout = *(int *)addr; - return (0); + return 0; case USB_SET_BULK_RA: if (endpt == USB_CONTROL_ENDPOINT) - return (EINVAL); + return EINVAL; sce = &sc->sc_endpoints[endpt][IN]; if (sce == NULL || sce->pipeh == NULL) - return (EINVAL); + return EINVAL; edesc = sce->edesc; if ((edesc->bmAttributes & UE_XFERTYPE) != UE_BULK) - return (EINVAL); + return EINVAL; if (*(int *)addr) { /* Only turn RA on if it's currently off. */ if (sce->state & UGEN_BULK_RA) - return (0); + return 0; if (sce->ra_wb_bufsize == 0 || sce->ra_wb_reqsize == 0) /* shouldn't happen */ - return (EINVAL); - sce->ra_wb_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sce->ra_wb_xfer == NULL) - return (ENOMEM); + return EINVAL; + error = usbd_create_xfer(sce->pipeh, + sce->ra_wb_reqsize, 0, 0, &sce->ra_wb_xfer); + if (error) + return error; sce->ra_wb_xferlen = sce->ra_wb_reqsize; - /* - * Set up a dmabuf because we reuse the xfer with - * the same (max) request length like isoc. - */ - if (usbd_alloc_buffer(sce->ra_wb_xfer, - sce->ra_wb_xferlen) == 0) { - usbd_free_xfer(sce->ra_wb_xfer); - return (ENOMEM); - } - sce->ibuf = malloc(sce->ra_wb_bufsize, - M_USBDEV, M_WAITOK); + sce->ibuf = kmem_alloc(sce->ra_wb_bufsize, KM_SLEEP); sce->fill = sce->cur = sce->ibuf; sce->limit = sce->ibuf + sce->ra_wb_bufsize; sce->ra_wb_used = 0; sce->state |= UGEN_BULK_RA; sce->state &= ~UGEN_RA_WB_STOP; /* Now start reading. */ - usbd_setup_xfer(sce->ra_wb_xfer, sce->pipeh, sce, - NULL, + usbd_setup_xfer(sce->ra_wb_xfer, sce, NULL, min(sce->ra_wb_xferlen, sce->ra_wb_bufsize), - USBD_NO_COPY, USBD_NO_TIMEOUT, - ugen_bulkra_intr); + 0, USBD_NO_TIMEOUT, ugen_bulkra_intr); err = usbd_transfer(sce->ra_wb_xfer); if (err != USBD_IN_PROGRESS) { sce->state &= ~UGEN_BULK_RA; - free(sce->ibuf, M_USBDEV); + kmem_free(sce->ibuf, sce->ra_wb_bufsize); sce->ibuf = NULL; - usbd_free_xfer(sce->ra_wb_xfer); - return (EIO); + usbd_destroy_xfer(sce->ra_wb_xfer); + return EIO; } } else { /* Only turn RA off if it's currently on. */ if (!(sce->state & UGEN_BULK_RA)) - return (0); + return 0; sce->state &= ~UGEN_BULK_RA; usbd_abort_pipe(sce->pipeh); - usbd_free_xfer(sce->ra_wb_xfer); + usbd_destroy_xfer(sce->ra_wb_xfer); /* * XXX Discard whatever's in the buffer, but we * should keep it around and drain the buffer * instead. */ - free(sce->ibuf, M_USBDEV); + kmem_free(sce->ibuf, sce->ra_wb_bufsize); sce->ibuf = NULL; } - return (0); + return 0; case USB_SET_BULK_WB: if (endpt == USB_CONTROL_ENDPOINT) - return (EINVAL); + return EINVAL; sce = &sc->sc_endpoints[endpt][OUT]; if (sce == NULL || sce->pipeh == NULL) - return (EINVAL); + return EINVAL; edesc = sce->edesc; if ((edesc->bmAttributes & UE_XFERTYPE) != UE_BULK) - return (EINVAL); + return EINVAL; if (*(int *)addr) { /* Only turn WB on if it's currently off. */ if (sce->state & UGEN_BULK_WB) - return (0); + return 0; if (sce->ra_wb_bufsize == 0 || sce->ra_wb_reqsize == 0) /* shouldn't happen */ - return (EINVAL); - sce->ra_wb_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sce->ra_wb_xfer == NULL) - return (ENOMEM); + return EINVAL; + error = usbd_create_xfer(sce->pipeh, sce->ra_wb_reqsize, + 0, 0, &sce->ra_wb_xfer); sce->ra_wb_xferlen = sce->ra_wb_reqsize; - /* - * Set up a dmabuf because we reuse the xfer with - * the same (max) request length like isoc. - */ - if (usbd_alloc_buffer(sce->ra_wb_xfer, - sce->ra_wb_xferlen) == 0) { - usbd_free_xfer(sce->ra_wb_xfer); - return (ENOMEM); - } - sce->ibuf = malloc(sce->ra_wb_bufsize, - M_USBDEV, M_WAITOK); + sce->ibuf = kmem_alloc(sce->ra_wb_bufsize, KM_SLEEP); sce->fill = sce->cur = sce->ibuf; sce->limit = sce->ibuf + sce->ra_wb_bufsize; sce->ra_wb_used = 0; @@ -1571,7 +1549,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, } else { /* Only turn WB off if it's currently on. */ if (!(sce->state & UGEN_BULK_WB)) - return (0); + return 0; sce->state &= ~UGEN_BULK_WB; /* @@ -1580,30 +1558,30 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, * drain the buffer instead. */ usbd_abort_pipe(sce->pipeh); - usbd_free_xfer(sce->ra_wb_xfer); - free(sce->ibuf, M_USBDEV); + usbd_destroy_xfer(sce->ra_wb_xfer); + kmem_free(sce->ibuf, sce->ra_wb_bufsize); sce->ibuf = NULL; } - return (0); + return 0; case USB_SET_BULK_RA_OPT: case USB_SET_BULK_WB_OPT: { struct usb_bulk_ra_wb_opt *opt; if (endpt == USB_CONTROL_ENDPOINT) - return (EINVAL); + return EINVAL; opt = (struct usb_bulk_ra_wb_opt *)addr; if (cmd == USB_SET_BULK_RA_OPT) sce = &sc->sc_endpoints[endpt][IN]; else sce = &sc->sc_endpoints[endpt][OUT]; if (sce == NULL || sce->pipeh == NULL) - return (EINVAL); + return EINVAL; if (opt->ra_wb_buffer_size < 1 || opt->ra_wb_buffer_size > UGEN_BULK_RA_WB_BUFMAX || opt->ra_wb_request_size < 1 || opt->ra_wb_request_size > opt->ra_wb_buffer_size) - return (EINVAL); + return EINVAL; /* * XXX These changes do not take effect until the * next time RA/WB mode is enabled but they ought to @@ -1611,14 +1589,14 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, */ sce->ra_wb_bufsize = opt->ra_wb_buffer_size; sce->ra_wb_reqsize = opt->ra_wb_request_size; - return (0); + return 0; } default: break; } if (endpt != USB_CONTROL_ENDPOINT) - return (EINVAL); + return EINVAL; switch (cmd) { #ifdef UGEN_DEBUG @@ -1629,20 +1607,20 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, case USB_GET_CONFIG: err = usbd_get_config(sc->sc_udev, &conf); if (err) - return (EIO); + return EIO; *(int *)addr = conf; break; case USB_SET_CONFIG: if (!(flag & FWRITE)) - return (EPERM); + return EPERM; err = ugen_set_config(sc, *(int *)addr); switch (err) { case USBD_NORMAL_COMPLETION: break; case USBD_IN_USE: - return (EBUSY); + return EBUSY; default: - return (EIO); + return EIO; } break; case USB_GET_ALTINTERFACE: @@ -1650,38 +1628,38 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, err = usbd_device2interface_handle(sc->sc_udev, ai->uai_interface_index, &iface); if (err) - return (EINVAL); + return EINVAL; idesc = usbd_get_interface_descriptor(iface); if (idesc == NULL) - return (EIO); + return EIO; ai->uai_alt_no = idesc->bAlternateSetting; break; case USB_SET_ALTINTERFACE: if (!(flag & FWRITE)) - return (EPERM); + return EPERM; ai = (struct usb_alt_interface *)addr; err = usbd_device2interface_handle(sc->sc_udev, ai->uai_interface_index, &iface); if (err) - return (EINVAL); + return EINVAL; err = ugen_set_interface(sc, ai->uai_interface_index, ai->uai_alt_no); if (err) - return (EINVAL); + return EINVAL; break; case USB_GET_NO_ALT: ai = (struct usb_alt_interface *)addr; - cdesc = ugen_get_cdesc(sc, ai->uai_config_index, 0); + cdesc = ugen_get_cdesc(sc, ai->uai_config_index, &cdesclen); if (cdesc == NULL) - return (EINVAL); + return EINVAL; idesc = usbd_find_idesc(cdesc, ai->uai_interface_index, 0); if (idesc == NULL) { - free(cdesc, M_TEMP); - return (EINVAL); + kmem_free(cdesc, cdesclen); + return EINVAL; } ai->uai_alt_no = usbd_get_no_alts(cdesc, idesc->bInterfaceNumber); - free(cdesc, M_TEMP); + kmem_free(cdesc, cdesclen); break; case USB_GET_DEVICE_DESC: *(usb_device_descriptor_t *)addr = @@ -1689,17 +1667,17 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, break; case USB_GET_CONFIG_DESC: cd = (struct usb_config_desc *)addr; - cdesc = ugen_get_cdesc(sc, cd->ucd_config_index, 0); + cdesc = ugen_get_cdesc(sc, cd->ucd_config_index, &cdesclen); if (cdesc == NULL) - return (EINVAL); + return EINVAL; cd->ucd_desc = *cdesc; - free(cdesc, M_TEMP); + kmem_free(cdesc, cdesclen); break; case USB_GET_INTERFACE_DESC: id = (struct usb_interface_desc *)addr; - cdesc = ugen_get_cdesc(sc, id->uid_config_index, 0); + cdesc = ugen_get_cdesc(sc, id->uid_config_index, &cdesclen); if (cdesc == NULL) - return (EINVAL); + return EINVAL; if (id->uid_config_index == USB_CURRENT_CONFIG_INDEX && id->uid_alt_index == USB_CURRENT_ALT_INDEX) alt = ugen_get_alt_index(sc, id->uid_interface_index); @@ -1707,17 +1685,17 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, alt = id->uid_alt_index; idesc = usbd_find_idesc(cdesc, id->uid_interface_index, alt); if (idesc == NULL) { - free(cdesc, M_TEMP); - return (EINVAL); + kmem_free(cdesc, cdesclen); + return EINVAL; } id->uid_desc = *idesc; - free(cdesc, M_TEMP); + kmem_free(cdesc, cdesclen); break; case USB_GET_ENDPOINT_DESC: ed = (struct usb_endpoint_desc *)addr; - cdesc = ugen_get_cdesc(sc, ed->ued_config_index, 0); + cdesc = ugen_get_cdesc(sc, ed->ued_config_index, &cdesclen); if (cdesc == NULL) - return (EINVAL); + return EINVAL; if (ed->ued_config_index == USB_CURRENT_CONFIG_INDEX && ed->ued_alt_index == USB_CURRENT_ALT_INDEX) alt = ugen_get_alt_index(sc, ed->ued_interface_index); @@ -1726,11 +1704,11 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, edesc = usbd_find_edesc(cdesc, ed->ued_interface_index, alt, ed->ued_endpoint_index); if (edesc == NULL) { - free(cdesc, M_TEMP); - return (EINVAL); + kmem_free(cdesc, cdesclen); + return EINVAL; } ed->ued_desc = *edesc; - free(cdesc, M_TEMP); + kmem_free(cdesc, cdesclen); break; case USB_GET_FULL_DESC: { @@ -1738,11 +1716,11 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, struct iovec iov; struct uio uio; struct usb_full_desc *fd = (struct usb_full_desc *)addr; - int error; - cdesc = ugen_get_cdesc(sc, fd->ufd_config_index, &len); + cdesc = ugen_get_cdesc(sc, fd->ufd_config_index, &cdesclen); if (cdesc == NULL) - return (EINVAL); + return EINVAL; + len = cdesclen; if (len > fd->ufd_size) len = fd->ufd_size; iov.iov_base = (void *)fd->ufd_data; @@ -1754,8 +1732,8 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, uio.uio_rw = UIO_READ; uio.uio_vmspace = l->l_proc->p_vmspace; error = uiomove((void *)cdesc, len, &uio); - free(cdesc, M_TEMP); - return (error); + kmem_free(cdesc, cdesclen); + return error; } case USB_GET_STRING_DESC: { int len; @@ -1763,7 +1741,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, err = usbd_get_string_desc(sc->sc_udev, si->usd_string_index, si->usd_language_id, &si->usd_desc, &len); if (err) - return (EINVAL); + return EINVAL; break; } case USB_DO_REQUEST: @@ -1774,10 +1752,11 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, struct uio uio; void *ptr = 0; usbd_status xerr; - int error = 0; + + error = 0; if (!(flag & FWRITE)) - return (EPERM); + return EPERM; /* Avoid requests that would damage the bus integrity. */ if ((ur->ucr_request.bmRequestType == UT_WRITE_DEVICE && ur->ucr_request.bRequest == UR_SET_ADDRESS) || @@ -1785,10 +1764,10 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, ur->ucr_request.bRequest == UR_SET_CONFIG) || (ur->ucr_request.bmRequestType == UT_WRITE_INTERFACE && ur->ucr_request.bRequest == UR_SET_INTERFACE)) - return (EINVAL); + return EINVAL; if (len < 0 || len > 32767) - return (EINVAL); + return EINVAL; if (len != 0) { iov.iov_base = (void *)ur->ucr_data; iov.iov_len = len; @@ -1800,7 +1779,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, ur->ucr_request.bmRequestType & UT_READ ? UIO_READ : UIO_WRITE; uio.uio_vmspace = l->l_proc->p_vmspace; - ptr = malloc(len, M_TEMP, M_WAITOK); + ptr = kmem_alloc(len, KM_SLEEP); if (uio.uio_rw == UIO_WRITE) { error = uiomove(ptr, len, &uio); if (error) @@ -1816,15 +1795,16 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, } if (len != 0) { if (uio.uio_rw == UIO_READ) { - error = uiomove(ptr, len, &uio); + size_t alen = min(len, ur->ucr_actlen); + error = uiomove(ptr, alen, &uio); if (error) goto ret; } } ret: if (ptr) - free(ptr, M_TEMP); - return (error); + kmem_free(ptr, len); + return error; } case USB_GET_DEVICEINFO: usbd_fill_deviceinfo(sc->sc_udev, @@ -1838,9 +1818,9 @@ ugen_do_ioctl(struct ugen_softc *sc, int endpt, u_long cmd, break; #endif default: - return (EINVAL); + return EINVAL; } - return (0); + return 0; } int @@ -1858,7 +1838,7 @@ ugenioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) error = ugen_do_ioctl(sc, endpt, cmd, addr, flag, l); if (--sc->sc_refcnt < 0) usb_detach_broadcast(sc->sc_dev, &sc->sc_detach_cv); - return (error); + return error; } int @@ -1873,7 +1853,7 @@ ugenpoll(dev_t dev, int events, struct lwp *l) return ENXIO; if (sc->sc_dying) - return (POLLHUP); + return POLLHUP; if (UGENENDPOINT(dev) == USB_CONTROL_ENDPOINT) return ENODEV; @@ -1881,16 +1861,16 @@ ugenpoll(dev_t dev, int events, struct lwp *l) sce_in = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; sce_out = &sc->sc_endpoints[UGENENDPOINT(dev)][OUT]; if (sce_in == NULL && sce_out == NULL) - return (POLLERR); + return POLLERR; #ifdef DIAGNOSTIC if (!sce_in->edesc && !sce_out->edesc) { printf("ugenpoll: no edesc\n"); - return (POLLERR); + return POLLERR; } /* It's possible to have only one pipe open. */ if (!sce_in->pipeh && !sce_out->pipeh) { printf("ugenpoll: no pipe\n"); - return (POLLERR); + return POLLERR; } #endif @@ -1957,7 +1937,7 @@ ugenpoll(dev_t dev, int events, struct lwp *l) mutex_exit(&sc->sc_lock); - return (revents); + return revents; } static void @@ -1977,7 +1957,7 @@ filt_ugenread_intr(struct knote *kn, long hint) struct ugen_endpoint *sce = kn->kn_hook; kn->kn_data = sce->q.c_cc; - return (kn->kn_data > 0); + return kn->kn_data > 0; } static int @@ -1986,7 +1966,7 @@ filt_ugenread_isoc(struct knote *kn, long hint) struct ugen_endpoint *sce = kn->kn_hook; if (sce->cur == sce->fill) - return (0); + return 0; if (sce->cur < sce->fill) kn->kn_data = sce->fill - sce->cur; @@ -1994,7 +1974,7 @@ filt_ugenread_isoc(struct knote *kn, long hint) kn->kn_data = (sce->limit - sce->cur) + (sce->fill - sce->ibuf); - return (1); + return 1; } static int @@ -2008,14 +1988,14 @@ filt_ugenread_bulk(struct knote *kn, long hint) * yield any data or a write will happen. * So, emulate "seltrue". */ - return (filt_seltrue(kn, hint)); + return filt_seltrue(kn, hint); if (sce->ra_wb_used == 0) - return (0); + return 0; kn->kn_data = sce->ra_wb_used; - return (1); + return 1; } static int @@ -2029,14 +2009,14 @@ filt_ugenwrite_bulk(struct knote *kn, long hint) * yield any data or a write will happen. * So, emulate "seltrue". */ - return (filt_seltrue(kn, hint)); + return filt_seltrue(kn, hint); if (sce->ra_wb_used == sce->limit - sce->ibuf) - return (0); + return 0; kn->kn_data = (sce->limit - sce->ibuf) - sce->ra_wb_used; - return (1); + return 1; } static const struct filterops ugenread_intr_filtops = @@ -2063,7 +2043,7 @@ ugenkqfilter(dev_t dev, struct knote *kn) return ENXIO; if (sc->sc_dying) - return (ENXIO); + return ENXIO; if (UGENENDPOINT(dev) == USB_CONTROL_ENDPOINT) return ENODEV; @@ -2072,7 +2052,7 @@ ugenkqfilter(dev_t dev, struct knote *kn) case EVFILT_READ: sce = &sc->sc_endpoints[UGENENDPOINT(dev)][IN]; if (sce == NULL) - return (EINVAL); + return EINVAL; klist = &sce->rsel.sel_klist; switch (sce->edesc->bmAttributes & UE_XFERTYPE) { @@ -2086,32 +2066,32 @@ ugenkqfilter(dev_t dev, struct knote *kn) kn->kn_fop = &ugenread_bulk_filtops; break; default: - return (EINVAL); + return EINVAL; } break; case EVFILT_WRITE: sce = &sc->sc_endpoints[UGENENDPOINT(dev)][OUT]; if (sce == NULL) - return (EINVAL); + return EINVAL; klist = &sce->rsel.sel_klist; switch (sce->edesc->bmAttributes & UE_XFERTYPE) { case UE_INTERRUPT: case UE_ISOCHRONOUS: /* XXX poll doesn't support this */ - return (EINVAL); + return EINVAL; case UE_BULK: kn->kn_fop = &ugenwrite_bulk_filtops; break; default: - return (EINVAL); + return EINVAL; } break; default: - return (EINVAL); + return EINVAL; } kn->kn_hook = sce; @@ -2120,5 +2100,5 @@ ugenkqfilter(dev_t dev, struct knote *kn) SLIST_INSERT_HEAD(klist, kn, kn_selnext); mutex_exit(&sc->sc_lock); - return (0); + return 0; } diff --git a/sys/dev/usb/ugensa.c b/sys/dev/usb/ugensa.c index 8e7136707cf..46b3780b1e5 100644 --- a/sys/dev/usb/ugensa.c +++ b/sys/dev/usb/ugensa.c @@ -1,4 +1,4 @@ -/* $NetBSD: ugensa.c,v 1.31 2013/08/03 16:04:30 soren Exp $ */ +/* $NetBSD: ugensa.c,v 1.32 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2004, 2005 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ugensa.c,v 1.31 2013/08/03 16:04:30 soren Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ugensa.c,v 1.32 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -61,8 +61,8 @@ int ugensadebug = 0; struct ugensa_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; /* device */ - usbd_interface_handle sc_iface; /* interface */ + struct usbd_device * sc_udev; /* device */ + struct usbd_interface * sc_iface; /* interface */ device_t sc_subdev; int sc_numcon; @@ -71,14 +71,14 @@ struct ugensa_softc { }; struct ucom_methods ugensa_methods = { - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + .ucom_get_status = NULL, + .ucom_set = NULL, + .ucom_param = NULL, + .ucom_ioctl = NULL, + .ucom_open = NULL, + .ucom_close = NULL, + .ucom_read = NULL, + .ucom_write = NULL, }; #define UGENSA_CONFIG_INDEX 0 @@ -87,7 +87,7 @@ struct ucom_methods ugensa_methods = { struct ugensa_type { struct usb_devno ugensa_dev; - u_int16_t ugensa_flags; + uint16_t ugensa_flags; #define UNTESTED 0x0001 }; @@ -104,8 +104,8 @@ static const struct ugensa_type ugensa_devs[] = { * to work in similar device drivers on other OSes: */ - {{ USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_ADU_500A }, UNTESTED }, - {{ USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_EXPRESSCARD }, UNTESTED }, + {{ USB_VENDOR_ANYDATA, USB_PRODUCT_ANYDATA_ADU_500A }, UNTESTED }, + {{ USB_VENDOR_NOVATEL2, USB_PRODUCT_NOVATEL2_EXPRESSCARD }, UNTESTED }, {{ USB_VENDOR_QUALCOMM, USB_PRODUCT_QUALCOMM_MSM_HSDPA }, UNTESTED }, {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD875 }, UNTESTED }, {{ USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM5625 }, UNTESTED }, @@ -122,31 +122,31 @@ extern struct cfdriver ugensa_cd; CFATTACH_DECL2_NEW(ugensa, sizeof(struct ugensa_softc), ugensa_match, ugensa_attach, ugensa_detach, ugensa_activate, NULL, ugensa_childdet); -int +int ugensa_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; DPRINTFN(20,("ugensa: vendor=0x%x, product=0x%x\n", - uaa->vendor, uaa->product)); + uaa->uaa_vendor, uaa->uaa_product)); - return (ugensa_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return ugensa_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } -void +void ugensa_attach(device_t parent, device_t self, void *aux) { struct ugensa_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface; + struct usbd_device *dev = uaa->uaa_device; + struct usbd_interface *iface; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devinfop; const char *devname = device_xname(self); usbd_status err; - struct ucom_attach_args uca; + struct ucom_attach_args ucaa; int i; DPRINTFN(10,("\nugensa_attach: sc=%p\n", sc)); @@ -175,7 +175,7 @@ ugensa_attach(device_t parent, device_t self, void *aux) goto bad; } - if (ugensa_lookup(uaa->vendor, uaa->product)->ugensa_flags & UNTESTED) + if (ugensa_lookup(uaa->uaa_vendor, uaa->uaa_product)->ugensa_flags & UNTESTED) aprint_normal_dev(self, "WARNING: This device is marked as " "untested. Please submit a report via send-pr(1).\n"); @@ -184,21 +184,21 @@ ugensa_attach(device_t parent, device_t self, void *aux) sc->sc_udev = dev; sc->sc_iface = iface; - uca.info = "Generic Serial Device"; - uca.ibufsize = UGENSA_BUFSIZE; - uca.obufsize = UGENSA_BUFSIZE; - uca.ibufsizepad = UGENSA_BUFSIZE; - uca.portno = UCOM_UNK_PORTNO; - uca.opkthdrlen = 0; - uca.device = dev; - uca.iface = iface; - uca.methods = &ugensa_methods; - uca.arg = sc; + ucaa.ucaa_info = "Generic Serial Device"; + ucaa.ucaa_ibufsize = UGENSA_BUFSIZE; + ucaa.ucaa_obufsize = UGENSA_BUFSIZE; + ucaa.ucaa_ibufsizepad = UGENSA_BUFSIZE; + ucaa.ucaa_portno = UCOM_UNK_PORTNO; + ucaa.ucaa_opkthdrlen = 0; + ucaa.ucaa_device = dev; + ucaa.ucaa_iface = iface; + ucaa.ucaa_methods = &ugensa_methods; + ucaa.ucaa_arg = sc; usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); - uca.bulkin = uca.bulkout = -1; + ucaa.ucaa_bulkin = ucaa.ucaa_bulkout = -1; for (i = 0; i < id->bNumEndpoints; i++) { int addr, dir, attr; @@ -214,30 +214,31 @@ ugensa_attach(device_t parent, device_t self, void *aux) dir = UE_GET_DIR(ed->bEndpointAddress); attr = ed->bmAttributes & UE_XFERTYPE; if (attr == UE_BULK) { - if (uca.bulkin == -1 && dir == UE_DIR_IN) { + if (ucaa.ucaa_bulkin == -1 && dir == UE_DIR_IN) { DPRINTF(("%s: Bulk in %d\n", devname, i)); - uca.bulkin = addr; + ucaa.ucaa_bulkin = addr; continue; } - if (uca.bulkout == -1 && dir == UE_DIR_OUT) { + if (ucaa.ucaa_bulkout == -1 && dir == UE_DIR_OUT) { DPRINTF(("%s: Bulk out %d\n", devname, i)); - uca.bulkout = addr; + ucaa.ucaa_bulkout = addr; continue; } } aprint_error_dev(self, "unexpected endpoint\n"); } - if (uca.bulkin == -1) { + if (ucaa.ucaa_bulkin == -1) { aprint_error_dev(self, "Could not find data bulk in\n"); goto bad; } - if (uca.bulkout == -1) { + if (ucaa.ucaa_bulkout == -1) { aprint_error_dev(self, "Could not find data bulk out\n"); goto bad; } - DPRINTF(("ugensa: in=0x%x out=0x%x\n", uca.bulkin, uca.bulkout)); - sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &uca, + DPRINTF(("ugensa: in=0x%x out=0x%x\n", ucaa.ucaa_bulkin, + ucaa.ucaa_bulkout)); + sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &ucaa, ucomprint, ucomsubmatch); if (!pmf_device_register(self, NULL, NULL)) @@ -275,7 +276,7 @@ ugensa_activate(device_t self, enum devact act) } } -int +int ugensa_detach(device_t self, int flags) { struct ugensa_softc *sc = device_private(self); @@ -292,5 +293,5 @@ ugensa_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - return (rv); + return rv; } diff --git a/sys/dev/usb/uhci.c b/sys/dev/usb/uhci.c index 5537fb80138..50bb30a7757 100644 --- a/sys/dev/usb/uhci.c +++ b/sys/dev/usb/uhci.c @@ -1,4 +1,4 @@ -/* $NetBSD: uhci.c,v 1.267 2016/03/13 07:01:43 skrll Exp $ */ +/* $NetBSD: uhci.c,v 1.268 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998, 2004, 2011, 2012 The NetBSD Foundation, Inc. @@ -42,19 +42,23 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.267 2016/03/13 07:01:43 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.268 2016/04/23 10:15:32 skrll Exp $"); + +#include "opt_usb.h" #include <sys/param.h> -#include <sys/systm.h> + +#include <sys/bus.h> +#include <sys/cpu.h> +#include <sys/device.h> #include <sys/kernel.h> #include <sys/kmem.h> -#include <sys/device.h> -#include <sys/select.h> -#include <sys/extent.h> +#include <sys/mutex.h> #include <sys/proc.h> #include <sys/queue.h> -#include <sys/bus.h> -#include <sys/cpu.h> +#include <sys/select.h> +#include <sys/sysctl.h> +#include <sys/systm.h> #include <machine/endian.h> @@ -62,27 +66,61 @@ __KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.267 2016/03/13 07:01:43 skrll Exp $"); #include <dev/usb/usbdi.h> #include <dev/usb/usbdivar.h> #include <dev/usb/usb_mem.h> -#include <dev/usb/usb_quirks.h> #include <dev/usb/uhcireg.h> #include <dev/usb/uhcivar.h> -#include <dev/usb/usbroothub_subr.h> +#include <dev/usb/usbroothub.h> +#include <dev/usb/usbhist.h> /* Use bandwidth reclamation for control transfers. Some devices choke on it. */ /*#define UHCI_CTL_LOOP */ - #ifdef UHCI_DEBUG uhci_softc_t *thesc; -#define DPRINTF(x) if (uhcidebug) printf x -#define DPRINTFN(n,x) if (uhcidebug>(n)) printf x -int uhcidebug = 0; int uhcinoloop = 0; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) #endif +#ifdef USB_DEBUG +#ifndef UHCI_DEBUG +#define uhcidebug 0 +#else +static int uhcidebug = 0; + +SYSCTL_SETUP(sysctl_hw_uhci_setup, "sysctl hw.uhci setup") +{ + int err; + const struct sysctlnode *rnode; + const struct sysctlnode *cnode; + + err = sysctl_createv(clog, 0, NULL, &rnode, + CTLFLAG_PERMANENT, CTLTYPE_NODE, "uhci", + SYSCTL_DESCR("uhci global controls"), + NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); + + if (err) + goto fail; + + /* control debugging printfs */ + err = sysctl_createv(clog, 0, &rnode, &cnode, + CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, + "debug", SYSCTL_DESCR("Enable debugging output"), + NULL, 0, &uhcidebug, sizeof(uhcidebug), CTL_CREATE, CTL_EOL); + if (err) + goto fail; + + return; +fail: + aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); +} + +#endif /* UHCI_DEBUG */ +#endif /* USB_DEBUG */ + +#define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(uhcidebug,1,FMT,A,B,C,D) +#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(uhcidebug,N,FMT,A,B,C,D) +#define UHCIHIST_FUNC() USBHIST_FUNC() +#define UHCIHIST_CALLED(name) USBHIST_CALLED(uhcidebug) + /* * The UHCI controller is little endian, so on big endian machines * the data stored in memory needs to be swapped. @@ -93,7 +131,7 @@ struct uhci_pipe { int nexttoggle; u_char aborting; - usbd_xfer_handle abortstart, abortend; + struct usbd_xfer *abortstart, abortend; /* Info needed for different pipe kinds. */ union { @@ -101,54 +139,61 @@ struct uhci_pipe { struct { uhci_soft_qh_t *sqh; usb_dma_t reqdma; - uhci_soft_td_t *setup, *stat; - u_int length; - } ctl; + uhci_soft_td_t *setup; + uhci_soft_td_t *stat; + } ctrl; /* Interrupt pipe */ struct { int npoll; - int isread; uhci_soft_qh_t **qhs; } intr; /* Bulk pipe */ struct { uhci_soft_qh_t *sqh; - u_int length; - int isread; } bulk; - /* Iso pipe */ - struct iso { + /* Isochronous pipe */ + struct isoc { uhci_soft_td_t **stds; int next, inuse; - } iso; - } u; + } isoc; + }; }; +typedef TAILQ_HEAD(ux_completeq, uhci_xfer) ux_completeq_t; + Static void uhci_globalreset(uhci_softc_t *); Static usbd_status uhci_portreset(uhci_softc_t*, int); Static void uhci_reset(uhci_softc_t *); -Static usbd_status uhci_run(uhci_softc_t *, int run, int locked); +Static usbd_status uhci_run(uhci_softc_t *, int, int); Static uhci_soft_td_t *uhci_alloc_std(uhci_softc_t *); Static void uhci_free_std(uhci_softc_t *, uhci_soft_td_t *); +Static void uhci_free_std_locked(uhci_softc_t *, uhci_soft_td_t *); Static uhci_soft_qh_t *uhci_alloc_sqh(uhci_softc_t *); Static void uhci_free_sqh(uhci_softc_t *, uhci_soft_qh_t *); #if 0 Static void uhci_enter_ctl_q(uhci_softc_t *, uhci_soft_qh_t *, - uhci_intr_info_t *); + uhci_intr_info_t *); Static void uhci_exit_ctl_q(uhci_softc_t *, uhci_soft_qh_t *); #endif -Static void uhci_free_std_chain(uhci_softc_t *, - uhci_soft_td_t *, uhci_soft_td_t *); -Static usbd_status uhci_alloc_std_chain(struct uhci_pipe *, - uhci_softc_t *, int, int, u_int16_t, usb_dma_t *, - uhci_soft_td_t **, uhci_soft_td_t **); +#if 0 +Static void uhci_free_std_chain(uhci_softc_t *, uhci_soft_td_t *, + uhci_soft_td_t *); +#endif +Static int uhci_alloc_std_chain(uhci_softc_t *, struct usbd_xfer *, + int, int, uhci_soft_td_t **); +Static void uhci_free_stds(uhci_softc_t *, struct uhci_xfer *); + +Static void uhci_reset_std_chain(uhci_softc_t *, struct usbd_xfer *, + int, int, int *, uhci_soft_td_t **); + Static void uhci_poll_hub(void *); -Static void uhci_waitintr(uhci_softc_t *, usbd_xfer_handle); -Static void uhci_check_intr(uhci_softc_t *, uhci_intr_info_t *); -Static void uhci_idone(uhci_intr_info_t *); +Static void uhci_waitintr(uhci_softc_t *, struct usbd_xfer *); +Static void uhci_check_intr(uhci_softc_t *, struct uhci_xfer *, + ux_completeq_t *); +Static void uhci_idone(struct uhci_xfer *, ux_completeq_t *); -Static void uhci_abort_xfer(usbd_xfer_handle, usbd_status status); +Static void uhci_abort_xfer(struct usbd_xfer *, usbd_status); Static void uhci_timeout(void *); Static void uhci_timeout_task(void *); @@ -158,71 +203,69 @@ Static void uhci_add_bulk(uhci_softc_t *, uhci_soft_qh_t *); Static void uhci_remove_ls_ctrl(uhci_softc_t *,uhci_soft_qh_t *); Static void uhci_remove_hs_ctrl(uhci_softc_t *,uhci_soft_qh_t *); Static void uhci_remove_bulk(uhci_softc_t *,uhci_soft_qh_t *); -Static void uhci_add_loop(uhci_softc_t *sc); -Static void uhci_rem_loop(uhci_softc_t *sc); +Static void uhci_add_loop(uhci_softc_t *); +Static void uhci_rem_loop(uhci_softc_t *); -Static usbd_status uhci_setup_isoc(usbd_pipe_handle pipe); -Static void uhci_device_isoc_enter(usbd_xfer_handle); +Static usbd_status uhci_setup_isoc(struct usbd_pipe *); -Static usbd_status uhci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t); -Static void uhci_freem(struct usbd_bus *, usb_dma_t *); - -Static usbd_xfer_handle uhci_allocx(struct usbd_bus *); -Static void uhci_freex(struct usbd_bus *, usbd_xfer_handle); +Static struct usbd_xfer * + uhci_allocx(struct usbd_bus *, unsigned int); +Static void uhci_freex(struct usbd_bus *, struct usbd_xfer *); Static void uhci_get_lock(struct usbd_bus *, kmutex_t **); - -Static usbd_status uhci_device_ctrl_transfer(usbd_xfer_handle); -Static usbd_status uhci_device_ctrl_start(usbd_xfer_handle); -Static void uhci_device_ctrl_abort(usbd_xfer_handle); -Static void uhci_device_ctrl_close(usbd_pipe_handle); -Static void uhci_device_ctrl_done(usbd_xfer_handle); - -Static usbd_status uhci_device_intr_transfer(usbd_xfer_handle); -Static usbd_status uhci_device_intr_start(usbd_xfer_handle); -Static void uhci_device_intr_abort(usbd_xfer_handle); -Static void uhci_device_intr_close(usbd_pipe_handle); -Static void uhci_device_intr_done(usbd_xfer_handle); - -Static usbd_status uhci_device_bulk_transfer(usbd_xfer_handle); -Static usbd_status uhci_device_bulk_start(usbd_xfer_handle); -Static void uhci_device_bulk_abort(usbd_xfer_handle); -Static void uhci_device_bulk_close(usbd_pipe_handle); -Static void uhci_device_bulk_done(usbd_xfer_handle); - -Static usbd_status uhci_device_isoc_transfer(usbd_xfer_handle); -Static usbd_status uhci_device_isoc_start(usbd_xfer_handle); -Static void uhci_device_isoc_abort(usbd_xfer_handle); -Static void uhci_device_isoc_close(usbd_pipe_handle); -Static void uhci_device_isoc_done(usbd_xfer_handle); - -Static usbd_status uhci_root_ctrl_transfer(usbd_xfer_handle); -Static usbd_status uhci_root_ctrl_start(usbd_xfer_handle); -Static void uhci_root_ctrl_abort(usbd_xfer_handle); -Static void uhci_root_ctrl_close(usbd_pipe_handle); -Static void uhci_root_ctrl_done(usbd_xfer_handle); - -Static usbd_status uhci_root_intr_transfer(usbd_xfer_handle); -Static usbd_status uhci_root_intr_start(usbd_xfer_handle); -Static void uhci_root_intr_abort(usbd_xfer_handle); -Static void uhci_root_intr_close(usbd_pipe_handle); -Static void uhci_root_intr_done(usbd_xfer_handle); - -Static usbd_status uhci_open(usbd_pipe_handle); +Static int uhci_roothub_ctrl(struct usbd_bus *, + usb_device_request_t *, void *, int); + +Static int uhci_device_ctrl_init(struct usbd_xfer *); +Static void uhci_device_ctrl_fini(struct usbd_xfer *); +Static usbd_status uhci_device_ctrl_transfer(struct usbd_xfer *); +Static usbd_status uhci_device_ctrl_start(struct usbd_xfer *); +Static void uhci_device_ctrl_abort(struct usbd_xfer *); +Static void uhci_device_ctrl_close(struct usbd_pipe *); +Static void uhci_device_ctrl_done(struct usbd_xfer *); + +Static int uhci_device_intr_init(struct usbd_xfer *); +Static void uhci_device_intr_fini(struct usbd_xfer *); +Static usbd_status uhci_device_intr_transfer(struct usbd_xfer *); +Static usbd_status uhci_device_intr_start(struct usbd_xfer *); +Static void uhci_device_intr_abort(struct usbd_xfer *); +Static void uhci_device_intr_close(struct usbd_pipe *); +Static void uhci_device_intr_done(struct usbd_xfer *); + +Static int uhci_device_bulk_init(struct usbd_xfer *); +Static void uhci_device_bulk_fini(struct usbd_xfer *); +Static usbd_status uhci_device_bulk_transfer(struct usbd_xfer *); +Static usbd_status uhci_device_bulk_start(struct usbd_xfer *); +Static void uhci_device_bulk_abort(struct usbd_xfer *); +Static void uhci_device_bulk_close(struct usbd_pipe *); +Static void uhci_device_bulk_done(struct usbd_xfer *); + +Static int uhci_device_isoc_init(struct usbd_xfer *); +Static void uhci_device_isoc_fini(struct usbd_xfer *); +Static usbd_status uhci_device_isoc_transfer(struct usbd_xfer *); +Static void uhci_device_isoc_abort(struct usbd_xfer *); +Static void uhci_device_isoc_close(struct usbd_pipe *); +Static void uhci_device_isoc_done(struct usbd_xfer *); + +Static usbd_status uhci_root_intr_transfer(struct usbd_xfer *); +Static usbd_status uhci_root_intr_start(struct usbd_xfer *); +Static void uhci_root_intr_abort(struct usbd_xfer *); +Static void uhci_root_intr_close(struct usbd_pipe *); +Static void uhci_root_intr_done(struct usbd_xfer *); + +Static usbd_status uhci_open(struct usbd_pipe *); Static void uhci_poll(struct usbd_bus *); Static void uhci_softintr(void *); -Static usbd_status uhci_device_request(usbd_xfer_handle xfer); - Static void uhci_add_intr(uhci_softc_t *, uhci_soft_qh_t *); Static void uhci_remove_intr(uhci_softc_t *, uhci_soft_qh_t *); -Static usbd_status uhci_device_setintr(uhci_softc_t *sc, - struct uhci_pipe *pipe, int ival); +Static usbd_status uhci_device_setintr(uhci_softc_t *, + struct uhci_pipe *, int); -Static void uhci_device_clear_toggle(usbd_pipe_handle pipe); -Static void uhci_noop(usbd_pipe_handle pipe); +Static void uhci_device_clear_toggle(struct usbd_pipe *); +Static void uhci_noop(struct usbd_pipe *); -static inline uhci_soft_qh_t *uhci_find_prev_qh(uhci_soft_qh_t *, - uhci_soft_qh_t *); +static inline uhci_soft_qh_t * + uhci_find_prev_qh(uhci_soft_qh_t *, uhci_soft_qh_t *); #ifdef UHCI_DEBUG Static void uhci_dump_all(uhci_softc_t *); @@ -231,7 +274,7 @@ Static void uhci_dump_qhs(uhci_soft_qh_t *); Static void uhci_dump_qh(uhci_soft_qh_t *); Static void uhci_dump_tds(uhci_soft_td_t *); Static void uhci_dump_td(uhci_soft_td_t *); -Static void uhci_dump_ii(uhci_intr_info_t *ii); +Static void uhci_dump_ii(struct uhci_xfer *); void uhci_dump(void); #endif @@ -246,6 +289,7 @@ void uhci_dump(void); #define UWRITE4(sc, r, x) \ do { UBARR(sc); bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)); \ } while (/*CONSTCOND*/0) + static __inline uint8_t UREAD1(uhci_softc_t *sc, bus_size_t r) { @@ -279,87 +323,87 @@ UREAD4(uhci_softc_t *sc, bus_size_t r) #define UHCI_CURFRAME(sc) (UREAD2(sc, UHCI_FRNUM) & UHCI_FRNUM_MASK) -#define UHCI_INTR_ENDPT 1 - const struct usbd_bus_methods uhci_bus_methods = { - .open_pipe = uhci_open, - .soft_intr = uhci_softintr, - .do_poll = uhci_poll, - .allocm = uhci_allocm, - .freem = uhci_freem, - .allocx = uhci_allocx, - .freex = uhci_freex, - .get_lock = uhci_get_lock, - .new_device = NULL, -}; - -const struct usbd_pipe_methods uhci_root_ctrl_methods = { - .transfer = uhci_root_ctrl_transfer, - .start = uhci_root_ctrl_start, - .abort = uhci_root_ctrl_abort, - .close = uhci_root_ctrl_close, - .cleartoggle = uhci_noop, - .done = uhci_root_ctrl_done, + .ubm_open = uhci_open, + .ubm_softint = uhci_softintr, + .ubm_dopoll = uhci_poll, + .ubm_allocx = uhci_allocx, + .ubm_freex = uhci_freex, + .ubm_getlock = uhci_get_lock, + .ubm_rhctrl = uhci_roothub_ctrl, }; const struct usbd_pipe_methods uhci_root_intr_methods = { - .transfer = uhci_root_intr_transfer, - .start = uhci_root_intr_start, - .abort = uhci_root_intr_abort, - .close = uhci_root_intr_close, - .cleartoggle = uhci_noop, - .done = uhci_root_intr_done, + .upm_transfer = uhci_root_intr_transfer, + .upm_start = uhci_root_intr_start, + .upm_abort = uhci_root_intr_abort, + .upm_close = uhci_root_intr_close, + .upm_cleartoggle = uhci_noop, + .upm_done = uhci_root_intr_done, }; const struct usbd_pipe_methods uhci_device_ctrl_methods = { - .transfer = uhci_device_ctrl_transfer, - .start = uhci_device_ctrl_start, - .abort = uhci_device_ctrl_abort, - .close = uhci_device_ctrl_close, - .cleartoggle = uhci_noop, - .done = uhci_device_ctrl_done, + .upm_init = uhci_device_ctrl_init, + .upm_fini = uhci_device_ctrl_fini, + .upm_transfer = uhci_device_ctrl_transfer, + .upm_start = uhci_device_ctrl_start, + .upm_abort = uhci_device_ctrl_abort, + .upm_close = uhci_device_ctrl_close, + .upm_cleartoggle = uhci_noop, + .upm_done = uhci_device_ctrl_done, }; const struct usbd_pipe_methods uhci_device_intr_methods = { - .transfer = uhci_device_intr_transfer, - .start = uhci_device_intr_start, - .abort = uhci_device_intr_abort, - .close = uhci_device_intr_close, - .cleartoggle = uhci_device_clear_toggle, - .done = uhci_device_intr_done, + .upm_init = uhci_device_intr_init, + .upm_fini = uhci_device_intr_fini, + .upm_transfer = uhci_device_intr_transfer, + .upm_start = uhci_device_intr_start, + .upm_abort = uhci_device_intr_abort, + .upm_close = uhci_device_intr_close, + .upm_cleartoggle = uhci_device_clear_toggle, + .upm_done = uhci_device_intr_done, }; const struct usbd_pipe_methods uhci_device_bulk_methods = { - .transfer = uhci_device_bulk_transfer, - .start = uhci_device_bulk_start, - .abort = uhci_device_bulk_abort, - .close = uhci_device_bulk_close, - .cleartoggle = uhci_device_clear_toggle, - .done = uhci_device_bulk_done, + .upm_init = uhci_device_bulk_init, + .upm_fini = uhci_device_bulk_fini, + .upm_transfer = uhci_device_bulk_transfer, + .upm_start = uhci_device_bulk_start, + .upm_abort = uhci_device_bulk_abort, + .upm_close = uhci_device_bulk_close, + .upm_cleartoggle = uhci_device_clear_toggle, + .upm_done = uhci_device_bulk_done, }; const struct usbd_pipe_methods uhci_device_isoc_methods = { - .transfer = uhci_device_isoc_transfer, - .start = uhci_device_isoc_start, - .abort = uhci_device_isoc_abort, - .close = uhci_device_isoc_close, - .cleartoggle = uhci_noop, - .done = uhci_device_isoc_done, + .upm_init = uhci_device_isoc_init, + .upm_fini = uhci_device_isoc_fini, + .upm_transfer = uhci_device_isoc_transfer, + .upm_abort = uhci_device_isoc_abort, + .upm_close = uhci_device_isoc_close, + .upm_cleartoggle = uhci_noop, + .upm_done = uhci_device_isoc_done, }; -#define uhci_add_intr_info(sc, ii) \ - LIST_INSERT_HEAD(&(sc)->sc_intrhead, (ii), list) -#define uhci_del_intr_info(ii) \ - do { \ - LIST_REMOVE((ii), list); \ - (ii)->list.le_prev = NULL; \ - } while (0) -#define uhci_active_intr_info(ii) ((ii)->list.le_prev != NULL) +static inline void +uhci_add_intr_list(uhci_softc_t *sc, struct uhci_xfer *ux) +{ + + TAILQ_INSERT_TAIL(&sc->sc_intrhead, ux, ux_list); +} + +static inline void +uhci_del_intr_list(uhci_softc_t *sc, struct uhci_xfer *ux) +{ + + TAILQ_REMOVE(&sc->sc_intrhead, ux, ux_list); +} static inline uhci_soft_qh_t * uhci_find_prev_qh(uhci_soft_qh_t *pqh, uhci_soft_qh_t *sqh) { - DPRINTFN(15,("uhci_find_prev_qh: pqh=%p sqh=%p\n", pqh, sqh)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(15, "pqh=%p sqh=%p", pqh, sqh, 0, 0); for (; pqh->hlink != sqh; pqh = pqh->hlink) { #if defined(DIAGNOSTIC) || defined(UHCI_DEBUG) @@ -368,12 +412,12 @@ uhci_find_prev_qh(uhci_soft_qh_t *pqh, uhci_soft_qh_t *sqh) sizeof(pqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); if (le32toh(pqh->qh.qh_hlink) & UHCI_PTR_T) { - printf("uhci_find_prev_qh: QH not found\n"); - return (NULL); + printf("%s: QH not found\n", __func__); + return NULL; } #endif } - return (pqh); + return pqh; } void @@ -384,7 +428,7 @@ uhci_globalreset(uhci_softc_t *sc) UHCICMD(sc, 0); /* do nothing */ } -usbd_status +int uhci_init(uhci_softc_t *sc) { usbd_status err; @@ -392,12 +436,12 @@ uhci_init(uhci_softc_t *sc) uhci_soft_qh_t *clsqh, *chsqh, *bsqh, *sqh, *lsqh; uhci_soft_td_t *std; - DPRINTFN(1,("uhci_init: start\n")); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); #ifdef UHCI_DEBUG thesc = sc; - if (uhcidebug > 2) + if (uhcidebug >= 2) uhci_dumpregs(sc); #endif @@ -407,19 +451,20 @@ uhci_init(uhci_softc_t *sc) uhci_globalreset(sc); /* reset the controller */ uhci_reset(sc); - usb_setup_reserve(sc->sc_dev, &sc->sc_dma_reserve, sc->sc_bus.dmatag, - USB_MEM_RESERVE); - /* Allocate and initialize real frame array. */ err = usb_allocmem(&sc->sc_bus, - UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t), - UHCI_FRAMELIST_ALIGN, &sc->sc_dma); + UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t), + UHCI_FRAMELIST_ALIGN, &sc->sc_dma); if (err) - return (err); + return err; sc->sc_pframes = KERNADDR(&sc->sc_dma, 0); UWRITE2(sc, UHCI_FRNUM, 0); /* set frame number to 0 */ UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0)); /* set frame list*/ + /* Initialise mutex early for uhci_alloc_* */ + mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); + mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB); + /* * Allocate a TD, inactive, that hangs from the last QH. * This is to avoid a bug in the PIIX that makes it run berserk @@ -427,7 +472,7 @@ uhci_init(uhci_softc_t *sc) */ std = uhci_alloc_std(sc); if (std == NULL) - return (USBD_NOMEM); + return ENOMEM; std->link.std = NULL; std->td.td_link = htole32(UHCI_PTR_T); std->td.td_status = htole32(0); /* inactive */ @@ -439,7 +484,7 @@ uhci_init(uhci_softc_t *sc) /* Allocate the dummy QH marking the end and used for looping the QHs.*/ lsqh = uhci_alloc_sqh(sc); if (lsqh == NULL) - return (USBD_NOMEM); + goto fail1; lsqh->hlink = NULL; lsqh->qh.qh_hlink = htole32(UHCI_PTR_T); /* end of QH chain */ lsqh->elink = std; @@ -451,7 +496,7 @@ uhci_init(uhci_softc_t *sc) /* Allocate the dummy QH where bulk traffic will be queued. */ bsqh = uhci_alloc_sqh(sc); if (bsqh == NULL) - return (USBD_NOMEM); + goto fail2; bsqh->hlink = lsqh; bsqh->qh.qh_hlink = htole32(lsqh->physaddr | UHCI_PTR_QH); bsqh->elink = NULL; @@ -463,7 +508,7 @@ uhci_init(uhci_softc_t *sc) /* Allocate dummy QH where high speed control traffic will be queued. */ chsqh = uhci_alloc_sqh(sc); if (chsqh == NULL) - return (USBD_NOMEM); + goto fail3; chsqh->hlink = bsqh; chsqh->qh.qh_hlink = htole32(bsqh->physaddr | UHCI_PTR_QH); chsqh->elink = NULL; @@ -475,7 +520,7 @@ uhci_init(uhci_softc_t *sc) /* Allocate dummy QH where control traffic will be queued. */ clsqh = uhci_alloc_sqh(sc); if (clsqh == NULL) - return (USBD_NOMEM); + goto fail4; clsqh->hlink = chsqh; clsqh->qh.qh_hlink = htole32(chsqh->physaddr | UHCI_PTR_QH); clsqh->elink = NULL; @@ -493,7 +538,7 @@ uhci_init(uhci_softc_t *sc) std = uhci_alloc_std(sc); sqh = uhci_alloc_sqh(sc); if (std == NULL || sqh == NULL) - return (USBD_NOMEM); + return USBD_NOMEM; std->link.sqh = sqh; std->td.td_link = htole32(sqh->physaddr | UHCI_PTR_QH); std->td.td_status = htole32(UHCI_TD_IOS); /* iso, inactive */ @@ -521,29 +566,39 @@ uhci_init(uhci_softc_t *sc) BUS_DMASYNC_PREWRITE); - LIST_INIT(&sc->sc_intrhead); + TAILQ_INIT(&sc->sc_intrhead); sc->sc_xferpool = pool_cache_init(sizeof(struct uhci_xfer), 0, 0, 0, "uhcixfer", NULL, IPL_USB, NULL, NULL, NULL); callout_init(&sc->sc_poll_handle, CALLOUT_MPSAFE); - mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); - mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB); cv_init(&sc->sc_softwake_cv, "uhciab"); /* Set up the bus struct. */ - sc->sc_bus.methods = &uhci_bus_methods; - sc->sc_bus.pipe_size = sizeof(struct uhci_pipe); + sc->sc_bus.ub_methods = &uhci_bus_methods; + sc->sc_bus.ub_pipesize = sizeof(struct uhci_pipe); + sc->sc_bus.ub_usedma = true; UHCICMD(sc, UHCI_CMD_MAXP); /* Assume 64 byte packets at frame end */ - DPRINTFN(1,("uhci_init: enabling\n")); + DPRINTF("Enabling...", 0, 0, 0, 0); - err = uhci_run(sc, 1, 0); /* and here we go... */ + err = uhci_run(sc, 1, 0); /* and here we go... */ UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */ return err; + +fail4: + uhci_free_sqh(sc, chsqh); +fail3: + uhci_free_sqh(sc, lsqh); +fail2: + uhci_free_sqh(sc, lsqh); +fail1: + uhci_free_std(sc, std); + + return ENOMEM; } int @@ -578,7 +633,7 @@ uhci_detach(struct uhci_softc *sc, int flags) rv = config_detach(sc->sc_child, flags); if (rv != 0) - return (rv); + return rv; callout_halt(&sc->sc_poll_handle, NULL); callout_destroy(&sc->sc_poll_handle); @@ -592,89 +647,39 @@ uhci_detach(struct uhci_softc *sc, int flags) /* XXX free other data structures XXX */ - return (rv); -} - -usbd_status -uhci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size) -{ - struct uhci_softc *sc = bus->hci_private; - usbd_status status; - u_int32_t n; - - /* - * XXX - * Since we are allocating a buffer we can assume that we will - * need TDs for it. Since we don't want to allocate those from - * an interrupt context, we allocate them here and free them again. - * This is no guarantee that we'll get the TDs next time... - */ - n = size / 8; - if (n > 16) { - u_int32_t i; - uhci_soft_td_t **stds; - - DPRINTF(("uhci_allocm: get %d TDs\n", n)); - stds = kmem_alloc(sizeof(uhci_soft_td_t *) * n, KM_SLEEP); - if (!stds) - return USBD_NOMEM; - for (i = 0; i < n; i++) - stds[i] = uhci_alloc_std(sc); - for (i = 0; i < n; i++) - if (stds[i] != NULL) - uhci_free_std(sc, stds[i]); - kmem_free(stds, sizeof(uhci_soft_td_t *) * n); - } - - status = usb_allocmem(&sc->sc_bus, size, 0, dma); - if (status == USBD_NOMEM) - status = usb_reserve_allocm(&sc->sc_dma_reserve, dma, size); - return status; + return rv; } -void -uhci_freem(struct usbd_bus *bus, usb_dma_t *dma) +struct usbd_xfer * +uhci_allocx(struct usbd_bus *bus, unsigned int nframes) { - if (dma->block->flags & USB_DMA_RESERVE) { - usb_reserve_freem(&((struct uhci_softc *)bus)->sc_dma_reserve, - dma); - return; - } - usb_freemem(&((struct uhci_softc *)bus)->sc_bus, dma); -} - -usbd_xfer_handle -uhci_allocx(struct usbd_bus *bus) -{ - struct uhci_softc *sc = bus->hci_private; - usbd_xfer_handle xfer; + struct uhci_softc *sc = UHCI_BUS2SC(bus); + struct usbd_xfer *xfer; xfer = pool_cache_get(sc->sc_xferpool, PR_NOWAIT); if (xfer != NULL) { memset(xfer, 0, sizeof(struct uhci_xfer)); - UXFER(xfer)->iinfo.sc = sc; + #ifdef DIAGNOSTIC - UXFER(xfer)->iinfo.isdone = 1; - xfer->busy_free = XFER_BUSY; + struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer); + uxfer->ux_isdone = true; + xfer->ux_state = XFER_BUSY; #endif } - return (xfer); + return xfer; } void -uhci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) +uhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) { - struct uhci_softc *sc = bus->hci_private; + struct uhci_softc *sc = UHCI_BUS2SC(bus); + struct uhci_xfer *uxfer __diagused = UHCI_XFER2UXFER(xfer); + KASSERTMSG(xfer->ux_state == XFER_BUSY, "xfer %p state %d\n", xfer, + xfer->ux_state); + KASSERTMSG(uxfer->ux_isdone, "xfer %p not done\n", xfer); #ifdef DIAGNOSTIC - if (xfer->busy_free != XFER_BUSY) { - printf("uhci_freex: xfer=%p not busy, 0x%08x\n", xfer, - xfer->busy_free); - } - xfer->busy_free = XFER_FREE; - if (!UXFER(xfer)->iinfo.isdone) { - printf("uhci_freex: !isdone\n"); - } + xfer->ux_state = XFER_FREE; #endif pool_cache_put(sc->sc_xferpool, xfer); } @@ -682,7 +687,7 @@ uhci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) Static void uhci_get_lock(struct usbd_bus *bus, kmutex_t **lock) { - struct uhci_softc *sc = bus->hci_private; + struct uhci_softc *sc = UHCI_BUS2SC(bus); *lock = &sc->sc_lock; } @@ -704,7 +709,7 @@ uhci_resume(device_t dv, const pmf_qual_t *qual) mutex_spin_enter(&sc->sc_intr_lock); cmd = UREAD2(sc, UHCI_CMD); - sc->sc_bus.use_polling++; + sc->sc_bus.ub_usepolling++; UWRITE2(sc, UHCI_INTR, 0); uhci_globalreset(sc); uhci_reset(sc); @@ -724,12 +729,12 @@ uhci_resume(device_t dv, const pmf_qual_t *qual) UHCICMD(sc, UHCI_CMD_MAXP); uhci_run(sc, 1, 1); /* and start traffic again */ usb_delay_ms_locked(&sc->sc_bus, USB_RESUME_RECOVERY, &sc->sc_intr_lock); - sc->sc_bus.use_polling--; + sc->sc_bus.ub_usepolling--; if (sc->sc_intr_xfer != NULL) callout_reset(&sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub, sc->sc_intr_xfer); #ifdef UHCI_DEBUG - if (uhcidebug > 2) + if (uhcidebug >= 2) uhci_dumpregs(sc); #endif @@ -750,13 +755,13 @@ uhci_suspend(device_t dv, const pmf_qual_t *qual) cmd = UREAD2(sc, UHCI_CMD); #ifdef UHCI_DEBUG - if (uhcidebug > 2) + if (uhcidebug >= 2) uhci_dumpregs(sc); #endif if (sc->sc_intr_xfer != NULL) callout_stop(&sc->sc_poll_handle); sc->sc_suspend = PWR_SUSPEND; - sc->sc_bus.use_polling++; + sc->sc_bus.ub_usepolling++; uhci_run(sc, 0, 1); /* stop the controller */ cmd &= ~UHCI_CMD_RS; @@ -769,7 +774,7 @@ uhci_suspend(device_t dv, const pmf_qual_t *qual) UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter suspend */ usb_delay_ms_locked(&sc->sc_bus, USB_RESUME_WAIT, &sc->sc_intr_lock); - sc->sc_bus.use_polling--; + sc->sc_bus.ub_usepolling--; mutex_spin_exit(&sc->sc_intr_lock); @@ -780,63 +785,68 @@ uhci_suspend(device_t dv, const pmf_qual_t *qual) Static void uhci_dumpregs(uhci_softc_t *sc) { - DPRINTFN(-1,("%s regs: cmd=%04x, sts=%04x, intr=%04x, frnum=%04x, " - "flbase=%08x, sof=%04x, portsc1=%04x, portsc2=%04x\n", - device_xname(sc->sc_dev), - UREAD2(sc, UHCI_CMD), - UREAD2(sc, UHCI_STS), - UREAD2(sc, UHCI_INTR), - UREAD2(sc, UHCI_FRNUM), - UREAD4(sc, UHCI_FLBASEADDR), - UREAD1(sc, UHCI_SOF), - UREAD2(sc, UHCI_PORTSC1), - UREAD2(sc, UHCI_PORTSC2))); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTF("cmd =%04x sts =%04x intr =%04x frnum =%04x", + UREAD2(sc, UHCI_CMD), UREAD2(sc, UHCI_STS), + UREAD2(sc, UHCI_INTR), UREAD2(sc, UHCI_FRNUM)); + DPRINTF("sof =%04x portsc1=%04x portsc2=%04x flbase=%08x", + UREAD1(sc, UHCI_SOF), UREAD2(sc, UHCI_PORTSC1), + UREAD2(sc, UHCI_PORTSC2), UREAD4(sc, UHCI_FLBASEADDR)); } void uhci_dump_td(uhci_soft_td_t *p) { - char sbuf[128], sbuf2[128]; - + UHCIHIST_FUNC(); UHCIHIST_CALLED(); usb_syncmem(&p->dma, p->offs, sizeof(p->td), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - DPRINTFN(-1,("TD(%p) at %08lx = link=0x%08lx status=0x%08lx " - "token=0x%08lx buffer=0x%08lx\n", - p, (long)p->physaddr, - (long)le32toh(p->td.td_link), - (long)le32toh(p->td.td_status), - (long)le32toh(p->td.td_token), - (long)le32toh(p->td.td_buffer))); - - snprintb(sbuf, sizeof(sbuf), "\20\1T\2Q\3VF", - (u_int32_t)le32toh(p->td.td_link)); - snprintb(sbuf2, sizeof(sbuf2), - "\20\22BITSTUFF\23CRCTO\24NAK\25BABBLE\26DBUFFER\27" - "STALLED\30ACTIVE\31IOC\32ISO\33LS\36SPD", - (u_int32_t)le32toh(p->td.td_status)); - - DPRINTFN(-1,(" %s %s,errcnt=%d,actlen=%d pid=%02x,addr=%d,endpt=%d," - "D=%d,maxlen=%d\n", sbuf, sbuf2, - UHCI_TD_GET_ERRCNT(le32toh(p->td.td_status)), - UHCI_TD_GET_ACTLEN(le32toh(p->td.td_status)), - UHCI_TD_GET_PID(le32toh(p->td.td_token)), - UHCI_TD_GET_DEVADDR(le32toh(p->td.td_token)), - UHCI_TD_GET_ENDPT(le32toh(p->td.td_token)), - UHCI_TD_GET_DT(le32toh(p->td.td_token)), - UHCI_TD_GET_MAXLEN(le32toh(p->td.td_token)))); - usb_syncmem(&p->dma, p->offs, sizeof(p->td), - BUS_DMASYNC_PREREAD); + + DPRINTF("TD(%p) at 0x%08x", p, p->physaddr, 0, 0); + DPRINTF(" link=0x%08x status=0x%08x " + "token=0x%08x buffer=0x%08x", + le32toh(p->td.td_link), + le32toh(p->td.td_status), + le32toh(p->td.td_token), + le32toh(p->td.td_buffer)); + + DPRINTF("bitstuff=%d crcto =%d nak =%d babble =%d", + !!(le32toh(p->td.td_status) & UHCI_TD_BITSTUFF), + !!(le32toh(p->td.td_status) & UHCI_TD_CRCTO), + !!(le32toh(p->td.td_status) & UHCI_TD_NAK), + !!(le32toh(p->td.td_status) & UHCI_TD_BABBLE)); + DPRINTF("dbuffer =%d stalled =%d active =%d ioc =%d", + !!(le32toh(p->td.td_status) & UHCI_TD_DBUFFER), + !!(le32toh(p->td.td_status) & UHCI_TD_STALLED), + !!(le32toh(p->td.td_status) & UHCI_TD_ACTIVE), + !!(le32toh(p->td.td_status) & UHCI_TD_IOC)); + DPRINTF("ios =%d ls =%d spd =%d", + !!(le32toh(p->td.td_status) & UHCI_TD_IOS), + !!(le32toh(p->td.td_status) & UHCI_TD_LS), + !!(le32toh(p->td.td_status) & UHCI_TD_SPD), 0); + DPRINTF("errcnt =%d actlen =%d pid=%02x", + UHCI_TD_GET_ERRCNT(le32toh(p->td.td_status)), + UHCI_TD_GET_ACTLEN(le32toh(p->td.td_status)), + UHCI_TD_GET_PID(le32toh(p->td.td_token)), 0); + DPRINTF("addr=%d endpt=%d D=%d maxlen=%d,", + UHCI_TD_GET_DEVADDR(le32toh(p->td.td_token)), + UHCI_TD_GET_ENDPT(le32toh(p->td.td_token)), + UHCI_TD_GET_DT(le32toh(p->td.td_token)), + UHCI_TD_GET_MAXLEN(le32toh(p->td.td_token))); } void uhci_dump_qh(uhci_soft_qh_t *sqh) { + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - DPRINTFN(-1,("QH(%p) at %08x: hlink=%08x elink=%08x\n", sqh, + + DPRINTF("QH(%p) at 0x%08x: hlink=%08x elink=%08x", sqh, (int)sqh->physaddr, le32toh(sqh->qh.qh_hlink), - le32toh(sqh->qh.qh_elink))); + le32toh(sqh->qh.qh_elink)); + usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREREAD); } @@ -853,7 +863,6 @@ void uhci_dump_all(uhci_softc_t *sc) { uhci_dumpregs(sc); - printf("intrs=%d\n", sc->sc_bus.no_intrs); /*printf("framelist[i].link = %08x\n", sc->sc_framelist[0].link);*/ uhci_dump_qhs(sc->sc_lctl_start); } @@ -862,9 +871,12 @@ uhci_dump_all(uhci_softc_t *sc) void uhci_dump_qhs(uhci_soft_qh_t *sqh) { + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + uhci_dump_qh(sqh); - /* uhci_dump_qhs displays all the QHs and TDs from the given QH onwards + /* + * uhci_dump_qhs displays all the QHs and TDs from the given QH onwards * Traverses sideways first, then down. * * QH1 @@ -878,19 +890,18 @@ uhci_dump_qhs(uhci_soft_qh_t *sqh) * TD2.x being the TDs queued at QH2 and QH1 being referenced from QH1. */ - usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); if (sqh->hlink != NULL && !(le32toh(sqh->qh.qh_hlink) & UHCI_PTR_T)) uhci_dump_qhs(sqh->hlink); else - DPRINTF(("No QH\n")); + DPRINTF("No QH", 0, 0, 0, 0); usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREREAD); if (sqh->elink != NULL && !(le32toh(sqh->qh.qh_elink) & UHCI_PTR_T)) uhci_dump_tds(sqh->elink); else - DPRINTF(("No TD\n")); + DPRINTF("No QH", 0, 0, 0, 0); } void @@ -902,7 +913,8 @@ uhci_dump_tds(uhci_soft_td_t *std) for (td = std; td != NULL; td = td->link.std) { uhci_dump_td(td); - /* Check whether the link pointer in this TD marks + /* + * 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). @@ -920,62 +932,50 @@ uhci_dump_tds(uhci_soft_td_t *std) } Static void -uhci_dump_ii(uhci_intr_info_t *ii) +uhci_dump_ii(struct uhci_xfer *ux) { - usbd_pipe_handle pipe; + struct usbd_pipe *pipe; usb_endpoint_descriptor_t *ed; - usbd_device_handle dev; + struct usbd_device *dev; -#ifdef DIAGNOSTIC -#define DONE ii->isdone -#else -#define DONE 0 -#endif - if (ii == NULL) { - printf("ii NULL\n"); - return; - } - if (ii->xfer == NULL) { - printf("ii %p: done=%d xfer=NULL\n", - ii, DONE); - return; - } - pipe = ii->xfer->pipe; - if (pipe == NULL) { - printf("ii %p: done=%d xfer=%p pipe=NULL\n", - ii, DONE, ii->xfer); - return; - } - if (pipe->endpoint == NULL) { - printf("ii %p: done=%d xfer=%p pipe=%p pipe->endpoint=NULL\n", - ii, DONE, ii->xfer, pipe); - return; - } - if (pipe->device == NULL) { - printf("ii %p: done=%d xfer=%p pipe=%p pipe->device=NULL\n", - ii, DONE, ii->xfer, pipe); - return; - } - ed = pipe->endpoint->edesc; - dev = pipe->device; - printf("ii %p: done=%d xfer=%p dev=%p vid=0x%04x pid=0x%04x addr=%d pipe=%p ep=0x%02x attr=0x%02x\n", - ii, DONE, ii->xfer, dev, - UGETW(dev->ddesc.idVendor), - UGETW(dev->ddesc.idProduct), - dev->address, pipe, + if (ux == NULL) { + printf("ux NULL\n"); + return; + } + pipe = ux->ux_xfer.ux_pipe; + if (pipe == NULL) { + printf("ux %p: done=%d pipe=NULL\n", ux, ux->ux_isdone); + return; + } + if (pipe->up_endpoint == NULL) { + printf("ux %p: done=%d pipe=%p pipe->up_endpoint=NULL\n", + ux, ux->ux_isdone, pipe); + return; + } + if (pipe->up_dev == NULL) { + printf("ux %p: done=%d pipe=%p pipe->up_dev=NULL\n", + ux, ux->ux_isdone, pipe); + return; + } + ed = pipe->up_endpoint->ue_edesc; + dev = pipe->up_dev; + printf("ux %p: done=%d dev=%p vid=0x%04x pid=0x%04x addr=%d pipe=%p ep=0x%02x attr=0x%02x\n", + ux, ux->ux_isdone, dev, + UGETW(dev->ud_ddesc.idVendor), + UGETW(dev->ud_ddesc.idProduct), + dev->ud_addr, pipe, ed->bEndpointAddress, ed->bmAttributes); -#undef DONE } void uhci_dump_iis(struct uhci_softc *sc); void uhci_dump_iis(struct uhci_softc *sc) { - uhci_intr_info_t *ii; + struct uhci_xfer *ux; - printf("intr_info list:\n"); - for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = LIST_NEXT(ii, list)) - uhci_dump_ii(ii); + printf("interrupt list:\n"); + TAILQ_FOREACH(ux, &sc->sc_intrhead, ux_list) + uhci_dump_ii(ux); } void iidump(void); @@ -990,19 +990,19 @@ void iidump(void) { uhci_dump_iis(thesc); } void uhci_poll_hub(void *addr) { - usbd_xfer_handle xfer = addr; - usbd_pipe_handle pipe = xfer->pipe; + struct usbd_xfer *xfer = addr; + struct usbd_pipe *pipe = xfer->ux_pipe; uhci_softc_t *sc; u_char *p; - DPRINTFN(20, ("uhci_poll_hub\n")); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); - if (__predict_false(pipe->device == NULL || pipe->device->bus == NULL)) + if (__predict_false(pipe->up_dev == NULL || pipe->up_dev->ud_bus == NULL)) return; /* device has detached */ - sc = pipe->device->bus->hci_private; + sc = UHCI_PIPE2SC(pipe); callout_reset(&sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub, xfer); - p = KERNADDR(&xfer->dmabuf, 0); + p = xfer->ux_buf; p[0] = 0; if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC)) p[0] |= 1<<1; @@ -1012,20 +1012,15 @@ uhci_poll_hub(void *addr) /* No change, try again in a while */ return; - xfer->actlen = 1; - xfer->status = USBD_NORMAL_COMPLETION; + xfer->ux_actlen = 1; + xfer->ux_status = USBD_NORMAL_COMPLETION; mutex_enter(&sc->sc_lock); usb_transfer_complete(xfer); mutex_exit(&sc->sc_lock); } void -uhci_root_intr_done(usbd_xfer_handle xfer) -{ -} - -void -uhci_root_ctrl_done(usbd_xfer_handle xfer) +uhci_root_intr_done(struct usbd_xfer *xfer) { } @@ -1036,13 +1031,16 @@ uhci_root_ctrl_done(usbd_xfer_handle xfer) * If we are already looping, just count it. */ void -uhci_add_loop(uhci_softc_t *sc) { +uhci_add_loop(uhci_softc_t *sc) +{ + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + #ifdef UHCI_DEBUG if (uhcinoloop) return; #endif if (++sc->sc_loops == 1) { - DPRINTFN(5,("uhci_start_loop: add\n")); + DPRINTFN(5, "add loop", 0, 0, 0, 0); /* Note, we don't loop back the soft pointer. */ sc->sc_last_qh->qh.qh_hlink = htole32(sc->sc_hctl_start->physaddr | UHCI_PTR_QH); @@ -1054,13 +1052,16 @@ uhci_add_loop(uhci_softc_t *sc) { } void -uhci_rem_loop(uhci_softc_t *sc) { +uhci_rem_loop(uhci_softc_t *sc) +{ + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + #ifdef UHCI_DEBUG if (uhcinoloop) return; #endif if (--sc->sc_loops == 0) { - DPRINTFN(5,("uhci_end_loop: remove\n")); + DPRINTFN(5, "remove loop", 0, 0, 0, 0); sc->sc_last_qh->qh.qh_hlink = htole32(UHCI_PTR_T); usb_syncmem(&sc->sc_last_qh->dma, sc->sc_last_qh->offs + offsetof(uhci_qh_t, qh_hlink), @@ -1075,9 +1076,11 @@ uhci_add_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) { uhci_soft_qh_t *eqh; + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTFN(10, ("uhci_add_ctrl: sqh=%p\n", sqh)); + DPRINTFN(10, "sqh %p", sqh, 0, 0, 0); eqh = sc->sc_hctl_end; usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), sizeof(eqh->qh.qh_hlink), @@ -1105,7 +1108,8 @@ uhci_remove_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTFN(10, ("uhci_remove_hs_ctrl: sqh=%p\n", sqh)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(10, "sqh %p", sqh, 0, 0, 0); #ifdef UHCI_CTL_LOOP uhci_rem_loop(sc); #endif @@ -1158,7 +1162,9 @@ uhci_add_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTFN(10, ("uhci_add_ls_ctrl: sqh=%p\n", sqh)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(10, "sqh %p", sqh, 0, 0, 0); + eqh = sc->sc_lctl_end; usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); @@ -1182,7 +1188,9 @@ uhci_remove_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTFN(10, ("uhci_remove_ls_ctrl: sqh=%p\n", sqh)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(10, "sqh %p", sqh, 0, 0, 0); + /* See comment in uhci_remove_hs_ctrl() */ usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), sizeof(sqh->qh.qh_elink), @@ -1219,7 +1227,9 @@ uhci_add_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh) KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTFN(10, ("uhci_add_bulk: sqh=%p\n", sqh)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(10, "sqh %p", sqh, 0, 0, 0); + eqh = sc->sc_bulk_end; usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); @@ -1243,7 +1253,9 @@ uhci_remove_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh) KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTFN(10, ("uhci_remove_bulk: sqh=%p\n", sqh)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(10, "sqh %p", sqh, 0, 0, 0); + uhci_rem_loop(sc); /* See comment in uhci_remove_hs_ctrl() */ usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), @@ -1277,15 +1289,15 @@ uhci_intr(void *arg) uhci_softc_t *sc = arg; int ret = 0; + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + mutex_spin_enter(&sc->sc_intr_lock); if (sc->sc_dying || !device_has_power(sc->sc_dev)) goto done; - if (sc->sc_bus.use_polling || UREAD2(sc, UHCI_INTR) == 0) { -#ifdef DIAGNOSTIC - DPRINTFN(16, ("uhci_intr: ignored interrupt while polling\n")); -#endif + if (sc->sc_bus.ub_usepolling || UREAD2(sc, UHCI_INTR) == 0) { + DPRINTFN(16, "ignored interrupt while polling", 0, 0, 0, 0); goto done; } @@ -1302,9 +1314,11 @@ uhci_intr1(uhci_softc_t *sc) int status; int ack; + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + #ifdef UHCI_DEBUG - if (uhcidebug > 15) { - DPRINTF(("%s: uhci_intr1\n", device_xname(sc->sc_dev))); + if (uhcidebug >= 15) { + DPRINTF("sc %p", sc, 0, 0, 0); uhci_dumpregs(sc); } #endif @@ -1312,8 +1326,9 @@ uhci_intr1(uhci_softc_t *sc) KASSERT(mutex_owned(&sc->sc_intr_lock)); status = UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS; - if (status == 0) /* The interrupt was not for us. */ - return (0); + /* Check if the interrupt was for us. */ + if (status == 0) + return 0; if (sc->sc_suspend != PWR_RESUME) { #ifdef DIAGNOSTIC @@ -1321,7 +1336,7 @@ uhci_intr1(uhci_softc_t *sc) device_xname(sc->sc_dev)); #endif UWRITE2(sc, UHCI_STS, status); /* acknowledge the ints */ - return (0); + return 0; } ack = 0; @@ -1359,28 +1374,30 @@ uhci_intr1(uhci_softc_t *sc) } if (!ack) - return (0); /* nothing to acknowledge */ + return 0; /* nothing to acknowledge */ UWRITE2(sc, UHCI_STS, ack); /* acknowledge the ints */ - sc->sc_bus.no_intrs++; usb_schedsoftintr(&sc->sc_bus); - DPRINTFN(15, ("%s: uhci_intr: exit\n", device_xname(sc->sc_dev))); + DPRINTFN(15, "sc %p done", sc, 0, 0, 0); - return (1); + return 1; } void uhci_softintr(void *v) { struct usbd_bus *bus = v; - uhci_softc_t *sc = bus->hci_private; - uhci_intr_info_t *ii, *nextii; + uhci_softc_t *sc = UHCI_BUS2SC(bus); + struct uhci_xfer *ux, *nextux; + ux_completeq_t cq; - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTF("sc %p", sc, 0, 0, 0); - DPRINTFN(10,("%s: uhci_softintr\n", device_xname(sc->sc_dev))); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + TAILQ_INIT(&cq); /* * Interrupts on UHCI really suck. When the host controller * interrupts because a transfer is completed there is no @@ -1392,9 +1409,18 @@ uhci_softintr(void *v) * We scan all interrupt descriptors to see if any have * completed. */ - for (ii = LIST_FIRST(&sc->sc_intrhead); ii; ii = nextii) { - nextii = LIST_NEXT(ii, list); - uhci_check_intr(sc, ii); + TAILQ_FOREACH_SAFE(ux, &sc->sc_intrhead, ux_list, nextux) { + uhci_check_intr(sc, ux, &cq); + } + + /* + * We abuse ux_list for the interrupt and complete lists and + * interrupt transfers will get re-added here so use + * the _SAFE version of TAILQ_FOREACH. + */ + TAILQ_FOREACH_SAFE(ux, &cq, ux_list, nextux) { + DPRINTF("ux %p", ux, 0, 0, 0); + usb_transfer_complete(&ux->ux_xfer); } if (sc->sc_softwake) { @@ -1405,33 +1431,43 @@ uhci_softintr(void *v) /* Check for an interrupt. */ void -uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *ii) +uhci_check_intr(uhci_softc_t *sc, struct uhci_xfer *ux, ux_completeq_t *cqp) { - uhci_soft_td_t *std, *lstd; - u_int32_t status; + uhci_soft_td_t *std, *fstd = NULL, *lstd = NULL; + uint32_t status; - DPRINTFN(15, ("uhci_check_intr: ii=%p\n", ii)); -#ifdef DIAGNOSTIC - if (ii == NULL) { - printf("uhci_check_intr: no ii? %p\n", ii); - return; - } -#endif - if (ii->xfer->status == USBD_CANCELLED || - ii->xfer->status == USBD_TIMEOUT) { - DPRINTF(("uhci_check_intr: aborted xfer=%p\n", ii->xfer)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(15, "ux %p", ux, 0, 0, 0); + + KASSERT(ux != NULL); + + struct usbd_xfer *xfer = &ux->ux_xfer; + if (xfer->ux_status == USBD_CANCELLED || + xfer->ux_status == USBD_TIMEOUT) { + DPRINTF("aborted xfer %p", xfer, 0, 0, 0); return; } - if (ii->stdstart == NULL) - return; - lstd = ii->stdend; -#ifdef DIAGNOSTIC - if (lstd == NULL) { - printf("uhci_check_intr: std==0\n"); - return; + switch (ux->ux_type) { + case UX_CTRL: + fstd = ux->ux_setup; + lstd = ux->ux_stat; + break; + case UX_BULK: + case UX_INTR: + case UX_ISOC: + fstd = ux->ux_stdstart; + lstd = ux->ux_stdend; + break; + default: + KASSERT(false); + break; } -#endif + if (fstd == NULL) + return; + + KASSERT(lstd != NULL); + usb_syncmem(&lstd->dma, lstd->offs + offsetof(uhci_td_t, td_status), sizeof(lstd->td.td_status), @@ -1445,9 +1481,10 @@ uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *ii) /* If the last TD is not marked active we can complete */ if (!(status & UHCI_TD_ACTIVE)) { done: - DPRINTFN(12, ("uhci_check_intr: ii=%p done\n", ii)); - callout_stop(&ii->xfer->timeout_handle); - uhci_idone(ii); + DPRINTFN(12, "ux=%p done", ux, 0, 0, 0); + + callout_stop(&xfer->ux_callout); + uhci_idone(ux, cqp); return; } @@ -1456,8 +1493,8 @@ uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *ii) * is an error somewhere in the middle, or whether there was a * short packet (SPD and not ACTIVE). */ - DPRINTFN(12, ("uhci_check_intr: active ii=%p\n", ii)); - for (std = ii->stdstart; std != lstd; std = std->link.std) { + DPRINTFN(12, "active ux=%p", ux, 0, 0, 0); + for (std = fstd; std != lstd; std = std->link.std) { usb_syncmem(&std->dma, std->offs + offsetof(uhci_td_t, td_status), sizeof(std->td.td_status), @@ -1469,8 +1506,8 @@ uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *ii) /* If there's an active TD the xfer isn't done. */ if (status & UHCI_TD_ACTIVE) { - DPRINTFN(12, ("%s: ii=%p std=%p still active\n", - __func__, ii, std)); + DPRINTFN(12, "ux=%p std=%p still active", + ux, std, 0, 0); return; } @@ -1482,19 +1519,15 @@ uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *ii) * If the data phase of a control transfer is short, we need * to complete the status stage */ - usbd_xfer_handle xfer = ii->xfer; - usb_endpoint_descriptor_t *ed = xfer->pipe->endpoint->edesc; - uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes); - if ((status & UHCI_TD_SPD) && xfertype == UE_CONTROL) { + if ((status & UHCI_TD_SPD) && ux->ux_type == UX_CTRL) { struct uhci_pipe *upipe = - (struct uhci_pipe *)xfer->pipe; - uhci_soft_qh_t *sqh = upipe->u.ctl.sqh; - uhci_soft_td_t *stat = upipe->u.ctl.stat; + UHCI_PIPE2UPIPE(xfer->ux_pipe); + uhci_soft_qh_t *sqh = upipe->ctrl.sqh; + uhci_soft_td_t *stat = upipe->ctrl.stat; - DPRINTFN(12, ("%s: ii=%p std=%p control status" - "phase needs completion\n", __func__, ii, - ii->stdstart)); + DPRINTFN(12, "ux=%p std=%p control status" + "phase needs completion", ux, ux->ux_stdstart, 0, 0); sqh->qh.qh_elink = htole32(stat->physaddr | UHCI_PTR_TD); @@ -1519,55 +1552,52 @@ uhci_check_intr(uhci_softc_t *sc, uhci_intr_info_t *ii) /* Called with USB lock held. */ void -uhci_idone(uhci_intr_info_t *ii) +uhci_idone(struct uhci_xfer *ux, ux_completeq_t *cqp) { - usbd_xfer_handle xfer = ii->xfer; - struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; -#ifdef DIAGNOSTIC - uhci_softc_t *sc = upipe->pipe.device->bus->hci_private; -#endif + struct usbd_xfer *xfer = &ux->ux_xfer; + uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer); + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); uhci_soft_td_t *std; - u_int32_t status = 0, nstatus; + uint32_t status = 0, nstatus; int actlen; - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(12, "ux=%p", ux, 0, 0, 0); - DPRINTFN(12, ("uhci_idone: ii=%p\n", ii)); #ifdef DIAGNOSTIC - { - /* XXX SMP? */ - int s = splhigh(); - if (ii->isdone) { - splx(s); #ifdef UHCI_DEBUG - printf("uhci_idone: ii is done!\n "); - uhci_dump_ii(ii); -#else - printf("uhci_idone: ii=%p is done!\n", ii); -#endif - return; - } - ii->isdone = 1; - splx(s); + if (ux->ux_isdone) { + DPRINTF("--- dump start ---", 0, 0, 0, 0); + uhci_dump_ii(ux); + DPRINTF("--- dump end ---", 0, 0, 0, 0); } #endif + KASSERT(!ux->ux_isdone); + KASSERTMSG(!ux->ux_isdone, "xfer %p type %d status %d", xfer, + ux->ux_type, xfer->ux_status); + ux->ux_isdone = true; +#endif - if (xfer->nframes != 0) { + if (xfer->ux_nframes != 0) { /* Isoc transfer, do things differently. */ - uhci_soft_td_t **stds = upipe->u.iso.stds; + uhci_soft_td_t **stds = upipe->isoc.stds; int i, n, nframes, len; - DPRINTFN(5,("uhci_idone: ii=%p isoc ready\n", ii)); + DPRINTFN(5, "ux=%p isoc ready", ux, 0, 0, 0); - nframes = xfer->nframes; + nframes = xfer->ux_nframes; actlen = 0; - n = UXFER(xfer)->curframe; + n = ux->ux_curframe; for (i = 0; i < nframes; i++) { std = stds[n]; #ifdef UHCI_DEBUG - if (uhcidebug > 5) { - DPRINTFN(-1,("uhci_idone: isoc TD %d\n", i)); + if (uhcidebug >= 5) { + DPRINTF("isoc TD %d", i, 0, 0, 0); + DPRINTF("--- dump start ---", 0, 0, 0, 0); uhci_dump_td(std); + DPRINTF("--- dump end ---", 0, 0, 0, 0); } #endif if (++n >= UHCI_VFRAMELIST_COUNT) @@ -1578,25 +1608,27 @@ uhci_idone(uhci_intr_info_t *ii) BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); status = le32toh(std->td.td_status); len = UHCI_TD_GET_ACTLEN(status); - xfer->frlengths[i] = len; + xfer->ux_frlengths[i] = len; actlen += len; } - upipe->u.iso.inuse -= nframes; - xfer->actlen = actlen; - xfer->status = USBD_NORMAL_COMPLETION; + upipe->isoc.inuse -= nframes; + xfer->ux_actlen = actlen; + xfer->ux_status = USBD_NORMAL_COMPLETION; goto end; } #ifdef UHCI_DEBUG - DPRINTFN(10, ("uhci_idone: ii=%p, xfer=%p, pipe=%p ready\n", - ii, xfer, upipe)); - if (uhcidebug > 10) - uhci_dump_tds(ii->stdstart); + DPRINTFN(10, "ux=%p, xfer=%p, pipe=%p ready", ux, xfer, upipe, 0); + if (uhcidebug >= 10) { + DPRINTF("--- dump start ---", 0, 0, 0, 0); + uhci_dump_tds(ux->ux_stdstart); + DPRINTF("--- dump end ---", 0, 0, 0, 0); + } #endif /* The transfer is done, compute actual length and status. */ actlen = 0; - for (std = ii->stdstart; std != NULL; std = std->link.std) { + for (std = ux->ux_stdstart; std != NULL; std = std->link.std) { usb_syncmem(&std->dma, std->offs, sizeof(std->td), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); nstatus = le32toh(std->td.td_status); @@ -1622,37 +1654,43 @@ uhci_idone(uhci_intr_info_t *ii) upipe->nexttoggle = UHCI_TD_GET_DT(le32toh(std->td.td_token)); status &= UHCI_TD_ERROR; - DPRINTFN(10, ("uhci_idone: actlen=%d, status=0x%x\n", - actlen, status)); - xfer->actlen = actlen; + DPRINTFN(10, "actlen=%d, status=0x%x", actlen, status, 0, 0); + xfer->ux_actlen = actlen; if (status != 0) { -#ifdef UHCI_DEBUG - char sbuf[128]; - - snprintb(sbuf, sizeof(sbuf), - "\20\22BITSTUFF\23CRCTO\24NAK\25" - "BABBLE\26DBUFFER\27STALLED\30ACTIVE",(u_int32_t)status); - - DPRINTFN((status == UHCI_TD_STALLED)*10, - ("uhci_idone: error, addr=%d, endpt=0x%02x, " - "status 0x%s\n", - xfer->pipe->device->address, - xfer->pipe->endpoint->edesc->bEndpointAddress, - sbuf)); -#endif + + DPRINTFN((status == UHCI_TD_STALLED) * 10, + "error, addr=%d, endpt=0x%02x", + xfer->ux_pipe->up_dev->ud_addr, + xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress, + 0, 0); + DPRINTFN((status == UHCI_TD_STALLED) * 10, + "bitstuff=%d crcto =%d nak =%d babble =%d", + !!(status & UHCI_TD_BITSTUFF), + !!(status & UHCI_TD_CRCTO), + !!(status & UHCI_TD_NAK), + !!(status & UHCI_TD_BABBLE)); + DPRINTFN((status == UHCI_TD_STALLED) * 10, + "dbuffer =%d stalled =%d active =%d", + !!(status & UHCI_TD_DBUFFER), + !!(status & UHCI_TD_STALLED), + !!(status & UHCI_TD_ACTIVE), + 0); if (status == UHCI_TD_STALLED) - xfer->status = USBD_STALLED; + xfer->ux_status = USBD_STALLED; else - xfer->status = USBD_IOERROR; /* more info XXX */ + xfer->ux_status = USBD_IOERROR; /* more info XXX */ } else { - xfer->status = USBD_NORMAL_COMPLETION; + xfer->ux_status = USBD_NORMAL_COMPLETION; } end: - usb_transfer_complete(xfer); - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); - DPRINTFN(12, ("uhci_idone: ii=%p done\n", ii)); + uhci_del_intr_list(sc, ux); + if (cqp) + TAILQ_INSERT_TAIL(cqp, ux, ux_list); + + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + DPRINTFN(12, "ux=%p done", ux, 0, 0, 0); } /* @@ -1661,34 +1699,37 @@ uhci_idone(uhci_intr_info_t *ii) void uhci_timeout(void *addr) { - uhci_intr_info_t *ii = addr; - struct uhci_xfer *uxfer = UXFER(ii->xfer); - struct uhci_pipe *upipe = (struct uhci_pipe *)uxfer->xfer.pipe; - uhci_softc_t *sc = upipe->pipe.device->bus->hci_private; + struct usbd_xfer *xfer = addr; + struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer); + uhci_softc_t *sc = UHCI_XFER2SC(xfer); + + UHCIHIST_FUNC(); UHCIHIST_CALLED(); - DPRINTF(("uhci_timeout: uxfer=%p\n", uxfer)); + DPRINTF("uxfer %p", uxfer, 0, 0, 0); if (sc->sc_dying) { mutex_enter(&sc->sc_lock); - uhci_abort_xfer(&uxfer->xfer, USBD_TIMEOUT); + uhci_abort_xfer(xfer, USBD_TIMEOUT); mutex_exit(&sc->sc_lock); return; } /* Execute the abort in a process context. */ - usb_init_task(&uxfer->abort_task, uhci_timeout_task, ii->xfer, + usb_init_task(&uxfer->ux_aborttask, uhci_timeout_task, xfer, USB_TASKQ_MPSAFE); - usb_add_task(uxfer->xfer.pipe->device, &uxfer->abort_task, + usb_add_task(uxfer->ux_xfer.ux_pipe->up_dev, &uxfer->ux_aborttask, USB_TASKQ_HC); } void uhci_timeout_task(void *addr) { - usbd_xfer_handle xfer = addr; - uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; + struct usbd_xfer *xfer = addr; + uhci_softc_t *sc = UHCI_XFER2SC(xfer); - DPRINTF(("uhci_timeout_task: xfer=%p\n", xfer)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + + DPRINTF("xfer=%p", xfer, 0, 0, 0); mutex_enter(&sc->sc_lock); uhci_abort_xfer(xfer, USBD_TIMEOUT); @@ -1702,39 +1743,40 @@ uhci_timeout_task(void *addr) * Only used during boot when interrupts are not enabled yet. */ void -uhci_waitintr(uhci_softc_t *sc, usbd_xfer_handle xfer) +uhci_waitintr(uhci_softc_t *sc, struct usbd_xfer *xfer) { - int timo = xfer->timeout; - uhci_intr_info_t *ii; + int timo = xfer->ux_timeout; + struct uhci_xfer *ux; mutex_enter(&sc->sc_lock); - DPRINTFN(10,("uhci_waitintr: timeout = %dms\n", timo)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(10, "timeout = %dms", timo, 0, 0, 0); - xfer->status = USBD_IN_PROGRESS; + xfer->ux_status = USBD_IN_PROGRESS; for (; timo >= 0; timo--) { usb_delay_ms_locked(&sc->sc_bus, 1, &sc->sc_lock); - DPRINTFN(20,("uhci_waitintr: 0x%04x\n", UREAD2(sc, UHCI_STS))); + DPRINTFN(20, "0x%04x", + UREAD2(sc, UHCI_STS), 0, 0, 0); if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) { mutex_spin_enter(&sc->sc_intr_lock); uhci_intr1(sc); mutex_spin_exit(&sc->sc_intr_lock); - if (xfer->status != USBD_IN_PROGRESS) + if (xfer->ux_status != USBD_IN_PROGRESS) goto done; } } /* Timeout */ - DPRINTF(("uhci_waitintr: timeout\n")); - for (ii = LIST_FIRST(&sc->sc_intrhead); - ii != NULL && ii->xfer != xfer; - ii = LIST_NEXT(ii, list)) - ; -#ifdef DIAGNOSTIC - if (ii == NULL) - panic("uhci_waitintr: lost intr_info"); -#endif - uhci_idone(ii); + DPRINTF("timeout", 0, 0, 0, 0); + TAILQ_FOREACH(ux, &sc->sc_intrhead, ux_list) + if (&ux->ux_xfer == xfer) + break; + + KASSERT(ux != NULL); + + uhci_idone(ux, NULL); + usb_transfer_complete(&ux->ux_xfer); done: mutex_exit(&sc->sc_lock); @@ -1743,7 +1785,7 @@ done: void uhci_poll(struct usbd_bus *bus) { - uhci_softc_t *sc = bus->hci_private; + uhci_softc_t *sc = UHCI_BUS2SC(bus); if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) { mutex_spin_enter(&sc->sc_intr_lock); @@ -1771,12 +1813,15 @@ usbd_status uhci_run(uhci_softc_t *sc, int run, int locked) { int n, running; - u_int16_t cmd; + uint16_t cmd; + + UHCIHIST_FUNC(); UHCIHIST_CALLED(); run = run != 0; if (!locked) mutex_spin_enter(&sc->sc_intr_lock); - DPRINTF(("uhci_run: setting run=%d\n", run)); + + DPRINTF("setting run=%d", run, 0, 0, 0); cmd = UREAD2(sc, UHCI_CMD); if (run) cmd |= UHCI_CMD_RS; @@ -1789,9 +1834,9 @@ uhci_run(uhci_softc_t *sc, int run, int locked) if (run == running) { if (!locked) mutex_spin_exit(&sc->sc_intr_lock); - DPRINTF(("uhci_run: done cmd=0x%x sts=0x%x\n", - UREAD2(sc, UHCI_CMD), UREAD2(sc, UHCI_STS))); - return (USBD_NORMAL_COMPLETION); + DPRINTF("done cmd=0x%x sts=0x%x", + UREAD2(sc, UHCI_CMD), UREAD2(sc, UHCI_STS), 0, 0); + return USBD_NORMAL_COMPLETION; } usb_delay_ms_locked(&sc->sc_bus, 1, &sc->sc_intr_lock); } @@ -1799,7 +1844,7 @@ uhci_run(uhci_softc_t *sc, int run, int locked) mutex_spin_exit(&sc->sc_intr_lock); printf("%s: cannot %s\n", device_xname(sc->sc_dev), run ? "start" : "stop"); - return (USBD_IOERROR); + return USBD_IOERROR; } /* @@ -1808,7 +1853,7 @@ uhci_run(uhci_softc_t *sc, int run, int locked) * uhci_alloc_sqh allocates QHs * These two routines do their own free list management, * partly for speed, partly because allocating DMAable memory - * has page size granularaity so much memory would be wasted if + * has page size granularity so much memory would be wasted if * only one TD/QH (32 bytes) was placed in each allocated chunk. */ @@ -1820,12 +1865,19 @@ uhci_alloc_std(uhci_softc_t *sc) int i, offs; usb_dma_t dma; + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + + mutex_enter(&sc->sc_lock); if (sc->sc_freetds == NULL) { - DPRINTFN(2,("uhci_alloc_std: allocating chunk\n")); + DPRINTFN(2, "allocating chunk", 0, 0, 0, 0); + mutex_exit(&sc->sc_lock); + err = usb_allocmem(&sc->sc_bus, UHCI_STD_SIZE * UHCI_STD_CHUNK, UHCI_TD_ALIGN, &dma); if (err) - return (0); + return NULL; + + mutex_enter(&sc->sc_lock); for (i = 0; i < UHCI_STD_CHUNK; i++) { offs = i * UHCI_STD_SIZE; std = KERNADDR(&dma, offs); @@ -1838,25 +1890,40 @@ uhci_alloc_std(uhci_softc_t *sc) } std = sc->sc_freetds; sc->sc_freetds = std->link.std; + mutex_exit(&sc->sc_lock); + memset(&std->td, 0, sizeof(uhci_td_t)); + return std; } +#define TD_IS_FREE 0x12345678 + void -uhci_free_std(uhci_softc_t *sc, uhci_soft_td_t *std) +uhci_free_std_locked(uhci_softc_t *sc, uhci_soft_td_t *std) { + KASSERT(mutex_owned(&sc->sc_lock)); + #ifdef DIAGNOSTIC -#define TD_IS_FREE 0x12345678 if (le32toh(std->td.td_token) == TD_IS_FREE) { - printf("uhci_free_std: freeing free TD %p\n", std); + printf("%s: freeing free TD %p\n", __func__, std); return; } std->td.td_token = htole32(TD_IS_FREE); #endif + std->link.std = sc->sc_freetds; sc->sc_freetds = std; } +void +uhci_free_std(uhci_softc_t *sc, uhci_soft_td_t *std) +{ + mutex_enter(&sc->sc_lock); + uhci_free_std_locked(sc, std); + mutex_exit(&sc->sc_lock); +} + uhci_soft_qh_t * uhci_alloc_sqh(uhci_softc_t *sc) { @@ -1865,12 +1932,19 @@ uhci_alloc_sqh(uhci_softc_t *sc) int i, offs; usb_dma_t dma; + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + + mutex_enter(&sc->sc_lock); if (sc->sc_freeqhs == NULL) { - DPRINTFN(2, ("uhci_alloc_sqh: allocating chunk\n")); + DPRINTFN(2, "allocating chunk", 0, 0, 0, 0); + mutex_exit(&sc->sc_lock); + err = usb_allocmem(&sc->sc_bus, UHCI_SQH_SIZE * UHCI_SQH_CHUNK, UHCI_QH_ALIGN, &dma); if (err) - return (0); + return NULL; + + mutex_enter(&sc->sc_lock); for (i = 0; i < UHCI_SQH_CHUNK; i++) { offs = i * UHCI_SQH_SIZE; sqh = KERNADDR(&dma, offs); @@ -1883,17 +1957,23 @@ uhci_alloc_sqh(uhci_softc_t *sc) } sqh = sc->sc_freeqhs; sc->sc_freeqhs = sqh->hlink; + mutex_exit(&sc->sc_lock); + memset(&sqh->qh, 0, sizeof(uhci_qh_t)); - return (sqh); + + return sqh; } void uhci_free_sqh(uhci_softc_t *sc, uhci_soft_qh_t *sqh) { + KASSERT(mutex_owned(&sc->sc_lock)); + sqh->hlink = sc->sc_freeqhs; sc->sc_freeqhs = sqh; } +#if 0 void uhci_free_std_chain(uhci_softc_t *sc, uhci_soft_td_t *std, uhci_soft_td_t *stdend) @@ -1931,103 +2011,262 @@ uhci_free_std_chain(uhci_softc_t *sc, uhci_soft_td_t *std, uhci_free_std(sc, std); } } +#endif -usbd_status -uhci_alloc_std_chain(struct uhci_pipe *upipe, uhci_softc_t *sc, int len, - int rd, u_int16_t flags, usb_dma_t *dma, - uhci_soft_td_t **sp, uhci_soft_td_t **ep) +int +uhci_alloc_std_chain(uhci_softc_t *sc, struct usbd_xfer *xfer, int len, + int rd, uhci_soft_td_t **sp) { - uhci_soft_td_t *p, *lastp; - uhci_physaddr_t lastlink; - int i, ntd, l, tog, maxp; - u_int32_t status; - int addr = upipe->pipe.device->address; - int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress; + struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer); + uint16_t flags = xfer->ux_flags; + uhci_soft_td_t *p; + + UHCIHIST_FUNC(); UHCIHIST_CALLED(); - DPRINTFN(8, ("uhci_alloc_std_chain: addr=%d endpt=%d len=%d speed=%d " - "flags=0x%x\n", addr, UE_GET_ADDR(endpt), len, - upipe->pipe.device->speed, flags)); + DPRINTFN(8, "xfer=%p pipe=%p", xfer, xfer->ux_pipe, 0, 0); - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + ASSERT_SLEEPABLE(); + KASSERT(sp); - maxp = UGETW(upipe->pipe.endpoint->edesc->wMaxPacketSize); + int maxp = UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize); if (maxp == 0) { - printf("uhci_alloc_std_chain: maxp=0\n"); - return (USBD_INVAL); + printf("%s: maxp=0\n", __func__); + return EINVAL; } - ntd = (len + maxp - 1) / maxp; - if ((flags & USBD_FORCE_SHORT_XFER) && len % maxp == 0) + size_t ntd = (len + maxp - 1) / maxp; + if (!rd && (flags & USBD_FORCE_SHORT_XFER)) { ntd++; - DPRINTFN(10, ("uhci_alloc_std_chain: maxp=%d ntd=%d\n", maxp, ntd)); + } + DPRINTFN(10, "maxp=%d ntd=%d", maxp, ntd, 0, 0); + + uxfer->ux_stds = NULL; + uxfer->ux_nstd = ntd; + p = NULL; if (ntd == 0) { - *sp = *ep = 0; - DPRINTFN(-1,("uhci_alloc_std_chain: ntd=0\n")); - return (USBD_NORMAL_COMPLETION); + *sp = NULL; + DPRINTF("ntd=0", 0, 0, 0, 0); + return 0; } - tog = upipe->nexttoggle; - if (ntd % 2 == 0) - tog ^= 1; - upipe->nexttoggle = tog ^ 1; - lastp = NULL; - lastlink = UHCI_PTR_T; + uxfer->ux_stds = kmem_alloc(sizeof(uhci_soft_td_t *) * ntd, + KM_SLEEP); + ntd--; + for (int i = ntd; i >= 0; i--) { + p = uhci_alloc_std(sc); + if (p == NULL) { + uhci_free_stds(sc, uxfer); + kmem_free(uxfer->ux_stds, + sizeof(uhci_soft_td_t *) * ntd); + return ENOMEM; + } + uxfer->ux_stds[i] = p; + } + + *sp = uxfer->ux_stds[0]; + + return 0; +} + +Static void +uhci_free_stds(uhci_softc_t *sc, struct uhci_xfer *ux) +{ + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + + DPRINTFN(8, "ux=%p", ux, 0, 0, 0); + + mutex_enter(&sc->sc_lock); + for (size_t i = 0; i < ux->ux_nstd; i++) { + uhci_soft_td_t *std = ux->ux_stds[i]; +#ifdef DIAGNOSTIC + if (le32toh(std->td.td_token) == TD_IS_FREE) { + printf("%s: freeing free TD %p\n", __func__, std); + return; + } + std->td.td_token = htole32(TD_IS_FREE); +#endif + ux->ux_stds[i]->link.std = sc->sc_freetds; + sc->sc_freetds = std; + } + mutex_exit(&sc->sc_lock); +} + + +Static void +uhci_reset_std_chain(uhci_softc_t *sc, struct usbd_xfer *xfer, + int length, int isread, int *toggle, uhci_soft_td_t **lstd) +{ + struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer); + struct usbd_pipe *pipe = xfer->ux_pipe; + usb_dma_t *dma = &xfer->ux_dmabuf; + uint16_t flags = xfer->ux_flags; + uhci_soft_td_t *std, *prev; + int len = length; + int tog = *toggle; + int maxp; + uint32_t status; + size_t i; + + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(8, "xfer=%p len %d isread %d toggle %d", xfer, + len, isread, *toggle); + + KASSERT(len != 0 || (!isread && (flags & USBD_FORCE_SHORT_XFER))); + + maxp = UGETW(pipe->up_endpoint->ue_edesc->wMaxPacketSize); + KASSERT(maxp != 0); + + int addr = xfer->ux_pipe->up_dev->ud_addr; + int endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress; + status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE); - if (upipe->pipe.device->speed == USB_SPEED_LOW) + if (pipe->up_dev->ud_speed == USB_SPEED_LOW) status |= UHCI_TD_LS; if (flags & USBD_SHORT_XFER_OK) status |= UHCI_TD_SPD; usb_syncmem(dma, 0, len, - rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); - for (i = ntd; i >= 0; i--) { - p = uhci_alloc_std(sc); - if (p == NULL) { - KASSERT(lastp != NULL); - uhci_free_std_chain(sc, lastp, NULL); - return (USBD_NOMEM); - } - p->link.std = lastp; - p->td.td_link = htole32(lastlink | UHCI_PTR_VF | UHCI_PTR_TD); - lastp = p; - lastlink = p->physaddr; - p->td.td_status = htole32(status); - if (i == ntd) { - /* last TD */ - l = len % maxp; - if (l == 0 && !(flags & USBD_FORCE_SHORT_XFER)) - l = maxp; - *ep = p; - } else + isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); + std = prev = NULL; + for (i = 0; len != 0 && i < uxfer->ux_nstd; i++, prev = std) { + int l = len; + std = uxfer->ux_stds[i]; + if (l > maxp) l = maxp; - p->td.td_token = - htole32(rd ? UHCI_TD_IN (l, endpt, addr, tog) : - UHCI_TD_OUT(l, endpt, addr, tog)); - p->td.td_buffer = htole32(DMAADDR(dma, i * maxp)); - usb_syncmem(&p->dma, p->offs, sizeof(p->td), + + if (prev) { + prev->link.std = std; + prev->td.td_link = htole32( + std->physaddr | UHCI_PTR_VF | UHCI_PTR_TD + ); + usb_syncmem(&prev->dma, prev->offs, sizeof(prev->td), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + } + + usb_syncmem(&std->dma, std->offs, sizeof(std->td), + BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); + + std->td.td_link = htole32(UHCI_PTR_T | UHCI_PTR_VF | UHCI_PTR_TD); + std->td.td_status = htole32(status); + std->td.td_token = htole32( + UHCI_TD_SET_ENDPT(UE_GET_ADDR(endpt)) | + UHCI_TD_SET_DEVADDR(addr) | + UHCI_TD_SET_PID(isread ? UHCI_TD_PID_IN : UHCI_TD_PID_OUT) | + UHCI_TD_SET_DT(tog) | + UHCI_TD_SET_MAXLEN(l) + ); + std->td.td_buffer = htole32(DMAADDR(dma, i * maxp)); + + std->link.std = NULL; + + usb_syncmem(&std->dma, std->offs, sizeof(std->td), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + tog ^= 1; + + len -= l; + } + KASSERTMSG(len == 0, "xfer %p alen %d len %d mps %d ux_nqtd %zu i %zu", + xfer, length, len, maxp, uxfer->ux_nstd, i); + + if (!isread && + (flags & USBD_FORCE_SHORT_XFER) && + length % maxp == 0) { + /* Force a 0 length transfer at the end. */ + KASSERTMSG(i < uxfer->ux_nstd, "i=%zu nstd=%zu", i, + uxfer->ux_nstd); + std = uxfer->ux_stds[i++]; + + std->td.td_link = htole32(UHCI_PTR_T | UHCI_PTR_VF | UHCI_PTR_TD); + std->td.td_status = htole32(status); + std->td.td_token = htole32( + UHCI_TD_SET_ENDPT(UE_GET_ADDR(endpt)) | + UHCI_TD_SET_DEVADDR(addr) | + UHCI_TD_SET_PID(UHCI_TD_PID_OUT) | + UHCI_TD_SET_DT(tog) | + UHCI_TD_SET_MAXLEN(0) + ); + std->td.td_buffer = 0; + usb_syncmem(&std->dma, std->offs, sizeof(std->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + + std->link.std = NULL; + if (prev) { + prev->link.std = std; + prev->td.td_link = htole32( + std->physaddr | UHCI_PTR_VF | UHCI_PTR_TD + ); + usb_syncmem(&prev->dma, prev->offs, sizeof(prev->td), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + } tog ^= 1; } - *sp = lastp; - DPRINTFN(10, ("uhci_alloc_std_chain: nexttog=%d\n", - upipe->nexttoggle)); - return (USBD_NORMAL_COMPLETION); + *lstd = std; + *toggle = tog; } void -uhci_device_clear_toggle(usbd_pipe_handle pipe) +uhci_device_clear_toggle(struct usbd_pipe *pipe) { - struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe); upipe->nexttoggle = 0; } void -uhci_noop(usbd_pipe_handle pipe) +uhci_noop(struct usbd_pipe *pipe) { } +int +uhci_device_bulk_init(struct usbd_xfer *xfer) +{ + uhci_softc_t *sc = UHCI_XFER2SC(xfer); + struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer); + usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc; + int endpt = ed->bEndpointAddress; + int isread = UE_GET_DIR(endpt) == UE_DIR_IN; + int len = xfer->ux_bufsize; + int err = 0; + + + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(3, "xfer=%p len=%d flags=%d", xfer, len, xfer->ux_flags, 0); + + if (sc->sc_dying) + return USBD_IOERROR; + + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); + + uxfer->ux_type = UX_BULK; + err = uhci_alloc_std_chain(sc, xfer, len, isread, &uxfer->ux_stdstart); + if (err) + return err; + +#ifdef UHCI_DEBUG + if (uhcidebug >= 10) { + DPRINTF("--- dump start ---", 0, 0, 0, 0); + uhci_dump_tds(uxfer->ux_stdstart); + DPRINTF("--- dump end ---", 0, 0, 0, 0); + } +#endif + + return 0; +} + +Static void +uhci_device_bulk_fini(struct usbd_xfer *xfer) +{ + uhci_softc_t *sc = UHCI_XFER2SC(xfer); + struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); + + KASSERT(ux->ux_type == UX_BULK); + + uhci_free_stds(sc, ux); + if (ux->ux_nstd) + kmem_free(ux->ux_stds, sizeof(uhci_soft_td_t *) * ux->ux_nstd); +} + usbd_status -uhci_device_bulk_transfer(usbd_xfer_handle xfer) +uhci_device_bulk_transfer(struct usbd_xfer *xfer) { - uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; + uhci_softc_t *sc = UHCI_XFER2SC(xfer); usbd_status err; /* Insert last in queue. */ @@ -2035,77 +2274,68 @@ uhci_device_bulk_transfer(usbd_xfer_handle xfer) err = usb_insert_transfer(xfer); mutex_exit(&sc->sc_lock); if (err) - return (err); + return err; /* * Pipe isn't running (otherwise err would be USBD_INPROG), * so start it first. */ - return (uhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return uhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } usbd_status -uhci_device_bulk_start(usbd_xfer_handle xfer) +uhci_device_bulk_start(struct usbd_xfer *xfer) { - struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; - usbd_device_handle dev = upipe->pipe.device; - uhci_softc_t *sc = dev->bus->hci_private; - uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); + struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); + uhci_softc_t *sc = UHCI_XFER2SC(xfer); uhci_soft_td_t *data, *dataend; uhci_soft_qh_t *sqh; - usbd_status err; - int len, isread, endpt; + int len; + int endpt; + int isread; - DPRINTFN(3, ("uhci_device_bulk_start: xfer=%p len=%d flags=%d ii=%p\n", - xfer, xfer->length, xfer->flags, ii)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(3, "xfer=%p len=%d flags=%d", xfer, xfer->ux_length, + xfer->ux_flags, 0); if (sc->sc_dying) - return (USBD_IOERROR); - -#ifdef DIAGNOSTIC - if (xfer->rqflags & URQ_REQUEST) - panic("uhci_device_bulk_transfer: a request"); -#endif + return USBD_IOERROR; - mutex_enter(&sc->sc_lock); + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); + KASSERT(xfer->ux_length <= xfer->ux_bufsize); - len = xfer->length; - endpt = upipe->pipe.endpoint->edesc->bEndpointAddress; + len = xfer->ux_length; + endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; isread = UE_GET_DIR(endpt) == UE_DIR_IN; - sqh = upipe->u.bulk.sqh; + sqh = upipe->bulk.sqh; - upipe->u.bulk.isread = isread; - upipe->u.bulk.length = len; + /* Take lock here to protect nexttoggle */ + mutex_enter(&sc->sc_lock); - err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags, - &xfer->dmabuf, &data, &dataend); - if (err) { - mutex_exit(&sc->sc_lock); - return (err); - } + uhci_reset_std_chain(sc, xfer, len, isread, &upipe->nexttoggle, + &dataend); + + data = ux->ux_stdstart; + ux->ux_stdend = dataend; dataend->td.td_status |= htole32(UHCI_TD_IOC); usb_syncmem(&dataend->dma, dataend->offs + offsetof(uhci_td_t, td_status), sizeof(dataend->td.td_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - #ifdef UHCI_DEBUG - if (uhcidebug > 8) { - DPRINTF(("uhci_device_bulk_transfer: data(1)\n")); + if (uhcidebug >= 10) { + DPRINTF("--- dump start ---", 0, 0, 0, 0); + DPRINTFN(10, "before transfer", 0, 0, 0, 0); uhci_dump_tds(data); + DPRINTF("--- dump end ---", 0, 0, 0, 0); } #endif - /* Set up interrupt info. */ - ii->xfer = xfer; - ii->stdstart = data; - ii->stdend = dataend; + KASSERT(ux->ux_isdone); #ifdef DIAGNOSTIC - if (!ii->isdone) { - printf("uhci_device_bulk_transfer: not done, ii=%p\n", ii); - } - ii->isdone = 0; + ux->ux_isdone = false; #endif sqh->elink = data; @@ -2113,39 +2343,31 @@ uhci_device_bulk_start(usbd_xfer_handle xfer) /* uhci_add_bulk() will do usb_syncmem(sqh) */ uhci_add_bulk(sc, sqh); - uhci_add_intr_info(sc, ii); - - if (xfer->timeout && !sc->sc_bus.use_polling) { - callout_reset(&xfer->timeout_handle, mstohz(xfer->timeout), - uhci_timeout, ii); - } - xfer->status = USBD_IN_PROGRESS; + uhci_add_intr_list(sc, ux); -#ifdef UHCI_DEBUG - if (uhcidebug > 10) { - DPRINTF(("uhci_device_bulk_transfer: data(2)\n")); - uhci_dump_tds(data); + if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { + callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), + uhci_timeout, xfer); } -#endif + xfer->ux_status = USBD_IN_PROGRESS; + mutex_exit(&sc->sc_lock); - if (sc->sc_bus.use_polling) + if (sc->sc_bus.ub_usepolling) uhci_waitintr(sc, xfer); - mutex_exit(&sc->sc_lock); - return (USBD_IN_PROGRESS); + return USBD_IN_PROGRESS; } /* Abort a device bulk request. */ void -uhci_device_bulk_abort(usbd_xfer_handle xfer) +uhci_device_bulk_abort(struct usbd_xfer *xfer) { -#ifdef DIAGNOSTIC - uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; -#endif + uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer); KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTF(("uhci_device_bulk_abort:\n")); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + uhci_abort_xfer(xfer, USBD_CANCELLED); } @@ -2162,56 +2384,57 @@ uhci_device_bulk_abort(usbd_xfer_handle xfer) * XXXMRG this doesn't make sense anymore. */ void -uhci_abort_xfer(usbd_xfer_handle xfer, usbd_status status) +uhci_abort_xfer(struct usbd_xfer *xfer, usbd_status status) { - uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; - struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; - uhci_softc_t *sc = upipe->pipe.device->bus->hci_private; + struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); + uhci_softc_t *sc = UHCI_XFER2SC(xfer); uhci_soft_td_t *std; int wake; - DPRINTFN(1,("uhci_abort_xfer: xfer=%p, status=%d\n", xfer, status)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(1,"xfer=%p, status=%d", xfer, status, 0, 0); KASSERT(mutex_owned(&sc->sc_lock)); + ASSERT_SLEEPABLE(); if (sc->sc_dying) { /* If we're dying, just do the software part. */ - xfer->status = status; /* make software ignore it */ - callout_stop(&xfer->timeout_handle); + xfer->ux_status = status; /* make software ignore it */ + callout_stop(&xfer->ux_callout); usb_transfer_complete(xfer); return; } - if (cpu_intr_p() || cpu_softintr_p()) - panic("uhci_abort_xfer: not in process context"); - /* * If an abort is already in progress then just wait for it to * complete and return. */ - if (xfer->hcflags & UXFER_ABORTING) { - DPRINTFN(2, ("uhci_abort_xfer: already aborting\n")); + if (xfer->ux_hcflags & UXFER_ABORTING) { + DPRINTFN(2, "already aborting", 0, 0, 0, 0); #ifdef DIAGNOSTIC if (status == USBD_TIMEOUT) - printf("uhci_abort_xfer: TIMEOUT while aborting\n"); + printf("%s: TIMEOUT while aborting\n", __func__); #endif /* Override the status which might be USBD_TIMEOUT. */ - xfer->status = status; - DPRINTFN(2, ("uhci_abort_xfer: waiting for abort to finish\n")); - xfer->hcflags |= UXFER_ABORTWAIT; - while (xfer->hcflags & UXFER_ABORTING) - cv_wait(&xfer->hccv, &sc->sc_lock); + xfer->ux_status = status; + DPRINTFN(2, "waiting for abort to finish", 0, 0, 0, 0); + xfer->ux_hcflags |= UXFER_ABORTWAIT; + while (xfer->ux_hcflags & UXFER_ABORTING) + cv_wait(&xfer->ux_hccv, &sc->sc_lock); goto done; } - xfer->hcflags |= UXFER_ABORTING; + xfer->ux_hcflags |= UXFER_ABORTING; /* * Step 1: Make interrupt routine and hardware ignore xfer. */ - xfer->status = status; /* make software ignore it */ - callout_stop(&xfer->timeout_handle); - DPRINTFN(1,("uhci_abort_xfer: stop ii=%p\n", ii)); - for (std = ii->stdstart; std != NULL; std = std->link.std) { + xfer->ux_status = status; /* make software ignore it */ + callout_stop(&xfer->ux_callout); + uhci_del_intr_list(sc, ux); + + DPRINTF("stop ux=%p", ux, 0, 0, 0); + for (std = ux->ux_stdstart; std != NULL; std = std->link.std) { usb_syncmem(&std->dma, std->offs + offsetof(uhci_td_t, td_status), sizeof(std->td.td_status), @@ -2229,47 +2452,94 @@ uhci_abort_xfer(usbd_xfer_handle xfer, usbd_status status) * has run. */ /* Hardware finishes in 1ms */ - usb_delay_ms_locked(upipe->pipe.device->bus, 2, &sc->sc_lock); + usb_delay_ms_locked(upipe->pipe.up_dev->ud_bus, 2, &sc->sc_lock); sc->sc_softwake = 1; usb_schedsoftintr(&sc->sc_bus); - DPRINTFN(1,("uhci_abort_xfer: cv_wait\n")); + DPRINTF("cv_wait", 0, 0, 0, 0); cv_wait(&sc->sc_softwake_cv, &sc->sc_lock); /* * Step 3: Execute callback. */ - DPRINTFN(1,("uhci_abort_xfer: callback\n")); + DPRINTF("callback", 0, 0, 0, 0); #ifdef DIAGNOSTIC - ii->isdone = 1; + ux->ux_isdone = true; #endif - wake = xfer->hcflags & UXFER_ABORTWAIT; - xfer->hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); + wake = xfer->ux_hcflags & UXFER_ABORTWAIT; + xfer->ux_hcflags &= ~(UXFER_ABORTING | UXFER_ABORTWAIT); usb_transfer_complete(xfer); if (wake) - cv_broadcast(&xfer->hccv); + cv_broadcast(&xfer->ux_hccv); done: KASSERT(mutex_owned(&sc->sc_lock)); } /* Close a device bulk pipe. */ void -uhci_device_bulk_close(usbd_pipe_handle pipe) +uhci_device_bulk_close(struct usbd_pipe *pipe) { - struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; - usbd_device_handle dev = upipe->pipe.device; - uhci_softc_t *sc = dev->bus->hci_private; + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe); + uhci_softc_t *sc = UHCI_PIPE2SC(pipe); KASSERT(mutex_owned(&sc->sc_lock)); - uhci_free_sqh(sc, upipe->u.bulk.sqh); + uhci_free_sqh(sc, upipe->bulk.sqh); + + pipe->up_endpoint->ue_toggle = upipe->nexttoggle; +} + +int +uhci_device_ctrl_init(struct usbd_xfer *xfer) +{ + struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer); + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); + usb_device_request_t *req = &xfer->ux_request; + struct usbd_device *dev = upipe->pipe.up_dev; + uhci_softc_t *sc = dev->ud_bus->ub_hcpriv; + uhci_soft_td_t *data; + int len; + usbd_status err; + int isread; + + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(3, "xfer=%p len=%d, addr=%d, endpt=%d", xfer, xfer->ux_bufsize, + dev->ud_addr, upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress); + + isread = req->bmRequestType & UT_READ; + len = xfer->ux_bufsize; + + uxfer->ux_type = UX_CTRL; + /* Set up data transaction */ + if (len != 0) { + err = uhci_alloc_std_chain(sc, xfer, len, isread, &data); + if (err) + return err; + } + /* Set up interrupt info. */ + uxfer->ux_setup = upipe->ctrl.setup; + uxfer->ux_stat = upipe->ctrl.stat; + uxfer->ux_data = data; + + return 0; +} + +Static void +uhci_device_ctrl_fini(struct usbd_xfer *xfer) +{ + uhci_softc_t *sc = UHCI_XFER2SC(xfer); + struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); + + KASSERT(ux->ux_type == UX_CTRL); - pipe->endpoint->datatoggle = upipe->nexttoggle; + uhci_free_stds(sc, ux); + if (ux->ux_nstd) + kmem_free(ux->ux_stds, sizeof(uhci_soft_td_t *) * ux->ux_nstd); } usbd_status -uhci_device_ctrl_transfer(usbd_xfer_handle xfer) +uhci_device_ctrl_transfer(struct usbd_xfer *xfer) { - uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; + uhci_softc_t *sc = UHCI_XFER2SC(xfer); usbd_status err; /* Insert last in queue. */ @@ -2277,44 +2547,207 @@ uhci_device_ctrl_transfer(usbd_xfer_handle xfer) err = usb_insert_transfer(xfer); mutex_exit(&sc->sc_lock); if (err) - return (err); + return err; /* * Pipe isn't running (otherwise err would be USBD_INPROG), * so start it first. */ - return (uhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return uhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } usbd_status -uhci_device_ctrl_start(usbd_xfer_handle xfer) -{ - uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; - usbd_status err; +uhci_device_ctrl_start(struct usbd_xfer *xfer) +{ + uhci_softc_t *sc = UHCI_XFER2SC(xfer); + struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer); + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); + usb_device_request_t *req = &xfer->ux_request; + struct usbd_device *dev = upipe->pipe.up_dev; + int addr = dev->ud_addr; + int endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; + uhci_soft_td_t *setup, *stat, *next, *dataend; + uhci_soft_qh_t *sqh; + int len; + int isread; + + UHCIHIST_FUNC(); UHCIHIST_CALLED(); if (sc->sc_dying) - return (USBD_IOERROR); + return USBD_IOERROR; + + KASSERT(xfer->ux_rqflags & URQ_REQUEST); + + DPRINTFN(3, "type=0x%02x, request=0x%02x, " + "wValue=0x%04x, wIndex=0x%04x", + req->bmRequestType, req->bRequest, UGETW(req->wValue), + UGETW(req->wIndex)); + DPRINTFN(3, "len=%d, addr=%d, endpt=%d", + UGETW(req->wLength), dev->ud_addr, endpt, 0); + isread = req->bmRequestType & UT_READ; + len = UGETW(req->wLength); + + setup = upipe->ctrl.setup; + stat = upipe->ctrl.stat; + sqh = upipe->ctrl.sqh; + + memcpy(KERNADDR(&upipe->ctrl.reqdma, 0), req, sizeof(*req)); + usb_syncmem(&upipe->ctrl.reqdma, 0, sizeof(*req), BUS_DMASYNC_PREWRITE); + + mutex_enter(&sc->sc_lock); + + /* Set up data transaction */ + if (len != 0) { + upipe->nexttoggle = 1; + next = uxfer->ux_data; + uhci_reset_std_chain(sc, xfer, len, isread, + &upipe->nexttoggle, &dataend); + dataend->link.std = stat; + dataend->td.td_link = htole32(stat->physaddr | UHCI_PTR_TD); + usb_syncmem(&dataend->dma, + dataend->offs + offsetof(uhci_td_t, td_link), + sizeof(dataend->td.td_link), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + } else { + next = stat; + } + + const uint32_t status = UHCI_TD_ZERO_ACTLEN( + UHCI_TD_SET_ERRCNT(3) | + UHCI_TD_ACTIVE | + (dev->ud_speed == USB_SPEED_LOW ? UHCI_TD_LS : 0) + ); + setup->link.std = next; + setup->td.td_link = htole32(next->physaddr | UHCI_PTR_TD); + setup->td.td_status = htole32(status); + setup->td.td_token = htole32(UHCI_TD_SETUP(sizeof(*req), endpt, addr)); + setup->td.td_buffer = htole32(DMAADDR(&upipe->ctrl.reqdma, 0)); + + usb_syncmem(&setup->dma, setup->offs, sizeof(setup->td), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + + stat->link.std = NULL; + stat->td.td_link = htole32(UHCI_PTR_T); + stat->td.td_status = htole32(status | UHCI_TD_IOC); + stat->td.td_token = + htole32(isread ? UHCI_TD_OUT(0, endpt, addr, 1) : + UHCI_TD_IN (0, endpt, addr, 1)); + stat->td.td_buffer = htole32(0); + usb_syncmem(&stat->dma, stat->offs, sizeof(stat->td), + BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + +#ifdef UHCI_DEBUG + if (uhcidebug >= 10) { + DPRINTF("--- dump start ---", 0, 0, 0, 0); + DPRINTF("before transfer", 0, 0, 0, 0); + uhci_dump_tds(setup); + DPRINTF("--- dump end ---", 0, 0, 0, 0); + } +#endif + + /* Set up interrupt info. */ + uxfer->ux_setup = setup; + uxfer->ux_stat = stat; + KASSERT(uxfer->ux_isdone); #ifdef DIAGNOSTIC - if (!(xfer->rqflags & URQ_REQUEST)) - panic("uhci_device_ctrl_transfer: not a request"); + uxfer->ux_isdone = false; #endif - mutex_enter(&sc->sc_lock); - err = uhci_device_request(xfer); + sqh->elink = setup; + sqh->qh.qh_elink = htole32(setup->physaddr | UHCI_PTR_TD); + /* uhci_add_?s_ctrl() will do usb_syncmem(sqh) */ + + if (dev->ud_speed == USB_SPEED_LOW) + uhci_add_ls_ctrl(sc, sqh); + else + uhci_add_hs_ctrl(sc, sqh); + uhci_add_intr_list(sc, uxfer); +#ifdef UHCI_DEBUG + if (uhcidebug >= 12) { + uhci_soft_td_t *std; + uhci_soft_qh_t *xqh; + uhci_soft_qh_t *sxqh; + int maxqh = 0; + uhci_physaddr_t link; + DPRINTFN(12, "--- dump start ---", 0, 0, 0, 0); + DPRINTFN(12, "follow from [0]", 0, 0, 0, 0); + for (std = sc->sc_vframes[0].htd, link = 0; + (link & UHCI_PTR_QH) == 0; + std = std->link.std) { + link = le32toh(std->td.td_link); + uhci_dump_td(std); + } + 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); + } + DPRINTFN(12, "Enqueued QH:", 0, 0, 0, 0); + uhci_dump_qh(sqh); + uhci_dump_tds(sqh->elink); + DPRINTF("--- dump end ---", 0, 0, 0, 0); + } +#endif + if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { + callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), + uhci_timeout, xfer); + } + xfer->ux_status = USBD_IN_PROGRESS; mutex_exit(&sc->sc_lock); - if (err) - return (err); - if (sc->sc_bus.use_polling) + if (sc->sc_bus.ub_usepolling) uhci_waitintr(sc, xfer); - return (USBD_IN_PROGRESS); + + return USBD_IN_PROGRESS; +} + +int +uhci_device_intr_init(struct usbd_xfer *xfer) +{ + uhci_softc_t *sc = UHCI_XFER2SC(xfer); + struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); + usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc; + int endpt = ed->bEndpointAddress; + int isread = UE_GET_DIR(endpt) == UE_DIR_IN; + int len = xfer->ux_bufsize; + int err; + + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + + DPRINTFN(3, "xfer=%p len=%d flags=%d", xfer, xfer->ux_length, + xfer->ux_flags, 0); + + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); + KASSERT(len != 0); + + ux->ux_type = UX_INTR; + ux->ux_nstd = 0; + err = uhci_alloc_std_chain(sc, xfer, len, isread, &ux->ux_stdstart); + + return err; +} + +Static void +uhci_device_intr_fini(struct usbd_xfer *xfer) +{ + uhci_softc_t *sc = UHCI_XFER2SC(xfer); + struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); + + KASSERT(ux->ux_type == UX_INTR); + + uhci_free_stds(sc, ux); + if (ux->ux_nstd) + kmem_free(ux->ux_stds, sizeof(uhci_soft_td_t *) * ux->ux_nstd); } usbd_status -uhci_device_intr_transfer(usbd_xfer_handle xfer) +uhci_device_intr_transfer(struct usbd_xfer *xfer) { - uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; + uhci_softc_t *sc = UHCI_XFER2SC(xfer); usbd_status err; /* Insert last in queue. */ @@ -2322,83 +2755,71 @@ uhci_device_intr_transfer(usbd_xfer_handle xfer) err = usb_insert_transfer(xfer); mutex_exit(&sc->sc_lock); if (err) - return (err); + return err; /* * Pipe isn't running (otherwise err would be USBD_INPROG), * so start it first. */ - return (uhci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return uhci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } usbd_status -uhci_device_intr_start(usbd_xfer_handle xfer) +uhci_device_intr_start(struct usbd_xfer *xfer) { - struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; - usbd_device_handle dev = upipe->pipe.device; - uhci_softc_t *sc = dev->bus->hci_private; - uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; + struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); + uhci_softc_t *sc = UHCI_XFER2SC(xfer); uhci_soft_td_t *data, *dataend; uhci_soft_qh_t *sqh; - usbd_status err; int isread, endpt; int i; if (sc->sc_dying) - return (USBD_IOERROR); + return USBD_IOERROR; - DPRINTFN(3,("uhci_device_intr_transfer: xfer=%p len=%d flags=%d\n", - xfer, xfer->length, xfer->flags)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); -#ifdef DIAGNOSTIC - if (xfer->rqflags & URQ_REQUEST) - panic("uhci_device_intr_transfer: a request"); -#endif + DPRINTFN(3, "xfer=%p len=%d flags=%d", xfer, xfer->ux_length, + xfer->ux_flags, 0); - mutex_enter(&sc->sc_lock); + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); + KASSERT(xfer->ux_length <= xfer->ux_bufsize); - endpt = upipe->pipe.endpoint->edesc->bEndpointAddress; + endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; isread = UE_GET_DIR(endpt) == UE_DIR_IN; - upipe->u.intr.isread = isread; + data = ux->ux_stdstart; - err = uhci_alloc_std_chain(upipe, sc, xfer->length, isread, - xfer->flags, &xfer->dmabuf, &data, - &dataend); - if (err) { - mutex_exit(&sc->sc_lock); - return (err); - } + KASSERT(ux->ux_isdone); +#ifdef DIAGNOSTIC + ux->ux_isdone = false; +#endif + + /* Take lock to protect nexttoggle */ + mutex_enter(&sc->sc_lock); + uhci_reset_std_chain(sc, xfer, xfer->ux_length, isread, + &upipe->nexttoggle, &dataend); dataend->td.td_status |= htole32(UHCI_TD_IOC); usb_syncmem(&dataend->dma, dataend->offs + offsetof(uhci_td_t, td_status), sizeof(dataend->td.td_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); + ux->ux_stdend = dataend; #ifdef UHCI_DEBUG - if (uhcidebug > 10) { - DPRINTF(("uhci_device_intr_transfer: data(1)\n")); + if (uhcidebug >= 10) { + DPRINTF("--- dump start ---", 0, 0, 0, 0); uhci_dump_tds(data); - uhci_dump_qh(upipe->u.intr.qhs[0]); - } -#endif - - /* Set up interrupt info. */ - ii->xfer = xfer; - ii->stdstart = data; - ii->stdend = dataend; -#ifdef DIAGNOSTIC - if (!ii->isdone) { - printf("uhci_device_intr_transfer: not done, ii=%p\n", ii); + uhci_dump_qh(upipe->intr.qhs[0]); + DPRINTF("--- dump end ---", 0, 0, 0, 0); } - ii->isdone = 0; #endif - DPRINTFN(10,("uhci_device_intr_transfer: qhs[0]=%p\n", - upipe->u.intr.qhs[0])); - for (i = 0; i < upipe->u.intr.npoll; i++) { - sqh = upipe->u.intr.qhs[i]; + DPRINTFN(10, "qhs[0]=%p", upipe->intr.qhs[0], 0, 0, 0); + for (i = 0; i < upipe->intr.npoll; i++) { + sqh = upipe->intr.qhs[i]; sqh->elink = data; sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD); usb_syncmem(&sqh->dma, @@ -2406,71 +2827,76 @@ uhci_device_intr_start(usbd_xfer_handle xfer) sizeof(sqh->qh.qh_elink), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } - uhci_add_intr_info(sc, ii); - xfer->status = USBD_IN_PROGRESS; + uhci_add_intr_list(sc, ux); + xfer->ux_status = USBD_IN_PROGRESS; mutex_exit(&sc->sc_lock); #ifdef UHCI_DEBUG - if (uhcidebug > 10) { - DPRINTF(("uhci_device_intr_transfer: data(2)\n")); + if (uhcidebug >= 10) { + DPRINTF("--- dump start ---", 0, 0, 0, 0); uhci_dump_tds(data); - uhci_dump_qh(upipe->u.intr.qhs[0]); + uhci_dump_qh(upipe->intr.qhs[0]); + DPRINTF("--- dump end ---", 0, 0, 0, 0); } #endif - return (USBD_IN_PROGRESS); + return USBD_IN_PROGRESS; } /* Abort a device control request. */ void -uhci_device_ctrl_abort(usbd_xfer_handle xfer) +uhci_device_ctrl_abort(struct usbd_xfer *xfer) { -#ifdef DIAGNOSTIC - uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; -#endif + uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer); KASSERT(mutex_owned(&sc->sc_lock)); - DPRINTF(("uhci_device_ctrl_abort:\n")); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); uhci_abort_xfer(xfer, USBD_CANCELLED); } /* Close a device control pipe. */ void -uhci_device_ctrl_close(usbd_pipe_handle pipe) +uhci_device_ctrl_close(struct usbd_pipe *pipe) { + uhci_softc_t *sc = UHCI_PIPE2SC(pipe); + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe); + + uhci_free_sqh(sc, upipe->ctrl.sqh); + uhci_free_std_locked(sc, upipe->ctrl.setup); + uhci_free_std_locked(sc, upipe->ctrl.stat); + } /* Abort a device interrupt request. */ void -uhci_device_intr_abort(usbd_xfer_handle xfer) +uhci_device_intr_abort(struct usbd_xfer *xfer) { -#ifdef DIAGNOSTIC - uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; -#endif + uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer); KASSERT(mutex_owned(&sc->sc_lock)); - KASSERT(xfer->pipe->intrxfer == xfer); + KASSERT(xfer->ux_pipe->up_intrxfer == xfer); - DPRINTFN(1,("uhci_device_intr_abort: xfer=%p\n", xfer)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTF("xfer=%p", xfer, 0, 0, 0); uhci_abort_xfer(xfer, USBD_CANCELLED); } /* Close a device interrupt pipe. */ void -uhci_device_intr_close(usbd_pipe_handle pipe) +uhci_device_intr_close(struct usbd_pipe *pipe) { - struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; - uhci_softc_t *sc = pipe->device->bus->hci_private; + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe); + uhci_softc_t *sc = UHCI_PIPE2SC(pipe); int i, npoll; KASSERT(mutex_owned(&sc->sc_lock)); /* Unlink descriptors from controller data structures. */ - npoll = upipe->u.intr.npoll; + npoll = upipe->intr.npoll; for (i = 0; i < npoll; i++) - uhci_remove_intr(sc, upipe->u.intr.qhs[i]); + uhci_remove_intr(sc, upipe->intr.qhs[i]); /* * We now have to wait for any activity on the physical @@ -2479,233 +2905,100 @@ uhci_device_intr_close(usbd_pipe_handle pipe) usb_delay_ms_locked(&sc->sc_bus, 2, &sc->sc_lock); for (i = 0; i < npoll; i++) - uhci_free_sqh(sc, upipe->u.intr.qhs[i]); - kmem_free(upipe->u.intr.qhs, npoll * sizeof(uhci_soft_qh_t *)); - - /* XXX free other resources */ + uhci_free_sqh(sc, upipe->intr.qhs[i]); + kmem_free(upipe->intr.qhs, npoll * sizeof(uhci_soft_qh_t *)); } -usbd_status -uhci_device_request(usbd_xfer_handle xfer) -{ - 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 = dev->bus->hci_private; - int addr = dev->address; - int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress; - uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; - uhci_soft_td_t *setup, *data, *stat, *next, *dataend; - uhci_soft_qh_t *sqh; - int len; - u_int32_t ls; - usbd_status err; - int isread; - - KASSERT(mutex_owned(&sc->sc_lock)); - - DPRINTFN(3,("uhci_device_control type=0x%02x, request=0x%02x, " - "wValue=0x%04x, wIndex=0x%04x len=%d, addr=%d, endpt=%d\n", - req->bmRequestType, req->bRequest, UGETW(req->wValue), - UGETW(req->wIndex), UGETW(req->wLength), - addr, endpt)); - - ls = dev->speed == USB_SPEED_LOW ? UHCI_TD_LS : 0; - isread = req->bmRequestType & UT_READ; - len = UGETW(req->wLength); - - setup = upipe->u.ctl.setup; - stat = upipe->u.ctl.stat; - sqh = upipe->u.ctl.sqh; - - /* Set up data transaction */ - if (len != 0) { - upipe->nexttoggle = 1; - err = uhci_alloc_std_chain(upipe, sc, len, isread, xfer->flags, - &xfer->dmabuf, &data, &dataend); - if (err) - return (err); - next = data; - dataend->link.std = stat; - dataend->td.td_link = htole32(stat->physaddr | UHCI_PTR_TD); - usb_syncmem(&dataend->dma, - dataend->offs + offsetof(uhci_td_t, td_link), - sizeof(dataend->td.td_link), - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - } else { - next = stat; - } - upipe->u.ctl.length = len; - - memcpy(KERNADDR(&upipe->u.ctl.reqdma, 0), req, sizeof *req); - usb_syncmem(&upipe->u.ctl.reqdma, 0, sizeof *req, BUS_DMASYNC_PREWRITE); - - setup->link.std = next; - setup->td.td_link = htole32(next->physaddr | UHCI_PTR_TD); - setup->td.td_status = htole32(UHCI_TD_SET_ERRCNT(3) | ls | - UHCI_TD_ACTIVE); - setup->td.td_token = htole32(UHCI_TD_SETUP(sizeof *req, endpt, addr)); - setup->td.td_buffer = htole32(DMAADDR(&upipe->u.ctl.reqdma, 0)); - usb_syncmem(&setup->dma, setup->offs, sizeof(setup->td), - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - - stat->link.std = NULL; - stat->td.td_link = htole32(UHCI_PTR_T); - stat->td.td_status = htole32(UHCI_TD_SET_ERRCNT(3) | ls | - UHCI_TD_ACTIVE | UHCI_TD_IOC); - stat->td.td_token = - htole32(isread ? UHCI_TD_OUT(0, endpt, addr, 1) : - UHCI_TD_IN (0, endpt, addr, 1)); - stat->td.td_buffer = htole32(0); - usb_syncmem(&stat->dma, stat->offs, sizeof(stat->td), - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - -#ifdef UHCI_DEBUG - if (uhcidebug > 10) { - DPRINTF(("uhci_device_request: before transfer\n")); - uhci_dump_tds(setup); - } -#endif +int +uhci_device_isoc_init(struct usbd_xfer *xfer) +{ + struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); - /* Set up interrupt info. */ - ii->xfer = xfer; - ii->stdstart = setup; - ii->stdend = stat; -#ifdef DIAGNOSTIC - if (!ii->isdone) { - printf("uhci_device_request: not done, ii=%p\n", ii); - } - ii->isdone = 0; -#endif + KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); + KASSERT(xfer->ux_nframes != 0); + KASSERT(ux->ux_isdone); - sqh->elink = setup; - sqh->qh.qh_elink = htole32(setup->physaddr | UHCI_PTR_TD); - /* uhci_add_?s_ctrl() will do usb_syncmem(sqh) */ + ux->ux_type = UX_ISOC; + return 0; +} - if (dev->speed == USB_SPEED_LOW) - uhci_add_ls_ctrl(sc, sqh); - else - uhci_add_hs_ctrl(sc, sqh); - uhci_add_intr_info(sc, ii); -#ifdef UHCI_DEBUG - if (uhcidebug > 12) { - uhci_soft_td_t *std; - uhci_soft_qh_t *xqh; - uhci_soft_qh_t *sxqh; - int maxqh = 0; - uhci_physaddr_t link; - DPRINTF(("uhci_enter_ctl_q: follow from [0]\n")); - for (std = sc->sc_vframes[0].htd, link = 0; - (link & UHCI_PTR_QH) == 0; - std = std->link.std) { - link = le32toh(std->td.td_link); - uhci_dump_td(std); - } - 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); - } - DPRINTF(("Enqueued QH:\n")); - uhci_dump_qh(sqh); - uhci_dump_tds(sqh->elink); - } -#endif - if (xfer->timeout && !sc->sc_bus.use_polling) { - callout_reset(&xfer->timeout_handle, mstohz(xfer->timeout), - uhci_timeout, ii); - } - xfer->status = USBD_IN_PROGRESS; +Static void +uhci_device_isoc_fini(struct usbd_xfer *xfer) +{ + struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); - return (USBD_NORMAL_COMPLETION); + KASSERT(ux->ux_type == UX_ISOC); } usbd_status -uhci_device_isoc_transfer(usbd_xfer_handle xfer) +uhci_device_isoc_transfer(struct usbd_xfer *xfer) { - uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; - usbd_status err; + uhci_softc_t *sc = UHCI_XFER2SC(xfer); + usbd_status err __diagused; - DPRINTFN(5,("uhci_device_isoc_transfer: xfer=%p\n", xfer)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(5, "xfer=%p", xfer, 0, 0, 0); /* Put it on our queue, */ mutex_enter(&sc->sc_lock); err = usb_insert_transfer(xfer); mutex_exit(&sc->sc_lock); - /* bail out on error, */ - if (err && err != USBD_IN_PROGRESS) - return (err); - - /* XXX should check inuse here */ + KASSERT(err == USBD_NORMAL_COMPLETION); /* insert into schedule, */ - uhci_device_isoc_enter(xfer); - - /* and start if the pipe wasn't running */ - if (!err) - uhci_device_isoc_start(SIMPLEQ_FIRST(&xfer->pipe->queue)); - return (err); -} - -void -uhci_device_isoc_enter(usbd_xfer_handle xfer) -{ - struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; - usbd_device_handle dev = upipe->pipe.device; - uhci_softc_t *sc = dev->bus->hci_private; - struct iso *iso = &upipe->u.iso; - uhci_soft_td_t *std; - u_int32_t buf, len, status, offs; + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); + struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); + struct isoc *isoc = &upipe->isoc; + uhci_soft_td_t *std = NULL; + uint32_t buf, len, status, offs; int i, next, nframes; - int rd = UE_GET_DIR(upipe->pipe.endpoint->edesc->bEndpointAddress) == UE_DIR_IN; + int rd = UE_GET_DIR(upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN; - DPRINTFN(5,("uhci_device_isoc_enter: used=%d next=%d xfer=%p " - "nframes=%d\n", - iso->inuse, iso->next, xfer, xfer->nframes)); + DPRINTFN(5, "used=%d next=%d xfer=%p nframes=%d", + isoc->inuse, isoc->next, xfer, xfer->ux_nframes); if (sc->sc_dying) - return; + return USBD_IOERROR; - if (xfer->status == USBD_IN_PROGRESS) { + if (xfer->ux_status == USBD_IN_PROGRESS) { /* This request has already been entered into the frame list */ - printf("uhci_device_isoc_enter: xfer=%p in frame list\n", xfer); + printf("%s: xfer=%p in frame list\n", __func__, xfer); /* XXX */ } #ifdef DIAGNOSTIC - if (iso->inuse >= UHCI_VFRAMELIST_COUNT) - printf("uhci_device_isoc_enter: overflow!\n"); + if (isoc->inuse >= UHCI_VFRAMELIST_COUNT) + printf("%s: overflow!\n", __func__); #endif - next = iso->next; + KASSERT(xfer->ux_nframes != 0); + + mutex_enter(&sc->sc_lock); + next = isoc->next; if (next == -1) { /* Not in use yet, schedule it a few frames ahead. */ next = (UREAD2(sc, UHCI_FRNUM) + 3) % UHCI_VFRAMELIST_COUNT; - DPRINTFN(2,("uhci_device_isoc_enter: start next=%d\n", next)); + DPRINTFN(2, "start next=%d", next, 0, 0, 0); } - xfer->status = USBD_IN_PROGRESS; - UXFER(xfer)->curframe = next; + xfer->ux_status = USBD_IN_PROGRESS; + ux->ux_curframe = next; - buf = DMAADDR(&xfer->dmabuf, 0); + buf = DMAADDR(&xfer->ux_dmabuf, 0); offs = 0; status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(0) | UHCI_TD_ACTIVE | UHCI_TD_IOS); - nframes = xfer->nframes; - mutex_enter(&sc->sc_lock); + nframes = xfer->ux_nframes; for (i = 0; i < nframes; i++) { - std = iso->stds[next]; + std = isoc->stds[next]; if (++next >= UHCI_VFRAMELIST_COUNT) next = 0; - len = xfer->frlengths[i]; + len = xfer->ux_frlengths[i]; std->td.td_buffer = htole32(buf); - usb_syncmem(&xfer->dmabuf, offs, len, + usb_syncmem(&xfer->ux_dmabuf, offs, len, rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); if (i == nframes - 1) status |= UHCI_TD_IOC; @@ -2715,97 +3008,58 @@ uhci_device_isoc_enter(usbd_xfer_handle xfer) usb_syncmem(&std->dma, std->offs, sizeof(std->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); #ifdef UHCI_DEBUG - if (uhcidebug > 5) { - DPRINTFN(5,("uhci_device_isoc_enter: TD %d\n", i)); + if (uhcidebug >= 5) { + DPRINTF("--- dump start ---", 0, 0, 0, 0); + DPRINTF("TD %d", i, 0, 0, 0); uhci_dump_td(std); + DPRINTF("--- dump end ---", 0, 0, 0, 0); } #endif buf += len; offs += len; } - iso->next = next; - iso->inuse += xfer->nframes; - - mutex_exit(&sc->sc_lock); -} - -usbd_status -uhci_device_isoc_start(usbd_xfer_handle xfer) -{ - struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; - uhci_softc_t *sc = upipe->pipe.device->bus->hci_private; - uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; - uhci_soft_td_t *end; - int i; - - DPRINTFN(5,("uhci_device_isoc_start: xfer=%p\n", xfer)); - - mutex_enter(&sc->sc_lock); - - if (sc->sc_dying) { - mutex_exit(&sc->sc_lock); - return (USBD_IOERROR); - } - -#ifdef DIAGNOSTIC - if (xfer->status != USBD_IN_PROGRESS) - printf("uhci_device_isoc_start: not in progress %p\n", xfer); -#endif - - /* Find the last TD */ - i = UXFER(xfer)->curframe + xfer->nframes; - if (i >= UHCI_VFRAMELIST_COUNT) - i -= UHCI_VFRAMELIST_COUNT; - end = upipe->u.iso.stds[i]; - -#ifdef DIAGNOSTIC - if (end == NULL) { - printf("uhci_device_isoc_start: end == NULL\n"); - return (USBD_INVAL); - } -#endif + isoc->next = next; + isoc->inuse += xfer->ux_nframes; /* Set up interrupt info. */ - ii->xfer = xfer; - ii->stdstart = end; - ii->stdend = end; + ux->ux_stdstart = std; + ux->ux_stdend = std; + + KASSERT(ux->ux_isdone); #ifdef DIAGNOSTIC - if (!ii->isdone) - printf("uhci_device_isoc_start: not done, ii=%p\n", ii); - ii->isdone = 0; + ux->ux_isdone = false; #endif - uhci_add_intr_info(sc, ii); + uhci_add_intr_list(sc, ux); mutex_exit(&sc->sc_lock); - return (USBD_IN_PROGRESS); + return USBD_IN_PROGRESS; } void -uhci_device_isoc_abort(usbd_xfer_handle xfer) +uhci_device_isoc_abort(struct usbd_xfer *xfer) { -#ifdef DIAGNOSTIC - uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; -#endif - struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; - uhci_soft_td_t **stds = upipe->u.iso.stds; + uhci_softc_t *sc = UHCI_XFER2SC(xfer); + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); + struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); + uhci_soft_td_t **stds = upipe->isoc.stds; uhci_soft_td_t *std; int i, n, nframes, maxlen, len; KASSERT(mutex_owned(&sc->sc_lock)); /* Transfer is already done. */ - if (xfer->status != USBD_NOT_STARTED && - xfer->status != USBD_IN_PROGRESS) { + if (xfer->ux_status != USBD_NOT_STARTED && + xfer->ux_status != USBD_IN_PROGRESS) { return; } /* Give xfer the requested abort code. */ - xfer->status = USBD_CANCELLED; + xfer->ux_status = USBD_CANCELLED; /* make hardware ignore it, */ - nframes = xfer->nframes; - n = UXFER(xfer)->curframe; + nframes = xfer->ux_nframes; + n = ux->ux_curframe; maxlen = 0; for (i = 0; i < nframes; i++) { std = stds[n]; @@ -2833,22 +3087,24 @@ uhci_device_isoc_abort(usbd_xfer_handle xfer) delay(maxlen); #ifdef DIAGNOSTIC - UXFER(xfer)->iinfo.isdone = 1; + ux->ux_isdone = true; #endif - /* Run callback and remove from interrupt list. */ + /* Remove from interrupt list. */ + uhci_del_intr_list(sc, ux); + + /* Run callback. */ usb_transfer_complete(xfer); KASSERT(mutex_owned(&sc->sc_lock)); } void -uhci_device_isoc_close(usbd_pipe_handle pipe) +uhci_device_isoc_close(struct usbd_pipe *pipe) { - struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; - usbd_device_handle dev = upipe->pipe.device; - uhci_softc_t *sc = dev->bus->hci_private; + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe); + uhci_softc_t *sc = UHCI_PIPE2SC(pipe); uhci_soft_td_t *std, *vstd; - struct iso *iso; + struct isoc *isoc; int i; KASSERT(mutex_owned(&sc->sc_lock)); @@ -2859,10 +3115,10 @@ uhci_device_isoc_close(usbd_pipe_handle pipe) * Unschedule. * Deallocate. */ - iso = &upipe->u.iso; + isoc = &upipe->isoc; for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { - std = iso->stds[i]; + std = isoc->stds[i]; usb_syncmem(&std->dma, std->offs + offsetof(uhci_td_t, td_status), sizeof(std->td.td_status), @@ -2877,14 +3133,14 @@ uhci_device_isoc_close(usbd_pipe_handle pipe) usb_delay_ms_locked(&sc->sc_bus, 2, &sc->sc_lock); for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { - std = iso->stds[i]; + std = isoc->stds[i]; for (vstd = sc->sc_vframes[i].htd; vstd != NULL && vstd->link.std != std; vstd = vstd->link.std) ; if (vstd == NULL) { /*panic*/ - printf("uhci_device_isoc_close: %p not found\n", std); + printf("%s: %p not found\n", __func__, std); mutex_exit(&sc->sc_lock); return; } @@ -2898,38 +3154,35 @@ uhci_device_isoc_close(usbd_pipe_handle pipe) vstd->offs + offsetof(uhci_td_t, td_link), sizeof(vstd->td.td_link), BUS_DMASYNC_PREWRITE); - uhci_free_std(sc, std); + uhci_free_std_locked(sc, std); } - kmem_free(iso->stds, UHCI_VFRAMELIST_COUNT * sizeof (uhci_soft_td_t *)); + kmem_free(isoc->stds, UHCI_VFRAMELIST_COUNT * sizeof(uhci_soft_td_t *)); } usbd_status -uhci_setup_isoc(usbd_pipe_handle pipe) +uhci_setup_isoc(struct usbd_pipe *pipe) { - struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; - usbd_device_handle dev = upipe->pipe.device; - uhci_softc_t *sc = dev->bus->hci_private; - int addr = upipe->pipe.device->address; - int endpt = upipe->pipe.endpoint->edesc->bEndpointAddress; + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe); + uhci_softc_t *sc = UHCI_PIPE2SC(pipe); + int addr = upipe->pipe.up_dev->ud_addr; + int endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; int rd = UE_GET_DIR(endpt) == UE_DIR_IN; uhci_soft_td_t *std, *vstd; - u_int32_t token; - struct iso *iso; + uint32_t token; + struct isoc *isoc; int i; - iso = &upipe->u.iso; - iso->stds = kmem_alloc(UHCI_VFRAMELIST_COUNT * - sizeof (uhci_soft_td_t *), - KM_SLEEP); - if (iso->stds == NULL) + isoc = &upipe->isoc; + + isoc->stds = kmem_alloc( + UHCI_VFRAMELIST_COUNT * sizeof(uhci_soft_td_t *), KM_SLEEP); + if (isoc->stds == NULL) return USBD_NOMEM; token = rd ? UHCI_TD_IN (0, endpt, addr, 0) : UHCI_TD_OUT(0, endpt, addr, 0); - mutex_enter(&sc->sc_lock); - /* Allocate the TDs and mark as inactive; */ for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { std = uhci_alloc_std(sc); @@ -2939,12 +3192,14 @@ uhci_setup_isoc(usbd_pipe_handle pipe) std->td.td_token = htole32(token); usb_syncmem(&std->dma, std->offs, sizeof(std->td), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - iso->stds[i] = std; + isoc->stds[i] = std; } + mutex_enter(&sc->sc_lock); + /* Insert TDs into schedule. */ for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { - std = iso->stds[i]; + std = isoc->stds[i]; vstd = sc->sc_vframes[i].htd; usb_syncmem(&vstd->dma, vstd->offs + offsetof(uhci_td_t, td_link), @@ -2965,85 +3220,77 @@ uhci_setup_isoc(usbd_pipe_handle pipe) } mutex_exit(&sc->sc_lock); - iso->next = -1; - iso->inuse = 0; + isoc->next = -1; + isoc->inuse = 0; - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; bad: while (--i >= 0) - uhci_free_std(sc, iso->stds[i]); - mutex_exit(&sc->sc_lock); - kmem_free(iso->stds, UHCI_VFRAMELIST_COUNT * sizeof (uhci_soft_td_t *)); - return (USBD_NOMEM); + uhci_free_std(sc, isoc->stds[i]); + kmem_free(isoc->stds, UHCI_VFRAMELIST_COUNT * sizeof(uhci_soft_td_t *)); + return USBD_NOMEM; } void -uhci_device_isoc_done(usbd_xfer_handle xfer) +uhci_device_isoc_done(struct usbd_xfer *xfer) { - uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; - struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); + struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); int i, offs; - int rd = UE_GET_DIR(upipe->pipe.endpoint->edesc->bEndpointAddress) == UE_DIR_IN; + int rd = UE_GET_DIR(upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN; - - DPRINTFN(4, ("uhci_isoc_done: length=%d, busy_free=0x%08x\n", - xfer->actlen, xfer->busy_free)); - - if (ii->xfer != xfer) - /* Not on interrupt list, ignore it. */ - return; - - if (!uhci_active_intr_info(ii)) - return; + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(4, "length=%d, ux_state=0x%08x", + xfer->ux_actlen, xfer->ux_state, 0, 0); #ifdef DIAGNOSTIC - if (ii->stdend == NULL) { - printf("uhci_device_isoc_done: xfer=%p stdend==NULL\n", xfer); + if (ux->ux_stdend == NULL) { + printf("%s: xfer=%p stdend==NULL\n", __func__, xfer); #ifdef UHCI_DEBUG - uhci_dump_ii(ii); + DPRINTF("--- dump start ---", 0, 0, 0, 0); + uhci_dump_ii(ux); + DPRINTF("--- dump end ---", 0, 0, 0, 0); #endif return; } #endif /* Turn off the interrupt since it is active even if the TD is not. */ - usb_syncmem(&ii->stdend->dma, - ii->stdend->offs + offsetof(uhci_td_t, td_status), - sizeof(ii->stdend->td.td_status), + usb_syncmem(&ux->ux_stdend->dma, + ux->ux_stdend->offs + offsetof(uhci_td_t, td_status), + sizeof(ux->ux_stdend->td.td_status), BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); - ii->stdend->td.td_status &= htole32(~UHCI_TD_IOC); - usb_syncmem(&ii->stdend->dma, - ii->stdend->offs + offsetof(uhci_td_t, td_status), - sizeof(ii->stdend->td.td_status), + ux->ux_stdend->td.td_status &= htole32(~UHCI_TD_IOC); + usb_syncmem(&ux->ux_stdend->dma, + ux->ux_stdend->offs + offsetof(uhci_td_t, td_status), + sizeof(ux->ux_stdend->td.td_status), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - uhci_del_intr_info(ii); /* remove from active list */ - offs = 0; - for (i = 0; i < xfer->nframes; i++) { - usb_syncmem(&xfer->dmabuf, offs, xfer->frlengths[i], + for (i = 0; i < xfer->ux_nframes; i++) { + usb_syncmem(&xfer->ux_dmabuf, offs, xfer->ux_frlengths[i], rd ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); - offs += xfer->frlengths[i]; + offs += xfer->ux_frlengths[i]; } } void -uhci_device_intr_done(usbd_xfer_handle xfer) +uhci_device_intr_done(struct usbd_xfer *xfer) { - uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; - uhci_softc_t *sc = ii->sc; - struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; + uhci_softc_t *sc = UHCI_XFER2SC(xfer); + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); uhci_soft_qh_t *sqh; - int i, npoll, isread; + int i, npoll; - DPRINTFN(5, ("uhci_device_intr_done: length=%d\n", xfer->actlen)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(5, "length=%d", xfer->ux_actlen, 0, 0, 0); - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); - npoll = upipe->u.intr.npoll; + npoll = upipe->intr.npoll; for (i = 0; i < npoll; i++) { - sqh = upipe->u.intr.qhs[i]; + sqh = upipe->intr.qhs[i]; sqh->elink = NULL; sqh->qh.qh_elink = htole32(UHCI_PTR_T); usb_syncmem(&sqh->dma, @@ -3051,125 +3298,66 @@ uhci_device_intr_done(usbd_xfer_handle xfer) sizeof(sqh->qh.qh_elink), BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); } - uhci_free_std_chain(sc, ii->stdstart, NULL); - - isread = UE_GET_DIR(upipe->pipe.endpoint->edesc->bEndpointAddress) == UE_DIR_IN; - usb_syncmem(&xfer->dmabuf, 0, xfer->length, + const int endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; + const bool isread = UE_GET_DIR(endpt) == UE_DIR_IN; + usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); - - /* XXX Wasteful. */ - if (xfer->pipe->repeat) { - uhci_soft_td_t *data, *dataend; - - DPRINTFN(5,("uhci_device_intr_done: requeing\n")); - - /* This alloc cannot fail since we freed the chain above. */ - uhci_alloc_std_chain(upipe, sc, xfer->length, - upipe->u.intr.isread, xfer->flags, - &xfer->dmabuf, &data, &dataend); - dataend->td.td_status |= htole32(UHCI_TD_IOC); - usb_syncmem(&dataend->dma, - dataend->offs + offsetof(uhci_td_t, td_status), - sizeof(dataend->td.td_status), - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - -#ifdef UHCI_DEBUG - if (uhcidebug > 10) { - DPRINTF(("uhci_device_intr_done: data(1)\n")); - uhci_dump_tds(data); - uhci_dump_qh(upipe->u.intr.qhs[0]); - } -#endif - - ii->stdstart = data; - ii->stdend = dataend; -#ifdef DIAGNOSTIC - if (!ii->isdone) { - printf("uhci_device_intr_done: not done, ii=%p\n", ii); - } - ii->isdone = 0; -#endif - for (i = 0; i < npoll; i++) { - sqh = upipe->u.intr.qhs[i]; - sqh->elink = data; - sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD); - usb_syncmem(&sqh->dma, - sqh->offs + offsetof(uhci_qh_t, qh_elink), - sizeof(sqh->qh.qh_elink), - BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); - } - xfer->status = USBD_IN_PROGRESS; - /* The ii is already on the examined list, just leave it. */ - } else { - DPRINTFN(5,("uhci_device_intr_done: removing\n")); - if (uhci_active_intr_info(ii)) - uhci_del_intr_info(ii); - } } /* Deallocate request data structures */ void -uhci_device_ctrl_done(usbd_xfer_handle xfer) +uhci_device_ctrl_done(struct usbd_xfer *xfer) { - uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; - uhci_softc_t *sc = ii->sc; - struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; - int len = UGETW(xfer->request.wLength); - int isread = (xfer->request.bmRequestType & UT_READ); + uhci_softc_t *sc = UHCI_XFER2SC(xfer); + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); + int len = UGETW(xfer->ux_request.wLength); + int isread = (xfer->ux_request.bmRequestType & UT_READ); - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); -#ifdef DIAGNOSTIC - if (!(xfer->rqflags & URQ_REQUEST)) - panic("uhci_device_ctrl_done: not a request"); -#endif + UHCIHIST_FUNC(); UHCIHIST_CALLED(); - if (!uhci_active_intr_info(ii)) - return; + KASSERT(xfer->ux_rqflags & URQ_REQUEST); - uhci_del_intr_info(ii); /* remove from active list */ - - if (upipe->pipe.device->speed == USB_SPEED_LOW) - uhci_remove_ls_ctrl(sc, upipe->u.ctl.sqh); + /* XXXNH move to uhci_idone??? */ + if (upipe->pipe.up_dev->ud_speed == USB_SPEED_LOW) + uhci_remove_ls_ctrl(sc, upipe->ctrl.sqh); else - uhci_remove_hs_ctrl(sc, upipe->u.ctl.sqh); - - if (upipe->u.ctl.length != 0) - uhci_free_std_chain(sc, ii->stdstart->link.std, ii->stdend); + uhci_remove_hs_ctrl(sc, upipe->ctrl.sqh); if (len) { - usb_syncmem(&xfer->dmabuf, 0, len, + usb_syncmem(&xfer->ux_dmabuf, 0, len, isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); } - usb_syncmem(&upipe->u.ctl.reqdma, 0, + usb_syncmem(&upipe->ctrl.reqdma, 0, sizeof(usb_device_request_t), BUS_DMASYNC_POSTWRITE); - DPRINTFN(5, ("uhci_device_ctrl_done: length=%d\n", xfer->actlen)); + DPRINTF("length=%d", xfer->ux_actlen, 0, 0, 0); } /* Deallocate request data structures */ void -uhci_device_bulk_done(usbd_xfer_handle xfer) +uhci_device_bulk_done(struct usbd_xfer *xfer) { - uhci_intr_info_t *ii = &UXFER(xfer)->iinfo; - uhci_softc_t *sc = ii->sc; - struct uhci_pipe *upipe = (struct uhci_pipe *)xfer->pipe; + uhci_softc_t *sc = UHCI_XFER2SC(xfer); + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); + usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc; + int endpt = ed->bEndpointAddress; + int isread = UE_GET_DIR(endpt) == UE_DIR_IN; - DPRINTFN(5,("uhci_device_bulk_done: xfer=%p ii=%p sc=%p upipe=%p\n", - xfer, ii, sc, upipe)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(5, "xfer=%p sc=%p upipe=%p", xfer, sc, upipe, 0); KASSERT(mutex_owned(&sc->sc_lock)); - if (!uhci_active_intr_info(ii)) - return; - - uhci_del_intr_info(ii); /* remove from active list */ - - uhci_remove_bulk(sc, upipe->u.bulk.sqh); + uhci_remove_bulk(sc, upipe->bulk.sqh); - uhci_free_std_chain(sc, ii->stdstart, NULL); + if (xfer->ux_length) { + usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, + isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); + } - DPRINTFN(5, ("uhci_device_bulk_done: length=%d\n", xfer->actlen)); + DPRINTFN(5, "length=%d", xfer->ux_actlen, 0, 0, 0); } /* Add interrupt QH, called with vflock. */ @@ -3179,7 +3367,8 @@ uhci_add_intr(uhci_softc_t *sc, uhci_soft_qh_t *sqh) struct uhci_vframe *vf = &sc->sc_vframes[sqh->pos]; uhci_soft_qh_t *eqh; - DPRINTFN(4, ("uhci_add_intr: n=%d sqh=%p\n", sqh->pos, sqh)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(4, "n=%d sqh=%p", sqh->pos, sqh, 0, 0); eqh = vf->eqh; usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), @@ -3206,7 +3395,8 @@ uhci_remove_intr(uhci_softc_t *sc, uhci_soft_qh_t *sqh) struct uhci_vframe *vf = &sc->sc_vframes[sqh->pos]; uhci_soft_qh_t *pqh; - DPRINTFN(4, ("uhci_remove_intr: n=%d sqh=%p\n", sqh->pos, sqh)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(4, "n=%d sqh=%p", sqh->pos, sqh, 0, 0); /* See comment in uhci_remove_ctrl() */ @@ -3244,21 +3434,22 @@ uhci_device_setintr(uhci_softc_t *sc, struct uhci_pipe *upipe, int ival) int i, npoll; u_int bestbw, bw, bestoffs, offs; - DPRINTFN(2, ("uhci_device_setintr: pipe=%p\n", upipe)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTFN(2, "pipe=%p", upipe, 0, 0, 0); if (ival == 0) { - printf("uhci_device_setintr: 0 interval\n"); - return (USBD_INVAL); + printf("%s: 0 interval\n", __func__); + return USBD_INVAL; } if (ival > UHCI_VFRAMELIST_COUNT) ival = UHCI_VFRAMELIST_COUNT; npoll = (UHCI_VFRAMELIST_COUNT + ival - 1) / ival; - DPRINTFN(2, ("uhci_device_setintr: ival=%d npoll=%d\n", ival, npoll)); + DPRINTF("ival=%d npoll=%d", ival, npoll, 0, 0); - upipe->u.intr.npoll = npoll; - upipe->u.intr.qhs = + upipe->intr.npoll = npoll; + upipe->intr.qhs = kmem_alloc(npoll * sizeof(uhci_soft_qh_t *), KM_SLEEP); - if (upipe->u.intr.qhs == NULL) + if (upipe->intr.qhs == NULL) return USBD_NOMEM; /* @@ -3274,11 +3465,9 @@ uhci_device_setintr(uhci_softc_t *sc, struct uhci_pipe *upipe, int ival) bestoffs = offs; } } - DPRINTFN(1, ("uhci_device_setintr: bw=%d offs=%d\n", bestbw, bestoffs)); - - mutex_enter(&sc->sc_lock); + DPRINTF("bw=%d offs=%d", bestbw, bestoffs, 0, 0); for (i = 0; i < npoll; i++) { - upipe->u.intr.qhs[i] = sqh = uhci_alloc_sqh(sc); + upipe->intr.qhs[i] = sqh = uhci_alloc_sqh(sc); sqh->elink = NULL; sqh->qh.qh_elink = htole32(UHCI_PTR_T); usb_syncmem(&sqh->dma, @@ -3289,93 +3478,97 @@ uhci_device_setintr(uhci_softc_t *sc, struct uhci_pipe *upipe, int ival) } #undef MOD + mutex_enter(&sc->sc_lock); /* Enter QHs into the controller data structures. */ for (i = 0; i < npoll; i++) - uhci_add_intr(sc, upipe->u.intr.qhs[i]); + uhci_add_intr(sc, upipe->intr.qhs[i]); mutex_exit(&sc->sc_lock); - DPRINTFN(5, ("uhci_device_setintr: returns %p\n", upipe)); - return (USBD_NORMAL_COMPLETION); + DPRINTFN(5, "returns %p", upipe, 0, 0, 0); + + return USBD_NORMAL_COMPLETION; } /* Open a new pipe. */ usbd_status -uhci_open(usbd_pipe_handle pipe) +uhci_open(struct usbd_pipe *pipe) { - uhci_softc_t *sc = pipe->device->bus->hci_private; - struct uhci_pipe *upipe = (struct uhci_pipe *)pipe; - usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc; + uhci_softc_t *sc = UHCI_PIPE2SC(pipe); + struct usbd_bus *bus = pipe->up_dev->ud_bus; + struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe); + usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc; usbd_status err = USBD_NOMEM; int ival; - DPRINTFN(1, ("uhci_open: pipe=%p, addr=%d, endpt=%d (%d)\n", - pipe, pipe->device->address, - ed->bEndpointAddress, sc->sc_addr)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTF("pipe=%p, addr=%d, endpt=%d (%d)", + pipe, pipe->up_dev->ud_addr, ed->bEndpointAddress, bus->ub_rhaddr); if (sc->sc_dying) return USBD_IOERROR; upipe->aborting = 0; /* toggle state needed for bulk endpoints */ - upipe->nexttoggle = pipe->endpoint->datatoggle; + upipe->nexttoggle = pipe->up_endpoint->ue_toggle; - if (pipe->device->address == sc->sc_addr) { + if (pipe->up_dev->ud_addr == bus->ub_rhaddr) { switch (ed->bEndpointAddress) { case USB_CONTROL_ENDPOINT: - pipe->methods = &uhci_root_ctrl_methods; + pipe->up_methods = &roothub_ctrl_methods; break; - case UE_DIR_IN | UHCI_INTR_ENDPT: - pipe->methods = &uhci_root_intr_methods; + case UE_DIR_IN | USBROOTHUB_INTR_ENDPT: + pipe->up_methods = &uhci_root_intr_methods; break; default: - return (USBD_INVAL); + return USBD_INVAL; } } else { switch (ed->bmAttributes & UE_XFERTYPE) { case UE_CONTROL: - pipe->methods = &uhci_device_ctrl_methods; - upipe->u.ctl.sqh = uhci_alloc_sqh(sc); - if (upipe->u.ctl.sqh == NULL) + pipe->up_methods = &uhci_device_ctrl_methods; + upipe->ctrl.sqh = uhci_alloc_sqh(sc); + if (upipe->ctrl.sqh == NULL) goto bad; - upipe->u.ctl.setup = uhci_alloc_std(sc); - if (upipe->u.ctl.setup == NULL) { - uhci_free_sqh(sc, upipe->u.ctl.sqh); + upipe->ctrl.setup = uhci_alloc_std(sc); + if (upipe->ctrl.setup == NULL) { + uhci_free_sqh(sc, upipe->ctrl.sqh); goto bad; } - upipe->u.ctl.stat = uhci_alloc_std(sc); - if (upipe->u.ctl.stat == NULL) { - uhci_free_sqh(sc, upipe->u.ctl.sqh); - uhci_free_std(sc, upipe->u.ctl.setup); + upipe->ctrl.stat = uhci_alloc_std(sc); + if (upipe->ctrl.stat == NULL) { + uhci_free_sqh(sc, upipe->ctrl.sqh); + uhci_free_std(sc, upipe->ctrl.setup); goto bad; } err = usb_allocmem(&sc->sc_bus, sizeof(usb_device_request_t), - 0, &upipe->u.ctl.reqdma); + 0, &upipe->ctrl.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); + uhci_free_sqh(sc, upipe->ctrl.sqh); + uhci_free_std(sc, upipe->ctrl.setup); + uhci_free_std(sc, upipe->ctrl.stat); goto bad; } break; case UE_INTERRUPT: - pipe->methods = &uhci_device_intr_methods; - ival = pipe->interval; + pipe->up_methods = &uhci_device_intr_methods; + ival = pipe->up_interval; if (ival == USBD_DEFAULT_INTERVAL) ival = ed->bInterval; - return (uhci_device_setintr(sc, upipe, ival)); + return uhci_device_setintr(sc, upipe, ival); case UE_ISOCHRONOUS: - pipe->methods = &uhci_device_isoc_methods; - return (uhci_setup_isoc(pipe)); + pipe->up_serialise = false; + pipe->up_methods = &uhci_device_isoc_methods; + return uhci_setup_isoc(pipe); case UE_BULK: - pipe->methods = &uhci_device_bulk_methods; - upipe->u.bulk.sqh = uhci_alloc_sqh(sc); - if (upipe->u.bulk.sqh == NULL) + pipe->up_methods = &uhci_device_bulk_methods; + upipe->bulk.sqh = uhci_alloc_sqh(sc); + if (upipe->bulk.sqh == NULL) goto bad; break; } } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; bad: return USBD_NOMEM; @@ -3384,64 +3577,6 @@ uhci_open(usbd_pipe_handle pipe) /* * Data structures and routines to emulate the root hub. */ -usb_device_descriptor_t uhci_devd = { - USB_DEVICE_DESCRIPTOR_SIZE, - UDESC_DEVICE, /* type */ - {0x00, 0x01}, /* USB version */ - UDCLASS_HUB, /* class */ - UDSUBCLASS_HUB, /* subclass */ - UDPROTO_FSHUB, /* protocol */ - 64, /* max packet */ - {0},{0},{0x00,0x01}, /* device id */ - 1,2,0, /* string indicies */ - 1 /* # of configurations */ -}; - -const usb_config_descriptor_t uhci_confd = { - USB_CONFIG_DESCRIPTOR_SIZE, - UDESC_CONFIG, - {USB_CONFIG_DESCRIPTOR_SIZE + - USB_INTERFACE_DESCRIPTOR_SIZE + - USB_ENDPOINT_DESCRIPTOR_SIZE}, - 1, - 1, - 0, - UC_ATTR_MBO | UC_SELF_POWERED, - 0 /* max power */ -}; - -const usb_interface_descriptor_t uhci_ifcd = { - USB_INTERFACE_DESCRIPTOR_SIZE, - UDESC_INTERFACE, - 0, - 0, - 1, - UICLASS_HUB, - UISUBCLASS_HUB, - UIPROTO_FSHUB, - 0 -}; - -const usb_endpoint_descriptor_t uhci_endpd = { - USB_ENDPOINT_DESCRIPTOR_SIZE, - UDESC_ENDPOINT, - UE_DIR_IN | UHCI_INTR_ENDPT, - UE_INTERRUPT, - {8}, - 255 -}; - -const usb_hub_descriptor_t uhci_hubd_piix = { - USB_HUB_DESCRIPTOR_SIZE, - UDESC_HUB, - 2, - { UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL, 0 }, - 50, /* power on to power good */ - 0, - { 0x00 }, /* both ports are removable */ - { 0 }, -}; - /* * The USB hub protocol requires that SET_FEATURE(PORT_RESET) also * enables the port, and also states that SET_FEATURE(PORT_ENABLE) @@ -3457,29 +3592,30 @@ Static usbd_status uhci_portreset(uhci_softc_t *sc, int index) { int lim, port, x; + UHCIHIST_FUNC(); UHCIHIST_CALLED(); if (index == 1) port = UHCI_PORTSC1; else if (index == 2) port = UHCI_PORTSC2; else - return (USBD_IOERROR); + return USBD_IOERROR; x = URWMASK(UREAD2(sc, port)); UWRITE2(sc, port, x | UHCI_PORTSC_PR); usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY); - DPRINTFN(3,("uhci port %d reset, status0 = 0x%04x\n", - index, UREAD2(sc, port))); + DPRINTF("uhci port %d reset, status0 = 0x%04x", index, + UREAD2(sc, port), 0, 0); x = URWMASK(UREAD2(sc, port)); UWRITE2(sc, port, x & ~(UHCI_PORTSC_PR | UHCI_PORTSC_SUSP)); delay(100); - DPRINTFN(3,("uhci port %d reset, status1 = 0x%04x\n", - index, UREAD2(sc, port))); + DPRINTF("uhci port %d reset, status1 = 0x%04x", index, + UREAD2(sc, port), 0, 0); x = URWMASK(UREAD2(sc, port)); UWRITE2(sc, port, x | UHCI_PORTSC_PE); @@ -3488,9 +3624,8 @@ uhci_portreset(uhci_softc_t *sc, int index) usb_delay_ms(&sc->sc_bus, USB_PORT_RESET_DELAY); x = UREAD2(sc, port); - - DPRINTFN(3,("uhci port %d iteration %u, status = 0x%04x\n", - index, lim, x)); + DPRINTF("uhci port %d iteration %u, status = 0x%04x", index, + lim, x, 0); if (!(x & UHCI_PORTSC_CCS)) { /* @@ -3501,8 +3636,8 @@ uhci_portreset(uhci_softc_t *sc, int index) * connection will have been registered. 50ms * appears to be sufficient, but 20ms is not. */ - DPRINTFN(3,("uhci port %d loop %u, device detached\n", - index, lim)); + DPRINTFN(3, "uhci port %d loop %u, device detached", + index, lim, 0, 0); break; } @@ -3525,199 +3660,86 @@ uhci_portreset(uhci_softc_t *sc, int index) UWRITE2(sc, port, URWMASK(x) | UHCI_PORTSC_PE); } - DPRINTFN(3,("uhci port %d reset, status2 = 0x%04x\n", - index, UREAD2(sc, port))); + DPRINTFN(3, "uhci port %d reset, status2 = 0x%04x", index, + UREAD2(sc, port), 0, 0); if (lim <= 0) { - DPRINTFN(1,("uhci port %d reset timed out\n", index)); - return (USBD_TIMEOUT); + DPRINTF("uhci port %d reset timed out", index, + 0, 0, 0); + return USBD_TIMEOUT; } sc->sc_isreset = 1; - return (USBD_NORMAL_COMPLETION); -} - -/* - * Simulate a hardware hub by handling all the necessary requests. - */ -usbd_status -uhci_root_ctrl_transfer(usbd_xfer_handle xfer) -{ - uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; - usbd_status err; - - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return (err); - - /* - * Pipe isn't running (otherwise err would be USBD_INPROG), - * so start it first. - */ - return (uhci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return USBD_NORMAL_COMPLETION; } -usbd_status -uhci_root_ctrl_start(usbd_xfer_handle xfer) +Static int +uhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, + void *buf, int buflen) { - uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; - usb_device_request_t *req; - void *buf = NULL; + uhci_softc_t *sc = UHCI_BUS2SC(bus); int port, x; - int len, value, index, status, change, l, totlen = 0; + int status, change, totlen = 0; + uint16_t len, value, index; usb_port_status_t ps; usbd_status err; - if (sc->sc_dying) - return (USBD_IOERROR); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); -#ifdef DIAGNOSTIC - if (!(xfer->rqflags & URQ_REQUEST)) - panic("uhci_root_ctrl_start: not a request"); -#endif - req = &xfer->request; + if (sc->sc_dying) + return -1; - DPRINTFN(2,("uhci_root_ctrl_control type=0x%02x request=%02x\n", - req->bmRequestType, req->bRequest)); + DPRINTF("type=0x%02x request=%02x", req->bmRequestType, + req->bRequest, 0, 0); len = UGETW(req->wLength); value = UGETW(req->wValue); index = UGETW(req->wIndex); - if (len != 0) - buf = KERNADDR(&xfer->dmabuf, 0); - #define C(x,y) ((x) | ((y) << 8)) - switch(C(req->bRequest, req->bmRequestType)) { - case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE): - case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE): - case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT): - /* - * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops - * for the integrated root hub. - */ - break; - case C(UR_GET_CONFIG, UT_READ_DEVICE): - if (len > 0) { - *(u_int8_t *)buf = sc->sc_conf; - totlen = 1; - } - break; + switch (C(req->bRequest, req->bmRequestType)) { case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): - DPRINTFN(2,("uhci_root_ctrl_control wValue=0x%04x\n", value)); + DPRINTF("wValue=0x%04x", value, 0, 0, 0); if (len == 0) break; - switch(value >> 8) { - case UDESC_DEVICE: - if ((value & 0xff) != 0) { - err = USBD_IOERROR; - goto ret; - } - totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE); - USETW(uhci_devd.idVendor, sc->sc_id_vendor); - memcpy(buf, &uhci_devd, l); + switch (value) { + case C(0, UDESC_DEVICE): { + usb_device_descriptor_t devd; + + totlen = min(buflen, sizeof(devd)); + memcpy(&devd, buf, totlen); + USETW(devd.idVendor, sc->sc_id_vendor); + memcpy(buf, &devd, totlen); break; - case UDESC_CONFIG: - if ((value & 0xff) != 0) { - err = USBD_IOERROR; - goto ret; - } - totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE); - memcpy(buf, &uhci_confd, l); - buf = (char *)buf + l; - len -= l; - l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE); - totlen += l; - memcpy(buf, &uhci_ifcd, l); - buf = (char *)buf + l; - len -= l; - l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE); - totlen += l; - memcpy(buf, &uhci_endpd, l); - break; - case UDESC_STRING: + } + case C(1, UDESC_STRING): #define sd ((usb_string_descriptor_t *)buf) - switch (value & 0xff) { - case 0: /* Language table */ - totlen = usb_makelangtbl(sd, len); - break; - case 1: /* Vendor */ - totlen = usb_makestrdesc(sd, len, - sc->sc_vendor); - break; - case 2: /* Product */ - totlen = usb_makestrdesc(sd, len, - "UHCI root hub"); - break; - } -#undef sd + /* Vendor */ + totlen = usb_makestrdesc(sd, len, sc->sc_vendor); break; + case C(2, UDESC_STRING): + /* Product */ + totlen = usb_makestrdesc(sd, len, "UHCI root hub"); + break; +#undef sd default: - err = USBD_IOERROR; - goto ret; - } - break; - case C(UR_GET_INTERFACE, UT_READ_INTERFACE): - if (len > 0) { - *(u_int8_t *)buf = 0; - totlen = 1; - } - break; - case C(UR_GET_STATUS, UT_READ_DEVICE): - if (len > 1) { - USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED); - totlen = 2; + /* default from usbroothub */ + return buflen; } break; - case C(UR_GET_STATUS, UT_READ_INTERFACE): - case C(UR_GET_STATUS, UT_READ_ENDPOINT): - if (len > 1) { - USETW(((usb_status_t *)buf)->wStatus, 0); - totlen = 2; - } - break; - case C(UR_SET_ADDRESS, UT_WRITE_DEVICE): - if (value >= USB_MAX_DEVICES) { - err = USBD_IOERROR; - goto ret; - } - sc->sc_addr = value; - break; - case C(UR_SET_CONFIG, UT_WRITE_DEVICE): - if (value != 0 && value != 1) { - err = USBD_IOERROR; - goto ret; - } - sc->sc_conf = value; - break; - case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE): - break; - case C(UR_SET_FEATURE, UT_WRITE_DEVICE): - case C(UR_SET_FEATURE, UT_WRITE_INTERFACE): - case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT): - err = USBD_IOERROR; - goto ret; - case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE): - break; - case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT): - break; + /* Hub requests */ case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE): break; case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): - DPRINTFN(3, ("uhci_root_ctrl_control: UR_CLEAR_PORT_FEATURE " - "port=%d feature=%d\n", - index, value)); + DPRINTF("UR_CLEAR_PORT_FEATURE port=%d feature=%d", index, + value, 0, 0); if (index == 1) port = UHCI_PORTSC1; else if (index == 2) port = UHCI_PORTSC2; else { - err = USBD_IOERROR; - goto ret; + return -1; } switch(value) { case UHF_PORT_ENABLE: @@ -3752,16 +3774,14 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer) break; case UHF_C_PORT_RESET: sc->sc_isreset = 0; - err = USBD_NORMAL_COMPLETION; - goto ret; + break; case UHF_PORT_CONNECTION: case UHF_PORT_OVER_CURRENT: case UHF_PORT_POWER: case UHF_PORT_LOW_SPEED: case UHF_C_PORT_SUSPEND: default: - err = USBD_IOERROR; - goto ret; + return -1; } break; case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER): @@ -3770,13 +3790,11 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer) else if (index == 2) port = UHCI_PORTSC2; else { - err = USBD_IOERROR; - goto ret; + return -1; } if (len > 0) { - *(u_int8_t *)buf = - (UREAD2(sc, port) & UHCI_PORTSC_LS) >> - UHCI_PORTSC_LS_SHIFT; + *(uint8_t *)buf = + UHCI_PORTSC_GET_LS(UREAD2(sc, port)); totlen = 1; } break; @@ -3784,17 +3802,18 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer) if (len == 0) break; if ((value & 0xff) != 0) { - err = USBD_IOERROR; - goto ret; + return -1; } - l = min(len, USB_HUB_DESCRIPTOR_SIZE); - totlen = l; - memcpy(buf, &uhci_hubd_piix, l); + usb_hub_descriptor_t hubd; + + totlen = min(buflen, sizeof(hubd)); + memcpy(&hubd, buf, totlen); + hubd.bNbrPorts = 2; + memcpy(buf, &hubd, totlen); break; case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): if (len != 4) { - err = USBD_IOERROR; - goto ret; + return -1; } memset(buf, 0, len); totlen = len; @@ -3805,12 +3824,10 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer) else if (index == 2) port = UHCI_PORTSC2; else { - err = USBD_IOERROR; - goto ret; + return -1; } if (len != 4) { - err = USBD_IOERROR; - goto ret; + return -1; } x = UREAD2(sc, port); status = change = 0; @@ -3835,13 +3852,11 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer) change |= UPS_C_PORT_RESET; USETW(ps.wPortStatus, status); USETW(ps.wPortChange, change); - l = min(len, sizeof ps); - memcpy(buf, &ps, l); - totlen = l; + totlen = min(len, sizeof(ps)); + memcpy(buf, &ps, totlen); break; case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE): - err = USBD_IOERROR; - goto ret; + return -1; case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE): break; case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER): @@ -3850,8 +3865,7 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer) else if (index == 2) port = UHCI_PORTSC2; else { - err = USBD_IOERROR; - goto ret; + return -1; } switch(value) { case UHF_PORT_ENABLE: @@ -3864,11 +3878,12 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer) break; case UHF_PORT_RESET: err = uhci_portreset(sc, index); - goto ret; + if (err != USBD_NORMAL_COMPLETION) + return -1; + return 0; case UHF_PORT_POWER: /* Pretend we turned on power */ - err = USBD_NORMAL_COMPLETION; - goto ret; + return 0; case UHF_C_PORT_CONNECTION: case UHF_C_PORT_ENABLE: case UHF_C_PORT_OVER_CURRENT: @@ -3878,61 +3893,44 @@ uhci_root_ctrl_start(usbd_xfer_handle xfer) case UHF_C_PORT_SUSPEND: case UHF_C_PORT_RESET: default: - err = USBD_IOERROR; - goto ret; + return -1; } break; default: - err = USBD_IOERROR; - goto ret; + /* default from usbroothub */ + DPRINTF("returning %d (usbroothub default)", + buflen, 0, 0, 0); + return buflen; } - xfer->actlen = totlen; - err = USBD_NORMAL_COMPLETION; - ret: - xfer->status = err; - mutex_enter(&sc->sc_lock); - usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); - return (USBD_IN_PROGRESS); -} -/* Abort a root control request. */ -void -uhci_root_ctrl_abort(usbd_xfer_handle xfer) -{ - /* Nothing to do, all transfers are synchronous. */ -} + DPRINTF("returning %d", totlen, 0, 0, 0); -/* Close the root pipe. */ -void -uhci_root_ctrl_close(usbd_pipe_handle pipe) -{ - DPRINTF(("uhci_root_ctrl_close\n")); + return totlen; } /* Abort a root interrupt request. */ void -uhci_root_intr_abort(usbd_xfer_handle xfer) +uhci_root_intr_abort(struct usbd_xfer *xfer) { - uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; + uhci_softc_t *sc = UHCI_XFER2SC(xfer); KASSERT(mutex_owned(&sc->sc_lock)); - KASSERT(xfer->pipe->intrxfer == xfer); + KASSERT(xfer->ux_pipe->up_intrxfer == xfer); callout_stop(&sc->sc_poll_handle); sc->sc_intr_xfer = NULL; - xfer->status = USBD_CANCELLED; + xfer->ux_status = USBD_CANCELLED; #ifdef DIAGNOSTIC - UXFER(xfer)->iinfo.isdone = 1; + UHCI_XFER2UXFER(xfer)->ux_isdone = true; #endif usb_transfer_complete(xfer); } usbd_status -uhci_root_intr_transfer(usbd_xfer_handle xfer) +uhci_root_intr_transfer(struct usbd_xfer *xfer) { - uhci_softc_t *sc = xfer->pipe->device->bus->hci_private; + uhci_softc_t *sc = UHCI_XFER2SC(xfer); usbd_status err; /* Insert last in queue. */ @@ -3940,46 +3938,47 @@ uhci_root_intr_transfer(usbd_xfer_handle xfer) err = usb_insert_transfer(xfer); mutex_exit(&sc->sc_lock); if (err) - return (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))); + return uhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } /* Start a transfer on the root interrupt pipe */ usbd_status -uhci_root_intr_start(usbd_xfer_handle xfer) +uhci_root_intr_start(struct usbd_xfer *xfer) { - usbd_pipe_handle pipe = xfer->pipe; - uhci_softc_t *sc = pipe->device->bus->hci_private; + struct usbd_pipe *pipe = xfer->ux_pipe; + uhci_softc_t *sc = UHCI_PIPE2SC(pipe); unsigned int ival; - DPRINTFN(3, ("uhci_root_intr_start: xfer=%p len=%d flags=%d\n", - xfer, xfer->length, xfer->flags)); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); + DPRINTF("xfer=%p len=%d flags=%d", xfer, xfer->ux_length, + xfer->ux_flags, 0); if (sc->sc_dying) - return (USBD_IOERROR); + return USBD_IOERROR; /* XXX temporary variable needed to avoid gcc3 warning */ - ival = xfer->pipe->endpoint->edesc->bInterval; + ival = xfer->ux_pipe->up_endpoint->ue_edesc->bInterval; sc->sc_ival = mstohz(ival); callout_reset(&sc->sc_poll_handle, sc->sc_ival, uhci_poll_hub, xfer); sc->sc_intr_xfer = xfer; - return (USBD_IN_PROGRESS); + return USBD_IN_PROGRESS; } /* Close the root interrupt pipe. */ void -uhci_root_intr_close(usbd_pipe_handle pipe) +uhci_root_intr_close(struct usbd_pipe *pipe) { - uhci_softc_t *sc = pipe->device->bus->hci_private; + uhci_softc_t *sc = UHCI_PIPE2SC(pipe); + UHCIHIST_FUNC(); UHCIHIST_CALLED(); KASSERT(mutex_owned(&sc->sc_lock)); callout_stop(&sc->sc_poll_handle); sc->sc_intr_xfer = NULL; - DPRINTF(("uhci_root_intr_close\n")); } diff --git a/sys/dev/usb/uhcireg.h b/sys/dev/usb/uhcireg.h index 9cbb00623f3..59b0953dfe3 100644 --- a/sys/dev/usb/uhcireg.h +++ b/sys/dev/usb/uhcireg.h @@ -1,4 +1,4 @@ -/* $NetBSD: uhcireg.h,v 1.21 2015/09/05 06:40:12 skrll Exp $ */ +/* $NetBSD: uhcireg.h,v 1.22 2016/04/23 10:15:32 skrll Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhcireg.h,v 1.12 1999/11/17 22:33:42 n_hibma Exp $ */ /* @@ -43,17 +43,17 @@ #define PCI_USBREV_1_1 0x11 #define PCI_LEGSUP 0xc0 /* Legacy Support register */ -#define PCI_LEGSUP_A20PTS 0x8000 /* End of A20GATE passthru status */ -#define PCI_LEGSUP_USBPIRQDEN 0x2000 /* USB PIRQ D Enable */ -#define PCI_LEGSUP_USBIRQS 0x1000 /* USB IRQ status */ -#define PCI_LEGSUP_TBY64W 0x0800 /* Trap by 64h write status */ -#define PCI_LEGSUP_TBY64R 0x0400 /* Trap by 64h read status */ -#define PCI_LEGSUP_TBY60W 0x0200 /* Trap by 60h write status */ -#define PCI_LEGSUP_TBY60R 0x0100 /* Trap by 60h read status */ -#define PCI_LEGSUP_SMIEPTE 0x0080 /* SMI at end of passthru enable */ -#define PCI_LEGSUP_PSS 0x0040 /* Passthru status */ -#define PCI_LEGSUP_A20PTEN 0x0020 /* A20GATE passthru enable */ -#define PCI_LEGSUP_USBSMIEN 0x0010 /* Enable SMI# generation */ +#define PCI_LEGSUP_A20PTS __BIT(15) /* End of A20GATE passthru status */ +#define PCI_LEGSUP_USBPIRQDEN __BIT(13) /* USB PIRQ D Enable */ +#define PCI_LEGSUP_USBIRQS __BIT(12) /* USB IRQ status */ +#define PCI_LEGSUP_TBY64W __BIT(11) /* Trap by 64h write status */ +#define PCI_LEGSUP_TBY64R __BIT(10) /* Trap by 64h read status */ +#define PCI_LEGSUP_TBY60W __BIT(9) /* Trap by 60h write status */ +#define PCI_LEGSUP_TBY60R __BIT(8) /* Trap by 60h read status */ +#define PCI_LEGSUP_SMIEPTE __BIT(7) /* SMI at end of passthru enable */ +#define PCI_LEGSUP_PSS __BIT(6) /* Passthru status */ +#define PCI_LEGSUP_A20PTEN __BIT(5) /* A20GATE passthru enable */ +#define PCI_LEGSUP_USBSMIEN __BIT(4) /* Enable SMI# generation */ #define PCI_CBIO 0x20 /* configuration base IO */ @@ -62,53 +62,53 @@ /*** UHCI registers ***/ #define UHCI_CMD 0x00 -#define UHCI_CMD_RS 0x0001 -#define UHCI_CMD_HCRESET 0x0002 -#define UHCI_CMD_GRESET 0x0004 -#define UHCI_CMD_EGSM 0x0008 -#define UHCI_CMD_FGR 0x0010 -#define UHCI_CMD_SWDBG 0x0020 -#define UHCI_CMD_CF 0x0040 -#define UHCI_CMD_MAXP 0x0080 +#define UHCI_CMD_RS __BIT(0) +#define UHCI_CMD_HCRESET __BIT(1) +#define UHCI_CMD_GRESET __BIT(2) +#define UHCI_CMD_EGSM __BIT(3) +#define UHCI_CMD_FGR __BIT(4) +#define UHCI_CMD_SWDBG __BIT(5) +#define UHCI_CMD_CF __BIT(6) +#define UHCI_CMD_MAXP __BIT(7) #define UHCI_STS 0x02 -#define UHCI_STS_USBINT 0x0001 -#define UHCI_STS_USBEI 0x0002 -#define UHCI_STS_RD 0x0004 -#define UHCI_STS_HSE 0x0008 -#define UHCI_STS_HCPE 0x0010 -#define UHCI_STS_HCH 0x0020 -#define UHCI_STS_ALLINTRS 0x003f +#define UHCI_STS_USBINT __BIT(0) +#define UHCI_STS_USBEI __BIT(1) +#define UHCI_STS_RD __BIT(2) +#define UHCI_STS_HSE __BIT(3) +#define UHCI_STS_HCPE __BIT(4) +#define UHCI_STS_HCH __BIT(5) +#define UHCI_STS_ALLINTRS __BITS(5,0) #define UHCI_INTR 0x04 -#define UHCI_INTR_TOCRCIE 0x0001 -#define UHCI_INTR_RIE 0x0002 -#define UHCI_INTR_IOCE 0x0004 -#define UHCI_INTR_SPIE 0x0008 +#define UHCI_INTR_TOCRCIE __BIT(0) +#define UHCI_INTR_RIE __BIT(1) +#define UHCI_INTR_IOCE __BIT(2) +#define UHCI_INTR_SPIE __BIT(3) #define UHCI_FRNUM 0x06 -#define UHCI_FRNUM_MASK 0x03ff +#define UHCI_FRNUM_MASK __BITS(9,0) #define UHCI_FLBASEADDR 0x08 #define UHCI_SOF 0x0c -#define UHCI_SOF_MASK 0x7f - -#define UHCI_PORTSC1 0x010 -#define UHCI_PORTSC2 0x012 -#define UHCI_PORTSC_CCS 0x0001 -#define UHCI_PORTSC_CSC 0x0002 -#define UHCI_PORTSC_PE 0x0004 -#define UHCI_PORTSC_POEDC 0x0008 -#define UHCI_PORTSC_LS 0x0030 -#define UHCI_PORTSC_LS_SHIFT 4 -#define UHCI_PORTSC_RD 0x0040 -#define UHCI_PORTSC_LSDA 0x0100 -#define UHCI_PORTSC_PR 0x0200 -#define UHCI_PORTSC_OCI 0x0400 -#define UHCI_PORTSC_OCIC 0x0800 -#define UHCI_PORTSC_SUSP 0x1000 +#define UHCI_SOF_MASK __BITS(6,0) + +#define UHCI_PORTSC1 0x010 +#define UHCI_PORTSC2 0x012 +#define UHCI_PORTSC_CCS __BIT(0) +#define UHCI_PORTSC_CSC __BIT(1) +#define UHCI_PORTSC_PE __BIT(2) +#define UHCI_PORTSC_POEDC __BIT(3) +#define UHCI_PORTSC_LS_MASK __BITS(5,4) +#define UHCI_PORTSC_GET_LS(p) __SHIFTOUT((p), UHCI_PORTSC_LS_MASK) +#define UHCI_PORTSC_RD __BIT(6) +#define UHCI_PORTSC_LSDA __BIT(8) +#define UHCI_PORTSC_PR __BIT(9) +#define UHCI_PORTSC_OCI __BIT(10) +#define UHCI_PORTSC_OCIC __BIT(11) +#define UHCI_PORTSC_SUSP __BIT(12) #define URWMASK(x) \ ((x) & (UHCI_PORTSC_SUSP | UHCI_PORTSC_PR | UHCI_PORTSC_RD | UHCI_PORTSC_PE)) @@ -119,11 +119,11 @@ #define UHCI_TD_ALIGN 16 #define UHCI_QH_ALIGN 16 -typedef u_int32_t uhci_physaddr_t; -#define UHCI_PTR_T 0x00000001 +typedef uint32_t uhci_physaddr_t; +#define UHCI_PTR_T __BIT(0) #define UHCI_PTR_TD 0x00000000 -#define UHCI_PTR_QH 0x00000002 -#define UHCI_PTR_VF 0x00000004 +#define UHCI_PTR_QH __BIT(1) +#define UHCI_PTR_VF __BIT(2) /* * Wait this long after a QH has been removed. This gives that HC a @@ -145,7 +145,7 @@ typedef u_int32_t uhci_physaddr_t; typedef struct { volatile uhci_physaddr_t td_link; - volatile u_int32_t td_status; + volatile uint32_t td_status; #define UHCI_TD_ACTLEN_MASK __BITS(10,0) #define UHCI_TD_GET_ACTLEN(s) \ ((__SHIFTOUT((s), UHCI_TD_ACTLEN_MASK) + 1) & __SHIFTOUT_MASK(UHCI_TD_ACTLEN_MASK)) @@ -157,6 +157,7 @@ typedef struct { #define UHCI_TD_DBUFFER __BIT(21) #define UHCI_TD_STALLED __BIT(22) #define UHCI_TD_ACTIVE __BIT(23) +#define UHCI_TD_STATUS_MASK __BITS(16,23) #define UHCI_TD_IOC __BIT(24) #define UHCI_TD_IOS __BIT(25) #define UHCI_TD_LS __BIT(26) @@ -164,7 +165,7 @@ typedef struct { #define UHCI_TD_GET_ERRCNT(s) __SHIFTOUT((s), UHCI_TD_ERRCNT_MASK) #define UHCI_TD_SET_ERRCNT(n) __SHIFTIN((n), UHCI_TD_ERRCNT_MASK) #define UHCI_TD_SPD __BIT(29) - volatile u_int32_t td_token; + volatile uint32_t td_token; #define UHCI_TD_PID_IN 0x69 #define UHCI_TD_PID_OUT 0xe1 #define UHCI_TD_PID_SETUP 0x2d @@ -185,7 +186,7 @@ typedef struct { __SHIFTIN((((l)-1) & __SHIFTOUT_MASK(UHCI_TD_MAXLEN_MASK)), UHCI_TD_MAXLEN_MASK) #define UHCI_TD_GET_MAXLEN(s) \ (__SHIFTOUT((s), UHCI_TD_MAXLEN_MASK) + 1) - volatile u_int32_t td_buffer; + volatile uint32_t td_buffer; } uhci_td_t; #define UHCI_TD_ERROR \ diff --git a/sys/dev/usb/uhcivar.h b/sys/dev/usb/uhcivar.h index e5e2a9e91f2..f25279b021f 100644 --- a/sys/dev/usb/uhcivar.h +++ b/sys/dev/usb/uhcivar.h @@ -1,4 +1,4 @@ -/* $NetBSD: uhcivar.h,v 1.52 2013/01/29 00:00:15 christos Exp $ */ +/* $NetBSD: uhcivar.h,v 1.53 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -59,30 +59,43 @@ typedef union { struct uhci_soft_td *std; } uhci_soft_td_qh_t; -/* - * An interrupt info struct contains the information needed to - * execute a requested routine when the controller generates an - * interrupt. Since we cannot know which transfer generated - * the interrupt all structs are linked together so they can be - * searched at interrupt time. - */ -typedef struct uhci_intr_info { - struct uhci_softc *sc; - usbd_xfer_handle xfer; - uhci_soft_td_t *stdstart; - uhci_soft_td_t *stdend; - LIST_ENTRY(uhci_intr_info) list; - int isdone; /* used only when DIAGNOSTIC is defined */ -} uhci_intr_info_t; - struct uhci_xfer { - struct usbd_xfer xfer; - uhci_intr_info_t iinfo; - struct usb_task abort_task; - int curframe; + struct usbd_xfer ux_xfer; + struct usb_task ux_aborttask; + enum { + UX_NONE, UX_CTRL, UX_BULK, UX_INTR, UX_ISOC + } ux_type; + /* ctrl/bulk/intr */ + struct { + uhci_soft_td_t **ux_stds; + size_t ux_nstd; + }; + union { + /* ctrl */ + struct { + uhci_soft_td_t *ux_setup; + uhci_soft_td_t *ux_data; + uhci_soft_td_t *ux_stat; + }; + /* bulk/intr/isoc */ + struct { + uhci_soft_td_t *ux_stdstart; + uhci_soft_td_t *ux_stdend; + }; + }; + + TAILQ_ENTRY(uhci_xfer) ux_list; + int ux_curframe; + bool ux_isdone; /* used only when DIAGNOSTIC is defined */ }; -#define UXFER(xfer) ((struct uhci_xfer *)(xfer)) +#define UHCI_BUS2SC(bus) ((bus)->ub_hcpriv) +#define UHCI_PIPE2SC(pipe) UHCI_BUS2SC((pipe)->up_dev->ud_bus) +#define UHCI_XFER2SC(xfer) UHCI_BUS2SC((xfer)->ux_bus) +#define UHCI_UPIPE2SC(d) UHCI_BUS2SC((d)->pipe.up_dev->ud_bus) + +#define UHCI_XFER2UXFER(xfer) ((struct uhci_xfer *)(xfer)) +#define UHCI_PIPE2UPIPE(pipe) ((struct uhci_pipe *)(pipe)) /* * Extra information that we need for a TD. @@ -100,7 +113,7 @@ struct uhci_soft_td { * aligned. * NOTE: Minimum size is 32 bytes. */ -#define UHCI_STD_SIZE ((sizeof (struct uhci_soft_td) + UHCI_TD_ALIGN - 1) / UHCI_TD_ALIGN * UHCI_TD_ALIGN) +#define UHCI_STD_SIZE ((sizeof(struct uhci_soft_td) + UHCI_TD_ALIGN - 1) / UHCI_TD_ALIGN * UHCI_TD_ALIGN) #define UHCI_STD_CHUNK 128 /*(PAGE_SIZE / UHCI_TD_SIZE)*/ /* @@ -116,7 +129,7 @@ struct uhci_soft_qh { int offs; /* QH's offset in usb_dma_t */ }; /* See comment about UHCI_STD_SIZE. */ -#define UHCI_SQH_SIZE ((sizeof (struct uhci_soft_qh) + UHCI_QH_ALIGN - 1) / UHCI_QH_ALIGN * UHCI_QH_ALIGN) +#define UHCI_SQH_SIZE ((sizeof(struct uhci_soft_qh) + UHCI_QH_ALIGN - 1) / UHCI_QH_ALIGN * UHCI_QH_ALIGN) #define UHCI_SQH_CHUNK 128 /*(PAGE_SIZE / UHCI_QH_SIZE)*/ /* @@ -152,18 +165,15 @@ typedef struct uhci_softc { uhci_soft_qh_t *sc_bulk_start; /* dummy QH for bulk */ uhci_soft_qh_t *sc_bulk_end; /* last bulk transfer */ uhci_soft_qh_t *sc_last_qh; /* dummy QH at the end */ - u_int32_t sc_loops; /* number of QHs that wants looping */ + uint32_t sc_loops; /* number of QHs that wants looping */ uhci_soft_td_t *sc_freetds; /* TD free list */ uhci_soft_qh_t *sc_freeqhs; /* QH free list */ pool_cache_t sc_xferpool; /* free xfer pool */ - u_int8_t sc_addr; /* device address */ - u_int8_t sc_conf; /* device configuration */ - - u_int8_t sc_saved_sof; - u_int16_t sc_saved_frnum; + uint8_t sc_saved_sof; + uint16_t sc_saved_frnum; char sc_softwake; @@ -171,21 +181,20 @@ typedef struct uhci_softc { char sc_suspend; char sc_dying; - LIST_HEAD(, uhci_intr_info) sc_intrhead; + TAILQ_HEAD(, uhci_xfer) sc_intrhead; /* Info for the root hub interrupt "pipe". */ int sc_ival; /* time between root hub intrs */ - usbd_xfer_handle sc_intr_xfer; /* root hub interrupt transfer */ + struct usbd_xfer *sc_intr_xfer; /* root hub interrupt transfer */ struct callout sc_poll_handle; char sc_vendor[32]; /* vendor string for root hub */ int sc_id_vendor; /* vendor ID for root hub */ device_t sc_child; /* /dev/usb# device */ - struct usb_dma_reserve sc_dma_reserve; } uhci_softc_t; -usbd_status uhci_init(uhci_softc_t *); +int uhci_init(uhci_softc_t *); int uhci_intr(void *); int uhci_detach(uhci_softc_t *, int); void uhci_childdet(device_t, device_t); diff --git a/sys/dev/usb/uhid.c b/sys/dev/usb/uhid.c index 0432522b8d3..51060632910 100644 --- a/sys/dev/usb/uhid.c +++ b/sys/dev/usb/uhid.c @@ -1,4 +1,4 @@ -/* $NetBSD: uhid.c,v 1.94 2015/03/20 03:04:48 mrg Exp $ */ +/* $NetBSD: uhid.c,v 1.95 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998, 2004, 2008, 2012 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.94 2015/03/20 03:04:48 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.95 2016/04/23 10:15:32 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -44,7 +44,7 @@ __KERNEL_RCSID(0, "$NetBSD: uhid.c,v 1.94 2015/03/20 03:04:48 mrg Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/signalvar.h> #include <sys/device.h> #include <sys/ioctl.h> @@ -130,11 +130,11 @@ const struct cdevsw uhid_cdevsw = { .d_flag = D_OTHER }; -Static void uhid_intr(struct uhidev *, void *, u_int len); +Static void uhid_intr(struct uhidev *, void *, u_int); Static void uhid_softintr(void *); -Static int uhid_do_read(struct uhid_softc *, struct uio *uio, int); -Static int uhid_do_write(struct uhid_softc *, struct uio *uio, int); +Static int uhid_do_read(struct uhid_softc *, struct uio *, int); +Static int uhid_do_write(struct uhid_softc *, struct uio *, int); Static int uhid_do_ioctl(struct uhid_softc*, u_long, void *, int, struct lwp *); int uhid_match(device_t, cfdata_t, void *); @@ -186,7 +186,7 @@ uhid_attach(device_t parent, device_t self, void *aux) sc->sc_isize, sc->sc_osize, sc->sc_fsize); mutex_init(&sc->sc_access_lock, MUTEX_DEFAULT, IPL_NONE); - mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_USB); + mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); cv_init(&sc->sc_cv, "uhidrea"); cv_init(&sc->sc_detach_cv, "uhiddet"); @@ -263,7 +263,7 @@ uhid_intr(struct uhidev *addr, void *data, u_int len) #ifdef UHID_DEBUG if (uhiddebug > 5) { - u_int32_t i; + uint32_t i; DPRINTF(("uhid_intr: data =")); for (i = 0; i < len; i++) @@ -339,7 +339,7 @@ uhidopen(dev_t dev, int flag, int mode, struct lwp *l) } mutex_exit(&sc->sc_access_lock); - sc->sc_obuf = malloc(sc->sc_osize, M_USBDEV, M_WAITOK); + sc->sc_obuf = kmem_alloc(sc->sc_osize, KM_SLEEP); sc->sc_state &= ~UHID_IMMED; mutex_enter(proc_lock); @@ -367,7 +367,7 @@ uhidclose(dev_t dev, int flag, int mode, struct lwp *l) uhidev_stop(&sc->sc_hdev); clfree(&sc->sc_q); - free(sc->sc_obuf, M_USBDEV); + kmem_free(sc->sc_obuf, sc->sc_osize); uhidev_close(&sc->sc_hdev); @@ -572,7 +572,7 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, void *addr, case USB_GET_REPORT_DESC: uhidev_get_report_desc(sc->sc_hdev.sc_parent, &desc, &size); rd = (struct usb_ctl_report_desc *)addr; - size = min(size, sizeof rd->ucrd_data); + size = min(size, sizeof(rd->ucrd_data)); rd->ucrd_size = size; memcpy(rd->ucrd_data, desc, size); break; @@ -646,7 +646,7 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, void *addr, case USB_GET_DEVICEINFO: usbd_fill_deviceinfo(sc->sc_hdev.sc_parent->sc_udev, - (struct usb_device_info *)addr, 0); + (struct usb_device_info *)addr, 0); break; #ifdef COMPAT_30 case USB_GET_DEVICEINFO_OLD: @@ -655,15 +655,15 @@ uhid_do_ioctl(struct uhid_softc *sc, u_long cmd, void *addr, break; #endif - case USB_GET_STRING_DESC: + case USB_GET_STRING_DESC: { - struct usb_string_desc *si = (struct usb_string_desc *)addr; - err = usbd_get_string_desc(sc->sc_hdev.sc_parent->sc_udev, + struct usb_string_desc *si = (struct usb_string_desc *)addr; + err = usbd_get_string_desc(sc->sc_hdev.sc_parent->sc_udev, si->usd_string_index, - si->usd_language_id, &si->usd_desc, &size); - if (err) - return EINVAL; - break; + si->usd_language_id, &si->usd_desc, &size); + if (err) + return EINVAL; + break; } default: @@ -743,7 +743,7 @@ filt_uhidread(struct knote *kn, long hint) struct uhid_softc *sc = kn->kn_hook; kn->kn_data = sc->sc_q.c_cc; - return (kn->kn_data > 0); + return kn->kn_data > 0; } static const struct filterops uhidread_filtops = diff --git a/sys/dev/usb/uhidev.c b/sys/dev/usb/uhidev.c index e497226b345..c9edaa22112 100644 --- a/sys/dev/usb/uhidev.c +++ b/sys/dev/usb/uhidev.c @@ -1,4 +1,4 @@ -/* $NetBSD: uhidev.c,v 1.64 2015/04/13 16:33:25 riastradh Exp $ */ +/* $NetBSD: uhidev.c,v 1.65 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001, 2012 The NetBSD Foundation, Inc. @@ -35,12 +35,12 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.64 2015/04/13 16:33:25 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uhidev.c,v 1.65 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/signalvar.h> #include <sys/device.h> #include <sys/ioctl.h> @@ -76,7 +76,7 @@ int uhidevdebug = 0; #define DPRINTFN(n,x) #endif -Static void uhidev_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void uhidev_intr(struct usbd_xfer *, void *, usbd_status); Static int uhidev_maxrepid(void *, int); Static int uhidevprint(void *, const char *); @@ -93,28 +93,28 @@ CFATTACH_DECL2_NEW(uhidev, sizeof(struct uhidev_softc), uhidev_match, int uhidev_match(device_t parent, cfdata_t match, void *aux) { - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; /* Game controllers in "XInput" mode */ - if (USBIF_IS_XINPUT(uaa)) + if (USBIF_IS_XINPUT(uiaa)) return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO; /* Xbox One controllers */ - if (USBIF_IS_X1INPUT(uaa) && uaa->ifaceno == 0) + if (USBIF_IS_X1INPUT(uiaa) && uiaa->uiaa_ifaceno == 0) return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO; - if (uaa->class != UICLASS_HID) - return (UMATCH_NONE); - if (usbd_get_quirks(uaa->device)->uq_flags & UQ_HID_IGNORE) - return (UMATCH_NONE); - return (UMATCH_IFACECLASS_GENERIC); + if (uiaa->uiaa_class != UICLASS_HID) + return UMATCH_NONE; + if (usbd_get_quirks(uiaa->uiaa_device)->uq_flags & UQ_HID_IGNORE) + return UMATCH_NONE; + return UMATCH_IFACECLASS_GENERIC; } void uhidev_attach(device_t parent, device_t self, void *aux) { struct uhidev_softc *sc = device_private(self); - struct usbif_attach_arg *uaa = aux; - usbd_interface_handle iface = uaa->iface; + struct usbif_attach_arg *uiaa = aux; + struct usbd_interface *iface = uiaa->uiaa_iface; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; struct uhidev_attach_arg uha; @@ -130,17 +130,17 @@ uhidev_attach(device_t parent, device_t self, void *aux) int locs[UHIDBUSCF_NLOCS]; sc->sc_dev = self; - sc->sc_udev = uaa->device; + sc->sc_udev = uiaa->uiaa_device; sc->sc_iface = iface; aprint_naive("\n"); aprint_normal("\n"); - mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_USB); + mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); id = usbd_get_interface_descriptor(iface); - devinfop = usbd_devinfo_alloc(uaa->device, 0); + devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0); aprint_normal_dev(self, "%s, iclass %d/%d\n", devinfop, id->bInterfaceClass, id->bInterfaceSubClass); usbd_devinfo_free(devinfop); @@ -201,11 +201,11 @@ uhidev_attach(device_t parent, device_t self, void *aux) /* XXX need to extend this */ descptr = NULL; - if (uaa->vendor == USB_VENDOR_WACOM) { + if (uiaa->uiaa_vendor == USB_VENDOR_WACOM) { static uByte reportbuf[] = {2, 2, 2}; /* The report descriptor for the Wacom Graphire is broken. */ - switch (uaa->product) { + switch (uiaa->uiaa_product) { case USB_PRODUCT_WACOM_GRAPHIRE: case USB_PRODUCT_WACOM_GRAPHIRE2: case USB_PRODUCT_WACOM_GRAPHIRE3_4X5: @@ -216,10 +216,10 @@ uhidev_attach(device_t parent, device_t self, void *aux) * feature report ID 2 before it'll start * returning digitizer data. */ - usbd_set_report(uaa->iface, UHID_FEATURE_REPORT, 2, - &reportbuf, sizeof reportbuf); + usbd_set_report(uiaa->uiaa_iface, UHID_FEATURE_REPORT, 2, + &reportbuf, sizeof(reportbuf)); - size = sizeof uhid_graphire3_4x5_report_descr; + size = sizeof(uhid_graphire3_4x5_report_descr); descptr = uhid_graphire3_4x5_report_descr; break; default: @@ -227,18 +227,18 @@ uhidev_attach(device_t parent, device_t self, void *aux) break; } } - if (USBIF_IS_XINPUT(uaa)) { - size = sizeof uhid_xinput_report_descr; + if (USBIF_IS_XINPUT(uiaa)) { + size = sizeof(uhid_xinput_report_descr); descptr = uhid_xinput_report_descr; } - if (USBIF_IS_X1INPUT(uaa)) { + if (USBIF_IS_X1INPUT(uiaa)) { sc->sc_flags |= UHIDEV_F_XB1; - size = sizeof uhid_x1input_report_descr; + size = sizeof(uhid_x1input_report_descr); descptr = uhid_x1input_report_descr; } if (descptr) { - desc = malloc(size, M_USBDEV, M_NOWAIT); + desc = kmem_alloc(size, KM_SLEEP); if (desc == NULL) err = USBD_NOMEM; else { @@ -247,8 +247,7 @@ uhidev_attach(device_t parent, device_t self, void *aux) } } else { desc = NULL; - err = usbd_read_report_desc(uaa->iface, &desc, &size, - M_USBDEV); + err = usbd_read_report_desc(uiaa->uiaa_iface, &desc, &size); } if (err) { aprint_error_dev(self, "no report descriptor\n"); @@ -256,8 +255,8 @@ uhidev_attach(device_t parent, device_t self, void *aux) return; } - if (uaa->vendor == USB_VENDOR_HOSIDEN && - uaa->product == USB_PRODUCT_HOSIDEN_PPP) { + if (uiaa->uiaa_vendor == USB_VENDOR_HOSIDEN && + uiaa->uiaa_product == USB_PRODUCT_HOSIDEN_PPP) { static uByte reportbuf[] = { 1 }; /* * This device was sold by Konami with its ParaParaParadise @@ -265,12 +264,12 @@ uhidev_attach(device_t parent, device_t self, void *aux) * before it will send any reports. */ - usbd_set_report(uaa->iface, UHID_FEATURE_REPORT, 0, - &reportbuf, sizeof reportbuf); + usbd_set_report(uiaa->uiaa_iface, UHID_FEATURE_REPORT, 0, + &reportbuf, sizeof(reportbuf)); } - if (uaa->vendor == USB_VENDOR_LOGITECH && - uaa->product == USB_PRODUCT_LOGITECH_CBT44 && size == 0xb1) { + if (uiaa->uiaa_vendor == USB_VENDOR_LOGITECH && + uiaa->uiaa_product == USB_PRODUCT_LOGITECH_CBT44 && size == 0xb1) { uint8_t *data = desc; /* * This device has a odd USAGE_MINIMUM value that would @@ -287,8 +286,8 @@ uhidev_attach(device_t parent, device_t self, void *aux) * Enable the Six Axis and DualShock 3 controllers. * See http://ps3.jim.sh/sixaxis/usb/ */ - if (uaa->vendor == USB_VENDOR_SONY && - uaa->product == USB_PRODUCT_SONY_PS3CONTROLLER) { + if (uiaa->uiaa_vendor == USB_VENDOR_SONY && + uiaa->uiaa_product == USB_PRODUCT_SONY_PS3CONTROLLER) { usb_device_request_t req; char data[17]; int actlen; @@ -297,7 +296,7 @@ uhidev_attach(device_t parent, device_t self, void *aux) req.bRequest = 1; USETW(req.wValue, 0x3f2); USETW(req.wIndex, 0); - USETW(req.wLength, sizeof data); + USETW(req.wLength, sizeof(data)); usbd_do_request_flags(sc->sc_udev, &req, data, USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT); @@ -306,20 +305,20 @@ uhidev_attach(device_t parent, device_t self, void *aux) sc->sc_repdesc = desc; sc->sc_repdesc_size = size; - uha.uaa = uaa; + uha.uiaa = uiaa; nrepid = uhidev_maxrepid(desc, size); if (nrepid < 0) return; if (nrepid > 0) aprint_normal_dev(self, "%d report ids\n", nrepid); nrepid++; - repsizes = malloc(nrepid * sizeof(*repsizes), M_TEMP, M_NOWAIT); + repsizes = kmem_alloc(nrepid * sizeof(*repsizes), KM_SLEEP); if (repsizes == NULL) goto nomem; - sc->sc_subdevs = malloc(nrepid * sizeof(device_t), - M_USBDEV, M_NOWAIT | M_ZERO); + sc->sc_subdevs = kmem_zalloc(nrepid * sizeof(device_t), + KM_SLEEP); if (sc->sc_subdevs == NULL) { - free(repsizes, M_TEMP); + kmem_free(repsizes, nrepid * sizeof(*repsizes)); nomem: aprint_error_dev(self, "no memory\n"); return; @@ -362,7 +361,8 @@ nomem: DPRINTF(("uhidev_match: repid=%d dev=%p\n", repid, dev)); if (csc->sc_intr == NULL) { - free(repsizes, M_TEMP); + kmem_free(repsizes, + nrepid * sizeof(*repsizes)); aprint_error_dev(self, "sc_intr == NULL\n"); return; @@ -375,7 +375,7 @@ nomem: } } } - free(repsizes, M_TEMP); + kmem_free(repsizes, nrepid * sizeof(*repsizes)); return; } @@ -393,7 +393,7 @@ uhidev_maxrepid(void *buf, int len) if (h.report_ID > maxid) maxid = h.report_ID; hid_end_parse(d); - return (maxid); + return maxid; } int @@ -405,7 +405,7 @@ uhidevprint(void *aux, const char *pnp) aprint_normal("uhid at %s", pnp); if (uha->reportid != 0) aprint_normal(" reportid %d", uha->reportid); - return (UNCONF); + return UNCONF; } int @@ -450,7 +450,7 @@ uhidev_detach(device_t self, int flags) usbd_abort_pipe(sc->sc_ipipe); if (sc->sc_repdesc != NULL) - free(sc->sc_repdesc, M_USBDEV); + kmem_free(sc->sc_repdesc, sc->sc_repdesc_size); rv = 0; for (i = 0; i < sc->sc_nrepid; i++) { @@ -467,24 +467,24 @@ uhidev_detach(device_t self, int flags) pmf_device_deregister(self); mutex_destroy(&sc->sc_lock); - return (rv); + return rv; } void -uhidev_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) +uhidev_intr(struct usbd_xfer *xfer, void *addr, usbd_status status) { struct uhidev_softc *sc = addr; device_t cdev; struct uhidev *scd; u_char *p; u_int rep; - u_int32_t cc; + uint32_t cc; usbd_get_xfer_status(xfer, NULL, NULL, &cc, NULL); #ifdef UHIDEV_DEBUG if (uhidevdebug > 5) { - u_int32_t i; + uint32_t i; DPRINTF(("uhidev_intr: status=%d cc=%d\n", status, cc)); DPRINTF(("uhidev_intr: data =")); @@ -555,19 +555,19 @@ uhidev_open(struct uhidev *scd) mutex_enter(&sc->sc_lock); if (scd->sc_state & UHIDEV_OPEN) { mutex_exit(&sc->sc_lock); - return (EBUSY); + return EBUSY; } scd->sc_state |= UHIDEV_OPEN; if (sc->sc_refcnt++) { mutex_exit(&sc->sc_lock); - return (0); + return 0; } mutex_exit(&sc->sc_lock); if (sc->sc_isize == 0) - return (0); + return 0; - sc->sc_ibuf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK); + sc->sc_ibuf = kmem_alloc(sc->sc_isize, KM_SLEEP); /* Set up input interrupt pipe. */ DPRINTF(("uhidev_open: isize=%d, ep=0x%02x\n", sc->sc_isize, @@ -601,10 +601,10 @@ uhidev_open(struct uhidev *scd) } DPRINTF(("uhidev_open: sc->sc_opipe=%p\n", sc->sc_opipe)); - sc->sc_oxfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_oxfer == NULL) { + error = usbd_create_xfer(sc->sc_opipe, UHIDEV_OSIZE, 0, 0, + &sc->sc_oxfer); + if (error) { DPRINTF(("uhidev_open: couldn't allocate an xfer\n")); - error = ENOMEM; goto out3; } @@ -612,8 +612,7 @@ uhidev_open(struct uhidev *scd) uint8_t init_data[] = { 0x05, 0x20 }; int init_data_len = sizeof(init_data); err = usbd_intr_transfer(sc->sc_oxfer, sc->sc_opipe, 0, - USBD_NO_TIMEOUT, init_data, &init_data_len, - "uhidevxb1"); + USBD_NO_TIMEOUT, init_data, &init_data_len); if (err != USBD_NORMAL_COMPLETION) { DPRINTF(("uhidev_open: xb1 init failed, " "error=%d\n", err)); @@ -623,11 +622,11 @@ uhidev_open(struct uhidev *scd) } } - return (0); + return 0; out4: /* Free output xfer */ if (sc->sc_oxfer != NULL) - usbd_free_xfer(sc->sc_oxfer); + usbd_destroy_xfer(sc->sc_oxfer); out3: /* Abort output pipe */ usbd_close_pipe(sc->sc_opipe); @@ -636,7 +635,7 @@ out2: usbd_close_pipe(sc->sc_ipipe); out1: DPRINTF(("uhidev_open: failed in someway")); - free(sc->sc_ibuf, M_USBDEV); + kmem_free(sc->sc_ibuf, sc->sc_isize); mutex_enter(&sc->sc_lock); scd->sc_state &= ~UHIDEV_OPEN; sc->sc_refcnt = 0; @@ -667,7 +666,7 @@ uhidev_stop(struct uhidev *scd) } if (sc->sc_ibuf != NULL) { - free(sc->sc_ibuf, M_USBDEV); + kmem_free(sc->sc_ibuf, sc->sc_isize); sc->sc_ibuf = NULL; } } @@ -692,10 +691,11 @@ uhidev_close(struct uhidev *scd) DPRINTF(("uhidev_close: close pipe\n")); if (sc->sc_oxfer != NULL) { - usbd_free_xfer(sc->sc_oxfer); + usbd_destroy_xfer(sc->sc_oxfer); sc->sc_oxfer = NULL; } + /* Possibly redundant, but properly handled */ uhidev_stop(scd); } @@ -710,14 +710,14 @@ uhidev_set_report(struct uhidev *scd, int type, void *data, int len) return usbd_set_report(scd->sc_parent->sc_iface, type, scd->sc_report_id, data, len); - buf = malloc(len + 1, M_TEMP, M_WAITOK); + buf = kmem_alloc(len + 1, KM_SLEEP); buf[0] = scd->sc_report_id; memcpy(buf+1, data, len); retstat = usbd_set_report(scd->sc_parent->sc_iface, type, scd->sc_report_id, buf, len + 1); - free(buf, M_TEMP); + kmem_free(buf, len + 1); return retstat; } @@ -741,8 +741,8 @@ uhidev_write(struct uhidev_softc *sc, void *data, int len) #ifdef UHIDEV_DEBUG if (uhidevdebug > 50) { - u_int32_t i; - u_int8_t *d = data; + uint32_t i; + uint8_t *d = data; DPRINTF(("uhidev_write: data =")); for (i = 0; i < len; i++) @@ -750,6 +750,6 @@ uhidev_write(struct uhidev_softc *sc, void *data, int len) DPRINTF(("\n")); } #endif - return usbd_intr_transfer(sc->sc_oxfer, sc->sc_opipe, 0, - USBD_NO_TIMEOUT, data, &len, "uhidevwi"); + return usbd_intr_transfer(sc->sc_oxfer, sc->sc_opipe, 0, USBD_NO_TIMEOUT, + data, &len); } diff --git a/sys/dev/usb/uhidev.h b/sys/dev/usb/uhidev.h index 63fb0c3eff8..270c061f55b 100644 --- a/sys/dev/usb/uhidev.h +++ b/sys/dev/usb/uhidev.h @@ -1,4 +1,4 @@ -/* $NetBSD: uhidev.h,v 1.18 2015/04/13 16:33:25 riastradh Exp $ */ +/* $NetBSD: uhidev.h,v 1.19 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -35,16 +35,16 @@ struct uhidev_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; /* interface */ - usbd_pipe_handle sc_ipipe; /* input interrupt pipe */ + struct usbd_device *sc_udev; + struct usbd_interface *sc_iface; /* interface */ + struct usbd_pipe *sc_ipipe; /* input interrupt pipe */ int sc_iep_addr; u_char *sc_ibuf; u_int sc_isize; - usbd_pipe_handle sc_opipe; /* output interrupt pipe */ - usbd_xfer_handle sc_oxfer; /* write request */ + struct usbd_pipe *sc_opipe; /* output interrupt pipe */ + struct usbd_xfer *sc_oxfer; /* write request */ int sc_oep_addr; void *sc_repdesc; @@ -66,15 +66,15 @@ struct uhidev { device_t sc_dev; /* base device */ struct uhidev_softc *sc_parent; uByte sc_report_id; - u_int8_t sc_state; + uint8_t sc_state; int sc_in_rep_size; #define UHIDEV_OPEN 0x01 /* device is open */ void (*sc_intr)(struct uhidev *, void *, u_int); - krndsource_t rnd_source; + krndsource_t rnd_source; }; struct uhidev_attach_arg { - struct usbif_attach_arg *uaa; + struct usbif_attach_arg *uiaa; struct uhidev_softc *parent; int reportid; int reportsize; @@ -87,3 +87,5 @@ void uhidev_close(struct uhidev *); usbd_status uhidev_set_report(struct uhidev *, int, void *, int); usbd_status uhidev_get_report(struct uhidev *, int, void *, int); usbd_status uhidev_write(struct uhidev_softc *, void *, int); + +#define UHIDEV_OSIZE 64 diff --git a/sys/dev/usb/uhmodem.c b/sys/dev/usb/uhmodem.c index fac0a361846..46c345eb1a0 100644 --- a/sys/dev/usb/uhmodem.c +++ b/sys/dev/usb/uhmodem.c @@ -1,4 +1,4 @@ -/* $NetBSD: uhmodem.c,v 1.13 2011/12/23 00:51:46 jakllsch Exp $ */ +/* $NetBSD: uhmodem.c,v 1.14 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2008 Yojiro UO <yuo@nui.org>. @@ -71,12 +71,12 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uhmodem.c,v 1.13 2011/12/23 00:51:46 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uhmodem.c,v 1.14 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/ioccom.h> #include <sys/fcntl.h> #include <sys/conf.h> @@ -120,35 +120,35 @@ Static int uhmodemdebug = 0; #define DPRINTF(x) DPRINTFN(0, x) Static int uhmodem_open(void *, int); -Static usbd_status e220_modechange_request(usbd_device_handle); +Static usbd_status e220_modechange_request(struct usbd_device *); Static usbd_status uhmodem_endpointhalt(struct ubsa_softc *, int); -Static usbd_status uhmodem_regwrite(usbd_device_handle, uint8_t *, size_t); -Static usbd_status uhmodem_regread(usbd_device_handle, uint8_t *, size_t); -Static usbd_status a2502_init(usbd_device_handle); +Static usbd_status uhmodem_regwrite(struct usbd_device *, uint8_t *, size_t); +Static usbd_status uhmodem_regread(struct usbd_device *, uint8_t *, size_t); +Static usbd_status a2502_init(struct usbd_device *); #if 0 -Static usbd_status uhmodem_regsetup(usbd_device_handle, uint16_t); -Static usbd_status e220_init(usbd_device_handle); +Static usbd_status uhmodem_regsetup(struct usbd_device *, uint16_t); +Static usbd_status e220_init(struct usbd_device *); #endif struct uhmodem_softc { - struct ubsa_softc sc_ubsa; + struct ubsa_softc sc_ubsa; }; struct ucom_methods uhmodem_methods = { - ubsa_get_status, - ubsa_set, - ubsa_param, - NULL, - uhmodem_open, - ubsa_close, - NULL, - NULL + .ucom_get_status = ubsa_get_status, + .ucom_set = ubsa_set, + .ucom_param = ubsa_param, + .ucom_ioctl = NULL, + .ucom_open = uhmodem_open, + .ucom_close = ubsa_close, + .ucom_read = NULL, + .ucom_write = NULL }; struct uhmodem_type { struct usb_devno uhmodem_dev; - u_int16_t uhmodem_coms; /* number of serial interfaces on the device */ - u_int16_t uhmodem_flags; + uint16_t uhmodem_coms; /* number of serial interfaces on the device */ + uint16_t uhmodem_flags; #define E220 0x0001 #define A2502 0x0002 #define E620 0x0004 /* XXX */ @@ -174,31 +174,31 @@ extern struct cfdriver uhmodem_cd; CFATTACH_DECL2_NEW(uhmodem, sizeof(struct uhmodem_softc), uhmodem_match, uhmodem_attach, uhmodem_detach, uhmodem_activate, NULL, uhmodem_childdet); -int +int uhmodem_match(device_t parent, cfdata_t match, void *aux) { - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; - if (uhmodem_lookup(uaa->vendor, uaa->product) != NULL) + if (uhmodem_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product) != NULL) /* XXX interface# 0,1 provide modem function, but this driver handles all modem in single device. */ - if (uaa->ifaceno == 0) - return (UMATCH_VENDOR_PRODUCT); - return (UMATCH_NONE); + if (uiaa->uiaa_ifaceno == 0) + return UMATCH_VENDOR_PRODUCT; + return UMATCH_NONE; } -void +void uhmodem_attach(device_t parent, device_t self, void *aux) { struct uhmodem_softc *sc = device_private(self); - struct usbif_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; + struct usbif_attach_arg *uiaa = aux; + struct usbd_device *dev = uiaa->uiaa_device; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devinfop; usbd_status err; - struct ucom_attach_args uca; + struct ucom_attach_args ucaa; int i; int j; char comname[16]; @@ -211,15 +211,15 @@ uhmodem_attach(device_t parent, device_t self, void *aux) usbd_devinfo_free(devinfop); sc->sc_ubsa.sc_dev = self; - sc->sc_ubsa.sc_udev = dev; + sc->sc_ubsa.sc_udev = dev; sc->sc_ubsa.sc_config_index = UBSA_DEFAULT_CONFIG_INDEX; sc->sc_ubsa.sc_numif = 1; /* defaut device has one interface */ /* Hauwei E220 need special request to change its mode to modem */ - if ((uaa->ifaceno == 0) && (uaa->class != 255)) { + if ((uiaa->uiaa_ifaceno == 0) && (uiaa->uiaa_class != 255)) { err = e220_modechange_request(dev); if (err) { - aprint_error_dev(self, "failed to change mode: %s\n", + aprint_error_dev(self, "failed to change mode: %s\n", usbd_errstr(err)); sc->sc_ubsa.sc_dying = 1; goto error; @@ -239,8 +239,8 @@ uhmodem_attach(device_t parent, device_t self, void *aux) sc->sc_ubsa.sc_quadumts = 1; sc->sc_ubsa.sc_config_index = 0; - sc->sc_ubsa.sc_numif = uhmodem_lookup(uaa->vendor, uaa->product)->uhmodem_coms; - sc->sc_ubsa.sc_devflags = uhmodem_lookup(uaa->vendor, uaa->product)->uhmodem_flags; + sc->sc_ubsa.sc_numif = uhmodem_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product)->uhmodem_coms; + sc->sc_ubsa.sc_devflags = uhmodem_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product)->uhmodem_flags; DPRINTF(("uhmodem attach: sc = %p\n", sc)); @@ -283,7 +283,7 @@ uhmodem_attach(device_t parent, device_t self, void *aux) sc->sc_ubsa.sc_iface_number[i] = id->bInterfaceNumber; /* initialize endpoints */ - uca.bulkin = uca.bulkout = -1; + ucaa.ucaa_bulkin = ucaa.ucaa_bulkout = -1; for (j = 0; j < id->bNumEndpoints; j++) { ed = usbd_interface2endpoint_descriptor( @@ -301,10 +301,10 @@ uhmodem_attach(device_t parent, device_t self, void *aux) sc->sc_ubsa.sc_isize = UGETW(ed->wMaxPacketSize); } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - uca.bulkin = ed->bEndpointAddress; + ucaa.ucaa_bulkin = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - uca.bulkout = ed->bEndpointAddress; + ucaa.ucaa_bulkout = ed->bEndpointAddress; } } /* end of Endpoint loop */ @@ -318,14 +318,14 @@ uhmodem_attach(device_t parent, device_t self, void *aux) } else break; } - if (uca.bulkin == -1) { + if (ucaa.ucaa_bulkin == -1) { aprint_error_dev(self, "Could not find data bulk in\n"); sc->sc_ubsa.sc_dying = 1; goto error; } - if (uca.bulkout == -1) { + if (ucaa.ucaa_bulkout == -1) { aprint_error_dev(self, "Could not find data bulk out\n"); sc->sc_ubsa.sc_dying = 1; @@ -347,25 +347,26 @@ uhmodem_attach(device_t parent, device_t self, void *aux) break; } - uca.portno = i; - /* bulkin, bulkout set above */ - uca.ibufsize = UHMODEMIBUFSIZE; - uca.obufsize = UHMODEMOBUFSIZE; - uca.ibufsizepad = UHMODEMIBUFSIZE; - uca.opkthdrlen = 0; - uca.device = dev; - uca.iface = sc->sc_ubsa.sc_iface[i]; - uca.methods = &uhmodem_methods; - uca.arg = &sc->sc_ubsa; - uca.info = comname; + ucaa.ucaa_portno = i; + /* ucaa_bulkin, ucaa_bulkout set above */ + ucaa.ucaa_ibufsize = UHMODEMIBUFSIZE; + ucaa.ucaa_obufsize = UHMODEMOBUFSIZE; + ucaa.ucaa_ibufsizepad = UHMODEMIBUFSIZE; + ucaa.ucaa_opkthdrlen = 0; + ucaa.ucaa_device = dev; + ucaa.ucaa_iface = sc->sc_ubsa.sc_iface[i]; + ucaa.ucaa_methods = &uhmodem_methods; + ucaa.ucaa_arg = &sc->sc_ubsa; + ucaa.ucaa_info = comname; DPRINTF(("uhmodem: int#=%d, in = 0x%x, out = 0x%x, intr = 0x%x\n", - i, uca.bulkin, uca.bulkout, sc->sc_ubsa.sc_intr_number)); + i, ucaa.ucaa_bulkin, ucaa.ucaa_bulkout, + sc->sc_ubsa.sc_intr_number)); sc->sc_ubsa.sc_subdevs[i] = config_found_sm_loc(self, "ucombus", NULL, - &uca, ucomprint, ucomsubmatch); + &ucaa, ucomprint, ucomsubmatch); /* issue endpoint halt to each interface */ err = uhmodem_endpointhalt(&sc->sc_ubsa, i); - if (err) + if (err) aprint_error("%s: endpointhalt fail\n", __func__); else usbd_delay_ms(sc->sc_ubsa.sc_udev, 50); @@ -394,7 +395,7 @@ uhmodem_childdet(device_t self, device_t child) sc->sc_ubsa.sc_subdevs[i] = NULL; } -int +int uhmodem_detach(device_t self, int flags) { struct uhmodem_softc *sc = device_private(self); @@ -406,7 +407,7 @@ uhmodem_detach(device_t self, int flags) if (sc->sc_ubsa.sc_intr_pipe != NULL) { usbd_abort_pipe(sc->sc_ubsa.sc_intr_pipe); usbd_close_pipe(sc->sc_ubsa.sc_intr_pipe); - free(sc->sc_ubsa.sc_intr_buf, M_USBDEV); + kmem_free(sc->sc_ubsa.sc_intr_buf, sc->sc_ubsa.sc_isize); sc->sc_ubsa.sc_intr_pipe = NULL; } @@ -419,7 +420,7 @@ uhmodem_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_ubsa.sc_udev, sc->sc_ubsa.sc_dev); - return (rv); + return rv; } int @@ -443,12 +444,12 @@ uhmodem_open(void *addr, int portno) usbd_status err; if (sc->sc_dying) - return (ENXIO); + return ENXIO; DPRINTF(("%s: sc = %p\n", __func__, sc)); err = uhmodem_endpointhalt(sc, 0); - if (err) + if (err) aprint_error("%s: endpointhalt fail\n", __func__); else usbd_delay_ms(sc->sc_udev, 50); @@ -470,7 +471,7 @@ uhmodem_open(void *addr, int portno) } #endif if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) { - sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK); + sc->sc_intr_buf = kmem_alloc(sc->sc_isize, KM_SLEEP); /* XXX only iface# = 0 has intr line */ /* XXX E220 specific? need to check */ err = usbd_open_pipe_intr(sc->sc_iface[0], @@ -486,19 +487,19 @@ uhmodem_open(void *addr, int portno) aprint_error_dev(sc->sc_dev, "cannot open interrupt pipe (addr %d)\n", sc->sc_intr_number); - return (EIO); + return EIO; } } - return (0); + return 0; } /* * Hauwei E220 needs special request to enable modem function. * -- DEVICE_REMOTE_WAKEUP ruquest to endpoint 2. */ -Static usbd_status -e220_modechange_request(usbd_device_handle dev) +Static usbd_status +e220_modechange_request(struct usbd_device *dev) { #define E220_MODE_CHANGE_REQUEST 0x2 usb_device_request_t req; @@ -514,14 +515,14 @@ e220_modechange_request(usbd_device_handle dev) err = usbd_do_request(dev, &req, 0); if (err) { DPRINTF(("%s: E220 mode change fail\n", __func__)); - return (EIO); + return EIO; } - return (0); + return 0; #undef E220_MODE_CHANGE_REQUEST } -Static usbd_status +Static usbd_status uhmodem_endpointhalt(struct ubsa_softc *sc, int iface) { usb_device_request_t req; @@ -535,8 +536,8 @@ uhmodem_endpointhalt(struct ubsa_softc *sc, int iface) for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface[iface], i); - if (ed == NULL) - return (EIO); + if (ed == NULL) + return EIO; if (UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { /* issue ENDPOINT_HALT request */ @@ -547,19 +548,19 @@ uhmodem_endpointhalt(struct ubsa_softc *sc, int iface) USETW(req.wLength, 0); err = usbd_do_request(sc->sc_udev, &req, 0); if (err) { - DPRINTF(("%s: ENDPOINT_HALT to EP:%d fail\n", + DPRINTF(("%s: ENDPOINT_HALT to EP:%d fail\n", __func__, ed->bEndpointAddress)); - return (EIO); + return EIO; } } } /* end of Endpoint loop */ - return (0); + return 0; } Static usbd_status -uhmodem_regwrite(usbd_device_handle dev, uint8_t *data, size_t len) +uhmodem_regwrite(struct usbd_device *dev, uint8_t *data, size_t len) { usb_device_request_t req; usbd_status err; @@ -570,14 +571,14 @@ uhmodem_regwrite(usbd_device_handle dev, uint8_t *data, size_t len) USETW(req.wIndex, 0x0000); USETW(req.wLength, len); err = usbd_do_request(dev, &req, data); - if (err) + if (err) return err; return 0; } Static usbd_status -uhmodem_regread(usbd_device_handle dev, uint8_t *data, size_t len) +uhmodem_regread(struct usbd_device *dev, uint8_t *data, size_t len) { usb_device_request_t req; usbd_status err; @@ -597,7 +598,7 @@ uhmodem_regread(usbd_device_handle dev, uint8_t *data, size_t len) #if 0 Static usbd_status -uhmodem_regsetup(usbd_device_handle dev, uint16_t cmd) +uhmodem_regsetup(struct usbd_device *dev, uint16_t cmd) { usb_device_request_t req; usbd_status err; @@ -616,8 +617,8 @@ uhmodem_regsetup(usbd_device_handle dev, uint16_t cmd) } #endif -Static usbd_status -a2502_init(usbd_device_handle dev) +Static usbd_status +a2502_init(struct usbd_device *dev) { uint8_t data[8]; static uint8_t init_cmd[] = {0x00, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x08}; @@ -638,7 +639,7 @@ a2502_init(usbd_device_handle dev) return EIO; } - if (uhmodem_regread(dev, data, 7)) { + if (uhmodem_regread(dev, data, 7)) { DPRINTF(("%s: read fail\n", __func__)); return EIO; } @@ -654,13 +655,13 @@ a2502_init(usbd_device_handle dev) #if 0 -/* +/* * Windows device driver send these sequens of USB requests. * However currently I can't understand what the messege is, * disable this code when I get more information about it. - */ -Static usbd_status -e220_init(usbd_device_handle dev) + */ +Static usbd_status +e220_init(struct usbd_device *dev) { uint8_t data[8]; usb_device_request_t req; @@ -678,7 +679,7 @@ e220_init(usbd_device_handle dev) goto error; /* vendor specific unknown sequence */ - if(uhmodem_regsetup(dev, 0x1)) + if(uhmodem_regsetup(dev, 0x1)) goto error; if (uhmodem_regread(dev, data, 7)) @@ -696,10 +697,10 @@ e220_init(usbd_device_handle dev) if (uhmodem_regsetup(dev, 0x3)) goto error; - return (0); + return 0; error: DPRINTF(("%s: E220 init request fail\n", __func__)); - return (EIO); + return EIO; } #endif diff --git a/sys/dev/usb/uhso.c b/sys/dev/usb/uhso.c index 25ee8510d48..300bd29967c 100644 --- a/sys/dev/usb/uhso.c +++ b/sys/dev/usb/uhso.c @@ -1,4 +1,4 @@ -/* $NetBSD: uhso.c,v 1.18 2016/04/20 09:01:04 knakahara Exp $ */ +/* $NetBSD: uhso.c,v 1.19 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2009 Iain Hibbert @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uhso.c,v 1.18 2016/04/20 09:01:04 knakahara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uhso.c,v 1.19 2016/04/23 10:15:32 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -292,24 +292,24 @@ struct uhso_port { usbd_callback hp_read_cb; /* read callback */ uhso_callback hp_control; /* set control lines */ - usbd_interface_handle hp_ifh; /* interface handle */ + struct usbd_interface *hp_ifh; /* interface handle */ unsigned int hp_index; /* usb request index */ int hp_iaddr; /* interrupt endpoint */ - usbd_pipe_handle hp_ipipe; /* interrupt pipe */ + struct usbd_pipe *hp_ipipe; /* interrupt pipe */ void *hp_ibuf; /* interrupt buffer */ size_t hp_isize; /* allocated size */ int hp_raddr; /* bulk in endpoint */ - usbd_pipe_handle hp_rpipe; /* bulk in pipe */ - usbd_xfer_handle hp_rxfer; /* input xfer */ + struct usbd_pipe *hp_rpipe; /* bulk in pipe */ + struct usbd_xfer *hp_rxfer; /* input xfer */ void *hp_rbuf; /* input buffer */ size_t hp_rlen; /* fill length */ size_t hp_rsize; /* allocated size */ int hp_waddr; /* bulk out endpoint */ - usbd_pipe_handle hp_wpipe; /* bulk out pipe */ - usbd_xfer_handle hp_wxfer; /* output xfer */ + struct usbd_pipe *hp_wpipe; /* bulk out pipe */ + struct usbd_xfer *hp_wxfer; /* output xfer */ void *hp_wbuf; /* output buffer */ size_t hp_wlen; /* fill length */ size_t hp_wsize; /* allocated size */ @@ -324,7 +324,7 @@ struct uhso_port { struct uhso_softc { device_t sc_dev; /* self */ - usbd_device_handle sc_udev; + struct usbd_device *sc_udev; int sc_refcnt; struct uhso_port *sc_port[UHSO_PORT_MAX]; }; @@ -340,11 +340,11 @@ extern struct cfdriver uhso_cd; CFATTACH_DECL_NEW(uhso, sizeof(struct uhso_softc), uhso_match, uhso_attach, uhso_detach, NULL); -Static int uhso_switch_mode(usbd_device_handle); +Static int uhso_switch_mode(struct usbd_device *); Static int uhso_get_iface_spec(struct usb_attach_arg *, uint8_t, uint8_t *); -Static usb_endpoint_descriptor_t *uhso_get_endpoint(usbd_interface_handle, int, int); +Static usb_endpoint_descriptor_t *uhso_get_endpoint(struct usbd_interface *, int, int); -Static void uhso_mux_attach(struct uhso_softc *, usbd_interface_handle, int); +Static void uhso_mux_attach(struct uhso_softc *, struct usbd_interface *, int); Static int uhso_mux_abort(struct uhso_port *); Static int uhso_mux_detach(struct uhso_port *); Static int uhso_mux_init(struct uhso_port *); @@ -352,9 +352,9 @@ Static int uhso_mux_clean(struct uhso_port *); Static int uhso_mux_write(struct uhso_port *); Static int uhso_mux_read(struct uhso_port *); Static int uhso_mux_control(struct uhso_port *); -Static void uhso_mux_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void uhso_mux_intr(struct usbd_xfer *, void *, usbd_status); -Static void uhso_bulk_attach(struct uhso_softc *, usbd_interface_handle, int); +Static void uhso_bulk_attach(struct uhso_softc *, struct usbd_interface *, int); Static int uhso_bulk_abort(struct uhso_port *); Static int uhso_bulk_detach(struct uhso_port *); Static int uhso_bulk_init(struct uhso_port *); @@ -362,12 +362,12 @@ Static int uhso_bulk_clean(struct uhso_port *); Static int uhso_bulk_write(struct uhso_port *); Static int uhso_bulk_read(struct uhso_port *); Static int uhso_bulk_control(struct uhso_port *); -Static void uhso_bulk_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void uhso_bulk_intr(struct usbd_xfer *, void *, usbd_status); Static void uhso_tty_attach(struct uhso_port *); Static void uhso_tty_detach(struct uhso_port *); -Static void uhso_tty_read_cb(usbd_xfer_handle, usbd_private_handle, usbd_status); -Static void uhso_tty_write_cb(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void uhso_tty_read_cb(struct usbd_xfer *, void *, usbd_status); +Static void uhso_tty_write_cb(struct usbd_xfer *, void *, usbd_status); dev_type_open(uhso_tty_open); dev_type_close(uhso_tty_close); @@ -410,12 +410,12 @@ Static int uhso_tty_control(struct uhso_port *, u_long, int); #define UHSODIALOUT(x) TTDIALOUT(x) #define UHSOMINOR(u, p) ((((u) << 4) & UHSO_UNIT_MASK) | ((p) & UHSO_UNIT_MASK)) -Static void uhso_ifnet_attach(struct uhso_softc *, usbd_interface_handle, int); +Static void uhso_ifnet_attach(struct uhso_softc *, struct usbd_interface *, int); Static int uhso_ifnet_abort(struct uhso_port *); Static int uhso_ifnet_detach(struct uhso_port *); -Static void uhso_ifnet_read_cb(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void uhso_ifnet_read_cb(struct usbd_xfer *, void *, usbd_status); Static void uhso_ifnet_input(struct ifnet *, struct mbuf **, uint8_t *, size_t); -Static void uhso_ifnet_write_cb(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void uhso_ifnet_write_cb(struct usbd_xfer *, void *, usbd_status); Static int uhso_ifnet_ioctl(struct ifnet *, u_long, void *); Static int uhso_ifnet_init(struct uhso_port *); @@ -439,10 +439,10 @@ uhso_match(device_t parent, cfdata_t match, void *aux) * don't claim this device if autoswitch is disabled * and it is not in modem mode already */ - if (!uhso_autoswitch && uaa->class != UDCLASS_VENDOR) + if (!uhso_autoswitch && uaa->uaa_class != UDCLASS_VENDOR) return UMATCH_NONE; - if (uhso_lookup(uaa->vendor, uaa->product)) + if (uhso_lookup(uaa->uaa_vendor, uaa->uaa_product)) return UMATCH_VENDOR_PRODUCT; return UMATCH_NONE; @@ -453,7 +453,7 @@ uhso_attach(device_t parent, device_t self, void *aux) { struct uhso_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_interface_handle ifh; + struct usbd_interface *ifh; char *devinfop; uint8_t count, i, spec; usbd_status status; @@ -461,12 +461,12 @@ uhso_attach(device_t parent, device_t self, void *aux) DPRINTF(1, ": sc = %p, self=%p", sc, self); sc->sc_dev = self; - sc->sc_udev = uaa->device; + sc->sc_udev = uaa->uaa_device; aprint_naive("\n"); aprint_normal("\n"); - devinfop = usbd_devinfo_alloc(uaa->device, 0); + devinfop = usbd_devinfo_alloc(uaa->uaa_device, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); @@ -479,9 +479,9 @@ uhso_attach(device_t parent, device_t self, void *aux) return; } - if (uaa->class != UDCLASS_VENDOR) { + if (uaa->uaa_class != UDCLASS_VENDOR) { aprint_verbose_dev(self, "Switching device into modem mode..\n"); - if (uhso_switch_mode(uaa->device) != 0) + if (uhso_switch_mode(uaa->uaa_device) != 0) aprint_error_dev(self, "modem switch failed\n"); return; @@ -577,13 +577,13 @@ uhso_detach(device_t self, int flags) * Send SCSI REZERO_UNIT command to switch device into modem mode */ Static int -uhso_switch_mode(usbd_device_handle udev) +uhso_switch_mode(struct usbd_device *udev) { umass_bbb_cbw_t cmd; usb_endpoint_descriptor_t *ed; - usbd_interface_handle ifh; - usbd_pipe_handle pipe; - usbd_xfer_handle xfer; + struct usbd_interface *ifh; + struct usbd_pipe *pipe; + struct usbd_xfer *xfer; usbd_status status; status = usbd_device2interface_handle(udev, 0, &ifh); @@ -598,9 +598,9 @@ uhso_switch_mode(usbd_device_handle udev) if (status != USBD_NORMAL_COMPLETION) return EIO; - xfer = usbd_alloc_xfer(udev); - if (xfer == NULL) - return ENOMEM; + int error = usbd_create_xfer(pipe, sizeof(cmd), 0, 0, &xfer); + if (error) + return error; USETDW(cmd.dCBWSignature, CBWSIGNATURE); USETDW(cmd.dCBWTag, 1); @@ -612,14 +612,13 @@ uhso_switch_mode(usbd_device_handle udev) memset(&cmd.CBWCDB, 0, CBWCDBLENGTH); cmd.CBWCDB[0] = SCSI_REZERO_UNIT; - usbd_setup_xfer(xfer, pipe, NULL, &cmd, sizeof(cmd), + usbd_setup_xfer(xfer, NULL, &cmd, sizeof(cmd), USBD_SYNCHRONOUS, USBD_DEFAULT_TIMEOUT, NULL); status = usbd_transfer(xfer); - usbd_abort_pipe(pipe); + usbd_destroy_xfer(xfer); usbd_close_pipe(pipe); - usbd_free_xfer(xfer); return (status == USBD_NORMAL_COMPLETION ? 0 : EIO); } @@ -632,7 +631,7 @@ uhso_get_iface_spec(struct usb_attach_arg *uaa, uint8_t ifnum, uint8_t *spec) usb_device_request_t req; usbd_status status; - hd = uhso_lookup(uaa->vendor, uaa->product); + hd = uhso_lookup(uaa->uaa_vendor, uaa->uaa_product); KASSERT(hd != NULL); switch (hd->type) { @@ -657,7 +656,7 @@ uhso_get_iface_spec(struct usb_attach_arg *uaa, uint8_t ifnum, uint8_t *spec) USETW(req.wIndex, 0); USETW(req.wLength, sizeof(config)); - status = usbd_do_request(uaa->device, &req, config); + status = usbd_do_request(uaa->uaa_device, &req, config); if (status != USBD_NORMAL_COMPLETION) break; @@ -683,7 +682,7 @@ uhso_get_iface_spec(struct usb_attach_arg *uaa, uint8_t ifnum, uint8_t *spec) } Static usb_endpoint_descriptor_t * -uhso_get_endpoint(usbd_interface_handle ifh, int type, int dir) +uhso_get_endpoint(struct usbd_interface *ifh, int type, int dir) { usb_endpoint_descriptor_t *ed; uint8_t count, i; @@ -720,12 +719,12 @@ Static const int uhso_mux_port[] = { }; Static void -uhso_mux_attach(struct uhso_softc *sc, usbd_interface_handle ifh, int index) +uhso_mux_attach(struct uhso_softc *sc, struct usbd_interface *ifh, int index) { usbd_desc_iter_t iter; const usb_descriptor_t *desc; usb_endpoint_descriptor_t *ed; - usbd_pipe_handle pipe; + struct usbd_pipe *pipe; struct uhso_port *hp; uint8_t *buf; size_t size; @@ -877,6 +876,23 @@ uhso_mux_init(struct uhso_port *hp) CLR(hp->hp_flags, UHSO_PORT_MUXBUSY | UHSO_PORT_MUXREADY); SET(hp->hp_status, TIOCM_DSR | TIOCM_CAR); + + struct uhso_softc *sc = hp->hp_sc; + struct usbd_pipe *pipe0 = usbd_get_pipe0(sc->sc_udev); + int error; + + error = usbd_create_xfer(pipe0, hp->hp_rsize, 0, 0, &hp->hp_rxfer); + if (error) + return error; + + hp->hp_rbuf = usbd_get_buffer(hp->hp_rxfer); + + error = usbd_create_xfer(pipe0, hp->hp_wsize, 0, 0, &hp->hp_wxfer); + if (error) + return error; + + hp->hp_wbuf = usbd_get_buffer(hp->hp_wxfer); + return 0; } @@ -907,7 +923,7 @@ uhso_mux_write(struct uhso_port *hp) USETW(req.wLength, hp->hp_wlen); usbd_setup_default_xfer(hp->hp_wxfer, sc->sc_udev, hp, USBD_NO_TIMEOUT, - &req, hp->hp_wbuf, hp->hp_wlen, USBD_NO_COPY, hp->hp_write_cb); + &req, hp->hp_wbuf, hp->hp_wlen, 0, hp->hp_write_cb); status = usbd_transfer(hp->hp_wxfer); if (status != USBD_IN_PROGRESS) { @@ -943,7 +959,7 @@ uhso_mux_read(struct uhso_port *hp) USETW(req.wLength, hp->hp_rsize); usbd_setup_default_xfer(hp->hp_rxfer, sc->sc_udev, hp, USBD_NO_TIMEOUT, - &req, hp->hp_rbuf, hp->hp_rsize, USBD_NO_COPY | USBD_SHORT_XFER_OK, + &req, hp->hp_rbuf, hp->hp_rsize, USBD_SHORT_XFER_OK, hp->hp_read_cb); status = usbd_transfer(hp->hp_rxfer); @@ -967,7 +983,7 @@ uhso_mux_control(struct uhso_port *hp) } Static void -uhso_mux_intr(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) +uhso_mux_intr(struct usbd_xfer *xfer, void * p, usbd_status status) { struct uhso_softc *sc = p; struct uhso_port *hp; @@ -1014,7 +1030,7 @@ uhso_mux_intr(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) */ Static void -uhso_bulk_attach(struct uhso_softc *sc, usbd_interface_handle ifh, int index) +uhso_bulk_attach(struct uhso_softc *sc, struct usbd_interface *ifh, int index) { usb_endpoint_descriptor_t *ed; usb_interface_descriptor_t *id; @@ -1139,6 +1155,19 @@ uhso_bulk_init(struct uhso_port *hp) return EIO; } + int error = usbd_create_xfer(hp->hp_rpipe, hp->hp_rsize, + USBD_SHORT_XFER_OK, 0, &hp->hp_rxfer); + if (error) + return error; + + hp->hp_rbuf = usbd_get_buffer(hp->hp_rxfer); + + error = usbd_create_xfer(hp->hp_wpipe, hp->hp_wsize, 0, 0, + &hp->hp_wxfer); + if (error) + return error; + hp->hp_wbuf = usbd_get_buffer(hp->hp_wxfer); + return 0; } @@ -1161,12 +1190,30 @@ uhso_bulk_clean(struct uhso_port *hp) if (hp->hp_rpipe != NULL) { usbd_abort_pipe(hp->hp_rpipe); + } + + if (hp->hp_wpipe != NULL) { + usbd_abort_pipe(hp->hp_wpipe); + } + + if (hp->hp_rxfer != NULL) { + usbd_destroy_xfer(hp->hp_rxfer); + hp->hp_rxfer = NULL; + hp->hp_rbuf = NULL; + } + + if (hp->hp_wxfer != NULL) { + usbd_destroy_xfer(hp->hp_wxfer); + hp->hp_wxfer = NULL; + hp->hp_wbuf = NULL; + } + + if (hp->hp_rpipe != NULL) { usbd_close_pipe(hp->hp_rpipe); hp->hp_rpipe = NULL; } if (hp->hp_wpipe != NULL) { - usbd_abort_pipe(hp->hp_wpipe); usbd_close_pipe(hp->hp_wpipe); hp->hp_wpipe = NULL; } @@ -1182,8 +1229,8 @@ uhso_bulk_write(struct uhso_port *hp) DPRINTF(5, "hp=%p, wlen=%zd\n", hp, hp->hp_wlen); - usbd_setup_xfer(hp->hp_wxfer, hp->hp_wpipe, hp, hp->hp_wbuf, - hp->hp_wlen, USBD_NO_COPY, USBD_NO_TIMEOUT, hp->hp_write_cb); + usbd_setup_xfer(hp->hp_wxfer, hp, hp->hp_wbuf, hp->hp_wlen, 0, + USBD_NO_TIMEOUT, hp->hp_write_cb); status = usbd_transfer(hp->hp_wxfer); if (status != USBD_IN_PROGRESS) { @@ -1203,9 +1250,8 @@ uhso_bulk_read(struct uhso_port *hp) DPRINTF(5, "hp=%p\n", hp); - usbd_setup_xfer(hp->hp_rxfer, hp->hp_rpipe, hp, hp->hp_rbuf, - hp->hp_rsize, USBD_NO_COPY | USBD_SHORT_XFER_OK, - USBD_NO_TIMEOUT, hp->hp_read_cb); + usbd_setup_xfer(hp->hp_rxfer, hp, hp->hp_rbuf, hp->hp_rsize, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, hp->hp_read_cb); status = usbd_transfer(hp->hp_rxfer); if (status != USBD_IN_PROGRESS) { @@ -1258,7 +1304,7 @@ uhso_bulk_control(struct uhso_port *hp) } Static void -uhso_bulk_intr(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) +uhso_bulk_intr(struct usbd_xfer *xfer, void * p, usbd_status status) { struct uhso_port *hp = p; struct tty *tp = hp->hp_tp; @@ -1341,7 +1387,7 @@ uhso_tty_detach(struct uhso_port *hp) } Static void -uhso_tty_write_cb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) +uhso_tty_write_cb(struct usbd_xfer *xfer, void * p, usbd_status status) { struct uhso_port *hp = p; struct uhso_softc *sc = hp->hp_sc; @@ -1374,7 +1420,7 @@ uhso_tty_write_cb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status stat } Static void -uhso_tty_read_cb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) +uhso_tty_read_cb(struct usbd_xfer *xfer, void * p, usbd_status status) { struct uhso_port *hp = p; struct uhso_softc *sc = hp->hp_sc; @@ -1473,7 +1519,6 @@ uhso_tty_open(dev_t dev, int flag, int mode, struct lwp *l) Static int uhso_tty_init(struct uhso_port *hp) { - struct uhso_softc *sc = hp->hp_sc; struct tty *tp = hp->hp_tp; struct termios t; int error; @@ -1509,22 +1554,6 @@ uhso_tty_init(struct uhso_port *hp) if (error != 0) return error; - hp->hp_rxfer = usbd_alloc_xfer(sc->sc_udev); - if (hp->hp_rxfer == NULL) - return ENOMEM; - - hp->hp_rbuf = usbd_alloc_buffer(hp->hp_rxfer, hp->hp_rsize); - if (hp->hp_rbuf == NULL) - return ENOMEM; - - hp->hp_wxfer = usbd_alloc_xfer(sc->sc_udev); - if (hp->hp_wxfer == NULL) - return ENOMEM; - - hp->hp_wbuf = usbd_alloc_buffer(hp->hp_wxfer, hp->hp_wsize); - if (hp->hp_wbuf == NULL) - return ENOMEM; - /* * Turn on DTR. We must always do this, even if carrier is not * present, because otherwise we'd have to use TIOCSDTR @@ -1581,13 +1610,13 @@ uhso_tty_clean(struct uhso_port *hp) (*hp->hp_clean)(hp); if (hp->hp_rxfer != NULL) { - usbd_free_xfer(hp->hp_rxfer); + usbd_destroy_xfer(hp->hp_rxfer); hp->hp_rxfer = NULL; hp->hp_rbuf = NULL; } if (hp->hp_wxfer != NULL) { - usbd_free_xfer(hp->hp_wxfer); + usbd_destroy_xfer(hp->hp_wxfer); hp->hp_wxfer = NULL; hp->hp_wbuf = NULL; } @@ -1861,7 +1890,7 @@ uhso_tty_control(struct uhso_port *hp, u_long cmd, int bits) */ Static void -uhso_ifnet_attach(struct uhso_softc *sc, usbd_interface_handle ifh, int index) +uhso_ifnet_attach(struct uhso_softc *sc, struct usbd_interface *ifh, int index) { usb_endpoint_descriptor_t *ed; struct uhso_port *hp; @@ -1961,7 +1990,7 @@ uhso_ifnet_detach(struct uhso_port *hp) } Static void -uhso_ifnet_write_cb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status status) +uhso_ifnet_write_cb(struct usbd_xfer *xfer, void * p, usbd_status status) { struct uhso_port *hp = p; struct uhso_softc *sc= hp->hp_sc; @@ -2001,7 +2030,7 @@ uhso_ifnet_write_cb(usbd_xfer_handle xfer, usbd_private_handle p, usbd_status st } Static void -uhso_ifnet_read_cb(usbd_xfer_handle xfer, usbd_private_handle p, +uhso_ifnet_read_cb(struct usbd_xfer *xfer, void * p, usbd_status status) { struct uhso_port *hp = p; @@ -2253,22 +2282,6 @@ uhso_ifnet_init(struct uhso_port *hp) if (error != 0) return error; - hp->hp_rxfer = usbd_alloc_xfer(sc->sc_udev); - if (hp->hp_rxfer == NULL) - return ENOMEM; - - hp->hp_rbuf = usbd_alloc_buffer(hp->hp_rxfer, hp->hp_rsize); - if (hp->hp_rbuf == NULL) - return ENOMEM; - - hp->hp_wxfer = usbd_alloc_xfer(sc->sc_udev); - if (hp->hp_wxfer == NULL) - return ENOMEM; - - hp->hp_wbuf = usbd_alloc_buffer(hp->hp_wxfer, hp->hp_wsize); - if (hp->hp_wbuf == NULL) - return ENOMEM; - error = (*hp->hp_read)(hp); if (error != 0) return error; @@ -2283,18 +2296,6 @@ uhso_ifnet_clean(struct uhso_port *hp) DPRINTF(1, "hp=%p\n", hp); (*hp->hp_clean)(hp); - - if (hp->hp_rxfer != NULL) { - usbd_free_xfer(hp->hp_rxfer); - hp->hp_rxfer = NULL; - hp->hp_rbuf = NULL; - } - - if (hp->hp_wxfer != NULL) { - usbd_free_xfer(hp->hp_wxfer); - hp->hp_wxfer = NULL; - hp->hp_wbuf = NULL; - } } /* called at splnet() with IFF_OACTIVE not set */ diff --git a/sys/dev/usb/uhub.c b/sys/dev/usb/uhub.c index cf2a5e72894..659d05f11f0 100644 --- a/sys/dev/usb/uhub.c +++ b/sys/dev/usb/uhub.c @@ -1,5 +1,6 @@ -/* $NetBSD: uhub.c,v 1.132 2016/03/13 07:01:43 skrll Exp $ */ +/* $NetBSD: uhub.c,v 1.133 2016/04/23 10:15:32 skrll Exp $ */ /* $FreeBSD: src/sys/dev/usb/uhub.c,v 1.18 1999/11/17 22:33:43 n_hibma Exp $ */ +/* $OpenBSD: uhub.c,v 1.86 2015/06/29 18:27:40 mpi Exp $ */ /* * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. @@ -36,18 +37,18 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uhub.c,v 1.132 2016/03/13 07:01:43 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uhub.c,v 1.133 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> -#include <sys/systm.h> +#include <sys/bus.h> #include <sys/device.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/proc.h> #include <sys/sysctl.h> +#include <sys/systm.h> -#include <sys/bus.h> #include <dev/usb/usb.h> #include <dev/usb/usbdi.h> @@ -97,29 +98,31 @@ fail: #define UHUBHIST_CALLED(name) USBHIST_CALLED(uhubdebug) struct uhub_softc { - device_t sc_dev; /* base device */ - usbd_device_handle sc_hub; /* USB device */ - int sc_proto; /* device protocol */ - usbd_pipe_handle sc_ipipe; /* interrupt pipe */ - - /* XXX second buffer needed because we can't suspend pipes yet */ - u_int8_t *sc_statusbuf; - u_int8_t *sc_status; - size_t sc_statuslen; - int sc_explorepending; - int sc_isehciroothub; /* see comment in uhub_intr() */ - - u_char sc_running; + device_t sc_dev; /* base device */ + struct usbd_device *sc_hub; /* USB device */ + int sc_proto; /* device protocol */ + struct usbd_pipe *sc_ipipe; /* interrupt pipe */ + + kmutex_t sc_lock; + + uint8_t *sc_statusbuf; + uint8_t *sc_statuspend; + uint8_t *sc_status; + size_t sc_statuslen; + int sc_explorepending; + + u_char sc_running; }; -#define UHUB_IS_HIGH_SPEED(sc) ((sc)->sc_proto != UDPROTO_FSHUB) +#define UHUB_IS_HIGH_SPEED(sc) \ + ((sc)->sc_proto == UDPROTO_HSHUBSTT || (sc)->sc_proto == UDPROTO_HSHUBMTT) #define UHUB_IS_SINGLE_TT(sc) ((sc)->sc_proto == UDPROTO_HSHUBSTT) #define PORTSTAT_ISSET(sc, port) \ ((sc)->sc_status[(port) / 8] & (1 << ((port) % 8))) -Static usbd_status uhub_explore(usbd_device_handle hub); -Static void uhub_intr(usbd_xfer_handle, usbd_private_handle,usbd_status); +Static usbd_status uhub_explore(struct usbd_device *); +Static void uhub_intr(struct usbd_xfer *, void *, usbd_status); /* @@ -147,6 +150,76 @@ CFATTACH_DECL2_NEW(uroothub, sizeof(struct uhub_softc), uhub_match, */ int uhub_ubermatch = 0; +static usbd_status +usbd_get_hub_desc(struct usbd_device *dev, usb_hub_descriptor_t *hd, int speed) +{ + usb_device_request_t req; + usbd_status err; + int nports; + + UHUBHIST_FUNC(); UHUBHIST_CALLED(); + + /* don't issue UDESC_HUB to SS hub, or it would stall */ + if (dev->ud_depth != 0 && USB_IS_SS(dev->ud_speed)) { + usb_hub_ss_descriptor_t hssd; + int rmvlen; + + memset(&hssd, 0, sizeof(hssd)); + req.bmRequestType = UT_READ_CLASS_DEVICE; + req.bRequest = UR_GET_DESCRIPTOR; + USETW2(req.wValue, UDESC_SS_HUB, 0); + USETW(req.wIndex, 0); + USETW(req.wLength, USB_HUB_SS_DESCRIPTOR_SIZE); + DPRINTFN(1, "getting sshub descriptor", 0, 0, 0, 0); + err = usbd_do_request(dev, &req, &hssd); + nports = hssd.bNbrPorts; + if (dev->ud_depth != 0 && nports > UHD_SS_NPORTS_MAX) { + DPRINTF("num of ports %d exceeds maxports %d", + nports, UHD_SS_NPORTS_MAX, 0, 0); + nports = hd->bNbrPorts = UHD_SS_NPORTS_MAX; + } + rmvlen = (nports + 7) / 8; + hd->bDescLength = USB_HUB_DESCRIPTOR_SIZE + + (rmvlen > 1 ? rmvlen : 1) - 1; + memcpy(hd->DeviceRemovable, hssd.DeviceRemovable, rmvlen); + hd->bDescriptorType = hssd.bDescriptorType; + hd->bNbrPorts = hssd.bNbrPorts; + hd->wHubCharacteristics[0] = hssd.wHubCharacteristics[0]; + hd->wHubCharacteristics[1] = hssd.wHubCharacteristics[1]; + hd->bPwrOn2PwrGood = hssd.bPwrOn2PwrGood; + hd->bHubContrCurrent = hssd.bHubContrCurrent; + } else { + req.bmRequestType = UT_READ_CLASS_DEVICE; + req.bRequest = UR_GET_DESCRIPTOR; + USETW2(req.wValue, UDESC_HUB, 0); + USETW(req.wIndex, 0); + USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE); + DPRINTFN(1, "getting hub descriptor", 0, 0, 0, 0); + err = usbd_do_request(dev, &req, hd); + nports = hd->bNbrPorts; + if (!err && nports > 7) { + USETW(req.wLength, + USB_HUB_DESCRIPTOR_SIZE + (nports+1) / 8); + err = usbd_do_request(dev, &req, hd); + } + } + + return err; +} + +static usbd_status +usbd_set_hub_depth(struct usbd_device *dev, int depth) +{ + usb_device_request_t req; + + req.bmRequestType = UT_WRITE_CLASS_DEVICE; + req.bRequest = UR_SET_HUB_DEPTH; + USETW(req.wValue, depth); + USETW(req.wIndex, 0); + USETW(req.wLength, 0); + return usbd_do_request(dev, &req, 0); +} + int uhub_match(device_t parent, cfdata_t match, void *aux) { @@ -165,9 +238,9 @@ uhub_match(device_t parent, cfdata_t match, void *aux) * The subclass for hubs seems to be 0 for some and 1 for others, * so we just ignore the subclass. */ - if (uaa->class == UDCLASS_HUB) - return (matchvalue); - return (UMATCH_NONE); + if (uaa->uaa_class == UDCLASS_HUB) + return matchvalue; + return UMATCH_NONE; } void @@ -175,14 +248,13 @@ uhub_attach(device_t parent, device_t self, void *aux) { struct uhub_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; + struct usbd_device *dev = uaa->uaa_device; char *devinfop; usbd_status err; struct usbd_hub *hub = NULL; - usb_device_request_t req; usb_hub_descriptor_t hubdesc; int p, port, nports, nremov, pwrdly; - usbd_interface_handle iface; + struct usbd_interface *iface; usb_endpoint_descriptor_t *ed; struct usbd_tt *tts = NULL; @@ -190,14 +262,14 @@ uhub_attach(device_t parent, device_t self, void *aux) sc->sc_dev = self; sc->sc_hub = dev; - sc->sc_proto = uaa->proto; + sc->sc_proto = uaa->uaa_proto; devinfop = usbd_devinfo_alloc(dev, 1); aprint_naive("\n"); aprint_normal(": %s\n", devinfop); usbd_devinfo_free(devinfop); - if (dev->depth > 0 && UHUB_IS_HIGH_SPEED(sc)) { + if (dev->ud_depth > 0 && UHUB_IS_HIGH_SPEED(sc)) { aprint_normal_dev(self, "%s transaction translator%s\n", UHUB_IS_SINGLE_TT(sc) ? "single" : "multiple", UHUB_IS_SINGLE_TT(sc) ? "" : "s"); @@ -209,7 +281,7 @@ uhub_attach(device_t parent, device_t self, void *aux) return; } - if (dev->depth > USB_HUB_MAX_DEPTH) { + if (dev->ud_depth > USB_HUB_MAX_DEPTH) { aprint_error_dev(self, "hub depth (%d) exceeded, hub ignored\n", USB_HUB_MAX_DEPTH); @@ -217,20 +289,11 @@ uhub_attach(device_t parent, device_t self, void *aux) } /* Get hub descriptor. */ - req.bmRequestType = UT_READ_CLASS_DEVICE; - req.bRequest = UR_GET_DESCRIPTOR; - USETW2(req.wValue, UDESC_HUB, 0); - USETW(req.wIndex, 0); - USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE); - DPRINTF("uhub %d getting hub descriptor", device_unit(self), 0, 0, 0); - err = usbd_do_request(dev, &req, &hubdesc); + memset(&hubdesc, 0, sizeof(hubdesc)); + err = usbd_get_hub_desc(dev, &hubdesc, dev->ud_speed); nports = hubdesc.bNbrPorts; - if (!err && nports > 7) { - USETW(req.wLength, USB_HUB_DESCRIPTOR_SIZE + (nports+1) / 8); - err = usbd_do_request(dev, &req, &hubdesc); - } if (err) { - DPRINTF("getting hub descriptor failed, uhub %d error %d", + DPRINTF("getting hub descriptor failed, uhub%d error %d", device_unit(self), err, 0, 0); return; } @@ -240,21 +303,31 @@ uhub_attach(device_t parent, device_t self, void *aux) nremov++; aprint_verbose_dev(self, "%d port%s with %d removable, %s powered\n", nports, nports != 1 ? "s" : "", nremov, - dev->self_powered ? "self" : "bus"); + dev->ud_selfpowered ? "self" : "bus"); if (nports == 0) { aprint_debug_dev(self, "no ports, hub ignored\n"); goto bad; } - hub = malloc(sizeof(*hub) + (nports-1) * sizeof(struct usbd_port), - M_USBDEV, M_NOWAIT); + hub = kmem_alloc(sizeof(*hub) + (nports-1) * sizeof(struct usbd_port), + KM_SLEEP); if (hub == NULL) return; - dev->hub = hub; - dev->hub->hubsoftc = sc; - hub->explore = uhub_explore; - hub->hubdesc = hubdesc; + dev->ud_hub = hub; + dev->ud_hub->uh_hubsoftc = sc; + hub->uh_explore = uhub_explore; + hub->uh_hubdesc = hubdesc; + + if (USB_IS_SS(dev->ud_speed) && dev->ud_depth != 0) { + aprint_debug_dev(self, "setting hub depth %u\n", + dev->ud_depth-1); + err = usbd_set_hub_depth(dev, dev->ud_depth - 1); + if (err) { + aprint_error_dev(self, "can't set depth\n"); + goto bad; + } + } /* Set up interrupt pipe. */ err = usbd_device2interface_handle(dev, 0, &iface); @@ -280,14 +353,18 @@ uhub_attach(device_t parent, device_t self, void *aux) } sc->sc_statuslen = (nports + 1 + 7) / 8; - sc->sc_statusbuf = malloc(sc->sc_statuslen, M_USBDEV, M_NOWAIT); + sc->sc_statusbuf = kmem_alloc(sc->sc_statuslen, KM_SLEEP); if (!sc->sc_statusbuf) goto bad; - sc->sc_status = malloc(sc->sc_statuslen, M_USBDEV, M_NOWAIT); + sc->sc_statuspend = kmem_zalloc(sc->sc_statuslen, KM_SLEEP); + if (!sc->sc_statuspend) + goto bad; + sc->sc_status = kmem_alloc(sc->sc_statuslen, KM_SLEEP); if (!sc->sc_status) goto bad; - if (device_is_a(device_parent(device_parent(sc->sc_dev)), "ehci")) - sc->sc_isehciroothub = 1; + + mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); + memset(sc->sc_statuspend, 0, sc->sc_statuslen); /* force initial scan */ memset(sc->sc_status, 0xff, sc->sc_statuslen); @@ -333,35 +410,35 @@ uhub_attach(device_t parent, device_t self, void *aux) */ if (UHUB_IS_HIGH_SPEED(sc) && nports > 0) { - tts = malloc((UHUB_IS_SINGLE_TT(sc) ? 1 : nports) * - sizeof (struct usbd_tt), M_USBDEV, M_NOWAIT); + tts = kmem_alloc((UHUB_IS_SINGLE_TT(sc) ? 1 : nports) * + sizeof(struct usbd_tt), KM_SLEEP); if (!tts) goto bad; } /* Set up data structures */ for (p = 0; p < nports; p++) { - struct usbd_port *up = &hub->ports[p]; - up->device = NULL; - up->parent = dev; - up->portno = p+1; - if (dev->self_powered) + struct usbd_port *up = &hub->uh_ports[p]; + up->up_dev = NULL; + up->up_parent = dev; + up->up_portno = p + 1; + if (dev->ud_selfpowered) /* Self powered hub, give ports maximum current. */ - up->power = USB_MAX_POWER; + up->up_power = USB_MAX_POWER; else - up->power = USB_MIN_POWER; - up->restartcnt = 0; - up->reattach = 0; + up->up_power = USB_MIN_POWER; + up->up_restartcnt = 0; + up->up_reattach = 0; if (UHUB_IS_HIGH_SPEED(sc)) { - up->tt = &tts[UHUB_IS_SINGLE_TT(sc) ? 0 : p]; - up->tt->hub = hub; + up->up_tt = &tts[UHUB_IS_SINGLE_TT(sc) ? 0 : p]; + up->up_tt->utt_hub = hub; } else { - up->tt = NULL; + up->up_tt = NULL; } } /* XXX should check for none, individual, or ganged power? */ - pwrdly = dev->hub->hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR + pwrdly = dev->ud_hub->uh_hubdesc.bPwrOn2PwrGood * UHD_PWRON_FACTOR + USB_EXTRA_POWER_UP_TIME; for (port = 1; port <= nports; port++) { /* Turn the power on. */ @@ -369,12 +446,12 @@ uhub_attach(device_t parent, device_t self, void *aux) if (err) aprint_error_dev(self, "port %d power on failed, %s\n", port, usbd_errstr(err)); - DPRINTF("uhub %d turn on port %d power", device_unit(self), + DPRINTF("uhub%d turn on port %d power", device_unit(self), port, 0, 0); } /* Wait for stable power if we are not a root hub */ - if (dev->powersrc->parent != NULL) + if (dev->ud_powersrc->up_parent != NULL) usbd_delay_ms(dev, pwrdly); /* The usual exploration will finish the setup. */ @@ -388,20 +465,23 @@ uhub_attach(device_t parent, device_t self, void *aux) bad: if (sc->sc_status) - free(sc->sc_status, M_USBDEV); + kmem_free(sc->sc_status, sc->sc_statuslen); + if (sc->sc_statuspend) + kmem_free(sc->sc_statuspend, sc->sc_statuslen); if (sc->sc_statusbuf) - free(sc->sc_statusbuf, M_USBDEV); + kmem_free(sc->sc_statusbuf, sc->sc_statuslen); if (hub) - free(hub, M_USBDEV); - dev->hub = NULL; + kmem_free(hub, + sizeof(*hub) + (nports-1) * sizeof(struct usbd_port)); + dev->ud_hub = NULL; return; } usbd_status -uhub_explore(usbd_device_handle dev) +uhub_explore(struct usbd_device *dev) { - usb_hub_descriptor_t *hd = &dev->hub->hubdesc; - struct uhub_softc *sc = dev->hub->hubsoftc; + usb_hub_descriptor_t *hd = &dev->ud_hub->uh_hubdesc; + struct uhub_softc *sc = dev->ud_hub->uh_hubsoftc; struct usbd_port *up; usbd_status err; int speed; @@ -410,28 +490,28 @@ uhub_explore(usbd_device_handle dev) UHUBHIST_FUNC(); UHUBHIST_CALLED(); - DPRINTFN(10, "uhub %d dev=%p addr=%d speed=%u", - device_unit(sc->sc_dev), dev, dev->address, dev->speed); + DPRINTFN(10, "uhub%d dev=%p addr=%d speed=%u", + device_unit(sc->sc_dev), dev, dev->ud_addr, dev->ud_speed); if (!sc->sc_running) - return (USBD_NOT_STARTED); + return USBD_NOT_STARTED; /* Ignore hubs that are too deep. */ - if (dev->depth > USB_HUB_MAX_DEPTH) - return (USBD_TOO_DEEP); + if (dev->ud_depth > USB_HUB_MAX_DEPTH) + return USBD_TOO_DEEP; if (PORTSTAT_ISSET(sc, 0)) { /* hub status change */ usb_hub_status_t hs; err = usbd_get_hub_status(dev, &hs); if (err) { - DPRINTF("uhub %d get hub status failed, err %d", + DPRINTF("uhub%d get hub status failed, err %d", device_unit(sc->sc_dev), err, 0, 0); } else { /* just acknowledge */ status = UGETW(hs.wHubStatus); change = UGETW(hs.wHubChange); - DPRINTF("uhub %d s/c=%x/%x", device_unit(sc->sc_dev), + DPRINTF("uhub%d s/c=%x/%x", device_unit(sc->sc_dev), status, change, 0); if (change & UHS_LOCAL_POWER) @@ -444,37 +524,37 @@ uhub_explore(usbd_device_handle dev) } for (port = 1; port <= hd->bNbrPorts; port++) { - up = &dev->hub->ports[port-1]; + up = &dev->ud_hub->uh_ports[port - 1]; /* reattach is needed after firmware upload */ - reconnect = up->reattach; - up->reattach = 0; + reconnect = up->up_reattach; + up->up_reattach = 0; status = change = 0; /* don't check if no change summary notification */ if (PORTSTAT_ISSET(sc, port) || reconnect) { - err = usbd_get_port_status(dev, port, &up->status); + err = usbd_get_port_status(dev, port, &up->up_status); if (err) { - DPRINTF("uhub %d get port stat failed, err %d", + DPRINTF("uhub%d get port stat failed, err %d", device_unit(sc->sc_dev), err, 0, 0); continue; } - status = UGETW(up->status.wPortStatus); - change = UGETW(up->status.wPortChange); + status = UGETW(up->up_status.wPortStatus); + change = UGETW(up->up_status.wPortChange); - DPRINTF("uhub %d port %d: s/c=%x/%x", + DPRINTF("uhub%d port %d: s/c=%x/%x", device_unit(sc->sc_dev), port, status, change); } if (!change && !reconnect) { /* No status change, just do recursive explore. */ - if (up->device != NULL && up->device->hub != NULL) - up->device->hub->explore(up->device); + if (up->up_dev != NULL && up->up_dev->ud_hub != NULL) + up->up_dev->ud_hub->uh_explore(up->up_dev); continue; } if (change & UPS_C_PORT_ENABLED) { - DPRINTF("uhub %d port %d C_PORT_ENABLED", + DPRINTF("uhub%d port %d C_PORT_ENABLED", device_unit(sc->sc_dev), port, 0, 0); usbd_clear_port_feature(dev, port, UHF_C_PORT_ENABLE); if (change & UPS_C_CONNECT_STATUS) { @@ -485,12 +565,12 @@ uhub_explore(usbd_device_handle dev) "illegal enable change, port %d\n", port); } else { /* Port error condition. */ - if (up->restartcnt) /* no message first time */ + if (up->up_restartcnt) /* no message first time */ aprint_error_dev(sc->sc_dev, "port error, restarting port %d\n", port); - if (up->restartcnt++ < USBD_RESTART_MAX) + if (up->up_restartcnt++ < USBD_RESTART_MAX) goto disco; else aprint_error_dev(sc->sc_dev, @@ -498,20 +578,47 @@ uhub_explore(usbd_device_handle dev) port); } } + if (change & UPS_C_PORT_RESET) { + /* + * some xHCs set PortResetChange instead of CSC + * when port is reset. + */ + if ((status & UPS_CURRENT_CONNECT_STATUS) != 0) { + change |= UPS_C_CONNECT_STATUS; + } + usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET); + } + if (change & UPS_C_BH_PORT_RESET) { + /* + * some xHCs set WarmResetChange instead of CSC + * when port is reset. + */ + if ((status & UPS_CURRENT_CONNECT_STATUS) != 0) { + change |= UPS_C_CONNECT_STATUS; + } + usbd_clear_port_feature(dev, port, + UHF_C_BH_PORT_RESET); + } + if (change & UPS_C_PORT_LINK_STATE) + usbd_clear_port_feature(dev, port, + UHF_C_PORT_LINK_STATE); + if (change & UPS_C_PORT_CONFIG_ERROR) + usbd_clear_port_feature(dev, port, + UHF_C_PORT_CONFIG_ERROR); /* XXX handle overcurrent and resume events! */ if (!reconnect && !(change & UPS_C_CONNECT_STATUS)) { /* No status change, just do recursive explore. */ - if (up->device != NULL && up->device->hub != NULL) - up->device->hub->explore(up->device); + if (up->up_dev != NULL && up->up_dev->ud_hub != NULL) + up->up_dev->ud_hub->uh_explore(up->up_dev); continue; } /* We have a connect status change, handle it. */ - DPRINTF("status change hub=%d port=%d", dev->address, port, 0, - 0); + DPRINTF("uhub%d status change port %d", device_unit(sc->sc_dev), + port, 0, 0); usbd_clear_port_feature(dev, port, UHF_C_PORT_CONNECTION); /* * If there is already a device on the port the change status @@ -521,50 +628,57 @@ uhub_explore(usbd_device_handle dev) * the disconnect. */ disco: - if (up->device != NULL) { + if (up->up_dev != NULL) { /* Disconnected */ - DPRINTF("uhub %d device addr=%d disappeared on port %d", - device_unit(sc->sc_dev), up->device->address, port, + DPRINTF("uhub%d device addr=%d disappeared on port %d", + device_unit(sc->sc_dev), up->up_dev->ud_addr, port, 0); + usb_disconnect_port(up, sc->sc_dev, DETACH_FORCE); usbd_clear_port_feature(dev, port, UHF_C_PORT_CONNECTION); } if (!(status & UPS_CURRENT_CONNECT_STATUS)) { /* Nothing connected, just ignore it. */ - DPRINTFN(3, "uhub %d port=%d !CURRENT_CONNECT_STATUS", + DPRINTFN(3, "uhub%d port %d !CURRENT_CONNECT_STATUS", device_unit(sc->sc_dev), port, 0, 0); + usb_disconnect_port(up, sc->sc_dev, DETACH_FORCE); + usbd_clear_port_feature(dev, port, + UHF_C_PORT_CONNECTION); continue; } /* Connected */ DPRINTF("unit %d dev->speed=%u dev->depth=%u", - device_unit(sc->sc_dev), dev->speed, dev->depth, 0); - - if (!(status & UPS_PORT_POWER)) - aprint_normal_dev(sc->sc_dev, - "strange, connected port %d has no power\n", port); + device_unit(sc->sc_dev), dev->ud_speed, dev->ud_depth, 0); /* Wait for maximum device power up time. */ usbd_delay_ms(dev, USB_PORT_POWERUP_DELAY); /* Reset port, which implies enabling it. */ - if (usbd_reset_port(dev, port, &up->status)) { + if (usbd_reset_port(dev, port, &up->up_status)) { aprint_error_dev(sc->sc_dev, "port %d reset failed\n", port); continue; } #if 0 /* Get port status again, it might have changed during reset */ - err = usbd_get_port_status(dev, port, &up->status); + err = usbd_get_port_status(dev, port, &up->up_status); if (err) { - DPRINTF("uhub %d port=%d get port status failed, " + DPRINTF("uhub%d port %d get port status failed, " "err %d", device_unit(sc->sc_dev), port, err, 0); continue; } #endif - status = UGETW(up->status.wPortStatus); - change = UGETW(up->status.wPortChange); + /* + * Use the port status from the reset to check for the device + * disappearing, the port enable status, and the port speed + */ + status = UGETW(up->up_status.wPortStatus); + change = UGETW(up->up_status.wPortChange); + DPRINTF("uhub%d port %d after reset: s/c=%x/%x", + device_unit(sc->sc_dev), port, status, change); + if (!(status & UPS_CURRENT_CONNECT_STATUS)) { /* Nothing connected, just ignore it. */ #ifdef DIAGNOSTIC @@ -581,26 +695,68 @@ uhub_explore(usbd_device_handle dev) #endif continue; } + /* port reset may cause Warm Reset Change, drop it. */ + if (change & UPS_C_BH_PORT_RESET) + usbd_clear_port_feature(dev, port, + UHF_C_BH_PORT_RESET); - /* Figure out device speed */ -#if 0 - if (status & UPS_SUPER_SPEED) - speed = USB_SPEED_SUPER; - else -#endif - if (status & UPS_HIGH_SPEED) + /* + * Figure out device speed from power bit of port status. + * USB 2.0 ch 11.24.2.7.1 + * USB 3.1 ch 10.16.2.6.1 + */ + int sts = status; + if ((sts & UPS_PORT_POWER) == 0) + sts &= ~UPS_PORT_POWER_SS; + + if (sts & UPS_HIGH_SPEED) speed = USB_SPEED_HIGH; - else if (status & UPS_LOW_SPEED) + else if (sts & UPS_LOW_SPEED) speed = USB_SPEED_LOW; - else - speed = USB_SPEED_FULL; + else { + /* + * If there is no power bit set, it is certainly + * a Super Speed device, so use the speed of its + * parent hub. + */ + if (sts & UPS_PORT_POWER) + speed = USB_SPEED_FULL; + else + speed = dev->ud_speed; + } + + /* + * Reduce the speed, otherwise we won't setup the proper + * transfer methods. + */ + if (speed > dev->ud_speed) + speed = dev->ud_speed; - DPRINTF("uhub %d speed %u", device_unit(sc->sc_dev), speed, 0, + DPRINTF("uhub%d speed %u", device_unit(sc->sc_dev), speed, 0, 0); + /* + * To check whether port has power, + * check UPS_PORT_POWER_SS bit if port speed is SS, and + * check UPS_PORT_POWER bit if port speed is HS/FS/LS. + */ + if (USB_IS_SS(speed)) { + /* SS hub port */ + if (!(status & UPS_PORT_POWER_SS)) + aprint_normal_dev(sc->sc_dev, + "strange, connected port %d has no power\n", + port); + } else { + /* HS/FS/LS hub port */ + if (!(status & UPS_PORT_POWER)) + aprint_normal_dev(sc->sc_dev, + "strange, connected port %d has no power\n", + port); + } + /* Get device info and set its address. */ - err = usbd_new_device(sc->sc_dev, dev->bus, - dev->depth + 1, speed, port, up); + err = usbd_new_device(sc->sc_dev, dev->ud_bus, + dev->ud_depth + 1, speed, port, up); /* XXX retry a few times? */ if (err) { DPRINTF("usbd_new_device failed, error %d", err, 0, 0, @@ -618,17 +774,26 @@ uhub_explore(usbd_device_handle dev) usbd_clear_port_feature(dev, port, UHF_PORT_ENABLE); } else { /* The port set up succeeded, reset error count. */ - up->restartcnt = 0; + up->up_restartcnt = 0; - if (up->device->hub) - up->device->hub->explore(up->device); + if (up->up_dev->ud_hub) + up->up_dev->ud_hub->uh_explore(up->up_dev); } } - /* enable status change notifications again */ - if (!sc->sc_isehciroothub) - memset(sc->sc_status, 0, sc->sc_statuslen); + mutex_enter(&sc->sc_lock); sc->sc_explorepending = 0; - return (USBD_NORMAL_COMPLETION); + for (int i = 0; i < sc->sc_statuslen; i++) { + if (sc->sc_statuspend[i] != 0) { + memcpy(sc->sc_status, sc->sc_statuspend, + sc->sc_statuslen); + memset(sc->sc_statuspend, 0, sc->sc_statuslen); + usb_needs_explore(sc->sc_hub); + break; + } + } + mutex_exit(&sc->sc_lock); + + return USBD_NORMAL_COMPLETION; } /* @@ -639,24 +804,24 @@ int uhub_detach(device_t self, int flags) { struct uhub_softc *sc = device_private(self); - struct usbd_hub *hub = sc->sc_hub->hub; + struct usbd_hub *hub = sc->sc_hub->ud_hub; struct usbd_port *rup; int nports, port, rc; UHUBHIST_FUNC(); UHUBHIST_CALLED(); - DPRINTF("uhub %d flags=%d", device_unit(self), flags, 0, 0); + DPRINTF("uhub%d flags=%d", device_unit(self), flags, 0, 0); if (hub == NULL) /* Must be partially working */ - return (0); + return 0; /* XXXSMP usb */ KERNEL_LOCK(1, curlwp); - nports = hub->hubdesc.bNbrPorts; + nports = hub->uh_hubdesc.bNbrPorts; for (port = 0; port < nports; port++) { - rup = &hub->ports[port]; - if (rup->device == NULL) + rup = &hub->uh_ports[port]; + if (rup->up_dev == NULL) continue; if ((rc = usb_disconnect_port(rup, self, flags)) != 0) { /* XXXSMP usb */ @@ -672,31 +837,38 @@ uhub_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_hub, sc->sc_dev); - if (hub->ports[0].tt) - free(hub->ports[0].tt, M_USBDEV); - free(hub, M_USBDEV); - sc->sc_hub->hub = NULL; + if (hub->uh_ports[0].up_tt) + kmem_free(hub->uh_ports[0].up_tt, + (UHUB_IS_SINGLE_TT(sc) ? 1 : nports) * + sizeof(struct usbd_tt)); + kmem_free(hub, + sizeof(*hub) + (nports-1) * sizeof(struct usbd_port)); + sc->sc_hub->ud_hub = NULL; if (sc->sc_status) - free(sc->sc_status, M_USBDEV); + kmem_free(sc->sc_status, sc->sc_statuslen); + if (sc->sc_statuspend) + kmem_free(sc->sc_statuspend, sc->sc_statuslen); if (sc->sc_statusbuf) - free(sc->sc_statusbuf, M_USBDEV); + kmem_free(sc->sc_statusbuf, sc->sc_statuslen); + + mutex_destroy(&sc->sc_lock); /* XXXSMP usb */ KERNEL_UNLOCK_ONE(curlwp); - return (0); + return 0; } int uhub_rescan(device_t self, const char *ifattr, const int *locators) { struct uhub_softc *sc = device_private(self); - struct usbd_hub *hub = sc->sc_hub->hub; - usbd_device_handle dev; + struct usbd_hub *hub = sc->sc_hub->ud_hub; + struct usbd_device *dev; int port; - for (port = 0; port < hub->hubdesc.bNbrPorts; port++) { - dev = hub->ports[port].device; + for (port = 0; port < hub->uh_hubdesc.bNbrPorts; port++) { + dev = hub->uh_ports[port].up_dev; if (dev == NULL) continue; usbd_reattach_device(sc->sc_dev, dev, port, locators); @@ -709,31 +881,32 @@ void uhub_childdet(device_t self, device_t child) { struct uhub_softc *sc = device_private(self); - usbd_device_handle devhub = sc->sc_hub; - usbd_device_handle dev; + struct usbd_device *devhub = sc->sc_hub; + struct usbd_device *dev; int nports; int port; int i; - if (!devhub->hub) + if (!devhub->ud_hub) /* should never happen; children are only created after init */ panic("hub not fully initialised, but child deleted?"); - nports = devhub->hub->hubdesc.bNbrPorts; + nports = devhub->ud_hub->uh_hubdesc.bNbrPorts; for (port = 0; port < nports; port++) { - dev = devhub->hub->ports[port].device; - if (!dev || dev->subdevlen == 0) + dev = devhub->ud_hub->uh_ports[port].up_dev; + if (!dev || dev->ud_subdevlen == 0) continue; - for (i = 0; i < dev->subdevlen; i++) { - if (dev->subdevs[i] == child) { - dev->subdevs[i] = NULL; - dev->nifaces_claimed--; + for (i = 0; i < dev->ud_subdevlen; i++) { + if (dev->ud_subdevs[i] == child) { + dev->ud_subdevs[i] = NULL; + dev->ud_nifaces_claimed--; } } - if (dev->nifaces_claimed == 0) { - free(dev->subdevs, M_USB); - dev->subdevs = NULL; - dev->subdevlen = 0; + if (dev->ud_nifaces_claimed == 0) { + kmem_free(dev->ud_subdevs, + dev->ud_subdevlen * sizeof(device_t)); + dev->ud_subdevs = NULL; + dev->ud_subdevlen = 0; } } } @@ -746,33 +919,47 @@ uhub_childdet(device_t self, device_t child) * to be explored again. */ void -uhub_intr(usbd_xfer_handle xfer, usbd_private_handle addr, usbd_status status) +uhub_intr(struct usbd_xfer *xfer, void *addr, usbd_status status) { struct uhub_softc *sc = addr; UHUBHIST_FUNC(); UHUBHIST_CALLED(); - DPRINTFN(5, "uhub %d", device_unit(sc->sc_dev), 0, 0, 0); + DPRINTFN(5, "uhub%d", device_unit(sc->sc_dev), 0, 0, 0); if (status == USBD_STALLED) usbd_clear_endpoint_stall_async(sc->sc_ipipe); - else if (status == USBD_NORMAL_COMPLETION && - !sc->sc_explorepending) { - /* - * Make sure the status is not overwritten in between. - * XXX we should suspend the pipe instead - */ - memcpy(sc->sc_status, sc->sc_statusbuf, sc->sc_statuslen); - sc->sc_explorepending = 1; - usb_needs_explore(sc->sc_hub); + else if (status == USBD_NORMAL_COMPLETION) { + + mutex_enter(&sc->sc_lock); + + DPRINTFN(5, "uhub%d: explore pending %d", + device_unit(sc->sc_dev), sc->sc_explorepending, 0, 0); + + /* merge port bitmap into pending interrupts list */ + for (size_t i = 0; i < sc->sc_statuslen; i++) { + sc->sc_statuspend[i] |= sc->sc_statusbuf[i]; + + DPRINTFN(5, "uhub%d: pending/new ports " + "[%d] %#x/%#x", device_unit(sc->sc_dev), + i, sc->sc_statuspend[i], sc->sc_statusbuf[i]); + } + + if (!sc->sc_explorepending) { + sc->sc_explorepending = 1; + + memcpy(sc->sc_status, sc->sc_statuspend, + sc->sc_statuslen); + memset(sc->sc_statuspend, 0, sc->sc_statuslen); + + for (size_t i = 0; i < sc->sc_statuslen; i++) { + DPRINTFN(5, "uhub%d: exploring ports " + "[%d] %#x", device_unit(sc->sc_dev), + i, sc->sc_status[i], 0); + } + + usb_needs_explore(sc->sc_hub); + } + mutex_exit(&sc->sc_lock); } - /* - * XXX workaround for broken implementation of the interrupt - * pipe in EHCI root hub emulation which doesn't resend - * status change notifications until handled: force a rescan - * of the ports we touched in the last run - */ - if (status == USBD_NORMAL_COMPLETION && sc->sc_explorepending && - sc->sc_isehciroothub) - usb_needs_explore(sc->sc_hub); } diff --git a/sys/dev/usb/uipad.c b/sys/dev/usb/uipad.c index 56f7e88ec94..be277c1f95b 100644 --- a/sys/dev/usb/uipad.c +++ b/sys/dev/usb/uipad.c @@ -1,4 +1,4 @@ -/* $NetBSD: uipad.c,v 1.1 2011/12/31 00:08:48 christos Exp $ */ +/* $NetBSD: uipad.c,v 1.2 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -37,12 +37,11 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uipad.c,v 1.1 2011/12/31 00:08:48 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipad.c,v 1.2 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> #include <sys/device.h> #include <sys/ioctl.h> #include <sys/conf.h> @@ -71,7 +70,7 @@ int uipaddebug = 0; struct uipad_softc { device_t sc_dev; - usbd_device_handle sc_udev; + struct usbd_device * sc_udev; }; /* @@ -116,7 +115,7 @@ uipad_cmd(struct uipad_softc *sc, uint8_t requestType, uint8_t reqno, static void uipad_charge(struct uipad_softc *sc) { - if (sc->sc_udev->power != USB_MAX_POWER) + if (sc->sc_udev->ud_power != USB_MAX_POWER) uipad_cmd(sc, UT_VENDOR | UT_WRITE, 0x40, 0x6400, 0x6400); } @@ -126,7 +125,7 @@ uipad_match(device_t parent, cfdata_t match, void *aux) struct usb_attach_arg *uaa = aux; DPRINTFN(50, ("uipad_match\n")); - return uipad_lookup(uaa->vendor, uaa->product) != NULL ? + return uipad_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } @@ -135,7 +134,7 @@ uipad_attach(device_t parent, device_t self, void *aux) { struct uipad_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; + struct usbd_device * dev = uaa->uaa_device; char *devinfop; DPRINTFN(10,("uipad_attach: sc=%p\n", sc)); diff --git a/sys/dev/usb/uipaq.c b/sys/dev/usb/uipaq.c index 91a3582a548..2046b93d104 100644 --- a/sys/dev/usb/uipaq.c +++ b/sys/dev/usb/uipaq.c @@ -1,4 +1,4 @@ -/* $NetBSD: uipaq.c,v 1.19 2012/12/27 16:42:32 skrll Exp $ */ +/* $NetBSD: uipaq.c,v 1.20 2016/04/23 10:15:32 skrll Exp $ */ /* $OpenBSD: uipaq.c,v 1.1 2005/06/17 23:50:33 deraadt Exp $ */ /* @@ -33,7 +33,7 @@ /* * iPAQ driver - * + * * 19 July 2003: Incorporated changes suggested by Sam Lawrance from * the uppc module * @@ -42,7 +42,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uipaq.c,v 1.19 2012/12/27 16:42:32 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uipaq.c,v 1.20 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -78,13 +78,13 @@ int uipaqdebug = 0; struct uipaq_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; /* device */ - usbd_interface_handle sc_iface; /* interface */ + struct usbd_device * sc_udev; /* device */ + struct usbd_interface * sc_iface; /* interface */ device_t sc_subdev; /* ucom uses that */ - u_int16_t sc_lcr; /* state for DTR/RTS */ + uint16_t sc_lcr; /* state for DTR/RTS */ - u_int16_t sc_flags; + uint16_t sc_flags; u_char sc_dying; }; @@ -95,25 +95,25 @@ Static void uipaq_set(void *, int, int, int); /* Support routines. */ /* based on uppc module by Sam Lawrance */ -Static void uipaq_dtr(struct uipaq_softc *sc, int onoff); -Static void uipaq_rts(struct uipaq_softc *sc, int onoff); -Static void uipaq_break(struct uipaq_softc* sc, int onoff); +Static void uipaq_dtr(struct uipaq_softc *, int); +Static void uipaq_rts(struct uipaq_softc *, int); +Static void uipaq_break(struct uipaq_softc *, int); struct ucom_methods uipaq_methods = { - NULL, - uipaq_set, - NULL, - NULL, - NULL, /*open*/ - NULL, /*close*/ - NULL, - NULL + .ucom_get_status = NULL, + .ucom_set = uipaq_set, + .ucom_param = NULL, + .ucom_ioctl = NULL, + .ucom_open = NULL, + .ucom_close = NULL, + .ucom_read = NULL, + .ucom_write = NULL, }; struct uipaq_type { struct usb_devno uv_dev; - u_int16_t uv_flags; + uint16_t uv_flags; }; static const struct uipaq_type uipaq_devs[] = { @@ -136,32 +136,32 @@ extern struct cfdriver uipaq_cd; CFATTACH_DECL2_NEW(uipaq, sizeof(struct uipaq_softc), uipaq_match, uipaq_attach, uipaq_detach, uipaq_activate, NULL, uipaq_childdet); -int +int uipaq_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; DPRINTFN(20,("uipaq: vendor=0x%x, product=0x%x\n", - uaa->vendor, uaa->product)); + uaa->uaa_vendor, uaa->uaa_product)); - return (uipaq_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return uipaq_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } -void +void uipaq_attach(device_t parent, device_t self, void *aux) { struct uipaq_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface; + struct usbd_device *dev = uaa->uaa_device; + struct usbd_interface *iface; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devinfop; const char *devname = device_xname(self); int i; usbd_status err; - struct ucom_attach_args uca; + struct ucom_attach_args ucaa; DPRINTFN(10,("\nuipaq_attach: sc=%p\n", sc)); @@ -189,23 +189,23 @@ uipaq_attach(device_t parent, device_t self, void *aux) goto bad; } - sc->sc_flags = uipaq_lookup(uaa->vendor, uaa->product)->uv_flags; + sc->sc_flags = uipaq_lookup(uaa->uaa_vendor, uaa->uaa_product)->uv_flags; id = usbd_get_interface_descriptor(iface); sc->sc_udev = dev; sc->sc_iface = iface; - uca.ibufsize = UIPAQIBUFSIZE; - uca.obufsize = UIPAQOBUFSIZE; - uca.ibufsizepad = UIPAQIBUFSIZE; - uca.opkthdrlen = 0; - uca.device = dev; - uca.iface = iface; - uca.methods = &uipaq_methods; - uca.arg = sc; - uca.portno = UCOM_UNK_PORTNO; - uca.info = "Generic"; + ucaa.ucaa_ibufsize = UIPAQIBUFSIZE; + ucaa.ucaa_obufsize = UIPAQOBUFSIZE; + ucaa.ucaa_ibufsizepad = UIPAQIBUFSIZE; + ucaa.ucaa_opkthdrlen = 0; + ucaa.ucaa_device = dev; + ucaa.ucaa_iface = iface; + ucaa.ucaa_methods = &uipaq_methods; + ucaa.ucaa_arg = sc; + ucaa.ucaa_portno = UCOM_UNK_PORTNO; + ucaa.ucaa_info = "Generic"; /* err = uipaq_init(sc); if (err) { @@ -217,7 +217,7 @@ uipaq_attach(device_t parent, device_t self, void *aux) usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); - uca.bulkin = uca.bulkout = -1; + ucaa.ucaa_bulkin = ucaa.ucaa_bulkout = -1; for (i=0; i<id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(iface, i); if (ed == NULL) { @@ -227,19 +227,19 @@ uipaq_attach(device_t parent, device_t self, void *aux) } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) { - uca.bulkin = ed->bEndpointAddress; + ucaa.ucaa_bulkin = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) { - uca.bulkout = ed->bEndpointAddress; + ucaa.ucaa_bulkout = ed->bEndpointAddress; } } - if (uca.bulkin == -1 || uca.bulkout == -1) { + if (ucaa.ucaa_bulkin == -1 || ucaa.ucaa_bulkout == -1) { aprint_error_dev(self, "no proper endpoints found (%d,%d) \n", - uca.bulkin, uca.bulkout); + ucaa.ucaa_bulkin, ucaa.ucaa_bulkout); return; } - sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &uca, + sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &ucaa, ucomprint, ucomsubmatch); return; @@ -398,6 +398,6 @@ uipaq_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - return (rv); + return rv; } diff --git a/sys/dev/usb/uirda.c b/sys/dev/usb/uirda.c index f4308f63a13..4542548489e 100644 --- a/sys/dev/usb/uirda.c +++ b/sys/dev/usb/uirda.c @@ -1,4 +1,4 @@ -/* $NetBSD: uirda.c,v 1.38 2013/09/15 15:43:20 martin Exp $ */ +/* $NetBSD: uirda.c,v 1.39 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uirda.c,v 1.38 2013/09/15 15:43:20 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uirda.c,v 1.39 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -107,15 +107,15 @@ static struct { -int uirda_open(void *h, int flag, int mode, struct lwp *l); -int uirda_close(void *h, int flag, int mode, struct lwp *l); -int uirda_read(void *h, struct uio *uio, int flag); -int uirda_write(void *h, struct uio *uio, int flag); -int uirda_set_params(void *h, struct irda_params *params); -int uirda_get_speeds(void *h, int *speeds); -int uirda_get_turnarounds(void *h, int *times); -int uirda_poll(void *h, int events, struct lwp *l); -int uirda_kqfilter(void *h, struct knote *kn); +int uirda_open(void *, int, int, struct lwp *); +int uirda_close(void *, int, int, struct lwp *); +int uirda_read(void *, struct uio *, int); +int uirda_write(void *, struct uio *, int); +int uirda_set_params(void *, struct irda_params *); +int uirda_get_speeds(void *, int *); +int uirda_get_turnarounds(void *, int *); +int uirda_poll(void *, int, struct lwp *); +int uirda_kqfilter(void *, struct knote *); struct irframe_methods uirda_methods = { uirda_open, uirda_close, uirda_read, uirda_write, uirda_poll, @@ -123,7 +123,7 @@ struct irframe_methods uirda_methods = { uirda_get_turnarounds }; -void uirda_rd_cb(usbd_xfer_handle xfer, usbd_private_handle priv, +void uirda_rd_cb(struct usbd_xfer *xfer, void *priv, usbd_status status); usbd_status uirda_start_read(struct uirda_softc *sc); @@ -151,34 +151,34 @@ extern struct cfdriver uirda_cd; CFATTACH_DECL2_NEW(uirda, sizeof(struct uirda_softc), uirda_match, uirda_attach, uirda_detach, uirda_activate, NULL, uirda_childdet); -int +int uirda_match(device_t parent, cfdata_t match, void *aux) { - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; DPRINTFN(50,("uirda_match\n")); - if (uirda_lookup(uaa->vendor, uaa->product) != NULL) - return (UMATCH_VENDOR_PRODUCT); + if (uirda_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product) != NULL) + return UMATCH_VENDOR_PRODUCT; - if (uaa->class == UICLASS_APPL_SPEC && - uaa->subclass == UISUBCLASS_IRDA && - uaa->proto == UIPROTO_IRDA) - return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO); - return (UMATCH_NONE); + if (uiaa->uiaa_class == UICLASS_APPL_SPEC && + uiaa->uiaa_subclass == UISUBCLASS_IRDA && + uiaa->uiaa_proto == UIPROTO_IRDA) + return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO; + return UMATCH_NONE; } -void +void uirda_attach(device_t parent, device_t self, void *aux) { struct uirda_softc *sc = device_private(self); - struct usbif_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface = uaa->iface; + struct usbif_attach_arg *uiaa = aux; + struct usbd_device * dev = uiaa->uiaa_device; + struct usbd_interface *iface = uiaa->uiaa_iface; char *devinfop; usb_endpoint_descriptor_t *ed; usbd_status err; - u_int8_t epcount; + uint8_t epcount; u_int specrev; int i; struct ir_attach_args ia; @@ -291,7 +291,7 @@ uirda_attach(device_t parent, device_t self, void *aux) return; } -int +int uirda_detach(device_t self, int flags) { struct uirda_softc *sc = device_private(self); @@ -304,11 +304,25 @@ uirda_detach(device_t self, int flags) /* Abort all pipes. Causes processes waiting for transfer to wake. */ if (sc->sc_rd_pipe != NULL) { usbd_abort_pipe(sc->sc_rd_pipe); + } + if (sc->sc_wr_pipe != NULL) { + usbd_abort_pipe(sc->sc_wr_pipe); + } + if (sc->sc_rd_xfer != NULL) { + usbd_destroy_xfer(sc->sc_rd_xfer); + sc->sc_rd_xfer = NULL; + sc->sc_rd_buf = NULL; + } + if (sc->sc_wr_xfer != NULL) { + usbd_destroy_xfer(sc->sc_wr_xfer); + sc->sc_wr_xfer = NULL; + sc->sc_wr_buf = NULL; + } + if (sc->sc_rd_pipe != NULL) { usbd_close_pipe(sc->sc_rd_pipe); sc->sc_rd_pipe = NULL; } if (sc->sc_wr_pipe != NULL) { - usbd_abort_pipe(sc->sc_wr_pipe); usbd_close_pipe(sc->sc_wr_pipe); sc->sc_wr_pipe = NULL; } @@ -332,7 +346,7 @@ uirda_detach(device_t self, int flags) seldestroy(&sc->sc_rd_sel); seldestroy(&sc->sc_wr_sel); - return (rv); + return rv; } void @@ -378,29 +392,21 @@ uirda_open(void *h, int flag, int mode, error = EIO; goto bad2; } - sc->sc_rd_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_rd_xfer == NULL) { - error = ENOMEM; + error = usbd_create_xfer(sc->sc_rd_pipe, + IRDA_MAX_FRAME_SIZE + sc->sc_hdszi, USBD_SHORT_XFER_OK, 0, + &sc->sc_rd_xfer); + if (error) goto bad3; - } - sc->sc_wr_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_wr_xfer == NULL) { - error = ENOMEM; + sc->sc_rd_buf = usbd_get_buffer(sc->sc_rd_xfer); + + /* worst case ST-UIRDA length */ + error = usbd_create_xfer(sc->sc_wr_pipe, + IRDA_MAX_FRAME_SIZE + UIRDA_OUTPUT_HEADER_SIZE + 2 + 1, + USBD_FORCE_SHORT_XFER, 0, &sc->sc_wr_xfer); + if (error) goto bad4; - } - sc->sc_rd_buf = usbd_alloc_buffer(sc->sc_rd_xfer, - IRDA_MAX_FRAME_SIZE + sc->sc_hdszi); - if (sc->sc_rd_buf == NULL) { - error = ENOMEM; - goto bad5; - } - sc->sc_wr_buf = usbd_alloc_buffer(sc->sc_wr_xfer, - IRDA_MAX_FRAME_SIZE + UIRDA_OUTPUT_HEADER_SIZE + - 2 + 1 /* worst case ST-UIRDA */); - if (sc->sc_wr_buf == NULL) { - error = ENOMEM; - goto bad5; - } + sc->sc_wr_buf = usbd_get_buffer(sc->sc_wr_xfer); + sc->sc_rd_count = 0; sc->sc_rd_err = 0; sc->sc_params.speed = 0; @@ -411,13 +417,10 @@ uirda_open(void *h, int flag, int mode, err = uirda_start_read(sc); /* XXX check err */ - return (0); + return 0; -bad5: - usbd_free_xfer(sc->sc_wr_xfer); - sc->sc_wr_xfer = NULL; bad4: - usbd_free_xfer(sc->sc_rd_xfer); + usbd_destroy_xfer(sc->sc_rd_xfer); sc->sc_rd_xfer = NULL; bad3: usbd_close_pipe(sc->sc_wr_pipe); @@ -426,7 +429,7 @@ bad2: usbd_close_pipe(sc->sc_rd_pipe); sc->sc_rd_pipe = NULL; bad1: - return (error); + return error; } int @@ -439,26 +442,30 @@ uirda_close(void *h, int flag, int mode, if (sc->sc_rd_pipe != NULL) { usbd_abort_pipe(sc->sc_rd_pipe); - usbd_close_pipe(sc->sc_rd_pipe); - sc->sc_rd_pipe = NULL; } if (sc->sc_wr_pipe != NULL) { usbd_abort_pipe(sc->sc_wr_pipe); - usbd_close_pipe(sc->sc_wr_pipe); - sc->sc_wr_pipe = NULL; } if (sc->sc_rd_xfer != NULL) { - usbd_free_xfer(sc->sc_rd_xfer); + usbd_destroy_xfer(sc->sc_rd_xfer); sc->sc_rd_xfer = NULL; sc->sc_rd_buf = NULL; } if (sc->sc_wr_xfer != NULL) { - usbd_free_xfer(sc->sc_wr_xfer); + usbd_destroy_xfer(sc->sc_wr_xfer); sc->sc_wr_xfer = NULL; sc->sc_wr_buf = NULL; } + if (sc->sc_rd_pipe != NULL) { + usbd_close_pipe(sc->sc_rd_pipe); + sc->sc_rd_pipe = NULL; + } + if (sc->sc_wr_pipe != NULL) { + usbd_close_pipe(sc->sc_wr_pipe); + sc->sc_wr_pipe = NULL; + } - return (0); + return 0; } int @@ -472,11 +479,11 @@ uirda_read(void *h, struct uio *uio, int flag) DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); if (sc->sc_dying) - return (EIO); + return EIO; #ifdef DIAGNOSTIC if (sc->sc_rd_buf == NULL) - return (EINVAL); + return EINVAL; #endif sc->sc_refcnt++; @@ -518,7 +525,7 @@ uirda_read(void *h, struct uio *uio, int flag) ret: if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); - return (error); + return error; } int @@ -526,53 +533,52 @@ uirda_write(void *h, struct uio *uio, int flag) { struct uirda_softc *sc = h; usbd_status err; - u_int32_t n; + uint32_t n; int error = 0; DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); if (sc->sc_dying) - return (EIO); + return EIO; #ifdef DIAGNOSTIC if (sc->sc_wr_buf == NULL) - return (EINVAL); + return EINVAL; #endif n = uio->uio_resid; if (n > sc->sc_params.maxsize) - return (EINVAL); + return EINVAL; sc->sc_refcnt++; mutex_enter(&sc->sc_wr_buf_lk); sc->sc_wr_buf[0] = UIRDA_EB_NO_CHANGE | UIRDA_NO_SPEED; error = uiomove(sc->sc_wr_buf + UIRDA_OUTPUT_HEADER_SIZE, n, uio); - if (!error) { - DPRINTFN(1, ("uirdawrite: transfer %d bytes\n", n)); + if (error) + goto done; - n += UIRDA_OUTPUT_HEADER_SIZE; - err = usbd_bulk_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - UIRDA_WR_TIMEOUT, - sc->sc_wr_buf, &n, "uirdawr"); - DPRINTFN(2, ("uirdawrite: err=%d\n", err)); - if (err) { - if (err == USBD_INTERRUPTED) - error = EINTR; - else if (err == USBD_TIMEOUT) - error = ETIMEDOUT; - else - error = EIO; - } - } + DPRINTFN(1, ("uirdawrite: transfer %d bytes\n", n)); + n += UIRDA_OUTPUT_HEADER_SIZE; + err = usbd_bulk_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe, + USBD_FORCE_SHORT_XFER, UIRDA_WR_TIMEOUT, sc->sc_wr_buf, &n); + DPRINTFN(2, ("uirdawrite: err=%d\n", err)); + if (err) { + if (err == USBD_INTERRUPTED) + error = EINTR; + else if (err == USBD_TIMEOUT) + error = ETIMEDOUT; + else + error = EIO; + } +done: mutex_exit(&sc->sc_wr_buf_lk); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); DPRINTFN(1,("%s: sc=%p done\n", __func__, sc)); - return (error); + return error; } int @@ -598,7 +604,7 @@ uirda_poll(void *h, int events, struct lwp *l) } splx(s); - return (revents); + return revents; } static void @@ -618,7 +624,7 @@ filt_uirdaread(struct knote *kn, long hint) struct uirda_softc *sc = kn->kn_hook; kn->kn_data = sc->sc_rd_count; - return (kn->kn_data > 0); + return kn->kn_data > 0; } static void @@ -654,7 +660,7 @@ uirda_kqfilter(void *h, struct knote *kn) kn->kn_fop = &uirdawrite_filtops; break; default: - return (EINVAL); + return EINVAL; } kn->kn_hook = sc; @@ -663,7 +669,7 @@ uirda_kqfilter(void *h, struct knote *kn) SLIST_INSERT_HEAD(klist, kn, kn_selnext); splx(s); - return (0); + return 0; } int @@ -672,15 +678,15 @@ uirda_set_params(void *h, struct irda_params *p) struct uirda_softc *sc = h; usbd_status err; int i; - u_int8_t hdr; - u_int32_t n; + uint8_t hdr; + uint32_t n; u_int mask; DPRINTF(("%s: sc=%p, speed=%d ebofs=%d maxsize=%d\n", __func__, sc, p->speed, p->ebofs, p->maxsize)); if (sc->sc_dying) - return (EIO); + return EIO; hdr = 0; if (p->ebofs != sc->sc_params.ebofs) { @@ -706,7 +712,7 @@ uirda_set_params(void *h, struct irda_params *p) } } /* no good value found */ - return (EINVAL); + return EINVAL; found1: DPRINTF(("uirda_set_params: ebofs hdr=0x%02x\n", hdr)); ; @@ -723,40 +729,40 @@ uirda_set_params(void *h, struct irda_params *p) } } /* no good value found */ - return (EINVAL); + return EINVAL; found2: DPRINTF(("uirda_set_params: speed hdr=0x%02x\n", hdr)); ; } if (p->maxsize != sc->sc_params.maxsize) { if (p->maxsize > IRDA_MAX_FRAME_SIZE) - return (EINVAL); + return EINVAL; sc->sc_params.maxsize = p->maxsize; #if 0 DPRINTF(("%s: new buffers, old size=%d\n", __func__, sc->sc_params.maxsize)); if (p->maxsize > 10000 || p < 0) /* XXX */ - return (EINVAL); + return EINVAL; /* Change the write buffer */ mutex_enter(&sc->sc_wr_buf_lk); if (sc->sc_wr_buf != NULL) usbd_free_buffer(sc->sc_wr_xfer); - sc->sc_wr_buf = usbd_alloc_buffer(sc->sc_wr_xfer, p->maxsize+1); + sc->sc_wr_buf = usbd_get_buffer(sc->sc_wr_xfer, p->maxsize+1); mutex_exit(&sc->sc_wr_buf_lk); if (sc->sc_wr_buf == NULL) - return (ENOMEM); + return ENOMEM; /* Change the read buffer */ mutex_enter(&sc->sc_rd_buf_lk); usbd_abort_pipe(sc->sc_rd_pipe); if (sc->sc_rd_buf != NULL) usbd_free_buffer(sc->sc_rd_xfer); - sc->sc_rd_buf = usbd_alloc_buffer(sc->sc_rd_xfer, p->maxsize+1); + sc->sc_rd_buf = usbd_get_buffer(sc->sc_rd_xfer, p->maxsize+1); sc->sc_rd_count = 0; if (sc->sc_rd_buf == NULL) { mutex_exit(&sc->sc_rd_buf_lk); - return (ENOMEM); + return ENOMEM; } sc->sc_params.maxsize = p->maxsize; err = uirda_start_read(sc); /* XXX check */ @@ -776,8 +782,8 @@ uirda_set_params(void *h, struct irda_params *p) sc->sc_wr_buf[0] = hdr; n = UIRDA_OUTPUT_HEADER_SIZE; err = usbd_bulk_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - UIRDA_WR_TIMEOUT, sc->sc_wr_buf, &n, "uirdast"); + USBD_FORCE_SHORT_XFER, UIRDA_WR_TIMEOUT, + sc->sc_wr_buf, &n); if (err) { aprint_error_dev(sc->sc_dev, "set failed, err=%d\n", err); @@ -788,7 +794,7 @@ uirda_set_params(void *h, struct irda_params *p) sc->sc_params = *p; - return (0); + return 0; } int @@ -801,7 +807,7 @@ uirda_get_speeds(void *h, int *speeds) DPRINTF(("%s: sc=%p\n", __func__, sc)); if (sc->sc_dying) - return (EIO); + return EIO; usp = UGETW(sc->sc_irdadesc.wBaudRate); isp = 0; @@ -816,7 +822,7 @@ uirda_get_speeds(void *h, int *speeds) if (usp & UI_BR_2400) isp |= IRDA_SPEED_2400; *speeds = isp; DPRINTF(("%s: speeds = 0x%x\n", __func__, isp)); - return (0); + return 0; } int @@ -829,7 +835,7 @@ uirda_get_turnarounds(void *h, int *turnarounds) DPRINTF(("%s: sc=%p\n", __func__, sc)); if (sc->sc_dying) - return (EIO); + return EIO; uta = sc->sc_irdadesc.bmMinTurnaroundTime; ita = 0; @@ -842,15 +848,15 @@ uirda_get_turnarounds(void *h, int *turnarounds) if (uta & UI_TA_5000) ita |= IRDA_TURNT_5000; if (uta & UI_TA_10000) ita |= IRDA_TURNT_10000; *turnarounds = ita; - return (0); + return 0; } void -uirda_rd_cb(usbd_xfer_handle xfer, usbd_private_handle priv, +uirda_rd_cb(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct uirda_softc *sc = priv; - u_int32_t size; + uint32_t size; DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); @@ -878,7 +884,7 @@ uirda_start_read(struct uirda_softc *sc) sc->sc_params.maxsize + UIRDA_INPUT_HEADER_SIZE)); if (sc->sc_dying) - return (USBD_IOERROR); + return USBD_IOERROR; if (sc->sc_rd_err) { sc->sc_rd_err = 0; @@ -886,20 +892,19 @@ uirda_start_read(struct uirda_softc *sc) usbd_clear_endpoint_stall(sc->sc_rd_pipe); } - usbd_setup_xfer(sc->sc_rd_xfer, sc->sc_rd_pipe, sc, sc->sc_rd_buf, - sc->sc_params.maxsize + sc->sc_hdszi, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, uirda_rd_cb); + usbd_setup_xfer(sc->sc_rd_xfer, sc, sc->sc_rd_buf, + sc->sc_params.maxsize + sc->sc_hdszi, USBD_SHORT_XFER_OK, + USBD_NO_TIMEOUT, uirda_rd_cb); err = usbd_transfer(sc->sc_rd_xfer); if (err != USBD_IN_PROGRESS) { DPRINTF(("uirda_start_read: err=%d\n", err)); - return (err); + return err; } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } usbd_status -usbd_get_class_desc(usbd_device_handle dev, int type, int index, int len, void *desc) +usbd_get_class_desc(struct usbd_device *dev, int type, int index, int len, void *desc) { usb_device_request_t req; @@ -911,5 +916,5 @@ usbd_get_class_desc(usbd_device_handle dev, int type, int index, int len, void * USETW2(req.wValue, type, index); USETW(req.wIndex, 0); USETW(req.wLength, len); - return (usbd_do_request(dev, &req, desc)); + return usbd_do_request(dev, &req, desc); } diff --git a/sys/dev/usb/uirdavar.h b/sys/dev/usb/uirdavar.h index 5bb74797ebd..45ea765b95d 100644 --- a/sys/dev/usb/uirdavar.h +++ b/sys/dev/usb/uirdavar.h @@ -1,4 +1,4 @@ -/* $NetBSD: uirdavar.h,v 1.5 2010/11/03 22:34:24 dyoung Exp $ */ +/* $NetBSD: uirdavar.h,v 1.6 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001,2007 The NetBSD Foundation, Inc. @@ -118,23 +118,23 @@ typedef struct { struct uirda_softc { device_t sc_dev; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device *sc_udev; + struct usbd_interface *sc_iface; kmutex_t sc_rd_buf_lk; - u_int8_t *sc_rd_buf; + uint8_t *sc_rd_buf; int sc_rd_addr; - usbd_pipe_handle sc_rd_pipe; - usbd_xfer_handle sc_rd_xfer; + struct usbd_pipe *sc_rd_pipe; + struct usbd_xfer *sc_rd_xfer; struct selinfo sc_rd_sel; u_int sc_rd_count; u_char sc_rd_err; kmutex_t sc_wr_buf_lk; - u_int8_t *sc_wr_buf; + uint8_t *sc_wr_buf; int sc_wr_addr; - usbd_xfer_handle sc_wr_xfer; - usbd_pipe_handle sc_wr_pipe; + struct usbd_xfer *sc_wr_xfer; + struct usbd_pipe *sc_wr_pipe; int sc_wr_hdr; struct selinfo sc_wr_sel; @@ -144,21 +144,20 @@ struct uirda_softc { int sc_refcnt; char sc_dying; - u_int8_t sc_hdszi; /* set to value if != 1 needed */ + uint8_t sc_hdszi; /* set to value if != 1 needed */ int (*sc_loadfw)(struct uirda_softc *); struct irframe_methods *sc_irm; }; -usbd_status usbd_get_class_desc(usbd_device_handle, int type, int index, - int len, void *desc); +usbd_status usbd_get_class_desc(struct usbd_device *, int, int, int, void *); -int uirda_open(void *h, int flag, int mode, struct lwp *l); -int uirda_close(void *h, int flag, int mode, struct lwp *l); -int uirda_read(void *h, struct uio *uio, int flag); -int uirda_write(void *h, struct uio *uio, int flag); -int uirda_set_params(void *h, struct irda_params *params); -int uirda_get_speeds(void *h, int *speeds); -int uirda_get_turnarounds(void *h, int *times); -int uirda_poll(void *h, int events, struct lwp *l); -int uirda_kqfilter(void *h, struct knote *kn); +int uirda_open(void *, int, int, struct lwp *); +int uirda_close(void *, int, int, struct lwp *); +int uirda_read(void *, struct uio *, int); +int uirda_write(void *, struct uio *, int); +int uirda_set_params(void *, struct irda_params *); +int uirda_get_speeds(void *, int *); +int uirda_get_turnarounds(void *, int *); +int uirda_poll(void *, int, struct lwp *); +int uirda_kqfilter(void *, struct knote *); diff --git a/sys/dev/usb/ukbd.c b/sys/dev/usb/ukbd.c index c92eb404192..2bbf2b09e84 100644 --- a/sys/dev/usb/ukbd.c +++ b/sys/dev/usb/ukbd.c @@ -1,4 +1,4 @@ -/* $NetBSD: ukbd.c,v 1.130 2015/03/07 20:20:55 mrg Exp $ */ +/* $NetBSD: ukbd.c,v 1.131 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.130 2015/03/07 20:20:55 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ukbd.c,v 1.131 2016/04/23 10:15:32 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_ukbd.h" @@ -86,8 +86,8 @@ int ukbddebug = 0; #define MAXMOD 8 /* max 32 */ struct ukbd_data { - u_int32_t modifiers; - u_int8_t keycode[MAXKEYCODE]; + uint32_t modifiers; + uint8_t keycode[MAXKEYCODE]; }; #define PRESS 0x000 @@ -95,8 +95,8 @@ struct ukbd_data { #define CODEMASK 0x0ff struct ukbd_keycodetrans { - u_int16_t from; - u_int16_t to; + uint16_t from; + uint16_t to; }; #define IS_PMF 0x8000 @@ -195,7 +195,7 @@ Static const struct ukbd_keycodetrans trtab_generic[] = { * For example, some keys generate Fake ShiftL events (e0 2a) * before the actual key sequence. */ -Static const u_int8_t ukbd_trtab[256] = { +Static const uint8_t ukbd_trtab[256] = { NN, NN, NN, NN, 0x1e, 0x30, 0x2e, 0x20, /* 00 - 07 */ 0x12, 0x21, 0x22, 0x23, 0x17, 0x24, 0x25, 0x26, /* 08 - 0f */ 0x32, 0x31, 0x18, 0x19, 0x10, 0x13, 0x1f, 0x14, /* 10 - 17 */ @@ -243,8 +243,8 @@ struct ukbd_softc { struct hid_location sc_modloc[MAXMOD]; u_int sc_nmod; struct { - u_int32_t mask; - u_int8_t key; + uint32_t mask; + uint8_t key; } sc_mods[MAXMOD]; struct hid_location sc_keycodeloc; @@ -287,7 +287,7 @@ struct ukbd_softc { int sc_spl; int sc_npollchar; - u_int16_t sc_pollchars[MAXKEYS]; + uint16_t sc_pollchars[MAXKEYS]; u_char sc_dying; }; @@ -334,11 +334,11 @@ const struct wskbd_consops ukbd_consops = { .bell = NULL, }; -Static const char *ukbd_parse_desc(struct ukbd_softc *sc); +Static const char *ukbd_parse_desc(struct ukbd_softc *); -Static void ukbd_intr(struct uhidev *addr, void *ibuf, u_int len); -Static void ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud); -Static void ukbd_delayed_decode(void *addr); +Static void ukbd_intr(struct uhidev *, void *, u_int); +Static void ukbd_decode(struct ukbd_softc *, struct ukbd_data *); +Static void ukbd_delayed_decode(void *); Static int ukbd_enable(void *, int); Static void ukbd_set_leds(void *, int); @@ -389,9 +389,9 @@ ukbd_match(device_t parent, cfdata_t match, void *aux) uhidev_get_report_desc(uha->parent, &desc, &size); if (!hid_is_collection(desc, size, uha->reportid, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_KEYBOARD))) - return (UMATCH_NONE); + return UMATCH_NONE; - return (UMATCH_IFACECLASS); + return UMATCH_IFACECLASS; } void @@ -399,7 +399,7 @@ ukbd_attach(device_t parent, device_t self, void *aux) { struct ukbd_softc *sc = device_private(self); struct uhidev_attach_arg *uha = aux; - u_int32_t qflags; + uint32_t qflags; const char *parseerr; struct wskbddev_attach_args a; @@ -431,8 +431,8 @@ ukbd_attach(device_t parent, device_t self, void *aux) sc->sc_flags |= FLAG_APPLE_FIX_ISO; #ifdef GDIUM_KEYBOARD_HACK - if (uha->uaa->vendor == USB_VENDOR_CYPRESS && - uha->uaa->product == USB_PRODUCT_CYPRESS_LPRDK) + if (uha->uaa->uaa_vendor == USB_VENDOR_CYPRESS && + uha->uaa->uaa_product == USB_PRODUCT_CYPRESS_LPRDK) sc->sc_flags = FLAG_GDIUM_FN; #endif @@ -497,7 +497,7 @@ ukbd_enable(void *v, int on) struct ukbd_softc *sc = v; if (on && sc->sc_dying) - return (EIO); + return EIO; /* Should only be called to change state */ if ((sc->sc_flags & FLAG_ENABLED) != 0 && on != 0) { @@ -505,17 +505,17 @@ ukbd_enable(void *v, int on) printf("ukbd_enable: %s: bad call on=%d\n", device_xname(sc->sc_hdev.sc_dev), on); #endif - return (EBUSY); + return EBUSY; } DPRINTF(("ukbd_enable: sc=%p on=%d\n", sc, on)); if (on) { sc->sc_flags |= FLAG_ENABLED; - return (uhidev_open(&sc->sc_hdev)); + return uhidev_open(&sc->sc_hdev); } else { sc->sc_flags &= ~FLAG_ENABLED; uhidev_close(&sc->sc_hdev); - return (0); + return 0; } } @@ -586,7 +586,7 @@ ukbd_detach(device_t self, int flags) if (sc->sc_hdev.sc_state & UHIDEV_OPEN) uhidev_close(&sc->sc_hdev); - return (rv); + return rv; } static void @@ -595,7 +595,7 @@ ukbd_translate_keycodes(struct ukbd_softc *sc, struct ukbd_data *ud, { const struct ukbd_keycodetrans *tp; int i; - u_int8_t key; + uint8_t key; for (i = 0; i < sc->sc_nkeycode; i++) { key = ud->keycode[i]; @@ -614,8 +614,8 @@ ukbd_translate_keycodes(struct ukbd_softc *sc, struct ukbd_data *ud, } } -static u_int16_t -ukbd_translate_modifier(struct ukbd_softc *sc, u_int16_t key) +static uint16_t +ukbd_translate_modifier(struct ukbd_softc *sc, uint16_t key) { if ((sc->sc_flags & FLAG_APPLE_FN) && (key & CODEMASK) == 0x00e2) { if ((key & ~CODEMASK) == PRESS) { @@ -714,7 +714,7 @@ void ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud) { int mod, omod; - u_int16_t ibuf[MAXKEYS]; /* chars events */ + uint16_t ibuf[MAXKEYS]; /* chars events */ int s; int nkeys, i, j; int key; @@ -816,7 +816,7 @@ ukbd_decode(struct ukbd_softc *sc, struct ukbd_data *ud) if (sc->sc_flags & FLAG_POLLING) { DPRINTFN(1,("ukbd_intr: pollchar = 0x%03x\n", ibuf[0])); - memcpy(sc->sc_pollchars, ibuf, nkeys * sizeof(u_int16_t)); + memcpy(sc->sc_pollchars, ibuf, nkeys * sizeof(uint16_t)); sc->sc_npollchar = nkeys; return; } @@ -888,7 +888,7 @@ void ukbd_set_leds(void *v, int leds) { struct ukbd_softc *sc = v; - usbd_device_handle udev = sc->sc_hdev.sc_parent->sc_udev; + struct usbd_device *udev = sc->sc_hdev.sc_parent->sc_udev; DPRINTF(("ukbd_set_leds: sc=%p leds=%d, sc_leds=%d\n", sc, leds, sc->sc_leds)); @@ -947,13 +947,13 @@ ukbd_ioctl(void *v, u_long cmd, void *data, int flag, switch (cmd) { case WSKBDIO_GTYPE: *(int *)data = WSKBD_TYPE_USB; - return (0); + return 0; case WSKBDIO_SETLEDS: ukbd_set_leds(v, *(int *)data); - return (0); + return 0; case WSKBDIO_GETLEDS: *(int *)data = sc->sc_leds; - return (0); + return 0; #if defined(WSDISPLAY_COMPAT_RAWKBD) case WSKBDIO_SETMODE: DPRINTF(("ukbd_ioctl: set raw = %d\n", *(int *)data)); @@ -961,10 +961,10 @@ ukbd_ioctl(void *v, u_long cmd, void *data, int flag, #if defined(UKBD_REPEAT) callout_stop(&sc->sc_rawrepeat_ch); #endif - return (0); + return 0; #endif } - return (EPASSTHROUGH); + return EPASSTHROUGH; } /* @@ -1001,7 +1001,7 @@ ukbd_cngetc(void *v, u_int *type, int *data) c = sc->sc_pollchars[0]; sc->sc_npollchar--; memcpy(sc->sc_pollchars, sc->sc_pollchars+1, - sc->sc_npollchar * sizeof(u_int16_t)); + sc->sc_npollchar * sizeof(uint16_t)); *type = c & RELEASE ? WSCONS_EVENT_KEY_UP : WSCONS_EVENT_KEY_DOWN; *data = c & CODEMASK; DPRINTFN(0,("ukbd_cngetc: return 0x%02x\n", c)); @@ -1013,7 +1013,7 @@ void ukbd_cnpollc(void *v, int on) { struct ukbd_softc *sc = v; - usbd_device_handle dev; + struct usbd_device *dev; DPRINTFN(2,("ukbd_cnpollc: sc=%p on=%d\n", v, on)); @@ -1038,7 +1038,7 @@ ukbd_cnattach(void) * XXX keyboard until autconfiguration has run its course. */ ukbd_is_console = 1; - return (0); + return 0; } const char * @@ -1075,7 +1075,7 @@ ukbd_parse_desc(struct ukbd_softc *sc) h.usage, h.flags, h.loc.pos, h.loc.size, h.loc.count)); if (h.flags & HIO_VARIABLE) { if (h.loc.size != 1) - return ("bad modifier size"); + return "bad modifier size"; /* Single item */ if (imod < MAXMOD) { sc->sc_modloc[imod] = h.loc; @@ -1083,17 +1083,17 @@ ukbd_parse_desc(struct ukbd_softc *sc) sc->sc_mods[imod].key = HID_GET_USAGE(h.usage); imod++; } else - return ("too many modifier keys"); + return "too many modifier keys"; } else { /* Array */ if (h.loc.size != 8) - return ("key code size != 8"); + return "key code size != 8"; if (h.loc.count > MAXKEYCODE) h.loc.count = MAXKEYCODE; if (h.loc.pos % 8 != 0) - return ("key codes not on byte boundary"); + return "key codes not on byte boundary"; if (sc->sc_nkeycode != 0) - return ("multiple key code arrays\n"); + return "multiple key code arrays"; sc->sc_keycodeloc = h.loc; sc->sc_nkeycode = h.loc.count; } @@ -1110,5 +1110,5 @@ ukbd_parse_desc(struct ukbd_softc *sc) hid_locate(desc, size, HID_USAGE2(HUP_LEDS, HUD_LED_COMPOSE), sc->sc_hdev.sc_report_id, hid_output, &sc->sc_compose, NULL); - return (NULL); + return NULL; } diff --git a/sys/dev/usb/ukbdmap.c b/sys/dev/usb/ukbdmap.c index 68a74a15a99..55d69b9af43 100644 --- a/sys/dev/usb/ukbdmap.c +++ b/sys/dev/usb/ukbdmap.c @@ -1,4 +1,4 @@ -/* $NetBSD: ukbdmap.c,v 1.30 2015/12/10 21:38:59 jakllsch Exp $ */ +/* $NetBSD: ukbdmap.c,v 1.31 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1999,2001 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ukbdmap.c,v 1.30 2015/12/10 21:38:59 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ukbdmap.c,v 1.31 2016/04/23 10:15:32 skrll Exp $"); #include <sys/types.h> #include <dev/wscons/wsksymdef.h> diff --git a/sys/dev/usb/ukyopon.c b/sys/dev/usb/ukyopon.c index c8dc8611853..f0bdee09509 100644 --- a/sys/dev/usb/ukyopon.c +++ b/sys/dev/usb/ukyopon.c @@ -1,4 +1,4 @@ -/* $NetBSD: ukyopon.c,v 1.16 2012/02/24 06:48:26 mrg Exp $ */ +/* $NetBSD: ukyopon.c,v 1.17 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998, 2005 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ukyopon.c,v 1.16 2012/02/24 06:48:26 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ukyopon.c,v 1.17 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -86,14 +86,14 @@ Static void ukyopon_get_status(void *, int, u_char *, u_char *); Static int ukyopon_ioctl(void *, int, u_long, void *, int, proc_t *); Static struct ucom_methods ukyopon_methods = { - ukyopon_get_status, - umodem_set, - umodem_param, - ukyopon_ioctl, - umodem_open, - umodem_close, - NULL, - NULL, + .ucom_get_status = ukyopon_get_status, + .ucom_set = umodem_set, + .ucom_param = umodem_param, + .ucom_ioctl = ukyopon_ioctl, + .ucom_open = umodem_open, + .ucom_close = umodem_close, + .ucom_read = NULL, + .ucom_write = NULL, }; int ukyopon_match(device_t, cfdata_t, void *); @@ -103,34 +103,34 @@ int ukyopon_activate(device_t, enum devact); extern struct cfdriver ukyopon_cd; CFATTACH_DECL_NEW(ukyopon, sizeof(struct ukyopon_softc), ukyopon_match, ukyopon_attach, ukyopon_detach, ukyopon_activate); -int +int ukyopon_match(device_t parent, cfdata_t match, void *aux) { - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; - if (uaa->vendor == USB_VENDOR_KYOCERA && - uaa->product == USB_PRODUCT_KYOCERA_AHK3001V && - (uaa->ifaceno == UKYOPON_MODEM_IFACE_INDEX || - uaa->ifaceno == UKYOPON_DATA_IFACE_INDEX)) + if (uiaa->uiaa_vendor == USB_VENDOR_KYOCERA && + uiaa->uiaa_product == USB_PRODUCT_KYOCERA_AHK3001V && + (uiaa->uiaa_ifaceno == UKYOPON_MODEM_IFACE_INDEX || + uiaa->uiaa_ifaceno == UKYOPON_DATA_IFACE_INDEX)) return (UMATCH_VENDOR_PRODUCT); return (UMATCH_NONE); } -void +void ukyopon_attach(device_t parent, device_t self, void *aux) { struct ukyopon_softc *sc = device_private(self); - struct usbif_attach_arg *uaa = aux; - struct ucom_attach_args uca; + struct usbif_attach_arg *uiaa = aux; + struct ucom_attach_args ucaa; - uca.portno = (uaa->ifaceno == UKYOPON_MODEM_IFACE_INDEX) ? + ucaa.ucaa_portno = (uiaa->uiaa_ifaceno == UKYOPON_MODEM_IFACE_INDEX) ? UKYOPON_PORT_MODEM : UKYOPON_PORT_DATA; - uca.methods = &ukyopon_methods; - uca.info = (uaa->ifaceno == UKYOPON_MODEM_IFACE_INDEX) ? + ucaa.ucaa_methods = &ukyopon_methods; + ucaa.ucaa_info = (uiaa->uiaa_ifaceno == UKYOPON_MODEM_IFACE_INDEX) ? "modem port" : "data transfer port"; - if (umodem_common_attach(self, &sc->sc_umodem, uaa, &uca)) + if (umodem_common_attach(self, &sc->sc_umodem, uiaa, &ucaa)) return; return; } @@ -160,10 +160,10 @@ ukyopon_ioctl(void *addr, int portno, u_long cmd, void *data, int flag, switch (cmd) { case UKYOPON_IDENTIFY: - strncpy(arg_id->ui_name, UKYOPON_NAME, sizeof arg_id->ui_name); + strncpy(arg_id->ui_name, UKYOPON_NAME, sizeof(arg_id->ui_name)); arg_id->ui_busno = - device_unit(sc->sc_umodem.sc_udev->bus->usbctl); - arg_id->ui_address = sc->sc_umodem.sc_udev->address; + device_unit(sc->sc_umodem.sc_udev->ud_bus->ub_usbctl); + arg_id->ui_address = sc->sc_umodem.sc_udev->ud_addr; arg_id->ui_model = UKYOPON_MODEL_UNKNOWN; arg_id->ui_porttype = portno; break; @@ -184,7 +184,7 @@ ukyopon_activate(device_t self, enum devact act) return umodem_common_activate(&sc->sc_umodem, act); } -int +int ukyopon_detach(device_t self, int flags) { struct ukyopon_softc *sc = device_private(self); diff --git a/sys/dev/usb/ukyopon.h b/sys/dev/usb/ukyopon.h index 255a0cb473b..f30dfc5bee8 100644 --- a/sys/dev/usb/ukyopon.h +++ b/sys/dev/usb/ukyopon.h @@ -1,4 +1,4 @@ -/* $NetBSD: ukyopon.h,v 1.5 2015/09/06 06:01:01 dholland Exp $ */ +/* $NetBSD: ukyopon.h,v 1.6 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2005 The NetBSD Foundation, Inc. diff --git a/sys/dev/usb/ulpt.c b/sys/dev/usb/ulpt.c index 3181a14fb81..06d59dd7975 100644 --- a/sys/dev/usb/ulpt.c +++ b/sys/dev/usb/ulpt.c @@ -1,4 +1,4 @@ -/* $NetBSD: ulpt.c,v 1.95 2014/07/25 08:10:39 dholland Exp $ */ +/* $NetBSD: ulpt.c,v 1.96 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998, 2003 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ulpt.c,v 1.95 2014/07/25 08:10:39 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ulpt.c,v 1.96 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -64,7 +64,7 @@ __KERNEL_RCSID(0, "$NetBSD: ulpt.c,v 1.95 2014/07/25 08:10:39 dholland Exp $"); #define ULPT_BSIZE PAGE_SIZE #define ULPT_READS_PER_SEC 5 -/* XXX Why is 10 us a reasonable value? */ +/* XXX Why is 10 us a reasonable value? */ #define ULPT_READ_TIMO 10 #ifdef ULPT_DEBUG @@ -94,18 +94,18 @@ int ulptdebug = 0; struct ulpt_softc { device_t sc_dev; - usbd_device_handle sc_udev; /* device */ - usbd_interface_handle sc_iface; /* interface */ + struct usbd_device *sc_udev; /* device */ + struct usbd_interface *sc_iface; /* interface */ int sc_ifaceno; int sc_out; - usbd_pipe_handle sc_out_pipe; /* bulk out pipe */ - usbd_xfer_handle sc_out_xfer; + struct usbd_pipe *sc_out_pipe; /* bulk out pipe */ + struct usbd_xfer *sc_out_xfer; void *sc_out_buf; int sc_in; - usbd_pipe_handle sc_in_pipe; /* bulk in pipe */ - usbd_xfer_handle sc_in_xfer; + struct usbd_pipe *sc_in_pipe; /* bulk in pipe */ + struct usbd_xfer *sc_in_xfer; void *sc_in_buf; struct callout sc_read_callout; /* to drain input on write-only opens */ @@ -146,13 +146,13 @@ const struct cdevsw ulpt_cdevsw = { void ulpt_disco(void *); -int ulpt_do_write(struct ulpt_softc *, struct uio *uio, int); -int ulpt_do_read(struct ulpt_softc *, struct uio *uio, int); +int ulpt_do_write(struct ulpt_softc *, struct uio *, int); +int ulpt_do_read(struct ulpt_softc *, struct uio *, int); int ulpt_status(struct ulpt_softc *); void ulpt_reset(struct ulpt_softc *); int ulpt_statusmsg(u_char, struct ulpt_softc *); -void ulpt_read_cb(usbd_xfer_handle xfer, usbd_private_handle priv, - usbd_status status); +void ulpt_read_cb(struct usbd_xfer *, void *, + usbd_status); void ulpt_tick(void *xsc); #if 0 @@ -173,35 +173,35 @@ extern struct cfdriver ulpt_cd; CFATTACH_DECL_NEW(ulpt, sizeof(struct ulpt_softc), ulpt_match, ulpt_attach, ulpt_detach, ulpt_activate); -int +int ulpt_match(device_t parent, cfdata_t match, void *aux) { - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; /* XXX Print something useful, or don't. */ DPRINTFN(10,("ulpt_match\n")); - if (uaa->class == UICLASS_PRINTER && - uaa->subclass == UISUBCLASS_PRINTER && - (uaa->proto == UIPROTO_PRINTER_UNI || - uaa->proto == UIPROTO_PRINTER_BI || - uaa->proto == UIPROTO_PRINTER_1284)) - return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO); - return (UMATCH_NONE); + if (uiaa->uiaa_class == UICLASS_PRINTER && + uiaa->uiaa_subclass == UISUBCLASS_PRINTER && + (uiaa->uiaa_proto == UIPROTO_PRINTER_UNI || + uiaa->uiaa_proto == UIPROTO_PRINTER_BI || + uiaa->uiaa_proto == UIPROTO_PRINTER_1284)) + return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO; + return UMATCH_NONE; } -void +void ulpt_attach(device_t parent, device_t self, void *aux) { struct ulpt_softc *sc = device_private(self); - struct usbif_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface = uaa->iface; + struct usbif_attach_arg *uiaa = aux; + struct usbd_device *dev = uiaa->uiaa_device; + struct usbd_interface *iface = uiaa->uiaa_iface; usb_interface_descriptor_t *ifcd = usbd_get_interface_descriptor(iface); const usb_interface_descriptor_t *id; usbd_status err; char *devinfop; usb_endpoint_descriptor_t *ed; - u_int8_t epcount; + uint8_t epcount; int i, altno; usbd_desc_iter_t iter; @@ -341,7 +341,7 @@ ulpt_activate(device_t self, enum devact act) } } -int +int ulpt_detach(device_t self, int flags) { struct ulpt_softc *sc = device_private(self); @@ -375,7 +375,7 @@ ulpt_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - return (0); + return 0; } int @@ -393,9 +393,9 @@ ulpt_status(struct ulpt_softc *sc) err = usbd_do_request(sc->sc_udev, &req, &status); DPRINTFN(2, ("ulpt_status: status=0x%02x err=%d\n", status, err)); if (!err) - return (status); + return status; else - return (0); + return 0; } void @@ -440,10 +440,10 @@ ulptopen(dev_t dev, int flag, int mode, struct lwp *l) return ENXIO; if (sc == NULL || sc->sc_iface == NULL || sc->sc_dying) - return (ENXIO); + return ENXIO; if (sc->sc_state) - return (EBUSY); + return EBUSY; sc->sc_state = ULPT_INIT; sc->sc_flags = flags; @@ -482,16 +482,11 @@ ulptopen(dev_t dev, int flag, int mode, struct lwp *l) error = EIO; goto err0; } - sc->sc_out_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_out_xfer == NULL) { - error = ENOMEM; - goto err1; - } - sc->sc_out_buf = usbd_alloc_buffer(sc->sc_out_xfer, ULPT_BSIZE); - if (sc->sc_out_buf == NULL) { - error = ENOMEM; + error = usbd_create_xfer(sc->sc_out_pipe, ULPT_BSIZE, 0, 0, + &sc->sc_out_xfer); + if (error) goto err2; - } + sc->sc_out_buf = usbd_get_buffer(sc->sc_out_xfer); if (ulptusein && sc->sc_in != -1) { DPRINTFN(2, ("ulpt_open: opening input pipe %d\n", sc->sc_in)); @@ -500,17 +495,11 @@ ulptopen(dev_t dev, int flag, int mode, struct lwp *l) error = EIO; goto err2; } - sc->sc_in_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_in_xfer == NULL) { - error = ENOMEM; + error = usbd_create_xfer(sc->sc_in_pipe, ULPT_BSIZE, + USBD_SHORT_XFER_OK, 0, &sc->sc_in_xfer); + if (error) goto err3; - } - sc->sc_in_buf = usbd_alloc_buffer(sc->sc_in_xfer, ULPT_BSIZE); - if (sc->sc_in_buf == NULL) { - error = ENOMEM; - goto err4; - } - + sc->sc_in_buf = usbd_get_buffer(sc->sc_in_xfer); /* If it's not opened for read then set up a reader. */ if (!(flag & FREAD)) { DPRINTFN(2, ("ulpt_open: start read callout\n")); @@ -523,16 +512,13 @@ ulptopen(dev_t dev, int flag, int mode, struct lwp *l) sc->sc_state = ULPT_OPEN; goto done; - err4: - usbd_free_xfer(sc->sc_in_xfer); - sc->sc_in_xfer = NULL; err3: usbd_close_pipe(sc->sc_in_pipe); sc->sc_in_pipe = NULL; err2: - usbd_free_xfer(sc->sc_out_xfer); + usbd_destroy_xfer(sc->sc_out_xfer); sc->sc_out_xfer = NULL; - err1: + usbd_close_pipe(sc->sc_out_pipe); sc->sc_out_pipe = NULL; err0: @@ -543,7 +529,7 @@ ulptopen(dev_t dev, int flag, int mode, struct lwp *l) usb_detach_wakeupold(sc->sc_dev); DPRINTFN(2, ("ulptopen: done, error=%d\n", error)); - return (error); + return error; } /* @@ -565,7 +551,7 @@ ulpt_statusmsg(u_char status, struct ulpt_softc *sc) if (new & LPS_NERR) log(LOG_NOTICE, "%s: output error\n", device_xname(sc->sc_dev)); - return (status); + return status; } int @@ -578,7 +564,7 @@ ulptclose(dev_t dev, int flag, int mode, if (sc->sc_state != ULPT_OPEN) /* We are being forced to close before the open completed. */ - return (0); + return 0; if (sc->sc_has_callout) { DPRINTFN(2, ("ulptclose: stopping read callout\n")); @@ -589,37 +575,40 @@ ulptclose(dev_t dev, int flag, int mode, if (sc->sc_out_pipe != NULL) { usbd_abort_pipe(sc->sc_out_pipe); - usbd_close_pipe(sc->sc_out_pipe); - sc->sc_out_pipe = NULL; } if (sc->sc_out_xfer != NULL) { - usbd_free_xfer(sc->sc_out_xfer); + usbd_destroy_xfer(sc->sc_out_xfer); sc->sc_out_xfer = NULL; } - + if (sc->sc_out_pipe != NULL) { + usbd_close_pipe(sc->sc_out_pipe); + sc->sc_out_pipe = NULL; + } if (sc->sc_in_pipe != NULL) { usbd_abort_pipe(sc->sc_in_pipe); - usbd_close_pipe(sc->sc_in_pipe); - sc->sc_in_pipe = NULL; } if (sc->sc_in_xfer != NULL) { - usbd_free_xfer(sc->sc_in_xfer); + usbd_destroy_xfer(sc->sc_in_xfer); sc->sc_in_xfer = NULL; } + if (sc->sc_in_pipe != NULL) { + usbd_close_pipe(sc->sc_in_pipe); + sc->sc_in_pipe = NULL; + } sc->sc_state = 0; DPRINTFN(2, ("ulptclose: closed\n")); - return (0); + return 0; } int ulpt_do_write(struct ulpt_softc *sc, struct uio *uio, int flags) { - u_int32_t n; + uint32_t n; int error = 0; void *bufp; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; usbd_status err; DPRINTFN(3, ("ulptwrite\n")); @@ -631,8 +620,8 @@ ulpt_do_write(struct ulpt_softc *sc, struct uio *uio, int flags) if (error) break; DPRINTFN(4, ("ulptwrite: transfer %d bytes\n", n)); - err = usbd_bulk_transfer(xfer, sc->sc_out_pipe, USBD_NO_COPY, - USBD_NO_TIMEOUT, bufp, &n, "ulptwr"); + err = usbd_bulk_transfer(xfer, sc->sc_out_pipe, 0, + USBD_NO_TIMEOUT, bufp, &n); if (err) { DPRINTFN(3, ("ulptwrite: error=%d\n", err)); error = EIO; @@ -640,7 +629,7 @@ ulpt_do_write(struct ulpt_softc *sc, struct uio *uio, int flags) } } - return (error); + return error; } int @@ -652,19 +641,19 @@ ulptwrite(dev_t dev, struct uio *uio, int flags) sc = device_lookup_private(&ulpt_cd, ULPTUNIT(dev)); if (sc->sc_dying) - return (EIO); + return EIO; sc->sc_refcnt++; error = ulpt_do_write(sc, uio, flags); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); - return (error); + return error; } /* * Perform a read operation according to the given uio. * This should respect nonblocking I/O status. - * + * * XXX Doing a short read when more data is available seems to be * problematic. See * http://www.freebsd.org/cgi/query-pr.cgi?pr=91538&cat= for a fix. @@ -680,10 +669,10 @@ ulptwrite(dev_t dev, struct uio *uio, int flags) int ulpt_do_read(struct ulpt_softc *sc, struct uio *uio, int flags) { - u_int32_t n, nread, nreq; + uint32_t n, nread, nreq; int error = 0, nonblocking, timeout; void *bufp; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; usbd_status err = USBD_NORMAL_COMPLETION; /* XXX Resolve with background reader process. KASSERT? */ @@ -721,8 +710,7 @@ ulpt_do_read(struct ulpt_softc *sc, struct uio *uio, int flags) DPRINTFN(4, ("ulptread: transfer %d bytes, nonblocking=%d timeout=%d\n", n, nonblocking, timeout)); err = usbd_bulk_transfer(xfer, sc->sc_in_pipe, - USBD_NO_COPY | USBD_SHORT_XFER_OK, - timeout, bufp, &n, "ulptrd"); + USBD_SHORT_XFER_OK, timeout, bufp, &n); DPRINTFN(4, ("ulptread: transfer complete nreq %d n %d nread %d err %d\n", nreq, n, nread, err)); @@ -823,7 +811,7 @@ ulpt_do_read(struct ulpt_softc *sc, struct uio *uio, int flags) done: DPRINTFN(3, ("ulptread: finished n %d nread %d err %d error %d\n", n, nread, err, error)); - return (error); + return error; } int @@ -835,22 +823,22 @@ ulptread(dev_t dev, struct uio *uio, int flags) sc = device_lookup_private(&ulpt_cd, ULPTUNIT(dev)); if (sc->sc_dying) - return (EIO); + return EIO; sc->sc_refcnt++; error = ulpt_do_read(sc, uio, flags); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); - return (error); + return error; } void -ulpt_read_cb(usbd_xfer_handle xfer, usbd_private_handle priv, +ulpt_read_cb(struct usbd_xfer *xfer, void *priv, usbd_status status) { usbd_status err; - u_int32_t n; - usbd_private_handle xsc; + uint32_t n; + void *xsc; struct ulpt_softc *sc; usbd_get_xfer_status(xfer, &xsc, NULL, &n, &err); @@ -871,7 +859,7 @@ ulpt_read_cb(usbd_xfer_handle xfer, usbd_private_handle priv, * For devices which are not opened for reading, this function is * called continuously to start read bulk transfers to avoid the * printer overflowing its output buffer. - * + * * XXX This should be adapted for continuous reads to allow select to * work; see do_ulpt_read(). */ @@ -884,9 +872,8 @@ ulpt_tick(void *xsc) if (sc == NULL || sc->sc_dying) return; - usbd_setup_xfer(sc->sc_in_xfer, sc->sc_in_pipe, sc, sc->sc_in_buf, - ULPT_BSIZE, USBD_NO_COPY | USBD_SHORT_XFER_OK, - ULPT_READ_TIMO, ulpt_read_cb); + usbd_setup_xfer(sc->sc_in_xfer, sc, sc->sc_in_buf, ULPT_BSIZE, + USBD_SHORT_XFER_OK, ULPT_READ_TIMO, ulpt_read_cb); err = usbd_transfer(sc->sc_in_xfer); DPRINTFN(3, ("ulpt_tick: sc=%p err=%d\n", sc, err)); } diff --git a/sys/dev/usb/umass.c b/sys/dev/usb/umass.c index 4b16329aa1b..a6fd8439d49 100644 --- a/sys/dev/usb/umass.c +++ b/sys/dev/usb/umass.c @@ -1,4 +1,4 @@ -/* $NetBSD: umass.c,v 1.150 2016/04/03 17:41:30 martin Exp $ */ +/* $NetBSD: umass.c,v 1.151 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2003 The NetBSD Foundation, Inc. @@ -124,7 +124,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.150 2016/04/03 17:41:30 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umass.c,v 1.151 2016/04/23 10:15:32 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -224,46 +224,46 @@ CFATTACH_DECL2_NEW(umass, sizeof(struct umass_softc), umass_match, umass_attach, Static void umass_disco(struct umass_softc *sc); /* generic transfer functions */ -Static usbd_status umass_setup_transfer(struct umass_softc *sc, - usbd_pipe_handle pipe, - void *buffer, int buflen, int flags, - usbd_xfer_handle xfer); -Static usbd_status umass_setup_ctrl_transfer(struct umass_softc *sc, - usb_device_request_t *req, - void *buffer, int buflen, int flags, - usbd_xfer_handle xfer); -Static void umass_clear_endpoint_stall(struct umass_softc *sc, int endpt, - usbd_xfer_handle xfer); +Static usbd_status umass_setup_transfer(struct umass_softc *, + struct usbd_pipe *, + void *, int, int, + struct usbd_xfer *); +Static usbd_status umass_setup_ctrl_transfer(struct umass_softc *, + usb_device_request_t *, + void *, int, int, + struct usbd_xfer *); +Static void umass_clear_endpoint_stall(struct umass_softc *, int, + struct usbd_xfer *); #if 0 -Static void umass_reset(struct umass_softc *sc, transfer_cb_f cb, void *priv); +Static void umass_reset(struct umass_softc *, transfer_cb_f, void *); #endif /* Bulk-Only related functions */ Static void umass_bbb_transfer(struct umass_softc *, int, void *, int, void *, int, int, u_int, int, umass_callback, void *); Static void umass_bbb_reset(struct umass_softc *, int); -Static void umass_bbb_state(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void umass_bbb_state(struct usbd_xfer *, void *, usbd_status); -usbd_status umass_bbb_get_max_lun(struct umass_softc *, u_int8_t *); +usbd_status umass_bbb_get_max_lun(struct umass_softc *, uint8_t *); /* CBI related functions */ Static void umass_cbi_transfer(struct umass_softc *, int, void *, int, void *, int, int, u_int, int, umass_callback, void *); Static void umass_cbi_reset(struct umass_softc *, int); -Static void umass_cbi_state(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void umass_cbi_state(struct usbd_xfer *, void *, usbd_status); -Static int umass_cbi_adsc(struct umass_softc *, char *, int, int, usbd_xfer_handle); +Static int umass_cbi_adsc(struct umass_softc *, char *, int, int, struct usbd_xfer *); const struct umass_wire_methods umass_bbb_methods = { - umass_bbb_transfer, - umass_bbb_reset, - umass_bbb_state + .wire_xfer = umass_bbb_transfer, + .wire_reset = umass_bbb_reset, + .wire_state = umass_bbb_state }; const struct umass_wire_methods umass_cbi_methods = { - umass_cbi_transfer, - umass_cbi_reset, - umass_cbi_state + .wire_xfer = umass_cbi_transfer, + .wire_reset = umass_cbi_reset, + .wire_state = umass_cbi_state }; #ifdef UMASS_DEBUG @@ -272,7 +272,7 @@ Static void umass_bbb_dump_cbw(struct umass_softc *sc, umass_bbb_cbw_t *cbw); Static void umass_bbb_dump_csw(struct umass_softc *sc, umass_bbb_csw_t *csw); -Static void umass_dump_buffer(struct umass_softc *sc, u_int8_t *buffer, +Static void umass_dump_buffer(struct umass_softc *sc, uint8_t *buffer, int buflen, int printlen); #endif @@ -284,17 +284,17 @@ Static void umass_dump_buffer(struct umass_softc *sc, u_int8_t *buffer, int umass_match(device_t parent, cfdata_t match, void *aux) { - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; const struct umass_quirk *quirk; - quirk = umass_lookup(uaa->vendor, uaa->product); + quirk = umass_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product); if (quirk != NULL && quirk->uq_match != UMASS_QUIRK_USE_DEFAULTMATCH) - return (quirk->uq_match); + return quirk->uq_match; - if (uaa->class != UICLASS_MASS) - return (UMATCH_NONE); + if (uiaa->uiaa_class != UICLASS_MASS) + return UMATCH_NONE; - switch (uaa->subclass) { + switch (uiaa->uiaa_subclass) { case UISUBCLASS_RBC: case UISUBCLASS_SFF8020I: case UISUBCLASS_QIC157: @@ -303,27 +303,27 @@ umass_match(device_t parent, cfdata_t match, void *aux) case UISUBCLASS_SCSI: break; default: - return (UMATCH_IFACECLASS); + return UMATCH_IFACECLASS; } - switch (uaa->proto) { + switch (uiaa->uiaa_proto) { case UIPROTO_MASS_CBI_I: case UIPROTO_MASS_CBI: case UIPROTO_MASS_BBB_OLD: case UIPROTO_MASS_BBB: break; default: - return (UMATCH_IFACECLASS_IFACESUBCLASS); + return UMATCH_IFACECLASS_IFACESUBCLASS; } - return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO); + return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO; } void umass_attach(device_t parent, device_t self, void *aux) { struct umass_softc *sc = device_private(self); - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; const struct umass_quirk *quirk; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; @@ -337,18 +337,18 @@ umass_attach(device_t parent, device_t self, void *aux) aprint_naive("\n"); aprint_normal("\n"); - mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_USB); + mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); cv_init(&sc->sc_detach_cv, "umassdet"); - devinfop = usbd_devinfo_alloc(uaa->device, 0); + devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); - sc->sc_udev = uaa->device; - sc->sc_iface = uaa->iface; - sc->sc_ifaceno = uaa->ifaceno; + sc->sc_udev = uiaa->uiaa_device; + sc->sc_iface = uiaa->uiaa_iface; + sc->sc_ifaceno = uiaa->uiaa_ifaceno; - quirk = umass_lookup(uaa->vendor, uaa->product); + quirk = umass_lookup(uiaa->uiaa_vendor, uiaa->uiaa_product); if (quirk != NULL) { sc->sc_wire = quirk->uq_wire; sc->sc_cmd = quirk->uq_cmd; @@ -365,7 +365,7 @@ umass_attach(device_t parent, device_t self, void *aux) } if (sc->sc_wire == UMASS_WPROTO_UNSPEC) { - switch (uaa->proto) { + switch (uiaa->uiaa_proto) { case UIPROTO_MASS_CBI: sc->sc_wire = UMASS_WPROTO_CBI; break; @@ -380,13 +380,13 @@ umass_attach(device_t parent, device_t self, void *aux) DPRINTF(UDMASS_GEN, ("%s: Unsupported wire protocol %u\n", device_xname(sc->sc_dev), - uaa->proto)); + uiaa->uiaa_proto)); return; } } if (sc->sc_cmd == UMASS_CPROTO_UNSPEC) { - switch (uaa->subclass) { + switch (uiaa->uiaa_subclass) { case UISUBCLASS_SCSI: sc->sc_cmd = UMASS_CPROTO_SCSI; break; @@ -405,7 +405,7 @@ umass_attach(device_t parent, device_t self, void *aux) DPRINTF(UDMASS_GEN, ("%s: Unsupported command protocol %u\n", device_xname(sc->sc_dev), - uaa->subclass)); + uiaa->uiaa_subclass)); return; } } @@ -577,63 +577,144 @@ umass_attach(device_t parent, device_t self, void *aux) /* initialisation of generic part */ sc->transfer_state = TSTATE_IDLE; - /* request a sufficient number of xfer handles */ for (i = 0; i < XFER_NR; i++) { - sc->transfer_xfer[i] = usbd_alloc_xfer(uaa->device); - if (sc->transfer_xfer[i] == NULL) { - aprint_error_dev(self, "Out of memory\n"); - umass_disco(sc); - return; - } + sc->transfer_xfer[i] = NULL; } - /* Allocate buffer for data transfer (it's huge), command and - status data here as auto allocation cannot happen in interrupt - context */ + + /* + * Create the transfers + */ + struct usbd_pipe *pipe0 = usbd_get_pipe0(sc->sc_udev); switch (sc->sc_wire) { case UMASS_WPROTO_BBB: - sc->data_buffer = usbd_alloc_buffer( - sc->transfer_xfer[XFER_BBB_DATA], - UMASS_MAX_TRANSFER_SIZE); - sc->cmd_buffer = usbd_alloc_buffer( - sc->transfer_xfer[XFER_BBB_CBW], - UMASS_BBB_CBW_SIZE); - sc->s1_buffer = usbd_alloc_buffer( - sc->transfer_xfer[XFER_BBB_CSW1], - UMASS_BBB_CSW_SIZE); - sc->s2_buffer = usbd_alloc_buffer( - sc->transfer_xfer[XFER_BBB_CSW2], - UMASS_BBB_CSW_SIZE); + err = usbd_create_xfer(sc->sc_pipe[UMASS_BULKIN], + UMASS_MAX_TRANSFER_SIZE, USBD_SHORT_XFER_OK, 0, + &sc->transfer_xfer[XFER_BBB_DATAIN]); + if (err) + goto fail_create; + err = usbd_create_xfer(sc->sc_pipe[UMASS_BULKOUT], + UMASS_MAX_TRANSFER_SIZE, USBD_SHORT_XFER_OK, 0, + &sc->transfer_xfer[XFER_BBB_DATAOUT]); + if (err) + goto fail_create; + err = usbd_create_xfer(sc->sc_pipe[UMASS_BULKOUT], + UMASS_BBB_CBW_SIZE, USBD_SHORT_XFER_OK, 0, + &sc->transfer_xfer[XFER_BBB_CBW]); + if (err) + goto fail_create; + err = usbd_create_xfer(sc->sc_pipe[UMASS_BULKIN], + UMASS_BBB_CSW_SIZE, USBD_SHORT_XFER_OK, 0, + &sc->transfer_xfer[XFER_BBB_CSW1]); + if (err) + goto fail_create; + err = usbd_create_xfer(sc->sc_pipe[UMASS_BULKIN], + UMASS_BBB_CSW_SIZE, USBD_SHORT_XFER_OK, 0, + &sc->transfer_xfer[XFER_BBB_CSW2]); + if (err) + goto fail_create; + err = usbd_create_xfer(pipe0, 0, 0, 0, + &sc->transfer_xfer[XFER_BBB_SCLEAR]); + if (err) + goto fail_create; + err = usbd_create_xfer(pipe0, 0, 0, 0, + &sc->transfer_xfer[XFER_BBB_DCLEAR]); + if (err) + goto fail_create; + err = usbd_create_xfer(pipe0, 0, 0, 0, + &sc->transfer_xfer[XFER_BBB_RESET1]); + if (err) + goto fail_create; + err = usbd_create_xfer(pipe0, 0, 0, 0, + &sc->transfer_xfer[XFER_BBB_RESET2]); + if (err) + goto fail_create; + err = usbd_create_xfer(pipe0, 0, 0, 0, + &sc->transfer_xfer[XFER_BBB_RESET3]); + if (err) + goto fail_create; break; case UMASS_WPROTO_CBI: case UMASS_WPROTO_CBI_I: - sc->data_buffer = usbd_alloc_buffer( - sc->transfer_xfer[XFER_CBI_DATA], - UMASS_MAX_TRANSFER_SIZE); - sc->cmd_buffer = usbd_alloc_buffer( - sc->transfer_xfer[XFER_CBI_CB], - sizeof(sc->cbl)); - sc->s1_buffer = usbd_alloc_buffer( - sc->transfer_xfer[XFER_CBI_STATUS], - sizeof(sc->sbl)); - sc->s2_buffer = usbd_alloc_buffer( - sc->transfer_xfer[XFER_CBI_RESET1], - sizeof(sc->cbl)); + err = usbd_create_xfer(pipe0, sizeof(sc->cbl), 0, 0, + &sc->transfer_xfer[XFER_CBI_CB]); + if (err) + goto fail_create; + err = usbd_create_xfer(sc->sc_pipe[UMASS_BULKIN], + UMASS_MAX_TRANSFER_SIZE, USBD_SHORT_XFER_OK, 0, + &sc->transfer_xfer[XFER_CBI_DATAIN]); + if (err) + goto fail_create; + err = usbd_create_xfer(sc->sc_pipe[UMASS_BULKOUT], + UMASS_MAX_TRANSFER_SIZE, 0, 0, + &sc->transfer_xfer[XFER_CBI_DATAOUT]); + if (err) + goto fail_create; + err = usbd_create_xfer(pipe0, sizeof(sc->sbl), + 0, 0, &sc->transfer_xfer[XFER_CBI_STATUS]); + if (err) + goto fail_create; + err = usbd_create_xfer(pipe0, 0, 0, 0, + &sc->transfer_xfer[XFER_CBI_DCLEAR]); + if (err) + goto fail_create; + err = usbd_create_xfer(pipe0, 0, 0, 0, + &sc->transfer_xfer[XFER_CBI_SCLEAR]); + if (err) + goto fail_create; + err = usbd_create_xfer(pipe0, sizeof(sc->cbl), 0, 0, + &sc->transfer_xfer[XFER_CBI_RESET1]); + if (err) + goto fail_create; + err = usbd_create_xfer(pipe0, sizeof(sc->cbl), 0, 0, + &sc->transfer_xfer[XFER_CBI_RESET2]); + if (err) + goto fail_create; + err = usbd_create_xfer(pipe0, sizeof(sc->cbl), 0, 0, + &sc->transfer_xfer[XFER_CBI_RESET3]); + if (err) + goto fail_create; break; default: - break; - } - - if (sc->data_buffer == NULL || sc->cmd_buffer == NULL - || sc->s1_buffer == NULL || sc->s2_buffer == NULL) { - /* - * partially preallocated buffers are freed with - * the xfer structures - */ - aprint_error_dev(self, "no buffer memory\n"); + fail_create: + aprint_error_dev(self, "failed to create xfers\n"); umass_disco(sc); return; } + /* + * Record buffer pinters for data transfer (it's huge), command and + * status data here + */ + switch (sc->sc_wire) { + case UMASS_WPROTO_BBB: + sc->datain_buffer = + usbd_get_buffer(sc->transfer_xfer[XFER_BBB_DATAIN]); + sc->dataout_buffer = + usbd_get_buffer(sc->transfer_xfer[XFER_BBB_DATAOUT]); + sc->cmd_buffer = + usbd_get_buffer(sc->transfer_xfer[XFER_BBB_CBW]); + sc->s1_buffer = + usbd_get_buffer(sc->transfer_xfer[XFER_BBB_CSW1]); + sc->s2_buffer = + usbd_get_buffer(sc->transfer_xfer[XFER_BBB_CSW2]); + break; + case UMASS_WPROTO_CBI: + case UMASS_WPROTO_CBI_I: + sc->datain_buffer = + usbd_get_buffer(sc->transfer_xfer[XFER_CBI_DATAIN]); + sc->dataout_buffer = + usbd_get_buffer(sc->transfer_xfer[XFER_CBI_DATAOUT]); + sc->cmd_buffer = + usbd_get_buffer(sc->transfer_xfer[XFER_CBI_CB]); + sc->s1_buffer = + usbd_get_buffer(sc->transfer_xfer[XFER_CBI_STATUS]); + sc->s2_buffer = + usbd_get_buffer(sc->transfer_xfer[XFER_CBI_RESET1]); + break; + default: + break; + } + /* Initialise the wire protocol specific methods */ switch (sc->sc_wire) { case UMASS_WPROTO_BBB: @@ -746,7 +827,7 @@ umass_detach(device_t self, int flags) } if (rv != 0) - return (rv); + return rv; umass_disco(sc); @@ -756,7 +837,7 @@ umass_detach(device_t self, int flags) mutex_destroy(&sc->sc_lock); cv_destroy(&sc->sc_detach_cv); - return (rv); + return rv; } int @@ -787,8 +868,6 @@ umass_disco(struct umass_softc *sc) for (i = 0 ; i < UMASS_NEP ; i++) { if (sc->sc_pipe[i] != NULL) { usbd_abort_pipe(sc->sc_pipe[i]); - usbd_close_pipe(sc->sc_pipe[i]); - sc->sc_pipe[i] = NULL; } } @@ -796,11 +875,20 @@ umass_disco(struct umass_softc *sc) usbd_abort_default_pipe(sc->sc_udev); /* Free the xfers. */ - for (i = 0; i < XFER_NR; i++) + for (i = 0; i < XFER_NR; i++) { if (sc->transfer_xfer[i] != NULL) { - usbd_free_xfer(sc->transfer_xfer[i]); + usbd_destroy_xfer(sc->transfer_xfer[i]); sc->transfer_xfer[i] = NULL; } + } + + for (i = 0 ; i < UMASS_NEP ; i++) { + if (sc->sc_pipe[i] != NULL) { + usbd_close_pipe(sc->sc_pipe[i]); + sc->sc_pipe[i] = NULL; + } + } + } /* @@ -808,21 +896,21 @@ umass_disco(struct umass_softc *sc) */ Static usbd_status -umass_setup_transfer(struct umass_softc *sc, usbd_pipe_handle pipe, +umass_setup_transfer(struct umass_softc *sc, struct usbd_pipe *pipe, void *buffer, int buflen, int flags, - usbd_xfer_handle xfer) + struct usbd_xfer *xfer) { usbd_status err; USBHIST_FUNC(); USBHIST_CALLED(umassdebug); if (sc->sc_dying) - return (USBD_IOERROR); + return USBD_IOERROR; /* Initialiase a USB transfer and then schedule it */ - usbd_setup_xfer(xfer, pipe, (void *)sc, buffer, buflen, - flags, sc->timeout, sc->sc_methods->wire_state); + usbd_setup_xfer(xfer, sc, buffer, buflen, flags, sc->timeout, + sc->sc_methods->wire_state); USBHIST_LOG(umassdebug, "xfer %p, flags %d", xfer, flags, 0, 0); @@ -833,21 +921,21 @@ umass_setup_transfer(struct umass_softc *sc, usbd_pipe_handle pipe, if (err && err != USBD_IN_PROGRESS) { DPRINTF(UDMASS_BBB, ("%s: failed to setup transfer, %s\n", device_xname(sc->sc_dev), usbd_errstr(err))); - return (err); + return err; } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } Static usbd_status umass_setup_ctrl_transfer(struct umass_softc *sc, usb_device_request_t *req, - void *buffer, int buflen, int flags, usbd_xfer_handle xfer) + void *buffer, int buflen, int flags, struct usbd_xfer *xfer) { usbd_status err; if (sc->sc_dying) - return (USBD_IOERROR); + return USBD_IOERROR; /* Initialiase a USB control transfer and then schedule it */ @@ -860,15 +948,15 @@ umass_setup_ctrl_transfer(struct umass_softc *sc, usb_device_request_t *req, device_xname(sc->sc_dev), usbd_errstr(err))); /* do not reset, as this would make us loop */ - return (err); + return err; } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } Static void umass_clear_endpoint_stall(struct umass_softc *sc, int endpt, - usbd_xfer_handle xfer) + struct usbd_xfer *xfer) { if (sc->sc_dying) return; @@ -1062,11 +1150,11 @@ umass_bbb_transfer(struct umass_softc *sc, int lun, void *cmd, int cmdlen, Static void -umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv, +umass_bbb_state(struct usbd_xfer *xfer, void *priv, usbd_status err) { struct umass_softc *sc = (struct umass_softc *) priv; - usbd_xfer_handle next_xfer; + struct usbd_xfer *next_xfer; int residue; USBHIST_FUNC(); USBHIST_CALLED(umassdebug); @@ -1116,19 +1204,19 @@ umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv, sc->transfer_state = TSTATE_BBB_DATA; if (sc->transfer_dir == DIR_IN) { if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_BULKIN], - sc->data_buffer, sc->transfer_datalen, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - sc->transfer_xfer[XFER_BBB_DATA])) + sc->datain_buffer, sc->transfer_datalen, + USBD_SHORT_XFER_OK, + sc->transfer_xfer[XFER_BBB_DATAIN])) umass_bbb_reset(sc, STATUS_WIRE_FAILED); return; } else if (sc->transfer_dir == DIR_OUT) { - memcpy(sc->data_buffer, sc->transfer_data, + memcpy(sc->dataout_buffer, sc->transfer_data, sc->transfer_datalen); if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_BULKOUT], - sc->data_buffer, sc->transfer_datalen, - USBD_NO_COPY,/* fixed length transfer */ - sc->transfer_xfer[XFER_BBB_DATA])) + sc->dataout_buffer, sc->transfer_datalen, + 0,/* fixed length transfer */ + sc->transfer_xfer[XFER_BBB_DATAOUT])) umass_bbb_reset(sc, STATUS_WIRE_FAILED); return; @@ -1173,7 +1261,7 @@ umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv, /* FALLTHROUGH, err == 0 (no data phase or successful) */ case TSTATE_BBB_DCLEAR: /* stall clear after data phase */ if (sc->transfer_dir == DIR_IN) - memcpy(sc->transfer_data, sc->data_buffer, + memcpy(sc->transfer_data, sc->datain_buffer, sc->transfer_actlen); DIF(UDMASS_BBB, if (sc->transfer_dir == DIR_IN) @@ -1387,7 +1475,7 @@ umass_bbb_state(usbd_xfer_handle xfer, usbd_private_handle priv, Static int umass_cbi_adsc(struct umass_softc *sc, char *buffer, int buflen, int flags, - usbd_xfer_handle xfer) + struct usbd_xfer *xfer) { KASSERTMSG(sc->sc_wire & (UMASS_WPROTO_CBI|UMASS_WPROTO_CBI_I), "sc->sc_wire == 0x%02x wrong for umass_cbi_adsc\n", @@ -1522,7 +1610,7 @@ umass_cbi_transfer(struct umass_softc *sc, int lun, } Static void -umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv, +umass_cbi_state(struct usbd_xfer *xfer, void *priv, usbd_status err) { struct umass_softc *sc = (struct umass_softc *) priv; @@ -1575,19 +1663,19 @@ umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv, sc->transfer_state = TSTATE_CBI_DATA; if (sc->transfer_dir == DIR_IN) { if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_BULKIN], - sc->data_buffer, sc->transfer_datalen, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - sc->transfer_xfer[XFER_CBI_DATA])) + sc->datain_buffer, sc->transfer_datalen, + USBD_SHORT_XFER_OK, + sc->transfer_xfer[XFER_CBI_DATAIN])) umass_cbi_reset(sc, STATUS_WIRE_FAILED); return; } else if (sc->transfer_dir == DIR_OUT) { - memcpy(sc->data_buffer, sc->transfer_data, + memcpy(sc->dataout_buffer, sc->transfer_data, sc->transfer_datalen); if (umass_setup_transfer(sc, sc->sc_pipe[UMASS_BULKOUT], - sc->data_buffer, sc->transfer_datalen, - USBD_NO_COPY,/* fixed length transfer */ - sc->transfer_xfer[XFER_CBI_DATA])) + sc->dataout_buffer, sc->transfer_datalen, + 0, /* fixed length transfer */ + sc->transfer_xfer[XFER_CBI_DATAOUT])) umass_cbi_reset(sc, STATUS_WIRE_FAILED); return; @@ -1630,7 +1718,7 @@ umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv, } if (sc->transfer_dir == DIR_IN) - memcpy(sc->transfer_data, sc->data_buffer, + memcpy(sc->transfer_data, sc->datain_buffer, sc->transfer_actlen); DIF(UDMASS_CBI, if (sc->transfer_dir == DIR_IN) @@ -1677,7 +1765,7 @@ umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv, /* Dissect the information in the buffer */ { - u_int32_t actlen; + uint32_t actlen; usbd_get_xfer_status(xfer,NULL,NULL,&actlen,NULL); DPRINTF(UDMASS_CBI, ("%s: CBI_STATUS actlen=%d\n", device_xname(sc->sc_dev), actlen)); @@ -1811,7 +1899,7 @@ umass_cbi_state(usbd_xfer_handle xfer, usbd_private_handle priv, } usbd_status -umass_bbb_get_max_lun(struct umass_softc *sc, u_int8_t *maxlun) +umass_bbb_get_max_lun(struct umass_softc *sc, uint8_t *maxlun) { usb_device_request_t req; usbd_status err; @@ -1860,7 +1948,7 @@ umass_bbb_get_max_lun(struct umass_softc *sc, u_int8_t *maxlun) break; } - return (err); + return err; } @@ -1872,7 +1960,7 @@ umass_bbb_dump_cbw(struct umass_softc *sc, umass_bbb_cbw_t *cbw) { int clen = cbw->bCDBLength; int dlen = UGETDW(cbw->dCBWDataTransferLength); - u_int8_t *c = cbw->CBWCDB; + uint8_t *c = cbw->CBWCDB; int tag = UGETDW(cbw->dCBWTag); int flags = cbw->bCBWFlags; @@ -1905,7 +1993,7 @@ umass_bbb_dump_csw(struct umass_softc *sc, umass_bbb_csw_t *csw) } Static void -umass_dump_buffer(struct umass_softc *sc, u_int8_t *buffer, int buflen, +umass_dump_buffer(struct umass_softc *sc, uint8_t *buffer, int buflen, int printlen) { int i, j; diff --git a/sys/dev/usb/umass_isdata.c b/sys/dev/usb/umass_isdata.c index 39c1db399b6..68b8bc779d5 100644 --- a/sys/dev/usb/umass_isdata.c +++ b/sys/dev/usb/umass_isdata.c @@ -1,4 +1,4 @@ -/* $NetBSD: umass_isdata.c,v 1.31 2015/04/04 15:33:36 christos Exp $ */ +/* $NetBSD: umass_isdata.c,v 1.32 2016/04/23 10:15:32 skrll Exp $ */ /* * TODO: @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.31 2015/04/04 15:33:36 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umass_isdata.c,v 1.32 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -63,16 +63,16 @@ int umass_wd_attach(struct umass_softc *); /* XXX move this */ struct isd200_config { - uByte EventNotification; - uByte ExternalClock; - uByte ATAInitTimeout; - uByte ATAMisc1; + uByte EventNotification; + uByte ExternalClock; + uByte ATAInitTimeout; + uByte ATAMisc1; #define ATATiming 0x0f #define ATAPIReset 0x10 #define MasterSlaveSelection 0x20 #define ATAPICommandBlockSize 0xc0 - uByte ATAMajorCommand; - uByte ATAMinorCommand; + uByte ATAMajorCommand; + uByte ATAMinorCommand; uByte ATAMisc2; #define LastLUNIdentifier 0x07 #define DescriptOverride 0x08 @@ -109,7 +109,7 @@ int uisdata_bio1(struct ata_drive_datas *, struct ata_bio *); void uisdata_reset_drive(struct ata_drive_datas *, int, uint32_t *); void uisdata_reset_channel(struct ata_channel *, int); int uisdata_exec_command(struct ata_drive_datas *, struct ata_command *); -int uisdata_get_params(struct ata_drive_datas *, u_int8_t, struct ataparams *); +int uisdata_get_params(struct ata_drive_datas *, uint8_t, struct ataparams *); int uisdata_addref(struct ata_drive_datas *); void uisdata_delref(struct ata_drive_datas *); void uisdata_kill_pending(struct ata_drive_datas *); @@ -131,17 +131,17 @@ const struct ata_bustype uisdata_bustype = { }; struct ata_cmd { - u_int8_t ac_signature0; - u_int8_t ac_signature1; + uint8_t ac_signature0; + uint8_t ac_signature1; - u_int8_t ac_action_select; + uint8_t ac_action_select; #define AC_ReadRegisterAccess 0x01 #define AC_NoDeviceSelectionBit 0x02 #define AC_NoBSYPollBit 0x04 #define AC_IgnorePhaseErrorBit 0x08 #define AC_IgnoreDeviceErrorBit 0x10 - u_int8_t ac_register_select; + uint8_t ac_register_select; #define AC_SelectAlternateStatus 0x01 /* R */ #define AC_SelectDeviceControl 0x01 /* W */ #define AC_SelectError 0x02 /* R */ @@ -154,23 +154,23 @@ struct ata_cmd { #define AC_SelectStatus 0x80 /* R */ #define AC_SelectCommand 0x80 /* W */ - u_int8_t ac_transfer_blocksize; + uint8_t ac_transfer_blocksize; - u_int8_t ac_alternate_status; + uint8_t ac_alternate_status; #define ac_device_control ac_alternate_status - u_int8_t ac_error; + uint8_t ac_error; #define ac_features ac_error - u_int8_t ac_sector_count; - u_int8_t ac_sector_number; - u_int8_t ac_cylinder_low; - u_int8_t ac_cylinder_high; - u_int8_t ac_device_head; + uint8_t ac_sector_count; + uint8_t ac_sector_number; + uint8_t ac_cylinder_low; + uint8_t ac_cylinder_high; + uint8_t ac_device_head; - u_int8_t ac_status; + uint8_t ac_status; #define ac_command ac_status - u_int8_t ac_reserved[3]; + uint8_t ac_reserved[3]; }; #define ATA_DELAY 10000 /* 10s for a drive I/O */ @@ -184,7 +184,7 @@ umass_isdata_attach(struct umass_softc *sc) struct uisdata_softc *scbus; struct isd200_config *cf; - scbus = malloc(sizeof *scbus, M_DEVBUF, M_WAITOK | M_ZERO); + scbus = malloc(sizeof(*scbus), M_DEVBUF, M_WAITOK | M_ZERO); sc->bus = &scbus->base; cf = &scbus->sc_isd_config; @@ -192,7 +192,7 @@ umass_isdata_attach(struct umass_softc *sc) req.bRequest = 0x02; USETW(req.wValue, 0); USETW(req.wIndex, 2); - USETW(req.wLength, sizeof *cf); + USETW(req.wLength, sizeof(*cf)); err = usbd_do_request(sc->sc_udev, &req, cf); if (err) { @@ -218,7 +218,7 @@ umass_isdata_attach(struct umass_softc *sc) scbus->sc_drv_data.chnl_softc = sc; scbus->base.sc_child = config_found(sc->sc_dev, &adev, uwdprint); - return (0); + return 0; } @@ -268,7 +268,7 @@ uisdata_bio(struct ata_drive_datas *drv, struct ata_bio *ata_bio) struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus; scbus->sc_skip = 0; - return (uisdata_bio1(drv, ata_bio)); + return uisdata_bio1(drv, ata_bio); } int @@ -278,8 +278,8 @@ uisdata_bio1(struct ata_drive_datas *drv, struct ata_bio *ata_bio) struct uisdata_softc *scbus = (struct uisdata_softc *)sc->bus; struct isd200_config *cf = &scbus->sc_isd_config; struct ata_cmd ata; - u_int16_t cyl; - u_int8_t head, sect; + uint16_t cyl; + uint8_t head, sect; int dir; long nbytes; u_int nblks; @@ -291,12 +291,12 @@ uisdata_bio1(struct ata_drive_datas *drv, struct ata_bio *ata_bio) printf("%s: ATA_POLL not supported\n", __func__); ata_bio->error = TIMEOUT; ata_bio->flags |= ATA_ITSDONE; - return (ATACMD_COMPLETE); + return ATACMD_COMPLETE; } if (scbus->sc_ata_bio != NULL) { printf("%s: multiple uisdata_bio\n", __func__); - return (ATACMD_TRY_AGAIN); + return ATACMD_TRY_AGAIN; } else scbus->sc_ata_bio = ata_bio; @@ -325,7 +325,7 @@ uisdata_bio1(struct ata_drive_datas *drv, struct ata_bio *ata_bio) ata_bio->nblks = nblks; ata_bio->nbytes = nbytes; - memset(&ata, 0, sizeof ata); + memset(&ata, 0, sizeof(ata)); ata.ac_signature0 = cf->ATAMajorCommand; ata.ac_signature1 = cf->ATAMinorCommand; ata.ac_transfer_blocksize = 1; @@ -358,7 +358,7 @@ uisdata_bio1(struct ata_drive_datas *drv, struct ata_bio *ata_bio) ata.ac_sector_count, ata_bio->multi)); DPRINTF((" data=%p bcount=%ld, drive=%d\n", ata_bio->databuf, ata_bio->bcount, drv->drive)); - sc->sc_methods->wire_xfer(sc, drv->drive, &ata, sizeof ata, + sc->sc_methods->wire_xfer(sc, drv->drive, &ata, sizeof(ata), ata_bio->databuf + scbus->sc_skip, nbytes, dir, ATA_DELAY, 0, uisdata_bio_cb, ata_bio); @@ -367,11 +367,11 @@ uisdata_bio1(struct ata_drive_datas *drv, struct ata_bio *ata_bio) if (tsleep(ata_bio, PZERO, "uisdatabl", 0)) { ata_bio->error = TIMEOUT; ata_bio->flags |= ATA_ITSDONE; - return (ATACMD_COMPLETE); + return ATACMD_COMPLETE; } } - return (ata_bio->flags & ATA_ITSDONE) ? ATACMD_COMPLETE : ATACMD_QUEUED; + return ata_bio->flags & ATA_ITSDONE ? ATACMD_COMPLETE : ATACMD_QUEUED; } void @@ -434,7 +434,7 @@ uisdata_exec_command(struct ata_drive_datas *drv, struct ata_command *cmd) goto done; } - memset(&ata, 0, sizeof ata); + memset(&ata, 0, sizeof(ata)); ata.ac_signature0 = cf->ATAMajorCommand; ata.ac_signature1 = cf->ATAMinorCommand; ata.ac_transfer_blocksize = 1; @@ -454,7 +454,7 @@ uisdata_exec_command(struct ata_drive_datas *drv, struct ata_command *cmd) DPRINTF(("%s: execute ATA command 0x%02x, drive=%d\n", __func__, ata.ac_command, drv->drive)); sc->sc_methods->wire_xfer(sc, drv->drive, &ata, - sizeof ata, cmd->data, cmd->bcount, dir, + sizeof(ata), cmd->data, cmd->bcount, dir, cmd->timeout, 0, uisdata_exec_cb, cmd); if (cmd->flags & (AT_POLL | AT_WAIT)) { #if 0 @@ -469,7 +469,7 @@ uisdata_exec_command(struct ata_drive_datas *drv, struct ata_command *cmd) } done: - return (ATACMD_COMPLETE); + return ATACMD_COMPLETE; } int @@ -477,7 +477,7 @@ uisdata_addref(struct ata_drive_datas *drv) { DPRINTF(("%s\n", __func__)); /* Nothing to do */ - return (0); + return 0; } void @@ -506,7 +506,7 @@ uisdata_kill_pending(struct ata_drive_datas *drv) } int -uisdata_get_params(struct ata_drive_datas *drvp, u_int8_t flags, +uisdata_get_params(struct ata_drive_datas *drvp, uint8_t flags, struct ataparams *prms) { char tb[DEV_BSIZE]; @@ -514,7 +514,7 @@ uisdata_get_params(struct ata_drive_datas *drvp, u_int8_t flags, #if BYTE_ORDER == LITTLE_ENDIAN int i; - u_int16_t *p; + uint16_t *p; #endif DPRINTF(("%s\n", __func__)); @@ -530,12 +530,12 @@ uisdata_get_params(struct ata_drive_datas *drvp, u_int8_t flags, ata_c.bcount = DEV_BSIZE; if (uisdata_exec_command(drvp, &ata_c) != ATACMD_COMPLETE) { DPRINTF(("uisdata_get_parms: wdc_exec_command failed\n")); - return (CMD_AGAIN); + return CMD_AGAIN; } if (ata_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) { DPRINTF(("uisdata_get_parms: ata_c.flags=0x%x\n", ata_c.flags)); - return (CMD_ERR); + return CMD_ERR; } else { /* Read in parameter block. */ memcpy(prms, tb, sizeof(struct ataparams)); @@ -581,7 +581,7 @@ uwdprint(void *aux, const char *pnp) aprint_normal(" channel %d drive %d", adev->adev_channel, adev->adev_drv_data->drive); #endif - return (UNCONF); + return UNCONF; } @@ -591,7 +591,7 @@ int umass_wd_attach(struct umass_softc *); #if NWD > 0 case UMASS_CPROTO_ISD_ATA: - return (umass_wd_attach(sc)); + return umass_wd_attach(sc); #endif #endif diff --git a/sys/dev/usb/umass_isdata.h b/sys/dev/usb/umass_isdata.h index 35784edd100..eeb82e99c78 100644 --- a/sys/dev/usb/umass_isdata.h +++ b/sys/dev/usb/umass_isdata.h @@ -1,4 +1,4 @@ -/* $NetBSD: umass_isdata.h,v 1.2 2008/04/28 20:24:00 martin Exp $ */ +/* $NetBSD: umass_isdata.h,v 1.3 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -30,4 +30,4 @@ * POSSIBILITY OF SUCH DAMAGE. */ -int umass_isdata_attach(struct umass_softc *sc); +int umass_isdata_attach(struct umass_softc *); diff --git a/sys/dev/usb/umass_quirks.c b/sys/dev/usb/umass_quirks.c index b1ebc711108..a805585e8e0 100644 --- a/sys/dev/usb/umass_quirks.c +++ b/sys/dev/usb/umass_quirks.c @@ -1,4 +1,4 @@ -/* $NetBSD: umass_quirks.c,v 1.96 2014/09/12 16:40:38 skrll Exp $ */ +/* $NetBSD: umass_quirks.c,v 1.97 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001, 2004 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: umass_quirks.c,v 1.96 2014/09/12 16:40:38 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umass_quirks.c,v 1.97 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -209,13 +209,13 @@ Static const struct umass_quirk umass_quirks[] = { }, { { USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_I_BEAD100 }, UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, - 0, + 0, PQUIRK_NODOORLOCK | PQUIRK_NOSYNCCACHE, - UMATCH_VENDOR_PRODUCT, + UMATCH_VENDOR_PRODUCT, NULL, NULL }, { { USB_VENDOR_SIGMATEL, USB_PRODUCT_SIGMATEL_I_BEAD150 }, - UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, + UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 0, PQUIRK_NODOORLOCK | PQUIRK_NOSYNCCACHE, UMATCH_VENDOR_PRODUCT, @@ -262,7 +262,7 @@ Static const struct umass_quirk umass_quirks[] = { /* Meizu M6 doesn't like synchronize-cache, see PR 40442 */ { { USB_VENDOR_MEIZU, USB_PRODUCT_MEIZU_M6_SL }, - UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, + UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 0, PQUIRK_NOSYNCCACHE, UMATCH_VENDOR_PRODUCT, @@ -275,7 +275,7 @@ Static const struct umass_quirk umass_quirks[] = { * this is does not cause the device firmware to stop responding. */ { { USB_VENDOR_SANDISK, USB_PRODUCT_SANDISK_SANSA_CLIP }, - UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, + UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 0, PQUIRK_NOSYNCCACHE, UMATCH_VENDOR_PRODUCT, @@ -284,7 +284,7 @@ Static const struct umass_quirk umass_quirks[] = { /* Kingston USB pendrives don't like being told to lock the door */ { { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_DT101_II }, - UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, + UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 0, PQUIRK_NODOORLOCK, UMATCH_VENDOR_PRODUCT, @@ -292,7 +292,7 @@ Static const struct umass_quirk umass_quirks[] = { }, { { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_DT101_G2 }, - UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, + UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 0, PQUIRK_NODOORLOCK, UMATCH_VENDOR_PRODUCT, @@ -300,7 +300,7 @@ Static const struct umass_quirk umass_quirks[] = { }, { { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_DT102_G2 }, - UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, + UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 0, PQUIRK_NODOORLOCK, UMATCH_VENDOR_PRODUCT, @@ -308,7 +308,7 @@ Static const struct umass_quirk umass_quirks[] = { }, { { USB_VENDOR_KINGSTON, USB_PRODUCT_KINGSTON_DTMINI10 }, - UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, + UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 0, PQUIRK_NODOORLOCK, UMATCH_VENDOR_PRODUCT, @@ -317,7 +317,7 @@ Static const struct umass_quirk umass_quirks[] = { /* Also, some Kingston pendrives have Toshiba vendor ID */ { { USB_VENDOR_TOSHIBA, USB_PRODUCT_KINGSTON_DT100_G2 }, - UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, + UMASS_WPROTO_UNSPEC, UMASS_CPROTO_UNSPEC, 0, PQUIRK_NODOORLOCK, UMATCH_VENDOR_PRODUCT, @@ -343,10 +343,10 @@ Static const struct umass_quirk umass_quirks[] = { }; const struct umass_quirk * -umass_lookup(u_int16_t vendor, u_int16_t product) +umass_lookup(uint16_t vendor, uint16_t product) { - return ((const struct umass_quirk *) - usb_lookup(umass_quirks, vendor, product)); + return (const struct umass_quirk *) + usb_lookup(umass_quirks, vendor, product); } Static usbd_status @@ -359,17 +359,17 @@ umass_init_insystem(struct umass_softc *sc) DPRINTF(UDMASS_USB, ("%s: could not switch to Alt Interface 1\n", device_xname(sc->sc_dev))); - return (err); + return err; } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } Static usbd_status umass_init_shuttle(struct umass_softc *sc) { usb_device_request_t req; - u_int8_t status[2]; + uint8_t status[2]; /* The Linux driver does this */ req.bmRequestType = UT_READ_VENDOR_DEVICE; @@ -378,7 +378,7 @@ umass_init_shuttle(struct umass_softc *sc) USETW(req.wIndex, sc->sc_ifaceno); USETW(req.wLength, sizeof(status)); - return (usbd_do_request(sc->sc_udev, &req, &status)); + return usbd_do_request(sc->sc_udev, &req, &status); } Static void diff --git a/sys/dev/usb/umass_quirks.h b/sys/dev/usb/umass_quirks.h index 903eac29fdd..ca925b8ba46 100644 --- a/sys/dev/usb/umass_quirks.h +++ b/sys/dev/usb/umass_quirks.h @@ -1,4 +1,4 @@ -/* $NetBSD: umass_quirks.h,v 1.4 2008/04/28 20:24:00 martin Exp $ */ +/* $NetBSD: umass_quirks.h,v 1.5 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -39,16 +39,16 @@ typedef void (*umass_fixup_quirk)(struct umass_softc *); struct umass_quirk { struct usb_devno uq_dev; - u_int8_t uq_wire; - u_int8_t uq_cmd; - u_int32_t uq_flags; - u_int32_t uq_busquirks; + uint8_t uq_wire; + uint8_t uq_cmd; + uint32_t uq_flags; + uint32_t uq_busquirks; int uq_match; umass_init_quirk uq_init; umass_fixup_quirk uq_fixup; }; -const struct umass_quirk *umass_lookup(u_int16_t, u_int16_t); +const struct umass_quirk *umass_lookup(uint16_t, uint16_t); #endif /* _DEV_USB_UMASS_QUIRKS_H_ */ diff --git a/sys/dev/usb/umass_scsipi.c b/sys/dev/usb/umass_scsipi.c index 01173dbbd73..68ad318df87 100644 --- a/sys/dev/usb/umass_scsipi.c +++ b/sys/dev/usb/umass_scsipi.c @@ -1,4 +1,4 @@ -/* $NetBSD: umass_scsipi.c,v 1.49 2014/09/12 16:40:38 skrll Exp $ */ +/* $NetBSD: umass_scsipi.c,v 1.50 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001, 2003, 2012 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: umass_scsipi.c,v 1.49 2014/09/12 16:40:38 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umass_scsipi.c,v 1.50 2016/04/23 10:15:32 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -93,18 +93,18 @@ struct umass_scsipi_softc { Static void umass_scsipi_request(struct scsipi_channel *, scsipi_adapter_req_t, void *); -Static void umass_scsipi_minphys(struct buf *bp); +Static void umass_scsipi_minphys(struct buf *); Static int umass_scsipi_ioctl(struct scsipi_channel *, u_long, void *, int, proc_t *); -Static int umass_scsipi_getgeom(struct scsipi_periph *periph, - struct disk_parms *, u_long sectors); +Static int umass_scsipi_getgeom(struct scsipi_periph *, + struct disk_parms *, u_long); -Static void umass_scsipi_cb(struct umass_softc *sc, void *priv, - int residue, int status); -Static void umass_scsipi_sense_cb(struct umass_softc *sc, void *priv, - int residue, int status); +Static void umass_scsipi_cb(struct umass_softc *, void *, + int, int); +Static void umass_scsipi_sense_cb(struct umass_softc *, void *, + int, int); -Static struct umass_scsipi_softc *umass_scsipi_setup(struct umass_softc *sc); +Static struct umass_scsipi_softc *umass_scsipi_setup(struct umass_softc *); #if NATAPIBUS > 0 Static void umass_atapi_probe_device(struct atapibus_softc *, int); @@ -142,7 +142,7 @@ umass_scsi_attach(struct umass_softc *sc) if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); - return (0); + return 0; } #endif @@ -170,7 +170,7 @@ umass_atapi_attach(struct umass_softc *sc) if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); - return (0); + return 0; } #endif @@ -179,7 +179,7 @@ umass_scsipi_setup(struct umass_softc *sc) { struct umass_scsipi_softc *scbus; - scbus = malloc(sizeof *scbus, M_DEVBUF, M_WAITOK | M_ZERO); + scbus = malloc(sizeof(*scbus), M_DEVBUF, M_WAITOK | M_ZERO); sc->bus = &scbus->base; /* Only use big commands for USB SCSI devices. */ @@ -203,7 +203,7 @@ umass_scsipi_setup(struct umass_softc *sc) scbus->sc_channel.chan_max_periph = 1; scbus->sc_channel.chan_defquirks |= sc->sc_busquirks; - return (scbus); + return scbus; } Static void @@ -356,10 +356,10 @@ umass_scsipi_ioctl(struct scsipi_channel *chan, u_long cmd, case SCBUSIORESET: ccb->ccb_h.status = CAM_REQ_INPROG; umass_reset(sc, umass_cam_cb, (void *) ccb); - return (0); + return 0; #endif default: - return (ENOTTY); + return ENOTTY; } } @@ -372,7 +372,7 @@ umass_scsipi_getgeom(struct scsipi_periph *periph, struct disk_parms *dp, /* If it's not a floppy, we don't know what to do. */ if (sc->sc_cmd != UMASS_CPROTO_UFI) - return (0); + return 0; switch (sectors) { case 1440: @@ -380,15 +380,15 @@ umass_scsipi_getgeom(struct scsipi_periph *periph, struct disk_parms *dp, dp->heads = 2; dp->sectors = 9; dp->cyls = 80; - return (1); + return 1; case 2880: /* Most likely a double density 3.5" floppy. */ dp->heads = 2; dp->sectors = 18; dp->cyls = 80; - return (1); + return 1; default: - return (0); + return 0; } } diff --git a/sys/dev/usb/umass_scsipi.h b/sys/dev/usb/umass_scsipi.h index 619aa622876..560364283df 100644 --- a/sys/dev/usb/umass_scsipi.h +++ b/sys/dev/usb/umass_scsipi.h @@ -1,4 +1,4 @@ -/* $NetBSD: umass_scsipi.h,v 1.2 2008/04/28 20:24:00 martin Exp $ */ +/* $NetBSD: umass_scsipi.h,v 1.3 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -30,5 +30,5 @@ * POSSIBILITY OF SUCH DAMAGE. */ -int umass_scsi_attach(struct umass_softc *sc); -int umass_atapi_attach(struct umass_softc *sc); +int umass_scsi_attach(struct umass_softc *); +int umass_atapi_attach(struct umass_softc *); diff --git a/sys/dev/usb/umassvar.h b/sys/dev/usb/umassvar.h index e72ac779b29..95fb0c61c7c 100644 --- a/sys/dev/usb/umassvar.h +++ b/sys/dev/usb/umassvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: umassvar.h,v 1.35 2013/12/22 18:30:21 mlelstv Exp $ */ +/* $NetBSD: umassvar.h,v 1.36 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 1999 MAEKAWA Masahide <bishop@rr.iij4u.or.jp>, @@ -136,7 +136,7 @@ typedef void (*umass_callback)(struct umass_softc *, void *, int, int); typedef void (*umass_wire_xfer)(struct umass_softc *, int, void *, int, void *, int, int, u_int, int, umass_callback, void *); typedef void (*umass_wire_reset)(struct umass_softc *, int); -typedef void (*umass_wire_state)(usbd_xfer_handle, usbd_private_handle, +typedef void (*umass_wire_state)(struct usbd_xfer *, void *, usbd_status); struct umass_wire_methods { @@ -152,12 +152,12 @@ struct umassbus_softc { /* the per device structure */ struct umass_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; /* device */ - usbd_interface_handle sc_iface; /* interface */ + struct usbd_device * sc_udev; /* device */ + struct usbd_interface * sc_iface; /* interface */ int sc_ifaceno; /* interface number */ - u_int8_t sc_epaddr[UMASS_NEP]; - usbd_pipe_handle sc_pipe[UMASS_NEP]; + uint8_t sc_epaddr[UMASS_NEP]; + struct usbd_pipe * sc_pipe[UMASS_NEP]; usb_device_request_t sc_req; const struct umass_wire_methods *sc_methods; @@ -165,13 +165,13 @@ struct umass_softc { kmutex_t sc_lock; kcondvar_t sc_detach_cv; - u_int8_t sc_wire; /* wire protocol */ + uint8_t sc_wire; /* wire protocol */ #define UMASS_WPROTO_UNSPEC 0 #define UMASS_WPROTO_BBB 1 #define UMASS_WPROTO_CBI 2 #define UMASS_WPROTO_CBI_I 3 - u_int8_t sc_cmd; /* command protocol */ + uint8_t sc_cmd; /* command protocol */ #define UMASS_CPROTO_UNSPEC 0 #define UMASS_CPROTO_SCSI 1 #define UMASS_CPROTO_ATAPI 2 @@ -179,7 +179,7 @@ struct umass_softc { #define UMASS_CPROTO_RBC 4 #define UMASS_CPROTO_ISD_ATA 5 - u_int32_t sc_quirks; + uint32_t sc_quirks; #define UMASS_QUIRK_WRONG_CSWSIG 0x00000001 #define UMASS_QUIRK_WRONG_CSWTAG 0x00000002 #define UMASS_QUIRK_RBC_PAD_TO_12 0x00000004 @@ -187,7 +187,7 @@ struct umass_softc { #define UMASS_QUIRK_USE_DEFAULTMATCH -1 - u_int32_t sc_busquirks; + uint32_t sc_busquirks; /* Bulk specific variables for transfers in progress */ umass_bbb_cbw_t cbw; /* command block wrapper */ @@ -198,34 +198,37 @@ struct umass_softc { /* xfer handles * Most of our operations are initiated from interrupt context, so - * we need to avoid using the one that is in use. We want to avoid + * we need to avoid using the one that is in use. We have to avoid * allocating them in the interrupt context as well. */ /* indices into array below */ #define XFER_BBB_CBW 0 /* Bulk-Only */ -#define XFER_BBB_DATA 1 -#define XFER_BBB_DCLEAR 2 -#define XFER_BBB_CSW1 3 -#define XFER_BBB_CSW2 4 -#define XFER_BBB_SCLEAR 5 -#define XFER_BBB_RESET1 6 -#define XFER_BBB_RESET2 7 -#define XFER_BBB_RESET3 8 +#define XFER_BBB_DATAIN 1 +#define XFER_BBB_DATAOUT 2 +#define XFER_BBB_DCLEAR 3 +#define XFER_BBB_CSW1 4 +#define XFER_BBB_CSW2 5 +#define XFER_BBB_SCLEAR 6 +#define XFER_BBB_RESET1 7 +#define XFER_BBB_RESET2 8 +#define XFER_BBB_RESET3 9 #define XFER_CBI_CB 0 /* CBI */ -#define XFER_CBI_DATA 1 -#define XFER_CBI_STATUS 2 -#define XFER_CBI_DCLEAR 3 -#define XFER_CBI_SCLEAR 4 -#define XFER_CBI_RESET1 5 -#define XFER_CBI_RESET2 6 -#define XFER_CBI_RESET3 7 +#define XFER_CBI_DATAIN 1 +#define XFER_CBI_DATAOUT 2 +#define XFER_CBI_STATUS 3 +#define XFER_CBI_DCLEAR 4 +#define XFER_CBI_SCLEAR 5 +#define XFER_CBI_RESET1 6 +#define XFER_CBI_RESET2 7 +#define XFER_CBI_RESET3 8 -#define XFER_NR 9 /* maximum number */ +#define XFER_NR 10 /* maximum number */ - usbd_xfer_handle transfer_xfer[XFER_NR]; /* for ctrl xfers */ + struct usbd_xfer *transfer_xfer[XFER_NR]; /* for ctrl xfers */ - void *data_buffer; + void *datain_buffer; + void *dataout_buffer; void *cmd_buffer; void *s1_buffer; void *s2_buffer; @@ -262,7 +265,7 @@ struct umass_softc { int timeout; /* in msecs */ - u_int8_t maxlun; /* max lun supported */ + uint8_t maxlun; /* max lun supported */ #ifdef UMASS_DEBUG struct timeval tv; diff --git a/sys/dev/usb/umcs.c b/sys/dev/usb/umcs.c index 88b65316893..9792e25e60d 100644 --- a/sys/dev/usb/umcs.c +++ b/sys/dev/usb/umcs.c @@ -1,4 +1,4 @@ -/* $NetBSD: umcs.c,v 1.8 2014/08/23 21:37:56 martin Exp $ */ +/* $NetBSD: umcs.c,v 1.9 2016/04/23 10:15:32 skrll Exp $ */ /* $FreeBSD: head/sys/dev/usb/serial/umcs.c 260559 2014-01-12 11:44:28Z hselasky $ */ /*- @@ -41,7 +41,7 @@ * */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: umcs.c,v 1.8 2014/08/23 21:37:56 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umcs.c,v 1.9 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -85,9 +85,9 @@ struct umcs7840_softc_oneport { struct umcs7840_softc { device_t sc_dev; /* ourself */ - usbd_interface_handle sc_iface; /* the usb interface */ - usbd_device_handle sc_udev; /* the usb device */ - usbd_pipe_handle sc_intr_pipe; /* interrupt pipe */ + struct usbd_interface *sc_iface; /* the usb interface */ + struct usbd_device *sc_udev; /* the usb device */ + struct usbd_pipe *sc_intr_pipe; /* interrupt pipe */ uint8_t *sc_intr_buf; /* buffer for interrupt xfer */ unsigned int sc_intr_buflen; /* size of buffer */ struct usb_task sc_change_task; /* async status changes */ @@ -99,28 +99,28 @@ struct umcs7840_softc { bool sc_dying; /* we have been deactivated */ }; -static int umcs7840_get_reg(struct umcs7840_softc *sc, uint8_t reg, uint8_t *data); -static int umcs7840_set_reg(struct umcs7840_softc *sc, uint8_t reg, uint8_t data); -static int umcs7840_get_UART_reg(struct umcs7840_softc *sc, uint8_t portno, uint8_t reg, uint8_t *data); -static int umcs7840_set_UART_reg(struct umcs7840_softc *sc, uint8_t portno, uint8_t reg, uint8_t data); -static int umcs7840_calc_baudrate(uint32_t rate, uint16_t *divisor, uint8_t *clk); -static void umcs7840_dtr(struct umcs7840_softc *sc, int portno, bool onoff); -static void umcs7840_rts(struct umcs7840_softc *sc, int portno, bool onoff); -static void umcs7840_break(struct umcs7840_softc *sc, int portno, bool onoff); +static int umcs7840_get_reg(struct umcs7840_softc *, uint8_t, uint8_t *); +static int umcs7840_set_reg(struct umcs7840_softc *, uint8_t, uint8_t); +static int umcs7840_get_UART_reg(struct umcs7840_softc *, uint8_t, uint8_t, uint8_t *); +static int umcs7840_set_UART_reg(struct umcs7840_softc *, uint8_t, uint8_t, uint8_t ); +static int umcs7840_calc_baudrate(uint32_t, uint16_t *, uint8_t *); +static void umcs7840_dtr(struct umcs7840_softc *, int, bool); +static void umcs7840_rts(struct umcs7840_softc *, int, bool); +static void umcs7840_break(struct umcs7840_softc *, int, bool ); static int umcs7840_match(device_t, cfdata_t, void *); static void umcs7840_attach(device_t, device_t, void *); static int umcs7840_detach(device_t, int); -static void umcs7840_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status); +static void umcs7840_intr(struct usbd_xfer *, void *, usbd_status); static void umcs7840_change_task(void *arg); -static int umcs7840_activate(device_t, enum devact); +static int umcs7840_activate(device_t, enum devact); static void umcs7840_childdet(device_t, device_t); static void umcs7840_get_status(void *, int, u_char *, u_char *); static void umcs7840_set(void *, int, int, int); static int umcs7840_param(void *, int, struct termios *); -static int umcs7840_port_open(void *sc, int portno); -static void umcs7840_port_close(void *sc, int portno); +static int umcs7840_port_open(void *, int); +static void umcs7840_port_close(void *, int); struct ucom_methods umcs7840_methods = { .ucom_get_status = umcs7840_get_status, @@ -174,25 +174,25 @@ umcs7840_match(device_t dev, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (umcs7840_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return umcs7840_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } static void -umcs7840_attach(device_t parent, device_t self, void * aux) +umcs7840_attach(device_t parent, device_t self, void *aux) { struct umcs7840_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; + struct usbd_device *dev = uaa->uaa_device; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devinfop; - struct ucom_attach_args uca; + struct ucom_attach_args ucaa; int error, i, intr_addr; uint8_t data; sc->sc_dev = self; - sc->sc_udev = uaa->device; + sc->sc_udev = uaa->uaa_device; if (usbd_set_config_index(sc->sc_udev, MCS7840_CONFIG_INDEX, 1) != 0) { aprint_error(": could not set configuration no\n"); @@ -224,7 +224,7 @@ umcs7840_attach(device_t parent, device_t self, void * aux) sc->sc_numports = 4; /* physical port no are : 0, 1, 2, 3 */ } else { - if (uaa->product == USB_PRODUCT_MOSCHIP_MCS7810) + if (uaa->uaa_product == USB_PRODUCT_MOSCHIP_MCS7810) sc->sc_numports = 1; else { sc->sc_numports = 2; @@ -285,18 +285,18 @@ umcs7840_attach(device_t parent, device_t self, void * aux) usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); - memset(&uca, 0, sizeof uca); - uca.ibufsize = 256; - uca.obufsize = 256; - uca.ibufsizepad = 256; - uca.opkthdrlen = 0; - uca.device = sc->sc_udev; - uca.iface = sc->sc_iface; - uca.methods = &umcs7840_methods; - uca.arg = sc; + memset(&ucaa, 0, sizeof(ucaa)); + ucaa.ucaa_ibufsize = 256; + ucaa.ucaa_obufsize = 256; + ucaa.ucaa_ibufsizepad = 256; + ucaa.ucaa_opkthdrlen = 0; + ucaa.ucaa_device = sc->sc_udev; + ucaa.ucaa_iface = sc->sc_iface; + ucaa.ucaa_methods = &umcs7840_methods; + ucaa.ucaa_arg = sc; for (i = 0; i < sc->sc_numports; i++) { - uca.bulkin = uca.bulkout = -1; + ucaa.ucaa_bulkin = ucaa.ucaa_bulkout = -1; /* * On four port cards, endpoints are 0/1 for first, @@ -313,7 +313,7 @@ umcs7840_attach(device_t parent, device_t self, void * aux) "no bulk in endpoint found for %d\n", i); return; } - uca.bulkin = ed->bEndpointAddress; + ucaa.ucaa_bulkin = ed->bEndpointAddress; ed = usbd_interface2endpoint_descriptor(sc->sc_iface, phyport*2 + 1); @@ -322,14 +322,14 @@ umcs7840_attach(device_t parent, device_t self, void * aux) "no bulk out endpoint found for %d\n", i); return; } - uca.bulkout = ed->bEndpointAddress; - uca.portno = i; + ucaa.ucaa_bulkout = ed->bEndpointAddress; + ucaa.ucaa_portno = i; DPRINTF(("port %d physical port %d bulk-in %d bulk-out %d\n", - i, phyport, uca.bulkin, uca.bulkout)); + i, phyport, ucaa.ucaa_bulkin, ucaa.ucaa_bulkout)); sc->sc_ports[i].sc_port_phys = phyport; sc->sc_ports[i].sc_port_ucom = - config_found_sm_loc(self, "ucombus", NULL, &uca, + config_found_sm_loc(self, "ucombus", NULL, &ucaa, ucomprint, ucomsubmatch); } } @@ -432,12 +432,12 @@ umcs7840_set_baudrate(struct umcs7840_softc *sc, uint8_t portno, if (umcs7840_calc_baudrate(rate, &divisor, &clk)) { DPRINTF(("Port %d bad speed: %d\n", portno, rate)); - return (-1); + return -1; } if (divisor == 0 || (clk & MCS7840_DEV_SPx_CLOCK_MASK) != clk) { DPRINTF(("Port %d bad speed calculation: %d\n", portno, rate)); - return (-1); + return -1; } DPRINTF(("Port %d set speed: %d (%02x / %d)\n", portno, rate, clk, divisor)); @@ -469,7 +469,7 @@ umcs7840_set_baudrate(struct umcs7840_softc *sc, uint8_t portno, err = umcs7840_set_UART_reg(sc, physport, MCS7840_UART_REG_LCR, sc->sc_ports[portno].sc_port_lcr); if (err) return err; - return (0); + return 0; } static int @@ -484,7 +484,7 @@ umcs7840_calc_baudrate(uint32_t rate, uint16_t *divisor, uint8_t *clk) uint8_t i = 0; if (rate > umcs7840_baudrate_divisors[umcs7840_baudrate_divisors_len - 1]) - return (-1); + return -1; for (i = 0; i < umcs7840_baudrate_divisors_len - 1 && !(rate > umcs7840_baudrate_divisors[i] @@ -492,10 +492,10 @@ umcs7840_calc_baudrate(uint32_t rate, uint16_t *divisor, uint8_t *clk) *divisor = umcs7840_baudrate_divisors[i + 1] / rate; /* 0x00 .. 0x70 */ *clk = i << MCS7840_DEV_SPx_CLOCK_SHIFT; - return (0); + return 0; } -static int +static int umcs7840_detach(device_t self, int flags) { struct umcs7840_softc *sc = device_private(self); @@ -853,7 +853,7 @@ umcs7840_port_close(void *self, int portno) } static void -umcs7840_intr(usbd_xfer_handle xfer, usbd_private_handle priv, +umcs7840_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct umcs7840_softc *sc = priv; diff --git a/sys/dev/usb/umct.c b/sys/dev/usb/umct.c index 095bcc3fb8e..0c4443b1f91 100644 --- a/sys/dev/usb/umct.c +++ b/sys/dev/usb/umct.c @@ -1,4 +1,4 @@ -/* $NetBSD: umct.c,v 1.33 2015/11/02 08:37:28 skrll Exp $ */ +/* $NetBSD: umct.c,v 1.34 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. * All rights reserved. @@ -35,12 +35,11 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: umct.c,v 1.33 2015/11/02 08:37:28 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umct.c,v 1.34 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> #include <sys/ioctl.h> #include <sys/conf.h> #include <sys/tty.h> @@ -75,13 +74,13 @@ int umctdebug = 0; struct umct_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; /* USB device */ - usbd_interface_handle sc_iface; /* interface */ + struct usbd_device * sc_udev; /* USB device */ + struct usbd_interface * sc_iface; /* interface */ int sc_iface_number; /* interface number */ - u_int16_t sc_product; + uint16_t sc_product; int sc_intr_number; /* interrupt number */ - usbd_pipe_handle sc_intr_pipe; /* interrupt pipe */ + struct usbd_pipe * sc_intr_pipe; /* interrupt pipe */ u_char *sc_intr_buf; /* interrupt buffer */ int sc_isize; @@ -112,27 +111,27 @@ struct umct_softc { Static void umct_init(struct umct_softc *); Static void umct_set_baudrate(struct umct_softc *, u_int); Static void umct_set_lcr(struct umct_softc *, u_int); -Static void umct_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void umct_intr(struct usbd_xfer *, void *, usbd_status); Static void umct_set(void *, int, int, int); Static void umct_dtr(struct umct_softc *, int); Static void umct_rts(struct umct_softc *, int); Static void umct_break(struct umct_softc *, int); Static void umct_set_line_state(struct umct_softc *); -Static void umct_get_status(void *, int portno, u_char *lsr, u_char *msr); +Static void umct_get_status(void *, int, u_char *, u_char *); Static int umct_param(void *, int, struct termios *); Static int umct_open(void *, int); Static void umct_close(void *, int); struct ucom_methods umct_methods = { - umct_get_status, - umct_set, - umct_param, - NULL, - umct_open, - umct_close, - NULL, - NULL, + .ucom_get_status = umct_get_status, + .ucom_set = umct_set, + .ucom_param = umct_param, + .ucom_ioctl = NULL, + .ucom_open = umct_open, + .ucom_close = umct_close, + .ucom_read = NULL, + .ucom_write = NULL, }; static const struct usb_devno umct_devs[] = { @@ -161,8 +160,8 @@ umct_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (umct_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return umct_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } void @@ -170,7 +169,7 @@ umct_attach(device_t parent, device_t self, void *aux) { struct umct_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; + struct usbd_device *dev = uaa->uaa_device; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; @@ -178,7 +177,7 @@ umct_attach(device_t parent, device_t self, void *aux) char *devinfop; usbd_status err; int i; - struct ucom_attach_args uca; + struct ucom_attach_args ucaa; sc->sc_dev = self; @@ -189,13 +188,13 @@ umct_attach(device_t parent, device_t self, void *aux) aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); - sc->sc_udev = dev; - sc->sc_product = uaa->product; + sc->sc_udev = dev; + sc->sc_product = uaa->uaa_product; DPRINTF(("\n\numct attach: sc=%p\n", sc)); /* initialize endpoints */ - uca.bulkin = uca.bulkout = -1; + ucaa.ucaa_bulkin = ucaa.ucaa_bulkout = -1; sc->sc_intr_number = -1; sc->sc_intr_pipe = NULL; @@ -250,10 +249,10 @@ umct_attach(device_t parent, device_t self, void *aux) if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT && UGETW(ed->wMaxPacketSize) != 0x2) { - uca.bulkin = ed->bEndpointAddress; + ucaa.ucaa_bulkin = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - uca.bulkout = ed->bEndpointAddress; + ucaa.ucaa_bulkout = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->sc_intr_number = ed->bEndpointAddress; @@ -261,13 +260,13 @@ umct_attach(device_t parent, device_t self, void *aux) } } - if (uca.bulkin == -1) { + if (ucaa.ucaa_bulkin == -1) { aprint_error_dev(self, "Could not find data bulk in\n"); sc->sc_dying = 1; return; } - if (uca.bulkout == -1) { + if (ucaa.ucaa_bulkout == -1) { aprint_error_dev(self, "Could not find data bulk out\n"); sc->sc_dying = 1; return; @@ -280,20 +279,20 @@ umct_attach(device_t parent, device_t self, void *aux) } sc->sc_dtr = sc->sc_rts = 0; - uca.portno = UCOM_UNK_PORTNO; - /* bulkin, bulkout set above */ - uca.ibufsize = UMCTIBUFSIZE; + ucaa.ucaa_portno = UCOM_UNK_PORTNO; + /* ucaa_bulkin, ucaa_bulkout set above */ + ucaa.ucaa_ibufsize = UMCTIBUFSIZE; if (sc->sc_product == USB_PRODUCT_MCT_SITECOM_USB232) - uca.obufsize = 16; /* device is broken */ + ucaa.ucaa_obufsize = 16; /* device is broken */ else - uca.obufsize = UMCTOBUFSIZE; - uca.ibufsizepad = UMCTIBUFSIZE; - uca.opkthdrlen = 0; - uca.device = dev; - uca.iface = sc->sc_iface; - uca.methods = &umct_methods; - uca.arg = sc; - uca.info = NULL; + ucaa.ucaa_obufsize = UMCTOBUFSIZE; + ucaa.ucaa_ibufsizepad = UMCTIBUFSIZE; + ucaa.ucaa_opkthdrlen = 0; + ucaa.ucaa_device = dev; + ucaa.ucaa_iface = sc->sc_iface; + ucaa.ucaa_methods = &umct_methods; + ucaa.ucaa_arg = sc; + ucaa.ucaa_info = NULL; umct_init(sc); @@ -301,8 +300,8 @@ umct_attach(device_t parent, device_t self, void *aux) sc->sc_dev); DPRINTF(("umct: in=0x%x out=0x%x intr=0x%x\n", - uca.bulkin, uca.bulkout, sc->sc_intr_number )); - sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &uca, + ucaa.ucaa_bulkin, ucaa.ucaa_bulkout, sc->sc_intr_number)); + sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &ucaa, ucomprint, ucomsubmatch); return; @@ -325,12 +324,12 @@ umct_detach(device_t self, int flags) DPRINTF(("umct_detach: sc=%p flags=%d\n", sc, flags)); - if (sc->sc_intr_pipe != NULL) { - usbd_abort_pipe(sc->sc_intr_pipe); - usbd_close_pipe(sc->sc_intr_pipe); - free(sc->sc_intr_buf, M_USBDEV); - sc->sc_intr_pipe = NULL; - } + if (sc->sc_intr_pipe != NULL) { + usbd_abort_pipe(sc->sc_intr_pipe); + usbd_close_pipe(sc->sc_intr_pipe); + kmem_free(sc->sc_intr_buf, sc->sc_isize); + sc->sc_intr_pipe = NULL; + } sc->sc_dying = 1; if (sc->sc_subdev != NULL) @@ -339,7 +338,7 @@ umct_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - return (rv); + return rv; } int @@ -450,7 +449,7 @@ umct_set_lcr(struct umct_softc *sc, u_int data) void umct_set_baudrate(struct umct_softc *sc, u_int rate) { - usb_device_request_t req; + usb_device_request_t req; uDWord arate; u_int val; @@ -474,13 +473,13 @@ umct_set_baudrate(struct umct_softc *sc, u_int rate) } USETDW(arate, val); - req.bmRequestType = UMCT_SET_REQUEST; - req.bRequest = REQ_SET_BAUD_RATE; - USETW(req.wValue, 0); - USETW(req.wIndex, sc->sc_iface_number); - USETW(req.wLength, LENGTH_BAUD_RATE); + req.bmRequestType = UMCT_SET_REQUEST; + req.bRequest = REQ_SET_BAUD_RATE; + USETW(req.wValue, 0); + USETW(req.wIndex, sc->sc_iface_number); + USETW(req.wLength, LENGTH_BAUD_RATE); - (void)usbd_do_request(sc->sc_udev, &req, arate); /* XXX should check */ + (void)usbd_do_request(sc->sc_udev, &req, arate); /* XXX should check */ } void @@ -531,7 +530,7 @@ umct_param(void *addr, int portno, struct termios *t) sc->last_lcr = data; umct_set_lcr(sc, data); - return (0); + return 0; } int @@ -541,18 +540,18 @@ umct_open(void *addr, int portno) int err, lcr_data; if (sc->sc_dying) - return (EIO); + return EIO; DPRINTF(("umct_open: sc=%p\n", sc)); /* initialize LCR */ - lcr_data = LCR_DATA_BITS_8 | LCR_PARITY_NONE | + lcr_data = LCR_DATA_BITS_8 | LCR_PARITY_NONE | LCR_STOP_BITS_1; - umct_set_lcr(sc, lcr_data); + umct_set_lcr(sc, lcr_data); if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) { sc->sc_status = 0; /* clear status bit */ - sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK); + sc->sc_intr_buf = kmem_alloc(sc->sc_isize, KM_SLEEP); err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_intr_number, USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc, sc->sc_intr_buf, sc->sc_isize, @@ -560,11 +559,11 @@ umct_open(void *addr, int portno) if (err) { DPRINTF(("%s: cannot open interrupt pipe (addr %d)\n", device_xname(sc->sc_dev), sc->sc_intr_number)); - return (EIO); + return EIO; } } - return (0); + return 0; } void @@ -587,13 +586,13 @@ umct_close(void *addr, int portno) if (err) printf("%s: close interrupt pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); - free(sc->sc_intr_buf, M_USBDEV); + kmem_free(sc->sc_intr_buf, sc->sc_isize); sc->sc_intr_pipe = NULL; } } void -umct_intr(usbd_xfer_handle xfer, usbd_private_handle priv, +umct_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct umct_softc *sc = priv; diff --git a/sys/dev/usb/umidi.c b/sys/dev/usb/umidi.c index 155572a4752..b6905e6b06f 100644 --- a/sys/dev/usb/umidi.c +++ b/sys/dev/usb/umidi.c @@ -1,4 +1,4 @@ -/* $NetBSD: umidi.c,v 1.68 2015/01/02 20:42:44 mrg Exp $ */ +/* $NetBSD: umidi.c,v 1.69 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001, 2012, 2014 The NetBSD Foundation, Inc. @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: umidi.c,v 1.68 2015/01/02 20:42:44 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umidi.c,v 1.69 2016/04/23 10:15:32 skrll Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -162,11 +162,11 @@ struct umidi_endpoint { struct umidi_softc *sc; /* */ int addr; - usbd_pipe_handle pipe; - usbd_xfer_handle xfer; + struct usbd_pipe *pipe; + struct usbd_xfer *xfer; umidi_packet_bufp buffer; umidi_packet_bufp next_slot; - u_int32_t buffer_size; + uint32_t buffer_size; int num_scheduled; int num_open; int num_jacks; @@ -174,15 +174,15 @@ struct umidi_endpoint { void *solicit_cookie; int armed; struct umidi_jack *jacks[UMIDI_MAX_EPJACKS]; - u_int16_t this_schedule; /* see UMIDI_MAX_EPJACKS */ - u_int16_t next_schedule; + uint16_t this_schedule; /* see UMIDI_MAX_EPJACKS */ + uint16_t next_schedule; }; /* software context */ struct umidi_softc { device_t sc_dev; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device *sc_udev; + struct usbd_interface *sc_iface; const struct umidi_quirk *sc_quirk; int sc_dying; @@ -278,8 +278,8 @@ static void dump_jack(struct umidi_jack *); static usbd_status start_input_transfer(struct umidi_endpoint *); static usbd_status start_output_transfer(struct umidi_endpoint *); static int out_jack_output(struct umidi_jack *, u_char *, int, int); -static void in_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void out_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); +static void in_intr(struct usbd_xfer *, void *, usbd_status); +static void out_intr(struct usbd_xfer *, void *, usbd_status); static void out_solicit(void *); /* struct umidi_endpoint* for softintr */ static void out_solicit_locked(void *); /* pre-locked version */ @@ -314,29 +314,30 @@ extern struct cfdriver umidi_cd; CFATTACH_DECL2_NEW(umidi, sizeof(struct umidi_softc), umidi_match, umidi_attach, umidi_detach, umidi_activate, NULL, umidi_childdet); -int +int umidi_match(device_t parent, cfdata_t match, void *aux) { - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; DPRINTFN(1,("umidi_match\n")); - if (umidi_search_quirk(uaa->vendor, uaa->product, uaa->ifaceno)) + if (umidi_search_quirk(uiaa->uiaa_vendor, uiaa->uiaa_product, + uiaa->uiaa_ifaceno)) return UMATCH_IFACECLASS_IFACESUBCLASS; - if (uaa->class == UICLASS_AUDIO && - uaa->subclass == UISUBCLASS_MIDISTREAM) + if (uiaa->uiaa_class == UICLASS_AUDIO && + uiaa->uiaa_subclass == UISUBCLASS_MIDISTREAM) return UMATCH_IFACECLASS_IFACESUBCLASS; return UMATCH_NONE; } -void +void umidi_attach(device_t parent, device_t self, void *aux) { usbd_status err; struct umidi_softc *sc = device_private(self); - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; char *devinfop; DPRINTFN(1,("umidi_attach\n")); @@ -346,19 +347,20 @@ umidi_attach(device_t parent, device_t self, void *aux) aprint_naive("\n"); aprint_normal("\n"); - devinfop = usbd_devinfo_alloc(uaa->device, 0); + devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); - sc->sc_iface = uaa->iface; - sc->sc_udev = uaa->device; + sc->sc_iface = uiaa->uiaa_iface; + sc->sc_udev = uiaa->uiaa_device; + + sc->sc_quirk = umidi_search_quirk(uiaa->uiaa_vendor, + uiaa->uiaa_product, uiaa->uiaa_ifaceno); - sc->sc_quirk = - umidi_search_quirk(uaa->vendor, uaa->product, uaa->ifaceno); aprint_normal_dev(self, ""); umidi_print_quirk(sc->sc_quirk); - mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_USB); + mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); cv_init(&sc->sc_cv, "umidopcl"); cv_init(&sc->sc_detach_cv, "umidetcv"); sc->sc_refcnt = 0; @@ -403,7 +405,7 @@ umidi_attach(device_t parent, device_t self, void *aux) out_free_jacks: unbind_all_jacks(sc); free_all_jacks(sc); - + out_free_endpoints: free_all_endpoints(sc); @@ -447,7 +449,7 @@ umidi_activate(device_t self, enum devact act) } } -int +int umidi_detach(device_t self, int flags) { struct umidi_softc *sc = device_private(self); @@ -561,7 +563,7 @@ umidi_channelmsg(void *addr, int status, int channel, u_char *msg, if (!mididev->out_jack || !mididev->opened || mididev->closing) return EIO; - + return out_jack_output(mididev->out_jack, msg, len, (status>>4)&0xf); } @@ -582,7 +584,7 @@ umidi_commonmsg(void *addr, int status, u_char *msg, int len) case 3: cin = 3; break; default: return EIO; /* or gcc warns of cin uninitialized */ } - + return out_jack_output(mididev->out_jack, msg, len, cin); } @@ -603,7 +605,7 @@ umidi_sysex(void *addr, u_char *msg, int len) case 3: cin = (msg[2] == 0xf7) ? 7 : 4; break; default: return EIO; /* or gcc warns of cin uninitialized */ } - + return out_jack_output(mididev->out_jack, msg, len, cin); } @@ -658,13 +660,13 @@ alloc_pipe(struct umidi_endpoint *ep) struct umidi_softc *sc = ep->sc; usbd_status err; usb_endpoint_descriptor_t *epd; - + epd = usbd_get_endpoint_descriptor(sc->sc_iface, ep->addr); /* * For output, an improvement would be to have a buffer bigger than * wMaxPacketSize by num_jacks-1 additional packet slots; that would * allow out_solicit to fill the buffer to the full packet size in - * all cases. But to use usbd_alloc_buffer to get a slightly larger + * all cases. But to use usbd_create_xfer to get a slightly larger * buffer would not be a good way to do that, because if the addition * would make the buffer exceed USB_MEM_SMALL then a substantially * larger block may be wastefully allocated. Some flavor of double @@ -677,27 +679,23 @@ alloc_pipe(struct umidi_endpoint *ep) ep->buffer_size -= ep->buffer_size % UMIDI_PACKET_SIZE; DPRINTF(("%s: alloc_pipe %p, buffer size %u\n", - device_xname(sc->sc_dev), ep, ep->buffer_size)); + device_xname(sc->sc_dev), ep, ep->buffer_size)); ep->num_scheduled = 0; ep->this_schedule = 0; ep->next_schedule = 0; ep->soliciting = 0; ep->armed = 0; - ep->xfer = usbd_alloc_xfer(sc->sc_udev); - if (ep->xfer == NULL) { - err = USBD_NOMEM; - goto quit; - } - ep->buffer = usbd_alloc_buffer(ep->xfer, ep->buffer_size); - if (ep->buffer == NULL) { - usbd_free_xfer(ep->xfer); - err = USBD_NOMEM; - goto quit; - } - ep->next_slot = ep->buffer; err = usbd_open_pipe(sc->sc_iface, ep->addr, USBD_MPSAFE, &ep->pipe); if (err) - usbd_free_xfer(ep->xfer); + goto quit; + int error = usbd_create_xfer(ep->pipe, ep->buffer_size, + USBD_SHORT_XFER_OK, 0, &ep->xfer); + if (error) { + usbd_close_pipe(ep->pipe); + return USBD_NOMEM; + } + ep->buffer = usbd_get_buffer(ep->xfer); + ep->next_slot = ep->buffer; ep->solicit_cookie = softint_establish(SOFTINT_CLOCK | SOFTINT_MPSAFE, out_solicit, ep); quit: return err; @@ -708,8 +706,8 @@ free_pipe(struct umidi_endpoint *ep) { DPRINTF(("%s: free_pipe %p\n", device_xname(ep->sc->sc_dev), ep)); usbd_abort_pipe(ep->pipe); + usbd_destroy_xfer(ep->xfer); usbd_close_pipe(ep->pipe); - usbd_free_xfer(ep->xfer); softint_disestablish(ep->solicit_cookie); } @@ -1058,7 +1056,7 @@ alloc_all_jacks(struct umidi_softc *sc) struct umidi_endpoint *ep; struct umidi_jack *jack; const unsigned char *cn_spec; - + if (UMQ_ISTYPE(sc, UMQ_TYPE_CN_SEQ_PER_EP)) sc->cblnums_global = 0; else if (UMQ_ISTYPE(sc, UMQ_TYPE_CN_SEQ_GLOBAL)) @@ -1078,7 +1076,7 @@ alloc_all_jacks(struct umidi_softc *sc) */ sc->cblnums_global = 1; } - + if (UMQ_ISTYPE(sc, UMQ_TYPE_CN_FIXED)) cn_spec = umidi_get_quirk_data_from_type(sc->sc_quirk, UMQ_TYPE_CN_FIXED); @@ -1216,11 +1214,11 @@ unbind_all_jacks(struct umidi_softc *sc) { int i; - mutex_spin_enter(&sc->sc_lock); + mutex_enter(&sc->sc_lock); if (sc->sc_mididevs) for (i = 0; i < sc->sc_num_mididevs; i++) unbind_jacks_from_mididev(&sc->sc_mididevs[i]); - mutex_spin_exit(&sc->sc_lock); + mutex_exit(&sc->sc_lock); } static usbd_status @@ -1257,7 +1255,7 @@ assign_all_jacks_automatically(struct umidi_softc *sc) ++ asg_spec; } else { out = (i<sc->sc_out_num_jacks) ? &sc->sc_out_jacks[i] - : NULL; + : NULL; in = (i<sc->sc_in_num_jacks) ? &sc->sc_in_jacks[i] : NULL; } @@ -1287,7 +1285,7 @@ open_out_jack(struct umidi_jack *jack, void *arg, void (*intr)(void *)) jack->arg = arg; jack->u.out.intr = intr; jack->midiman_ppkt = NULL; - end = ep->buffer + ep->buffer_size / sizeof *ep->buffer; + end = ep->buffer + ep->buffer_size / sizeof(*ep->buffer); jack->opened = 1; ep->num_open++; /* @@ -1345,7 +1343,7 @@ close_out_jack(struct umidi_jack *jack) { struct umidi_endpoint *ep; struct umidi_softc *sc; - u_int16_t mask; + uint16_t mask; int err; if (jack->opened) { @@ -1389,9 +1387,9 @@ close_in_jack(struct umidi_jack *jack) * the abort operation. This is safe as this * either closing or dying will be set proerly. */ - mutex_spin_exit(&sc->sc_lock); + mutex_exit(&sc->sc_lock); usbd_abort_pipe(jack->endpoint->pipe); - mutex_spin_enter(&sc->sc_lock); + mutex_enter(&sc->sc_lock); } } } @@ -1403,7 +1401,7 @@ attach_mididev(struct umidi_softc *sc, struct umidi_mididev *mididev) return USBD_IN_USE; mididev->sc = sc; - + describe_mididev(mididev); mididev->mdev = midi_attach_mi(&umidi_hw_if, mididev, sc->sc_dev); @@ -1419,16 +1417,16 @@ detach_mididev(struct umidi_mididev *mididev, int flags) if (!sc) return USBD_NO_ADDR; - mutex_spin_enter(&sc->sc_lock); + mutex_enter(&sc->sc_lock); if (mididev->opened) { umidi_close(mididev); } unbind_jacks_from_mididev(mididev); - mutex_spin_exit(&sc->sc_lock); + mutex_exit(&sc->sc_lock); if (mididev->mdev != NULL) config_detach(mididev->mdev, flags); - + if (NULL != mididev->label) { kmem_free(mididev->label, mididev->label_len); mididev->label = NULL; @@ -1544,35 +1542,35 @@ describe_mididev(struct umidi_mididev *md) int show_ep_in; int show_ep_out; size_t len; - + sc = md->sc; show_ep_in = sc-> sc_in_num_endpoints > 1 && !sc->cblnums_global; show_ep_out = sc->sc_out_num_endpoints > 1 && !sc->cblnums_global; - + if (NULL == md->in_jack) in_label[0] = '\0'; else if (show_ep_in) - snprintf(in_label, sizeof in_label, "<%d(%x) ", + snprintf(in_label, sizeof(in_label), "<%d(%x) ", md->in_jack->cable_number, md->in_jack->endpoint->addr); else - snprintf(in_label, sizeof in_label, "<%d ", + snprintf(in_label, sizeof(in_label), "<%d ", md->in_jack->cable_number); - + if (NULL == md->out_jack) out_label[0] = '\0'; else if (show_ep_out) - snprintf(out_label, sizeof out_label, ">%d(%x) ", + snprintf(out_label, sizeof(out_label), ">%d(%x) ", md->out_jack->cable_number, md->out_jack->endpoint->addr); else - snprintf(out_label, sizeof out_label, ">%d ", + snprintf(out_label, sizeof(out_label), ">%d ", md->out_jack->cable_number); unit_label = device_xname(sc->sc_dev); - + len = strlen(in_label) + strlen(out_label) + strlen(unit_label) + 4; - + final_label = kmem_alloc(len, KM_SLEEP); - + snprintf(final_label, len, "%s%son %s", in_label, out_label, unit_label); @@ -1651,11 +1649,8 @@ static const int packet_length[16] = { static usbd_status start_input_transfer(struct umidi_endpoint *ep) { - usbd_setup_xfer(ep->xfer, ep->pipe, - (usbd_private_handle)ep, - ep->buffer, ep->buffer_size, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, in_intr); + usbd_setup_xfer(ep->xfer, ep, ep->buffer, ep->buffer_size, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, in_intr); return usbd_transfer(ep->xfer); } @@ -1663,18 +1658,17 @@ static usbd_status start_output_transfer(struct umidi_endpoint *ep) { usbd_status rv; - u_int32_t length; + uint32_t length; int i; - - length = (ep->next_slot - ep->buffer) * sizeof *ep->buffer; + + length = (ep->next_slot - ep->buffer) * sizeof(*ep->buffer); DPRINTFN(200,("umidi out transfer: start %p end %p length %u\n", ep->buffer, ep->next_slot, length)); - usbd_setup_xfer(ep->xfer, ep->pipe, - (usbd_private_handle)ep, - ep->buffer, length, - USBD_NO_COPY, USBD_NO_TIMEOUT, out_intr); + + usbd_setup_xfer(ep->xfer, ep, ep->buffer, length, 0, + USBD_NO_TIMEOUT, out_intr); rv = usbd_transfer(ep->xfer); - + /* * Once the transfer is scheduled, no more adding to partial * packets within it. @@ -1684,7 +1678,7 @@ start_output_transfer(struct umidi_endpoint *ep) if (NULL != ep->jacks[i]) ep->jacks[i]->midiman_ppkt = NULL; } - + return rv; } @@ -1746,10 +1740,10 @@ out_jack_output(struct umidi_jack *out_jack, u_char *src, int len, int cin) DPRINTFN(100, ("umidi out: %"PRIu64".%06"PRIu64"s ep=%p cn=%d len=%d cin=%#x\n", umidi_tv.tv_sec%100, (uint64_t)umidi_tv.tv_usec, ep, out_jack->cable_number, len, cin)); - + packet = *ep->next_slot++; KASSERT(ep->buffer_size >= - (ep->next_slot - ep->buffer) * sizeof *ep->buffer); + (ep->next_slot - ep->buffer) * sizeof(*ep->buffer)); memset(packet, 0, UMIDI_PACKET_SIZE); if (UMQ_ISTYPE(sc, UMQ_TYPE_MIDIMAN_GARBLE)) { if (NULL != out_jack->midiman_ppkt) { /* fill out a prev pkt */ @@ -1797,12 +1791,12 @@ out_jack_output(struct umidi_jack *out_jack, u_char *src, int len, int cin) if (--sc->sc_refcnt < 0) usb_detach_broadcast(sc->sc_dev, &sc->sc_detach_cv); - + return 0; } static void -in_intr(usbd_xfer_handle xfer, usbd_private_handle priv, +in_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) { int cn, len, i; @@ -1813,26 +1807,26 @@ in_intr(usbd_xfer_handle xfer, usbd_private_handle priv, umidi_packet_bufp slot; umidi_packet_bufp end; unsigned char *data; - u_int32_t count; + uint32_t count; if (ep->sc->sc_dying || !ep->num_open) return; mutex_enter(&sc->sc_lock); usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); - if (0 == count % UMIDI_PACKET_SIZE) { + if (0 == count % UMIDI_PACKET_SIZE) { DPRINTFN(200,("%s: input endpoint %p transfer length %u\n", device_xname(ep->sc->sc_dev), ep, count)); - } else { - DPRINTF(("%s: input endpoint %p odd transfer length %u\n", - device_xname(ep->sc->sc_dev), ep, count)); - } - + } else { + DPRINTF(("%s: input endpoint %p odd transfer length %u\n", + device_xname(ep->sc->sc_dev), ep, count)); + } + slot = ep->buffer; - end = slot + count / sizeof *slot; + end = slot + count / sizeof(*slot); for (packet = *slot; slot < end; packet = *++slot) { - + if (UMQ_ISTYPE(ep->sc, UMQ_TYPE_MIDIMAN_GARBLE)) { cn = (0xf0&(packet[3]))>>4; len = 0x0f&(packet[3]); @@ -1845,7 +1839,7 @@ in_intr(usbd_xfer_handle xfer, usbd_private_handle priv, /* 0 <= cn <= 15 by inspection of above code */ if (!(jack = ep->jacks[cn]) || cn != jack->cable_number) { DPRINTF(("%s: stray input endpoint %p cable %d len %d: " - "%02X %02X %02X (try CN_SEQ quirk?)\n", + "%02X %02X %02X (try CN_SEQ quirk?)\n", device_xname(ep->sc->sc_dev), ep, cn, len, (unsigned)data[0], (unsigned)data[1], @@ -1858,7 +1852,7 @@ in_intr(usbd_xfer_handle xfer, usbd_private_handle priv, continue; DPRINTFN(500,("%s: input endpoint %p cable %d len %d: " - "%02X %02X %02X\n", + "%02X %02X %02X\n", device_xname(ep->sc->sc_dev), ep, cn, len, (unsigned)data[0], (unsigned)data[1], @@ -1877,12 +1871,12 @@ in_intr(usbd_xfer_handle xfer, usbd_private_handle priv, } static void -out_intr(usbd_xfer_handle xfer, usbd_private_handle priv, +out_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct umidi_endpoint *ep = (struct umidi_endpoint *)priv; struct umidi_softc *sc = ep->sc; - u_int32_t count; + uint32_t count; if (sc->sc_dying) return; @@ -1893,16 +1887,16 @@ out_intr(usbd_xfer_handle xfer, usbd_private_handle priv, microtime(&umidi_tv); #endif usbd_get_xfer_status(xfer, NULL, NULL, &count, NULL); - if (0 == count % UMIDI_PACKET_SIZE) { + if (0 == count % UMIDI_PACKET_SIZE) { DPRINTFN(200,("%s: %"PRIu64".%06"PRIu64"s out ep %p xfer length %u\n", device_xname(ep->sc->sc_dev), umidi_tv.tv_sec%100, (uint64_t)umidi_tv.tv_usec, ep, count)); - } else { - DPRINTF(("%s: output endpoint %p odd transfer length %u\n", - device_xname(ep->sc->sc_dev), ep, count)); - } + } else { + DPRINTF(("%s: output endpoint %p odd transfer length %u\n", + device_xname(ep->sc->sc_dev), ep, count)); + } count /= UMIDI_PACKET_SIZE; - + /* * If while the transfer was pending we buffered any new messages, * move them to the start of the buffer. @@ -1947,13 +1941,13 @@ out_solicit_locked(void *arg) { struct umidi_endpoint *ep = arg; umidi_packet_bufp end; - u_int16_t which; + uint16_t which; struct umidi_jack *jack; KASSERT(mutex_owned(&ep->sc->sc_lock)); - - end = ep->buffer + ep->buffer_size / sizeof *ep->buffer; - + + end = ep->buffer + ep->buffer_size / sizeof(*ep->buffer); + for ( ;; ) { if (end - ep->next_slot <= ep->num_open - ep->num_scheduled) break; /* at IPL_USB */ @@ -1985,7 +1979,7 @@ out_solicit_locked(void *arg) which = (((which >> 4) + which) & 0x0f0f); which += (which >> 8); which &= 0x1f; /* the bit index a/k/a jack number */ - + jack = ep->jacks[which]; if (jack->u.out.intr) (*jack->u.out.intr)(jack->arg); diff --git a/sys/dev/usb/umidi_quirks.c b/sys/dev/usb/umidi_quirks.c index 79087f28e53..e772fe40554 100644 --- a/sys/dev/usb/umidi_quirks.c +++ b/sys/dev/usb/umidi_quirks.c @@ -1,4 +1,4 @@ -/* $NetBSD: umidi_quirks.c,v 1.19 2014/12/21 23:00:35 mrg Exp $ */ +/* $NetBSD: umidi_quirks.c,v 1.20 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -30,12 +30,11 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: umidi_quirks.c,v 1.19 2014/12/21 23:00:35 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umidi_quirks.c,v 1.20 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> #include <sys/device.h> #include <sys/ioctl.h> #include <sys/conf.h> @@ -666,7 +665,7 @@ umidi_print_quirk(const struct umidi_quirk *q) } const void * -umidi_get_quirk_data_from_type(const struct umidi_quirk *q, u_int32_t type) +umidi_get_quirk_data_from_type(const struct umidi_quirk *q, uint32_t type) { const struct umq_data *qd; if (q) { diff --git a/sys/dev/usb/umidi_quirks.h b/sys/dev/usb/umidi_quirks.h index d3988702e9f..c50de555094 100644 --- a/sys/dev/usb/umidi_quirks.h +++ b/sys/dev/usb/umidi_quirks.h @@ -1,4 +1,4 @@ -/* $NetBSD: umidi_quirks.h,v 1.8 2008/07/08 11:34:43 gmcgarry Exp $ */ +/* $NetBSD: umidi_quirks.h,v 1.9 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -55,7 +55,7 @@ struct umidi_quirk { int product; int iface; const struct umq_data *quirks; - u_int32_t type_mask; + uint32_t type_mask; }; #define UMQ_ISTYPE(q, type) \ ((q)->sc_quirk && ((q)->sc_quirk->type_mask & (1<<((type)-1)))) @@ -143,6 +143,6 @@ UMQ_TYPE(YAMAHA) /* extern const struct umidi_quirk umidi_quirklist[]; */ const struct umidi_quirk *umidi_search_quirk(int, int, int); void umidi_print_quirk(const struct umidi_quirk *); -const void *umidi_get_quirk_data_from_type(const struct umidi_quirk *, u_int32_t); +const void *umidi_get_quirk_data_from_type(const struct umidi_quirk *, uint32_t); #endif diff --git a/sys/dev/usb/umodem.c b/sys/dev/usb/umodem.c index ed551881730..496806e95be 100644 --- a/sys/dev/usb/umodem.c +++ b/sys/dev/usb/umodem.c @@ -1,4 +1,4 @@ -/* $NetBSD: umodem.c,v 1.67 2015/07/05 15:51:55 skrll Exp $ */ +/* $NetBSD: umodem.c,v 1.68 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -44,7 +44,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: umodem.c,v 1.67 2015/07/05 15:51:55 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umodem.c,v 1.68 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -71,14 +71,14 @@ __KERNEL_RCSID(0, "$NetBSD: umodem.c,v 1.67 2015/07/05 15:51:55 skrll Exp $"); #include <dev/usb/umodemvar.h> Static struct ucom_methods umodem_methods = { - umodem_get_status, - umodem_set, - umodem_param, - umodem_ioctl, - umodem_open, - umodem_close, - NULL, - NULL, + .ucom_get_status = umodem_get_status, + .ucom_set = umodem_set, + .ucom_param = umodem_param, + .ucom_ioctl = umodem_ioctl, + .ucom_open = umodem_open, + .ucom_close = umodem_close, + .ucom_read = NULL, + .ucom_write = NULL, }; int umodem_match(device_t, cfdata_t, void *); @@ -91,40 +91,40 @@ extern struct cfdriver umodem_cd; CFATTACH_DECL_NEW(umodem, sizeof(struct umodem_softc), umodem_match, umodem_attach, umodem_detach, umodem_activate); -int +int umodem_match(device_t parent, cfdata_t match, void *aux) { - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; usb_interface_descriptor_t *id; int cm, acm; - if (uaa->class != UICLASS_CDC || - uaa->subclass != UISUBCLASS_ABSTRACT_CONTROL_MODEL || - !(uaa->proto == UIPROTO_CDC_NOCLASS || uaa->proto == UIPROTO_CDC_AT)) - return (UMATCH_NONE); + if (uiaa->uiaa_class != UICLASS_CDC || + uiaa->uiaa_subclass != UISUBCLASS_ABSTRACT_CONTROL_MODEL || + !(uiaa->uiaa_proto == UIPROTO_CDC_NOCLASS || uiaa->uiaa_proto == UIPROTO_CDC_AT)) + return UMATCH_NONE; - id = usbd_get_interface_descriptor(uaa->iface); - if (umodem_get_caps(uaa->device, &cm, &acm, id) == -1) - return (UMATCH_NONE); + id = usbd_get_interface_descriptor(uiaa->uiaa_iface); + if (umodem_get_caps(uiaa->uiaa_device, &cm, &acm, id) == -1) + return UMATCH_NONE; - return (UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO); + return UMATCH_IFACECLASS_IFACESUBCLASS_IFACEPROTO; } - -void +// +void umodem_attach(device_t parent, device_t self, void *aux) { struct umodem_softc *sc = device_private(self); - struct usbif_attach_arg *uaa = aux; - struct ucom_attach_args uca; + struct usbif_attach_arg *uiaa = aux; + struct ucom_attach_args ucaa; - uca.portno = UCOM_UNK_PORTNO; - uca.methods = &umodem_methods; - uca.info = NULL; + ucaa.ucaa_portno = UCOM_UNK_PORTNO; + ucaa.ucaa_methods = &umodem_methods; + ucaa.ucaa_info = NULL; if (!pmf_device_register(self, NULL, NULL)) aprint_error_dev(self, "couldn't establish power handler"); - if (umodem_common_attach(self, sc, uaa, &uca)) + if (umodem_common_attach(self, sc, uiaa, &ucaa)) return; return; } @@ -137,7 +137,7 @@ umodem_activate(device_t self, enum devact act) return umodem_common_activate(sc, act); } -int +int umodem_detach(device_t self, int flags) { struct umodem_softc *sc = device_private(self); diff --git a/sys/dev/usb/umodem_common.c b/sys/dev/usb/umodem_common.c index 54f55eca62b..b39baf5af13 100644 --- a/sys/dev/usb/umodem_common.c +++ b/sys/dev/usb/umodem_common.c @@ -1,4 +1,4 @@ -/* $NetBSD: umodem_common.c,v 1.22 2010/11/03 22:34:24 dyoung Exp $ */ +/* $NetBSD: umodem_common.c,v 1.23 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -44,7 +44,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: umodem_common.c,v 1.22 2010/11/03 22:34:24 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: umodem_common.c,v 1.23 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -90,22 +90,22 @@ int umodemdebug = 0; #define UMODEMIBUFSIZE 4096 #define UMODEMOBUFSIZE 4096 -Static usbd_status umodem_set_comm_feature(struct umodem_softc *sc, - int feature, int state); -Static usbd_status umodem_set_line_coding(struct umodem_softc *sc, - usb_cdc_line_state_t *state); +Static usbd_status umodem_set_comm_feature(struct umodem_softc *, + int, int); +Static usbd_status umodem_set_line_coding(struct umodem_softc *, + usb_cdc_line_state_t *); Static void umodem_dtr(struct umodem_softc *, int); Static void umodem_rts(struct umodem_softc *, int); Static void umodem_break(struct umodem_softc *, int); Static void umodem_set_line_state(struct umodem_softc *); -Static void umodem_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void umodem_intr(struct usbd_xfer *, void *, usbd_status); int umodem_common_attach(device_t self, struct umodem_softc *sc, - struct usbif_attach_arg *uaa, struct ucom_attach_args *uca) + struct usbif_attach_arg *uiaa, struct ucom_attach_args *ucaa) { - usbd_device_handle dev = uaa->device; + struct usbd_device *dev = uiaa->uiaa_device; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devinfop; @@ -115,13 +115,13 @@ umodem_common_attach(device_t self, struct umodem_softc *sc, sc->sc_dev = self; sc->sc_udev = dev; - sc->sc_ctl_iface = uaa->iface; + sc->sc_ctl_iface = uiaa->uiaa_iface; aprint_naive("\n"); aprint_normal("\n"); id = usbd_get_interface_descriptor(sc->sc_ctl_iface); - devinfop = usbd_devinfo_alloc(uaa->device, 0); + devinfop = usbd_devinfo_alloc(uiaa->uiaa_device, 0); aprint_normal_dev(self, "%s, iclass %d/%d\n", devinfop, id->bInterfaceClass, id->bInterfaceSubClass); usbd_devinfo_free(devinfop); @@ -143,12 +143,12 @@ umodem_common_attach(device_t self, struct umodem_softc *sc, sc->sc_acm_cap & USB_CDC_ACM_HAS_BREAK ? "" : "no "); /* Get the data interface too. */ - for (i = 0; i < uaa->nifaces; i++) { - if (uaa->ifaces[i] != NULL) { - id = usbd_get_interface_descriptor(uaa->ifaces[i]); + for (i = 0; i < uiaa->uiaa_nifaces; i++) { + if (uiaa->uiaa_ifaces[i] != NULL) { + id = usbd_get_interface_descriptor(uiaa->uiaa_ifaces[i]); if (id != NULL && id->bInterfaceNumber == data_ifcno) { - sc->sc_data_iface = uaa->ifaces[i]; - uaa->ifaces[i] = NULL; + sc->sc_data_iface = uiaa->uiaa_ifaces[i]; + uiaa->uiaa_ifaces[i] = NULL; } } } @@ -161,7 +161,7 @@ umodem_common_attach(device_t self, struct umodem_softc *sc, * Find the bulk endpoints. * Iterate over all endpoints in the data interface and take note. */ - uca->bulkin = uca->bulkout = -1; + ucaa->ucaa_bulkin = ucaa->ucaa_bulkout = -1; id = usbd_get_interface_descriptor(sc->sc_data_iface); for (i = 0; i < id->bNumEndpoints; i++) { @@ -173,18 +173,18 @@ umodem_common_attach(device_t self, struct umodem_softc *sc, } if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) { - uca->bulkin = ed->bEndpointAddress; + ucaa->ucaa_bulkin = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) { - uca->bulkout = ed->bEndpointAddress; + ucaa->ucaa_bulkout = ed->bEndpointAddress; } } - if (uca->bulkin == -1) { + if (ucaa->ucaa_bulkin == -1) { aprint_error_dev(self, "Could not find data bulk in\n"); goto bad; } - if (uca->bulkout == -1) { + if (ucaa->ucaa_bulkout == -1) { aprint_error_dev(self, "Could not find data bulk out\n"); goto bad; } @@ -234,20 +234,20 @@ umodem_common_attach(device_t self, struct umodem_softc *sc, sc->sc_dtr = -1; - /* bulkin, bulkout set above */ - uca->ibufsize = UMODEMIBUFSIZE; - uca->obufsize = UMODEMOBUFSIZE; - uca->ibufsizepad = UMODEMIBUFSIZE; - uca->opkthdrlen = 0; - uca->device = sc->sc_udev; - uca->iface = sc->sc_data_iface; - uca->arg = sc; + /* ucaa_bulkin, ucaa_bulkout set above */ + ucaa->ucaa_ibufsize = UMODEMIBUFSIZE; + ucaa->ucaa_obufsize = UMODEMOBUFSIZE; + ucaa->ucaa_ibufsizepad = UMODEMIBUFSIZE; + ucaa->ucaa_opkthdrlen = 0; + ucaa->ucaa_device = sc->sc_udev; + ucaa->ucaa_iface = sc->sc_data_iface; + ucaa->ucaa_arg = sc; usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); DPRINTF(("umodem_common_attach: sc=%p\n", sc)); - sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, uca, + sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, ucaa, ucomprint, ucomsubmatch); return 0; @@ -303,7 +303,7 @@ umodem_close(void *addr, int portno) } Static void -umodem_intr(usbd_xfer_handle xfer, usbd_private_handle priv, +umodem_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct umodem_softc *sc = priv; @@ -366,13 +366,13 @@ umodem_intr(usbd_xfer_handle xfer, usbd_private_handle priv, } int -umodem_get_caps(usbd_device_handle dev, int *cm, int *acm, +umodem_get_caps(struct usbd_device *dev, int *cm, int *acm, usb_interface_descriptor_t *id) { const usb_cdc_cm_descriptor_t *cmd; const usb_cdc_acm_descriptor_t *cad; const usb_cdc_union_descriptor_t *cud; - u_int32_t uq_flags; + uint32_t uq_flags; *cm = *acm = 0; uq_flags = usbd_get_quirks(dev)->uq_flags; @@ -467,9 +467,9 @@ umodem_param(void *addr, int portno, struct termios *t) err = umodem_set_line_coding(sc, &ls); if (err) { DPRINTF(("umodem_param: err=%s\n", usbd_errstr(err))); - return (EPASSTHROUGH); + return EPASSTHROUGH; } - return (0); + return 0; } int @@ -480,7 +480,7 @@ umodem_ioctl(void *addr, int portno, u_long cmd, void *data, int error = 0; if (sc->sc_dying) - return (EIO); + return EIO; DPRINTF(("umodem_ioctl: cmd=0x%08lx\n", cmd)); @@ -501,7 +501,7 @@ umodem_ioctl(void *addr, int portno, u_long cmd, void *data, break; } - return (error); + return error; } void @@ -597,7 +597,7 @@ umodem_set_line_coding(struct umodem_softc *sc, usb_cdc_line_state_t *state) if (memcmp(state, &sc->sc_line_state, UCDC_LINE_STATE_LENGTH) == 0) { DPRINTF(("umodem_set_line_coding: already set\n")); - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } req.bmRequestType = UT_WRITE_CLASS_INTERFACE; @@ -610,12 +610,12 @@ umodem_set_line_coding(struct umodem_softc *sc, usb_cdc_line_state_t *state) if (err) { DPRINTF(("umodem_set_line_coding: failed, err=%s\n", usbd_errstr(err))); - return (err); + return err; } sc->sc_line_state = *state; - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } usbd_status @@ -639,10 +639,10 @@ umodem_set_comm_feature(struct umodem_softc *sc, int feature, int state) if (err) { DPRINTF(("umodem_set_comm_feature: feature=%d, err=%s\n", feature, usbd_errstr(err))); - return (err); + return err; } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } int @@ -679,5 +679,5 @@ umodem_common_detach(struct umodem_softc *sc, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - return (rv); + return rv; } diff --git a/sys/dev/usb/umodemvar.h b/sys/dev/usb/umodemvar.h index bede4fcfc30..2069149e0ac 100644 --- a/sys/dev/usb/umodemvar.h +++ b/sys/dev/usb/umodemvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: umodemvar.h,v 1.8 2010/11/03 22:34:24 dyoung Exp $ */ +/* $NetBSD: umodemvar.h,v 1.9 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -33,12 +33,12 @@ struct umodem_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; /* USB device */ + struct usbd_device * sc_udev; /* USB device */ int sc_ctl_iface_no; - usbd_interface_handle sc_ctl_iface; /* control interface */ + struct usbd_interface * sc_ctl_iface; /* control interface */ int sc_data_iface_no; - usbd_interface_handle sc_data_iface; /* data interface */ + struct usbd_interface * sc_data_iface; /* data interface */ int sc_cm_cap; /* CM capabilities */ int sc_acm_cap; /* ACM capabilities */ @@ -55,7 +55,7 @@ struct umodem_softc { u_char sc_dying; /* disconnecting */ int sc_ctl_notify; /* Notification endpoint */ - usbd_pipe_handle sc_notify_pipe; /* Notification pipe */ + struct usbd_pipe * sc_notify_pipe; /* Notification pipe */ usb_cdc_notification_t sc_notify_buf; /* Notification structure */ u_char sc_lsr; /* Local status register */ u_char sc_msr; /* Modem status register */ @@ -65,14 +65,14 @@ void umodem_common_childdet(struct umodem_softc *, device_t); int umodem_common_attach(device_t, struct umodem_softc *, struct usbif_attach_arg *, struct ucom_attach_args *); -int umodem_get_caps(usbd_device_handle, int *, int *, +int umodem_get_caps(struct usbd_device *, int *, int *, usb_interface_descriptor_t *); -void umodem_get_status(void *, int portno, u_char *lsr, u_char *msr); +void umodem_get_status(void *, int, u_char *, u_char *); void umodem_set(void *, int, int, int); int umodem_param(void *, int, struct termios *); int umodem_ioctl(void *, int, u_long, void *, int, proc_t *); -int umodem_open(void *, int portno); -void umodem_close(void *, int portno); +int umodem_open(void *, int); +void umodem_close(void *, int); int umodem_common_activate(struct umodem_softc *, enum devact); int umodem_common_detach(struct umodem_softc *, int); diff --git a/sys/dev/usb/ums.c b/sys/dev/usb/ums.c index 610a0473d1f..376c6253c63 100644 --- a/sys/dev/usb/ums.c +++ b/sys/dev/usb/ums.c @@ -1,4 +1,4 @@ -/* $NetBSD: ums.c,v 1.88 2016/01/25 18:37:38 christos Exp $ */ +/* $NetBSD: ums.c,v 1.89 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -35,12 +35,11 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ums.c,v 1.88 2016/01/25 18:37:38 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ums.c,v 1.89 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> #include <sys/device.h> #include <sys/ioctl.h> #include <sys/file.h> @@ -103,7 +102,7 @@ struct ums_softc { int nbuttons; - u_int32_t sc_buttons; /* mouse button status */ + uint32_t sc_buttons; /* mouse button status */ device_t sc_wsmousedev; char sc_dying; @@ -121,11 +120,11 @@ static const struct { #define MOUSE_FLAGS_MASK (HIO_CONST|HIO_RELATIVE) -Static void ums_intr(struct uhidev *addr, void *ibuf, u_int len); +Static void ums_intr(struct uhidev *, void *, u_int); Static int ums_enable(void *); Static void ums_disable(void *); -Static int ums_ioctl(void *, u_long, void *, int, struct lwp * ); +Static int ums_ioctl(void *, u_long, void *, int, struct lwp *); const struct wsmouse_accessops ums_accessops = { ums_enable, @@ -153,9 +152,9 @@ ums_match(device_t parent, cfdata_t match, void *aux) * Some (older) Griffin PowerMate knobs may masquerade as a * mouse, avoid treating them as such, they have only one axis. */ - if (uha->uaa->vendor == USB_VENDOR_GRIFFIN && - uha->uaa->product == USB_PRODUCT_GRIFFIN_POWERMATE) - return (UMATCH_NONE); + if (uha->uiaa->uiaa_vendor == USB_VENDOR_GRIFFIN && + uha->uiaa->uiaa_product == USB_PRODUCT_GRIFFIN_POWERMATE) + return UMATCH_NONE; uhidev_get_report_desc(uha->parent, &desc, &size); if (!hid_is_collection(desc, size, uha->reportid, @@ -163,10 +162,10 @@ ums_match(device_t parent, cfdata_t match, void *aux) !hid_is_collection(desc, size, uha->reportid, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_POINTER)) && !hid_is_collection(desc, size, uha->reportid, - HID_USAGE2(HUP_DIGITIZERS, 0x0002))) - return (UMATCH_NONE); + HID_USAGE2(HUP_DIGITIZERS, 0x0002))) + return UMATCH_NONE; - return (UMATCH_IFACECLASS); + return UMATCH_IFACECLASS; } void @@ -177,7 +176,7 @@ ums_attach(device_t parent, device_t self, void *aux) struct wsmousedev_attach_args a; int size; void *desc; - u_int32_t flags, quirks; + uint32_t flags, quirks; int i, hl; struct hid_location *zloc; bool isdigitizer; @@ -300,7 +299,7 @@ ums_attach(device_t parent, device_t self, void *aux) } } - if (uha->uaa->vendor == USB_VENDOR_MICROSOFT) { + if (uha->uiaa->uiaa_vendor == USB_VENDOR_MICROSOFT) { int fixpos; /* * The Microsoft Wireless Laser Mouse 6000 v2.0 and the @@ -308,7 +307,7 @@ ums_attach(device_t parent, device_t self, void *aux) * the wheel and wheel tilt controls -- should be in bytes * 3 & 4 of the report. Fix this if necessary. */ - switch (uha->uaa->product) { + switch (uha->uiaa->uiaa_product) { case USB_PRODUCT_MICROSOFT_24GHZ_XCVR10: case USB_PRODUCT_MICROSOFT_24GHZ_XCVR20: fixpos = 24; @@ -424,7 +423,7 @@ ums_detach(device_t self, int flags) pmf_device_deregister(self); - return (rv); + return rv; } void @@ -432,7 +431,7 @@ ums_intr(struct uhidev *addr, void *ibuf, u_int len) { struct ums_softc *sc = (struct ums_softc *)addr; int dx, dy, dz, dw; - u_int32_t buttons = 0; + uint32_t buttons = 0; int i, flags, s; DPRINTFN(5,("ums_intr: len=%d\n", len)); @@ -477,10 +476,10 @@ ums_enable(void *v) DPRINTFN(1,("ums_enable: sc=%p\n", sc)); if (sc->sc_dying) - return (EIO); + return EIO; if (sc->sc_enabled) - return (EBUSY); + return EBUSY; sc->sc_enabled = 1; sc->sc_buttons = 0; @@ -524,8 +523,8 @@ ums_ioctl(void *v, u_long cmd, void *data, int flag, *(u_int *)data = WSMOUSE_TYPE_TPANEL; else *(u_int *)data = WSMOUSE_TYPE_USB; - return (0); + return 0; } - return (EPASSTHROUGH); + return EPASSTHROUGH; } diff --git a/sys/dev/usb/uplcom.c b/sys/dev/usb/uplcom.c index 902b06d292e..1934057e744 100644 --- a/sys/dev/usb/uplcom.c +++ b/sys/dev/usb/uplcom.c @@ -1,4 +1,4 @@ -/* $NetBSD: uplcom.c,v 1.76 2015/11/01 21:31:40 skrll Exp $ */ +/* $NetBSD: uplcom.c,v 1.77 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. * All rights reserved. @@ -34,12 +34,12 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uplcom.c,v 1.76 2015/11/01 21:31:40 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uplcom.c,v 1.77 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/ioctl.h> #include <sys/conf.h> #include <sys/tty.h> @@ -84,13 +84,13 @@ enum pl2303_type { struct uplcom_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; /* USB device */ - usbd_interface_handle sc_iface; /* interface */ + struct usbd_device * sc_udev; /* USB device */ + struct usbd_interface * sc_iface; /* interface */ int sc_iface_number; /* interface number */ - usbd_interface_handle sc_intr_iface; /* interrupt interface */ + struct usbd_interface * sc_intr_iface; /* interrupt interface */ int sc_intr_number; /* interrupt number */ - usbd_pipe_handle sc_intr_pipe; /* interrupt pipe */ + struct usbd_pipe * sc_intr_pipe; /* interrupt pipe */ u_char *sc_intr_buf; /* interrupt buffer */ int sc_isize; @@ -116,34 +116,34 @@ struct uplcom_softc { #define UPLCOMOBUFSIZE 256 Static usbd_status uplcom_reset(struct uplcom_softc *); -Static usbd_status uplcom_set_line_coding(struct uplcom_softc *sc, - usb_cdc_line_state_t *state); +Static usbd_status uplcom_set_line_coding(struct uplcom_softc *, + usb_cdc_line_state_t *); Static usbd_status uplcom_set_crtscts(struct uplcom_softc *); -Static void uplcom_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void uplcom_intr(struct usbd_xfer *, void *, usbd_status); Static void uplcom_set(void *, int, int, int); Static void uplcom_dtr(struct uplcom_softc *, int); Static void uplcom_rts(struct uplcom_softc *, int); Static void uplcom_break(struct uplcom_softc *, int); Static void uplcom_set_line_state(struct uplcom_softc *); -Static void uplcom_get_status(void *, int portno, u_char *lsr, u_char *msr); +Static void uplcom_get_status(void *, int, u_char *, u_char *); #if TODO Static int uplcom_ioctl(void *, int, u_long, void *, int, proc_t *); #endif Static int uplcom_param(void *, int, struct termios *); Static int uplcom_open(void *, int); Static void uplcom_close(void *, int); -Static usbd_status uplcom_vendor_control_write(usbd_device_handle, u_int16_t, u_int16_t); +Static usbd_status uplcom_vendor_control_write(struct usbd_device *, uint16_t, uint16_t); struct ucom_methods uplcom_methods = { - uplcom_get_status, - uplcom_set, - uplcom_param, - NULL, /* uplcom_ioctl, TODO */ - uplcom_open, - uplcom_close, - NULL, - NULL, + .ucom_get_status = uplcom_get_status, + .ucom_set = uplcom_set, + .ucom_param = uplcom_param, + .ucom_ioctl = NULL, /* TODO */ + .ucom_open = uplcom_open, + .ucom_close = uplcom_close, + .ucom_read = NULL, + .ucom_write = NULL, }; static const struct usb_devno uplcom_devs[] = { @@ -205,21 +205,21 @@ extern struct cfdriver uplcom_cd; CFATTACH_DECL2_NEW(uplcom, sizeof(struct uplcom_softc), uplcom_match, uplcom_attach, uplcom_detach, uplcom_activate, NULL, uplcom_childdet); -int +int uplcom_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (uplcom_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return uplcom_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } -void +void uplcom_attach(device_t parent, device_t self, void *aux) { struct uplcom_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; + struct usbd_device *dev = uaa->uaa_device; usb_device_descriptor_t *ddesc; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; @@ -228,7 +228,7 @@ uplcom_attach(device_t parent, device_t self, void *aux) const char *devname = device_xname(self); usbd_status err; int i; - struct ucom_attach_args uca; + struct ucom_attach_args ucaa; sc->sc_dev = self; @@ -239,12 +239,12 @@ uplcom_attach(device_t parent, device_t self, void *aux) aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); - sc->sc_udev = dev; + sc->sc_udev = dev; DPRINTF(("\n\nuplcom attach: sc=%p\n", sc)); /* initialize endpoints */ - uca.bulkin = uca.bulkout = -1; + ucaa.ucaa_bulkin = ucaa.ucaa_bulkout = -1; sc->sc_intr_number = -1; sc->sc_intr_pipe = NULL; @@ -370,37 +370,37 @@ uplcom_attach(device_t parent, device_t self, void *aux) if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - uca.bulkin = ed->bEndpointAddress; + ucaa.ucaa_bulkin = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - uca.bulkout = ed->bEndpointAddress; + ucaa.ucaa_bulkout = ed->bEndpointAddress; } } - if (uca.bulkin == -1) { + if (ucaa.ucaa_bulkin == -1) { aprint_error_dev(self, "Could not find data bulk in\n"); sc->sc_dying = 1; return; } - if (uca.bulkout == -1) { + if (ucaa.ucaa_bulkout == -1) { aprint_error_dev(self, "Could not find data bulk out\n"); sc->sc_dying = 1; return; } sc->sc_dtr = sc->sc_rts = -1; - uca.portno = UCOM_UNK_PORTNO; - /* bulkin, bulkout set above */ - uca.ibufsize = UPLCOMIBUFSIZE; - uca.obufsize = UPLCOMOBUFSIZE; - uca.ibufsizepad = UPLCOMIBUFSIZE; - uca.opkthdrlen = 0; - uca.device = dev; - uca.iface = sc->sc_iface; - uca.methods = &uplcom_methods; - uca.arg = sc; - uca.info = NULL; + ucaa.ucaa_portno = UCOM_UNK_PORTNO; + /* ucaa_bulkin, ucaa_bulkout set above */ + ucaa.ucaa_ibufsize = UPLCOMIBUFSIZE; + ucaa.ucaa_obufsize = UPLCOMOBUFSIZE; + ucaa.ucaa_ibufsizepad = UPLCOMIBUFSIZE; + ucaa.ucaa_opkthdrlen = 0; + ucaa.ucaa_device = dev; + ucaa.ucaa_iface = sc->sc_iface; + ucaa.ucaa_methods = &uplcom_methods; + ucaa.ucaa_arg = sc; + ucaa.ucaa_info = NULL; err = uplcom_reset(sc); @@ -414,8 +414,8 @@ uplcom_attach(device_t parent, device_t self, void *aux) sc->sc_dev); DPRINTF(("uplcom: in=0x%x out=0x%x intr=0x%x\n", - uca.bulkin, uca.bulkout, sc->sc_intr_number )); - sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &uca, + ucaa.ucaa_bulkin, ucaa.ucaa_bulkout, sc->sc_intr_number )); + sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &ucaa, ucomprint, ucomsubmatch); if (!pmf_device_register(self, NULL, NULL)) @@ -433,7 +433,7 @@ uplcom_childdet(device_t self, device_t child) sc->sc_subdev = NULL; } -int +int uplcom_detach(device_t self, int flags) { struct uplcom_softc *sc = device_private(self); @@ -441,12 +441,12 @@ uplcom_detach(device_t self, int flags) DPRINTF(("uplcom_detach: sc=%p flags=%d\n", sc, flags)); - if (sc->sc_intr_pipe != NULL) { - usbd_abort_pipe(sc->sc_intr_pipe); - usbd_close_pipe(sc->sc_intr_pipe); - free(sc->sc_intr_buf, M_USBDEV); - sc->sc_intr_pipe = NULL; - } + if (sc->sc_intr_pipe != NULL) { + usbd_abort_pipe(sc->sc_intr_pipe); + usbd_close_pipe(sc->sc_intr_pipe); + kmem_free(sc->sc_intr_buf, sc->sc_isize); + sc->sc_intr_pipe = NULL; + } sc->sc_dying = 1; if (sc->sc_subdev != NULL) @@ -458,7 +458,7 @@ uplcom_detach(device_t self, int flags) if (rv == 0) pmf_device_deregister(self); - return (rv); + return rv; } int @@ -481,17 +481,17 @@ uplcom_reset(struct uplcom_softc *sc) usb_device_request_t req; usbd_status err; - req.bmRequestType = UT_WRITE_VENDOR_DEVICE; - req.bRequest = UPLCOM_SET_REQUEST; - USETW(req.wValue, 0); - USETW(req.wIndex, sc->sc_iface_number); - USETW(req.wLength, 0); + req.bmRequestType = UT_WRITE_VENDOR_DEVICE; + req.bRequest = UPLCOM_SET_REQUEST; + USETW(req.wValue, 0); + USETW(req.wIndex, sc->sc_iface_number); + USETW(req.wLength, 0); - err = usbd_do_request(sc->sc_udev, &req, 0); + err = usbd_do_request(sc->sc_udev, &req, 0); if (err) - return (EIO); + return EIO; - return (0); + return 0; } struct pl2303x_init { @@ -544,11 +544,11 @@ uplcom_pl2303x_init(struct uplcom_softc *sc) aprint_error_dev(sc->sc_dev, "uplcom_pl2303x_init failed: %s\n", usbd_errstr(err)); - return (EIO); + return EIO; } } - return (0); + return 0; } void @@ -659,10 +659,10 @@ uplcom_set_crtscts(struct uplcom_softc *sc) if (err) { DPRINTF(("uplcom_set_crtscts: failed, err=%s\n", usbd_errstr(err))); - return (err); + return err; } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } usbd_status @@ -677,7 +677,7 @@ uplcom_set_line_coding(struct uplcom_softc *sc, usb_cdc_line_state_t *state) if (memcmp(state, &sc->sc_line_state, UCDC_LINE_STATE_LENGTH) == 0) { DPRINTF(("uplcom_set_line_coding: already set\n")); - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } req.bmRequestType = UT_WRITE_CLASS_INTERFACE; @@ -690,12 +690,12 @@ uplcom_set_line_coding(struct uplcom_softc *sc, usb_cdc_line_state_t *state) if (err) { DPRINTF(("uplcom_set_line_coding: failed, err=%s\n", usbd_errstr(err))); - return (err); + return err; } sc->sc_line_state = *state; - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } int @@ -737,7 +737,7 @@ uplcom_param(void *addr, int portno, struct termios *t) err = uplcom_set_line_coding(sc, &ls); if (err) { DPRINTF(("uplcom_param: err=%s\n", usbd_errstr(err))); - return (EIO); + return EIO; } if (ISSET(t->c_cflag, CRTSCTS)) @@ -748,14 +748,14 @@ uplcom_param(void *addr, int portno, struct termios *t) if (err) { DPRINTF(("uplcom_param: err=%s\n", usbd_errstr(err))); - return (EIO); + return EIO; } - return (0); + return 0; } Static usbd_status -uplcom_vendor_control_write(usbd_device_handle dev, u_int16_t value, u_int16_t index) +uplcom_vendor_control_write(struct usbd_device *dev, uint16_t value, uint16_t index) { usb_device_request_t req; usbd_status err; @@ -783,7 +783,7 @@ uplcom_open(void *addr, int portno) usbd_status err; if (sc->sc_dying) - return (EIO); + return EIO; DPRINTF(("uplcom_open: sc=%p\n", sc)); @@ -792,9 +792,9 @@ uplcom_open(void *addr, int portno) uplcom_vendor_control_write(sc->sc_udev, 2, 0x44); else uplcom_vendor_control_write(sc->sc_udev, 2, 0x24); - + if (sc->sc_intr_number != -1 && sc->sc_intr_pipe == NULL) { - sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK); + sc->sc_intr_buf = kmem_alloc(sc->sc_isize, KM_SLEEP); err = usbd_open_pipe_intr(sc->sc_intr_iface, sc->sc_intr_number, USBD_SHORT_XFER_OK, &sc->sc_intr_pipe, sc, sc->sc_intr_buf, sc->sc_isize, @@ -802,14 +802,14 @@ uplcom_open(void *addr, int portno) if (err) { DPRINTF(("%s: cannot open interrupt pipe (addr %d)\n", device_xname(sc->sc_dev), sc->sc_intr_number)); - return (EIO); + return EIO; } } if (sc->sc_type == UPLCOM_TYPE_HX) - return (uplcom_pl2303x_init(sc)); + return uplcom_pl2303x_init(sc); - return (0); + return 0; } void @@ -832,13 +832,13 @@ uplcom_close(void *addr, int portno) if (err) printf("%s: close interrupt pipe failed: %s\n", device_xname(sc->sc_dev), usbd_errstr(err)); - free(sc->sc_intr_buf, M_USBDEV); + kmem_free(sc->sc_intr_buf, sc->sc_isize); sc->sc_intr_pipe = NULL; } } void -uplcom_intr(usbd_xfer_handle xfer, usbd_private_handle priv, +uplcom_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct uplcom_softc *sc = priv; @@ -895,7 +895,7 @@ uplcom_ioctl(void *addr, int portno, u_long cmd, void *data, int flag, int error = 0; if (sc->sc_dying) - return (EIO); + return EIO; DPRINTF(("uplcom_ioctl: cmd=0x%08lx\n", cmd)); @@ -913,6 +913,6 @@ uplcom_ioctl(void *addr, int portno, u_long cmd, void *data, int flag, break; } - return (error); + return error; } #endif diff --git a/sys/dev/usb/urio.c b/sys/dev/usb/urio.c index 40d112a0747..5d25a983374 100644 --- a/sys/dev/usb/urio.c +++ b/sys/dev/usb/urio.c @@ -1,4 +1,4 @@ -/* $NetBSD: urio.c,v 1.42 2014/07/25 08:10:39 dholland Exp $ */ +/* $NetBSD: urio.c,v 1.43 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -36,12 +36,12 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: urio.c,v 1.42 2014/07/25 08:10:39 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: urio.c,v 1.43 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/device.h> #include <sys/ioctl.h> #include <sys/conf.h> @@ -98,13 +98,13 @@ const struct cdevsw urio_cdevsw = { struct urio_softc { device_t sc_dev; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device * sc_udev; + struct usbd_interface * sc_iface; int sc_in_addr; - usbd_pipe_handle sc_in_pipe; + struct usbd_pipe * sc_in_pipe; int sc_out_addr; - usbd_pipe_handle sc_out_pipe; + struct usbd_pipe * sc_out_pipe; int sc_refcnt; char sc_dying; @@ -129,28 +129,28 @@ int urio_activate(device_t, enum devact); extern struct cfdriver urio_cd; CFATTACH_DECL_NEW(urio, sizeof(struct urio_softc), urio_match, urio_attach, urio_detach, urio_activate); -int +int urio_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; DPRINTFN(50,("urio_match\n")); - return (urio_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return urio_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } -void +void urio_attach(device_t parent, device_t self, void *aux) { struct urio_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface; + struct usbd_device * dev = uaa->uaa_device; + struct usbd_interface * iface; char *devinfop; usbd_status err; usb_endpoint_descriptor_t *ed; - u_int8_t epcount; + uint8_t epcount; int i; DPRINTFN(10,("urio_attach: sc=%p\n", sc)); @@ -212,7 +212,7 @@ urio_attach(device_t parent, device_t self, void *aux) return; } -int +int urio_detach(device_t self, int flags) { struct urio_softc *sc = device_private(self); @@ -251,7 +251,7 @@ urio_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - return (0); + return 0; } int @@ -282,25 +282,25 @@ urioopen(dev_t dev, int flag, int mode, struct lwp *l) flag, mode, URIOUNIT(dev))); if (sc->sc_dying) - return (EIO); + return EIO; if (sc->sc_in_pipe != NULL) - return (EBUSY); + return EBUSY; if ((flag & (FWRITE|FREAD)) != (FWRITE|FREAD)) - return (EACCES); + return EACCES; err = usbd_open_pipe(sc->sc_iface, sc->sc_in_addr, 0, &sc->sc_in_pipe); if (err) - return (EIO); + return EIO; err = usbd_open_pipe(sc->sc_iface, sc->sc_out_addr,0,&sc->sc_out_pipe); if (err) { usbd_close_pipe(sc->sc_in_pipe); sc->sc_in_pipe = NULL; - return (EIO); + return EIO; } - return (0); + return 0; } int @@ -324,17 +324,17 @@ urioclose(dev_t dev, int flag, int mode, sc->sc_out_pipe = NULL; } - return (0); + return 0; } int urioread(dev_t dev, struct uio *uio, int flag) { struct urio_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; usbd_status err; void *bufp; - u_int32_t n, tn; + uint32_t n, tn; int error = 0; sc = device_lookup_private(&urio_cd, URIOUNIT(dev)); @@ -342,24 +342,21 @@ urioread(dev_t dev, struct uio *uio, int flag) DPRINTFN(5, ("urioread: %d\n", URIOUNIT(dev))); if (sc->sc_dying) - return (EIO); - - xfer = usbd_alloc_xfer(sc->sc_udev); - if (xfer == NULL) - return (ENOMEM); - bufp = usbd_alloc_buffer(xfer, URIO_BSIZE); - if (bufp == NULL) { - usbd_free_xfer(xfer); - return (ENOMEM); + return EIO; + + error = usbd_create_xfer(sc->sc_in_pipe, URIO_BSIZE, 0, 0, &xfer); + if (error) { + return error; } + bufp = usbd_get_buffer(xfer); sc->sc_refcnt++; while ((n = min(URIO_BSIZE, uio->uio_resid)) != 0) { DPRINTFN(1, ("urioread: start transfer %d bytes\n", n)); tn = n; - err = usbd_bulk_transfer(xfer, sc->sc_in_pipe, USBD_NO_COPY, - URIO_RW_TIMEOUT, bufp, &tn, "uriors"); + err = usbd_bulk_transfer(xfer, sc->sc_in_pipe, 0, + URIO_RW_TIMEOUT, bufp, &tn); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; @@ -376,22 +373,22 @@ urioread(dev_t dev, struct uio *uio, int flag) if (error || tn < n) break; } - usbd_free_xfer(xfer); + usbd_destroy_xfer(xfer); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); - return (error); + return error; } int uriowrite(dev_t dev, struct uio *uio, int flag) { struct urio_softc *sc; - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; usbd_status err; void *bufp; - u_int32_t n; + uint32_t n; int error = 0; sc = device_lookup_private(&urio_cd, URIOUNIT(dev)); @@ -400,17 +397,13 @@ uriowrite(dev_t dev, struct uio *uio, int flag) (long)uio->uio_resid)); if (sc->sc_dying) - return (EIO); - - xfer = usbd_alloc_xfer(sc->sc_udev); - if (xfer == NULL) - return (ENOMEM); - bufp = usbd_alloc_buffer(xfer, URIO_BSIZE); - if (bufp == NULL) { - usbd_free_xfer(xfer); - return (ENOMEM); - } + return EIO; + error = usbd_create_xfer(sc->sc_out_pipe, URIO_BSIZE, 0, 0, &xfer); + if (error) { + return error; + } + bufp = usbd_get_buffer(xfer); sc->sc_refcnt++; while ((n = min(URIO_BSIZE, uio->uio_resid)) != 0) { @@ -420,8 +413,8 @@ uriowrite(dev_t dev, struct uio *uio, int flag) DPRINTFN(1, ("uriowrite: transfer %d bytes\n", n)); - err = usbd_bulk_transfer(xfer, sc->sc_out_pipe, USBD_NO_COPY, - URIO_RW_TIMEOUT, bufp, &n, "uriowr"); + err = usbd_bulk_transfer(xfer, sc->sc_out_pipe, 0, + URIO_RW_TIMEOUT, bufp, &n); DPRINTFN(2, ("uriowrite: err=%d\n", err)); if (err) { if (err == USBD_INTERRUPTED) @@ -434,7 +427,7 @@ uriowrite(dev_t dev, struct uio *uio, int flag) } } - usbd_free_xfer(xfer); + usbd_destroy_xfer(xfer); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); @@ -442,7 +435,7 @@ uriowrite(dev_t dev, struct uio *uio, int flag) DPRINTFN(5, ("uriowrite: done unit=%d, error=%d\n", URIOUNIT(dev), error)); - return (error); + return error; } @@ -458,14 +451,14 @@ urioioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) usb_device_request_t req; usbd_status err; int req_flags = 0; - u_int32_t req_actlen = 0; + uint32_t req_actlen = 0; void *ptr = NULL; int error = 0; sc = device_lookup_private(&urio_cd, unit); if (sc->sc_dying) - return (EIO); + return EIO; rcmd = (struct urio_command *)addr; @@ -479,12 +472,12 @@ urioioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) break; default: - return (EINVAL); + return EINVAL; break; } if (!(flag & FWRITE)) - return (EPERM); + return EPERM; len = rcmd->length; DPRINTFN(1,("urio_ioctl: cmd=0x%08lx reqtype=0x%0x req=0x%0x " @@ -500,7 +493,7 @@ urioioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) USETW(req.wLength, len); if (len < 0 || len > 32767) - return (EINVAL); + return EINVAL; if (len != 0) { iov.iov_base = (void *)rcmd->buffer; iov.iov_len = len; @@ -511,7 +504,7 @@ urioioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) uio.uio_rw = req.bmRequestType & UT_READ ? UIO_READ : UIO_WRITE; uio.uio_vmspace = l->l_proc->p_vmspace; - ptr = malloc(len, M_TEMP, M_WAITOK); + ptr = kmem_alloc(len, KM_SLEEP); if (uio.uio_rw == UIO_WRITE) { error = uiomove(ptr, len, &uio); if (error) @@ -536,6 +529,6 @@ urioioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) ret: if (ptr != NULL) - free(ptr, M_TEMP); - return (error); + kmem_free(ptr, len); + return error; } diff --git a/sys/dev/usb/urio.h b/sys/dev/usb/urio.h index 6f5cc060891..f1258600d6a 100644 --- a/sys/dev/usb/urio.h +++ b/sys/dev/usb/urio.h @@ -1,4 +1,4 @@ -/* $NetBSD: urio.h,v 1.4 2015/09/06 06:01:01 dholland Exp $ */ +/* $NetBSD: urio.h,v 1.5 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. diff --git a/sys/dev/usb/usb.c b/sys/dev/usb/usb.c index 2aa3fb4e67b..d807b3a3207 100644 --- a/sys/dev/usb/usb.c +++ b/sys/dev/usb/usb.c @@ -1,4 +1,4 @@ -/* $NetBSD: usb.c,v 1.161 2016/01/06 22:12:49 skrll Exp $ */ +/* $NetBSD: usb.c,v 1.162 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998, 2002, 2008, 2012 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.161 2016/01/06 22:12:49 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.162 2016/04/23 10:15:32 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -47,7 +47,7 @@ __KERNEL_RCSID(0, "$NetBSD: usb.c,v 1.161 2016/01/06 22:12:49 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/device.h> #include <sys/kthread.h> #include <sys/proc.h> @@ -87,9 +87,6 @@ USBHIST_DEFINE(usbhist) = KERNHIST_INITIALIZER(usbhist, usbhistbuf); #define USB_DEV_MINOR 255 #ifdef USB_DEBUG -#define DPRINTF(x) if (usbdebug) printf x -#define DPRINTFN(n,x) if (usbdebug>(n)) printf x -int usbdebug = 0; /* * 0 - do usual exploration * 1 - do not use timeout exploration @@ -97,6 +94,7 @@ int usbdebug = 0; */ int usb_noexplore = 0; +int usbdebug = 0; SYSCTL_SETUP(sysctl_hw_usb_setup, "sysctl hw.usb setup") { int err; @@ -123,18 +121,18 @@ SYSCTL_SETUP(sysctl_hw_usb_setup, "sysctl hw.usb setup") fail: aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); } - #else -#define DPRINTF(x) -#define DPRINTFN(n,x) #define usb_noexplore 0 #endif +#define DPRINTF(FMT,A,B,C,D) USBHIST_LOG(usbdebug,FMT,A,B,C,D) +#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(usbdebug,N,FMT,A,B,C,D) + struct usb_softc { #if 0 device_t sc_dev; /* base device */ #endif - usbd_bus_handle sc_bus; /* USB controller */ + struct usbd_bus *sc_bus; /* USB controller */ struct usbd_port sc_port; /* dummy port for root hub */ struct lwp *sc_event_thread; @@ -225,8 +223,9 @@ static const char *taskq_names[] = USB_TASKQ_NAMES; int usb_match(device_t parent, cfdata_t match, void *aux) { - DPRINTF(("usbd_match\n")); - return (UMATCH_GENERIC); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + return UMATCH_GENERIC; } void @@ -237,7 +236,7 @@ usb_attach(device_t parent, device_t self, void *aux) int usbrev; sc->sc_bus = aux; - usbrev = sc->sc_bus->usbrev; + usbrev = sc->sc_bus->ub_revision; aprint_naive("\n"); aprint_normal(": USB revision %s", usbrev_str[usbrev]); @@ -255,17 +254,17 @@ usb_attach(device_t parent, device_t self, void *aux) aprint_normal("\n"); /* XXX we should have our own level */ - sc->sc_bus->soft = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE, + sc->sc_bus->ub_soft = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE, usb_soft_intr, sc->sc_bus); - if (sc->sc_bus->soft == NULL) { + if (sc->sc_bus->ub_soft == NULL) { aprint_error("%s: can't register softintr\n", device_xname(self)); sc->sc_dying = 1; return; } - sc->sc_bus->methods->get_lock(sc->sc_bus, &sc->sc_bus->lock); - KASSERT(sc->sc_bus->lock != NULL); + sc->sc_bus->ub_methods->ubm_getlock(sc->sc_bus, &sc->sc_bus->ub_lock); + KASSERT(sc->sc_bus->ub_lock != NULL); RUN_ONCE(&init_control, usb_once_init); config_interrupts(self, usb_doattach); @@ -312,17 +311,17 @@ static void usb_doattach(device_t self) { struct usb_softc *sc = device_private(self); - usbd_device_handle dev; + struct usbd_device *dev; usbd_status err; int speed; struct usb_event *ue; - DPRINTF(("usbd_doattach\n")); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - sc->sc_bus->usbctl = self; - sc->sc_port.power = USB_MAX_POWER; + sc->sc_bus->ub_usbctl = self; + sc->sc_port.up_power = USB_MAX_POWER; - switch (sc->sc_bus->usbrev) { + switch (sc->sc_bus->ub_revision) { case USBREV_1_0: case USBREV_1_1: speed = USB_SPEED_FULL; @@ -337,7 +336,7 @@ usb_doattach(device_t self) panic("usb_doattach"); } - cv_init(&sc->sc_bus->needs_explore_cv, "usbevt"); + cv_init(&sc->sc_bus->ub_needsexplore_cv, "usbevt"); ue = usb_alloc_event(); ue->u.ue_ctrlr.ue_bus = device_unit(self); @@ -346,14 +345,14 @@ usb_doattach(device_t self) err = usbd_new_device(self, sc->sc_bus, 0, speed, 0, &sc->sc_port); if (!err) { - dev = sc->sc_port.device; - if (dev->hub == NULL) { + dev = sc->sc_port.up_dev; + if (dev->ud_hub == NULL) { sc->sc_dying = 1; aprint_error("%s: root device is not a hub\n", device_xname(self)); return; } - sc->sc_bus->root_hub = dev; + sc->sc_bus->ub_roothub = dev; usb_create_event_thread(self); #if 1 /* @@ -362,7 +361,7 @@ usb_doattach(device_t self) * the keyboard will not work until after cold boot. */ if (cold && (device_cfdata(self)->cf_flags & 1)) - dev->hub->explore(sc->sc_bus->root_hub); + dev->ud_hub->uh_explore(sc->sc_bus->ub_roothub); #endif } else { aprint_error("%s: root hub problem, error=%s\n", @@ -401,21 +400,23 @@ usb_create_event_thread(device_t self) * context ASAP. */ void -usb_add_task(usbd_device_handle dev, struct usb_task *task, int queue) +usb_add_task(struct usbd_device *dev, struct usb_task *task, int queue) { struct usb_taskq *taskq; + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + KASSERT(0 <= queue); KASSERT(queue < USB_NUM_TASKQS); taskq = &usb_taskq[queue]; mutex_enter(&taskq->lock); if (atomic_cas_uint(&task->queue, USB_NUM_TASKQS, queue) == USB_NUM_TASKQS) { - DPRINTFN(2,("usb_add_task: task=%p\n", task)); + DPRINTFN(2, "task=%p", task, 0, 0, 0); TAILQ_INSERT_TAIL(&taskq->tasks, task, next); cv_signal(&taskq->cv); } else { - DPRINTFN(3,("usb_add_task: task=%p on q\n", task)); + DPRINTFN(2, "task=%p on q", task, 0, 0, 0); } mutex_exit(&taskq->lock); } @@ -425,10 +426,12 @@ usb_add_task(usbd_device_handle dev, struct usb_task *task, int queue) * operation. Urgh... */ void -usb_rem_task(usbd_device_handle dev, struct usb_task *task) +usb_rem_task(struct usbd_device *dev, struct usb_task *task) { unsigned queue; + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + while ((queue = task->queue) != USB_NUM_TASKQS) { struct usb_taskq *taskq = &usb_taskq[queue]; mutex_enter(&taskq->lock); @@ -447,7 +450,7 @@ usb_event_thread(void *arg) { struct usb_softc *sc = arg; - DPRINTF(("usb_event_thread: start\n")); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); /* * In case this controller is a companion controller to an @@ -460,29 +463,29 @@ usb_event_thread(void *arg) usb_delay_ms(sc->sc_bus, 500); /* Make sure first discover does something. */ - mutex_enter(sc->sc_bus->lock); - sc->sc_bus->needs_explore = 1; + mutex_enter(sc->sc_bus->ub_lock); + sc->sc_bus->ub_needsexplore = 1; usb_discover(sc); - mutex_exit(sc->sc_bus->lock); - config_pending_decr(sc->sc_bus->usbctl); + mutex_exit(sc->sc_bus->ub_lock); + config_pending_decr(sc->sc_bus->ub_usbctl); - mutex_enter(sc->sc_bus->lock); + mutex_enter(sc->sc_bus->ub_lock); while (!sc->sc_dying) { if (usb_noexplore < 2) usb_discover(sc); - cv_timedwait(&sc->sc_bus->needs_explore_cv, - sc->sc_bus->lock, usb_noexplore ? 0 : hz * 60); + cv_timedwait(&sc->sc_bus->ub_needsexplore_cv, + sc->sc_bus->ub_lock, usb_noexplore ? 0 : hz * 60); - DPRINTFN(2,("usb_event_thread: woke up\n")); + DPRINTFN(2, "sc %p woke up", sc, 0, 0, 0); } sc->sc_event_thread = NULL; /* In case parent is waiting for us to exit. */ - cv_signal(&sc->sc_bus->needs_explore_cv); - mutex_exit(sc->sc_bus->lock); + cv_signal(&sc->sc_bus->ub_needsexplore_cv); + mutex_exit(sc->sc_bus->ub_lock); - DPRINTF(("usb_event_thread: exit\n")); + DPRINTF("sc %p exit", sc, 0, 0, 0); kthread_exit(0); } @@ -493,8 +496,10 @@ usb_task_thread(void *arg) struct usb_taskq *taskq; bool mpsafe; + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + taskq = arg; - DPRINTF(("usb_task_thread: start taskq %s\n", taskq->name)); + DPRINTF("start taskq %p", taskq, 0, 0, 0); mutex_enter(&taskq->lock); for (;;) { @@ -503,7 +508,7 @@ usb_task_thread(void *arg) cv_wait(&taskq->cv, &taskq->lock); task = TAILQ_FIRST(&taskq->tasks); } - DPRINTFN(2,("usb_task_thread: woke up task=%p\n", task)); + DPRINTFN(2, "woke up task=%p", task, 0, 0, 0); if (task != NULL) { mpsafe = ISSET(task->flags, USB_TASKQ_MPSAFE); TAILQ_REMOVE(&taskq->tasks, task, next); @@ -530,7 +535,7 @@ usbctlprint(void *aux, const char *pnp) if (pnp) aprint_normal("usb at %s", pnp); - return (UNCONF); + return UNCONF; } int @@ -541,22 +546,22 @@ usbopen(dev_t dev, int flag, int mode, struct lwp *l) if (unit == USB_DEV_MINOR) { if (usb_dev_open) - return (EBUSY); + return EBUSY; usb_dev_open = 1; mutex_enter(proc_lock); usb_async_proc = 0; mutex_exit(proc_lock); - return (0); + return 0; } sc = device_lookup_private(&usb_cd, unit); if (!sc) - return (ENXIO); + return ENXIO; if (sc->sc_dying) - return (EIO); + return EIO; - return (0); + return 0; } int @@ -570,13 +575,12 @@ usbread(dev_t dev, struct uio *uio, int flag) int error, n; if (minor(dev) != USB_DEV_MINOR) - return (ENXIO); + return ENXIO; switch (uio->uio_resid) { #ifdef COMPAT_30 case sizeof(struct usb_event_old): - ueo = malloc(sizeof(struct usb_event_old), M_USBDEV, - M_WAITOK|M_ZERO); + ueo = kmem_zalloc(sizeof(struct usb_event_old), KM_SLEEP); useold = 1; /* FALLTHRU */ #endif @@ -584,7 +588,7 @@ usbread(dev_t dev, struct uio *uio, int flag) ue = usb_alloc_event(); break; default: - return (EINVAL); + return EINVAL; } error = 0; @@ -630,18 +634,18 @@ usbread(dev_t dev, struct uio *uio, int flag) ; } - error = uiomove((void *)ueo, sizeof *ueo, uio); + error = uiomove((void *)ueo, sizeof(*ueo), uio); } else #endif - error = uiomove((void *)ue, sizeof *ue, uio); + error = uiomove((void *)ue, sizeof(*ue), uio); } usb_free_event(ue); #ifdef COMPAT_30 if (useold) - free(ueo, M_USBDEV); + kmem_free(ueo, sizeof(struct usb_event_old)); #endif - return (error); + return error; } int @@ -657,7 +661,7 @@ usbclose(dev_t dev, int flag, int mode, usb_dev_open = 0; } - return (0); + return 0; } int @@ -666,11 +670,13 @@ usbioctl(dev_t devt, u_long cmd, void *data, int flag, struct lwp *l) struct usb_softc *sc; int unit = minor(devt); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + if (unit == USB_DEV_MINOR) { switch (cmd) { case FIONBIO: /* All handled in the upper FS layer. */ - return (0); + return 0; case FIOASYNC: mutex_enter(proc_lock); @@ -679,23 +685,23 @@ usbioctl(dev_t devt, u_long cmd, void *data, int flag, struct lwp *l) else usb_async_proc = 0; mutex_exit(proc_lock); - return (0); + return 0; default: - return (EINVAL); + return EINVAL; } } sc = device_lookup_private(&usb_cd, unit); if (sc->sc_dying) - return (EIO); + return EIO; switch (cmd) { #ifdef USB_DEBUG case USB_SETDEBUG: if (!(flag & FWRITE)) - return (EBADF); + return EBADF; usbdebug = ((*(int *)data) & 0x000000ff); break; #endif /* USB_DEBUG */ @@ -711,14 +717,14 @@ usbioctl(dev_t devt, u_long cmd, void *data, int flag, struct lwp *l) int error = 0; if (!(flag & FWRITE)) - return (EBADF); + return EBADF; - DPRINTF(("usbioctl: USB_REQUEST addr=%d len=%d\n", addr, len)); + DPRINTF("USB_REQUEST addr=%d len=%d\n", addr, len, 0, 0); if (len < 0 || len > 32768) - return (EINVAL); + return EINVAL; if (addr < 0 || addr >= USB_MAX_DEVICES || - sc->sc_bus->devices[addr] == NULL) - return (EINVAL); + sc->sc_bus->ub_devices[addr] == NULL) + return EINVAL; if (len != 0) { iov.iov_base = (void *)ur->ucr_data; iov.iov_len = len; @@ -730,14 +736,14 @@ usbioctl(dev_t devt, u_long cmd, void *data, int flag, struct lwp *l) ur->ucr_request.bmRequestType & UT_READ ? UIO_READ : UIO_WRITE; uio.uio_vmspace = l->l_proc->p_vmspace; - ptr = malloc(len, M_TEMP, M_WAITOK); + ptr = kmem_alloc(len, KM_SLEEP); if (uio.uio_rw == UIO_WRITE) { error = uiomove(ptr, len, &uio); if (error) goto ret; } } - err = usbd_do_request_flags(sc->sc_bus->devices[addr], + err = usbd_do_request_flags(sc->sc_bus->ub_devices[addr], &ur->ucr_request, ptr, ur->ucr_flags, &ur->ucr_actlen, USBD_DEFAULT_TIMEOUT); if (err) { @@ -754,20 +760,22 @@ usbioctl(dev_t devt, u_long cmd, void *data, int flag, struct lwp *l) } } ret: - if (ptr) - free(ptr, M_TEMP); - return (error); + if (ptr) { + len = UGETW(ur->ucr_request.wLength); + kmem_free(ptr, len); + } + return error; } case USB_DEVICEINFO: { - usbd_device_handle dev; + struct usbd_device *dev; struct usb_device_info *di = (void *)data; int addr = di->udi_addr; if (addr < 0 || addr >= USB_MAX_DEVICES) return EINVAL; - if ((dev = sc->sc_bus->devices[addr]) == NULL) + if ((dev = sc->sc_bus->ub_devices[addr]) == NULL) return ENXIO; usbd_fill_deviceinfo(dev, di, 1); break; @@ -776,13 +784,13 @@ usbioctl(dev_t devt, u_long cmd, void *data, int flag, struct lwp *l) #ifdef COMPAT_30 case USB_DEVICEINFO_OLD: { - usbd_device_handle dev; + struct usbd_device *dev; struct usb_device_info_old *di = (void *)data; int addr = di->udi_addr; if (addr < 1 || addr >= USB_MAX_DEVICES) return EINVAL; - if ((dev = sc->sc_bus->devices[addr]) == NULL) + if ((dev = sc->sc_bus->ub_devices[addr]) == NULL) return ENXIO; usbd_fill_deviceinfo_old(dev, di, 1); break; @@ -790,13 +798,13 @@ usbioctl(dev_t devt, u_long cmd, void *data, int flag, struct lwp *l) #endif case USB_DEVICESTATS: - *(struct usb_device_stats *)data = sc->sc_bus->stats; + *(struct usb_device_stats *)data = sc->sc_bus->ub_stats; break; default: - return (EINVAL); + return EINVAL; } - return (0); + return 0; } int @@ -815,9 +823,9 @@ usbpoll(dev_t dev, int events, struct lwp *l) selrecord(l, &usb_selevent); mutex_exit(&usb_event_lock); - return (revents); + return revents; } else { - return (0); + return 0; } } @@ -835,10 +843,10 @@ filt_usbread(struct knote *kn, long hint) { if (usb_nevents == 0) - return (0); + return 0; kn->kn_data = sizeof(struct usb_event); - return (1); + return 1; } static const struct filterops usbread_filtops = @@ -852,13 +860,13 @@ usbkqfilter(dev_t dev, struct knote *kn) switch (kn->kn_filter) { case EVFILT_READ: if (minor(dev) != USB_DEV_MINOR) - return (1); + return 1; klist = &usb_selevent.sel_klist; kn->kn_fop = &usbread_filtops; break; default: - return (EINVAL); + return EINVAL; } kn->kn_hook = NULL; @@ -867,7 +875,7 @@ usbkqfilter(dev_t dev, struct knote *kn) SLIST_INSERT_HEAD(klist, kn, kn_selnext); mutex_exit(&usb_event_lock); - return (0); + return 0; } /* Explore device tree from the root. */ @@ -875,9 +883,10 @@ Static void usb_discover(struct usb_softc *sc) { - KASSERT(mutex_owned(sc->sc_bus->lock)); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + KASSERT(mutex_owned(sc->sc_bus->ub_lock)); - DPRINTFN(2,("usb_discover\n")); if (usb_noexplore > 1) return; /* @@ -885,35 +894,39 @@ usb_discover(struct usb_softc *sc) * but this is guaranteed since this function is only called * from the event thread for the controller. * - * Also, we now have sc_bus->lock held. + * Also, we now have sc_bus->ub_lock held. */ - while (sc->sc_bus->needs_explore && !sc->sc_dying) { - sc->sc_bus->needs_explore = 0; - mutex_exit(sc->sc_bus->lock); - sc->sc_bus->root_hub->hub->explore(sc->sc_bus->root_hub); - mutex_enter(sc->sc_bus->lock); + while (sc->sc_bus->ub_needsexplore && !sc->sc_dying) { + sc->sc_bus->ub_needsexplore = 0; + mutex_exit(sc->sc_bus->ub_lock); + sc->sc_bus->ub_roothub->ud_hub->uh_explore(sc->sc_bus->ub_roothub); + mutex_enter(sc->sc_bus->ub_lock); } } void -usb_needs_explore(usbd_device_handle dev) +usb_needs_explore(struct usbd_device *dev) { - DPRINTFN(2,("usb_needs_explore\n")); - mutex_enter(dev->bus->lock); - dev->bus->needs_explore = 1; - cv_signal(&dev->bus->needs_explore_cv); - mutex_exit(dev->bus->lock); + + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + mutex_enter(dev->ud_bus->ub_lock); + dev->ud_bus->ub_needsexplore = 1; + cv_signal(&dev->ud_bus->ub_needsexplore_cv); + mutex_exit(dev->ud_bus->ub_lock); } void -usb_needs_reattach(usbd_device_handle dev) +usb_needs_reattach(struct usbd_device *dev) { - DPRINTFN(2,("usb_needs_reattach\n")); - mutex_enter(dev->bus->lock); - dev->powersrc->reattach = 1; - dev->bus->needs_explore = 1; - cv_signal(&dev->bus->needs_explore_cv); - mutex_exit(dev->bus->lock); + + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + mutex_enter(dev->ud_bus->ub_lock); + dev->ud_powersrc->up_reattach = 1; + dev->ud_bus->ub_needsexplore = 1; + cv_signal(&dev->ud_bus->ub_needsexplore_cv); + mutex_exit(dev->ud_bus->ub_lock); } /* Called at with usb_event_lock held. */ @@ -925,13 +938,13 @@ usb_get_next_event(struct usb_event *ue) KASSERT(mutex_owned(&usb_event_lock)); if (usb_nevents <= 0) - return (0); + return 0; ueq = SIMPLEQ_FIRST(&usb_events); #ifdef DIAGNOSTIC if (ueq == NULL) { printf("usb: usb_nevents got out of sync! %d\n", usb_nevents); usb_nevents = 0; - return (0); + return 0; } #endif if (ue) @@ -939,11 +952,11 @@ usb_get_next_event(struct usb_event *ue) SIMPLEQ_REMOVE_HEAD(&usb_events, next); usb_free_event((struct usb_event *)(void *)ueq); usb_nevents--; - return (1); + return 1; } void -usbd_add_dev_event(int type, usbd_device_handle udev) +usbd_add_dev_event(int type, struct usbd_device *udev) { struct usb_event *ue = usb_alloc_event(); @@ -952,13 +965,13 @@ usbd_add_dev_event(int type, usbd_device_handle udev) } void -usbd_add_drv_event(int type, usbd_device_handle udev, device_t dev) +usbd_add_drv_event(int type, struct usbd_device *udev, device_t dev) { struct usb_event *ue = usb_alloc_event(); - ue->u.ue_driver.ue_cookie = udev->cookie; + ue->u.ue_driver.ue_cookie = udev->ud_cookie; strncpy(ue->u.ue_driver.ue_devname, device_xname(dev), - sizeof ue->u.ue_driver.ue_devname); + sizeof(ue->u.ue_driver.ue_devname)); usb_add_event(type, ue); } @@ -966,13 +979,13 @@ Static struct usb_event * usb_alloc_event(void) { /* Yes, this is right; we allocate enough so that we can use it later */ - return malloc(sizeof(struct usb_event_q), M_USBDEV, M_WAITOK|M_ZERO); + return kmem_zalloc(sizeof(struct usb_event_q), KM_SLEEP); } Static void usb_free_event(struct usb_event *uep) { - free(uep, M_USBDEV); + kmem_free(uep, sizeof(struct usb_event_q)); } Static void @@ -981,6 +994,8 @@ usb_add_event(int type, struct usb_event *uep) struct usb_event_q *ueq; struct timeval thetime; + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + microtime(&thetime); /* Don't want to wait here with usb_event_lock held */ ueq = (struct usb_event_q *)(void *)uep; @@ -991,7 +1006,7 @@ usb_add_event(int type, struct usb_event *uep) mutex_enter(&usb_event_lock); if (++usb_nevents >= USB_MAX_EVENTS) { /* Too many queued events, drop an old one. */ - DPRINTFN(-1,("usb: event dropped\n")); + DPRINTF("event dropped", 0, 0, 0, 0); (void)usb_get_next_event(0); } SIMPLEQ_INSERT_TAIL(&usb_events, ueq, next); @@ -1019,24 +1034,26 @@ usb_async_intr(void *cookie) Static void usb_soft_intr(void *arg) { - usbd_bus_handle bus = arg; + struct usbd_bus *bus = arg; - mutex_enter(bus->lock); - (*bus->methods->soft_intr)(bus); - mutex_exit(bus->lock); + mutex_enter(bus->ub_lock); + bus->ub_methods->ubm_softint(bus); + mutex_exit(bus->ub_lock); } void -usb_schedsoftintr(usbd_bus_handle bus) +usb_schedsoftintr(struct usbd_bus *bus) { - DPRINTFN(10,("usb_schedsoftintr: polling=%d\n", bus->use_polling)); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + DPRINTFN(10, "polling=%d", bus->ub_usepolling, 0, 0, 0); - if (bus->use_polling) { - bus->methods->soft_intr(bus); + if (bus->ub_usepolling) { + bus->ub_methods->ubm_softint(bus); } else { kpreempt_disable(); - softint_schedule(bus->soft); + softint_schedule(bus->ub_soft); kpreempt_enable(); } } @@ -1062,12 +1079,12 @@ usb_childdet(device_t self, device_t child) struct usb_softc *sc = device_private(self); struct usbd_device *dev; - if ((dev = sc->sc_port.device) == NULL || dev->subdevlen == 0) + if ((dev = sc->sc_port.up_dev) == NULL || dev->ud_subdevlen == 0) return; - for (i = 0; i < dev->subdevlen; i++) - if (dev->subdevs[i] == child) - dev->subdevs[i] = NULL; + for (i = 0; i < dev->ud_subdevlen; i++) + if (dev->ud_subdevs[i] == child) + dev->ud_subdevs[i] = NULL; } int @@ -1077,10 +1094,10 @@ usb_detach(device_t self, int flags) struct usb_event *ue; int rc; - DPRINTF(("usb_detach: start\n")); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); /* Make all devices disconnect. */ - if (sc->sc_port.device != NULL && + if (sc->sc_port.up_dev != NULL && (rc = usb_disconnect_port(&sc->sc_port, self, flags)) != 0) return rc; @@ -1088,26 +1105,26 @@ usb_detach(device_t self, int flags) /* Kill off event thread. */ sc->sc_dying = 1; while (sc->sc_event_thread != NULL) { - mutex_enter(sc->sc_bus->lock); - cv_signal(&sc->sc_bus->needs_explore_cv); - cv_timedwait(&sc->sc_bus->needs_explore_cv, - sc->sc_bus->lock, hz * 60); - mutex_exit(sc->sc_bus->lock); + mutex_enter(sc->sc_bus->ub_lock); + cv_signal(&sc->sc_bus->ub_needsexplore_cv); + cv_timedwait(&sc->sc_bus->ub_needsexplore_cv, + sc->sc_bus->ub_lock, hz * 60); + mutex_exit(sc->sc_bus->ub_lock); } - DPRINTF(("usb_detach: event thread dead\n")); + DPRINTF("event thread dead", 0, 0, 0, 0); - if (sc->sc_bus->soft != NULL) { - softint_disestablish(sc->sc_bus->soft); - sc->sc_bus->soft = NULL; + if (sc->sc_bus->ub_soft != NULL) { + softint_disestablish(sc->sc_bus->ub_soft); + sc->sc_bus->ub_soft = NULL; } ue = usb_alloc_event(); ue->u.ue_ctrlr.ue_bus = device_unit(self); usb_add_event(USB_EVENT_CTRLR_DETACH, ue); - cv_destroy(&sc->sc_bus->needs_explore_cv); + cv_destroy(&sc->sc_bus->ub_needsexplore_cv); - return (0); + return 0; } #ifdef COMPAT_30 diff --git a/sys/dev/usb/usb.h b/sys/dev/usb/usb.h index 29800cfc4e4..ac64abb2478 100644 --- a/sys/dev/usb/usb.h +++ b/sys/dev/usb/usb.h @@ -1,5 +1,4 @@ -/* $NetBSD: usb.h,v 1.112 2015/03/26 08:08:27 skrll Exp $ */ -/* $FreeBSD: src/sys/dev/usb/usb.h,v 1.14 1999/11/17 22:33:46 n_hibma Exp $ */ +/* $NetBSD: usb.h,v 1.113 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -41,11 +40,6 @@ #include <sys/ioctl.h> #if defined(_KERNEL) -#include <sys/mallocvar.h> - -MALLOC_DECLARE(M_USB); -MALLOC_DECLARE(M_USBDEV); -MALLOC_DECLARE(M_USBHC); #include <sys/device.h> @@ -75,31 +69,20 @@ MALLOC_DECLARE(M_USBHC); * and endian problem and should always be used to access non-byte * values. */ -typedef u_int8_t uByte; -typedef u_int8_t uWord[2]; -typedef u_int8_t uDWord[4]; +typedef uint8_t uByte; +typedef uint8_t uWord[2]; +typedef uint8_t uDWord[4]; -#define USETW2(w,h,l) ((w)[0] = (u_int8_t)(l), (w)[1] = (u_int8_t)(h)) +#define USETW2(w,h,l) ((w)[0] = (uint8_t)(l), (w)[1] = (uint8_t)(h)) -#if 1 #define UGETW(w) ((w)[0] | ((w)[1] << 8)) -#define USETW(w,v) ((w)[0] = (u_int8_t)(v), (w)[1] = (u_int8_t)((v) >> 8)) +#define USETW(w,v) ((w)[0] = (uint8_t)(v), (w)[1] = (uint8_t)((v) >> 8)) +#define USETWD(val) { (uint8_t)(val), (uint8_t)((val) >> 8) } #define UGETDW(w) ((w)[0] | ((w)[1] << 8) | ((w)[2] << 16) | ((w)[3] << 24)) -#define USETDW(w,v) ((w)[0] = (u_int8_t)(v), \ - (w)[1] = (u_int8_t)((v) >> 8), \ - (w)[2] = (u_int8_t)((v) >> 16), \ - (w)[3] = (u_int8_t)((v) >> 24)) -#else -/* - * On little-endian machines that can handle unaligned accesses - * (e.g. i386) these macros can be replaced by the following. - */ -#define UGETW(w) (*(u_int16_t *)(w)) -#define USETW(w,v) (*(u_int16_t *)(w) = (v)) -#define UGETDW(w) (*(u_int32_t *)(w)) -#define USETDW(w,v) (*(u_int32_t *)(w) = (v)) -#endif - +#define USETDW(w,v) ((w)[0] = (uint8_t)(v), \ + (w)[1] = (uint8_t)((v) >> 8), \ + (w)[2] = (uint8_t)((v) >> 16), \ + (w)[3] = (uint8_t)((v) >> 24)) #define UPACKED __packed typedef struct { @@ -411,15 +394,26 @@ typedef struct { } UPACKED usb_devcap_platform_descriptor_t; #define USB_DEVCAP_PLATFORM_DESCRIPTOR_SIZE 20 +/* usb 3.1 ch 9.6.2.5 */ typedef struct { uByte bLength; uByte bDescriptorType; uByte bDevCapabilityType; uByte bReserved; uDWord bmAttributes; +#define USB_DEVCAP_SSP_SSAC(x) __SHIFTOUT(x, __BITS(4,0)) +#define USB_DEVCAP_SSP_SSIC(x) __SHIFTOUT(x, __BITS(8,5)) uWord wFunctionalitySupport; +#define USB_DEVCAP_SSP_SSID(x) __SHIFTOUT(x, __BITS(3,0)) +#define USB_DEVCAP_SSP_MIN_RXLANE_COUNT(x) __SHIFTOUT(x, __BITS(11,8)) +#define USB_DEVCAP_SSP_MIN_TXLANE_COUNT(x) __SHIFTOUT(x, __BITS(15,12)) uWord wReserved; uDWord bmSublinkSpeedAttr[0]; +#define USB_DEVCAP_SSP_SSID(x) __SHIFTOUT(x, __BITS(3,0)) +#define USB_DEVCAP_SSP_LSE(x) __SHIFTOUT(x, __BITS(5,4)) +#define USB_DEVCAP_SSP_ST(x) __SHIFTOUT(x, __BITS(7,6)) +#define USB_DEVCAP_SSP_LP(x) __SHIFTOUT(x, __BITS(15,14)) +#define USB_DEVCAP_SSP_LSM(x) __SHIFTOUT(x, __BITS(31,16)) } UPACKED usb_devcap_ssp_descriptor_t; #define USB_DEVCAP_SSP_DESCRIPTOR_SIZE 12 /* variable length */ @@ -440,6 +434,10 @@ typedef struct { #define UR_STOP_TT 0x0b #define UR_SET_HUB_DEPTH 0x0c #define UR_GET_PORT_ERR_COUNT 0x0d +/* Port Status Type for GET_STATUS, USB 3.1 10.16.2.6 and Table 10-12 */ +#define UR_PST_PORT_STATUS 0 +#define UR_PST_PD_STATUS 1 +#define UR_PST_EXT_PORT_STATUS 2 /* * Hub features from USB 2.0 spec, table 11-17 and updated by the @@ -577,7 +575,9 @@ typedef struct { #define UPS_OVERCURRENT_INDICATOR 0x0008 #define UPS_RESET 0x0010 #define UPS_PORT_L1 0x0020 -#define UPS_PORT_LS_GET(x) __SHIFTOUT(x, __BITS(8,5)) +#define UPS_PORT_LS_MASK __BITS(8,5) +#define UPS_PORT_LS_GET(x) __SHIFTOUT(x, UPS_PORT_LS_MASK) +#define UPS_PORT_LS_SET(x) __SHIFTIN(x, UPS_PORT_LS_MASK) #define UPS_PORT_LS_U0 0x00 #define UPS_PORT_LS_U1 0x01 #define UPS_PORT_LS_U2 0x02 @@ -596,9 +596,9 @@ typedef struct { #define UPS_FULL_SPEED 0x0000 /* for completeness */ #define UPS_LOW_SPEED 0x0200 #define UPS_HIGH_SPEED 0x0400 -#define UPS_SUPER_SPEED 0x0800 #define UPS_PORT_TEST 0x0800 #define UPS_PORT_INDICATOR 0x1000 +#define UPS_OTHER_SPEED 0x2000 /* currently NetBSD specific */ uWord wPortChange; #define UPS_C_CONNECT_STATUS 0x0001 #define UPS_C_PORT_ENABLED 0x0002 @@ -611,6 +611,14 @@ typedef struct { #define UPS_C_PORT_CONFIG_ERROR 0x0080 } UPACKED usb_port_status_t; +/* 10.16.2.6 */ +/* Valid when port status type is UR_PST_EXT_PORT_STATUS. */ +typedef struct { + uWord wPortStatus; + uWord wPortChange; + uDWord dwExtPortStatus; +} UPACKED usb_port_status_ext_t; + /* Device class codes */ #define UDCLASS_IN_INTERFACE 0x00 #define UDCLASS_COMM 0x02 @@ -844,34 +852,36 @@ struct usb_ctl_report_desc { u_char ucrd_data[1024]; /* filled data size will vary */ }; -typedef struct { u_int32_t cookie; } usb_event_cookie_t; +typedef struct { uint32_t cookie; } usb_event_cookie_t; #define USB_MAX_DEVNAMES 4 #define USB_MAX_DEVNAMELEN 16 struct usb_device_info { - u_int8_t udi_bus; - u_int8_t udi_addr; /* device address */ + uint8_t udi_bus; + uint8_t udi_addr; /* device address */ usb_event_cookie_t udi_cookie; char udi_product[USB_MAX_ENCODED_STRING_LEN]; char udi_vendor[USB_MAX_ENCODED_STRING_LEN]; char udi_release[8]; char udi_serial[USB_MAX_ENCODED_STRING_LEN]; - u_int16_t udi_productNo; - u_int16_t udi_vendorNo; - u_int16_t udi_releaseNo; - u_int8_t udi_class; - u_int8_t udi_subclass; - u_int8_t udi_protocol; - u_int8_t udi_config; - u_int8_t udi_speed; + uint16_t udi_productNo; + uint16_t udi_vendorNo; + uint16_t udi_releaseNo; + uint8_t udi_class; + uint8_t udi_subclass; + uint8_t udi_protocol; + uint8_t udi_config; + uint8_t udi_speed; #define USB_SPEED_LOW 1 #define USB_SPEED_FULL 2 #define USB_SPEED_HIGH 3 #define USB_SPEED_SUPER 4 +#define USB_SPEED_SUPER_PLUS 5 +#define USB_IS_SS(X) ((X) == USB_SPEED_SUPER || (X) == USB_SPEED_SUPER_PLUS) int udi_power; /* power consumption in mA, 0 if selfpowered */ int udi_nports; char udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN]; - u_int8_t udi_ports[16];/* hub only: addresses of devices on ports */ + uint8_t udi_ports[16];/* hub only: addresses of devices on ports */ #define USB_PORT_ENABLED 0xff #define USB_PORT_SUSPENDED 0xfe #define USB_PORT_POWERED 0xfd @@ -880,24 +890,24 @@ struct usb_device_info { /* <=3.0 had this layout of the structure */ struct usb_device_info_old { - u_int8_t udi_bus; - u_int8_t udi_addr; /* device address */ - usb_event_cookie_t udi_cookie; - char udi_product[USB_MAX_STRING_LEN]; - char udi_vendor[USB_MAX_STRING_LEN]; - char udi_release[8]; - u_int16_t udi_productNo; - u_int16_t udi_vendorNo; - u_int16_t udi_releaseNo; - u_int8_t udi_class; - u_int8_t udi_subclass; - u_int8_t udi_protocol; - u_int8_t udi_config; - u_int8_t udi_speed; - int udi_power; /* power consumption in mA, 0 if selfpowered */ - int udi_nports; - char udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN]; - u_int8_t udi_ports[16];/* hub only: addresses of devices on ports */ + uint8_t udi_bus; + uint8_t udi_addr; /* device address */ + usb_event_cookie_t udi_cookie; + char udi_product[USB_MAX_STRING_LEN]; + char udi_vendor[USB_MAX_STRING_LEN]; + char udi_release[8]; + uint16_t udi_productNo; + uint16_t udi_vendorNo; + uint16_t udi_releaseNo; + uint8_t udi_class; + uint8_t udi_subclass; + uint8_t udi_protocol; + uint8_t udi_config; + uint8_t udi_speed; + int udi_power; /* power consumption in mA, 0 if selfpowered */ + int udi_nports; + char udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN]; + uint8_t udi_ports[16];/* hub only: addresses of devices on ports */ }; struct usb_ctl_report { diff --git a/sys/dev/usb/usb_mem.c b/sys/dev/usb/usb_mem.c index 7a1d4f4d120..d85d95a40b2 100644 --- a/sys/dev/usb/usb_mem.c +++ b/sys/dev/usb/usb_mem.c @@ -1,4 +1,4 @@ -/* $NetBSD: usb_mem.c,v 1.66 2016/02/19 21:41:59 skrll Exp $ */ +/* $NetBSD: usb_mem.c,v 1.67 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -38,7 +38,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usb_mem.c,v 1.66 2016/02/19 21:41:59 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usb_mem.c,v 1.67 2016/04/23 10:15:32 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -54,8 +54,6 @@ __KERNEL_RCSID(0, "$NetBSD: usb_mem.c,v 1.66 2016/02/19 21:41:59 skrll Exp $"); #include <sys/cpu.h> #include <sys/once.h> -#include <sys/extent.h> - #ifdef DIAGNOSTIC #include <sys/proc.h> #endif @@ -64,15 +62,10 @@ __KERNEL_RCSID(0, "$NetBSD: usb_mem.c,v 1.66 2016/02/19 21:41:59 skrll Exp $"); #include <dev/usb/usbdi.h> #include <dev/usb/usbdivar.h> /* just for usb_dma_t */ #include <dev/usb/usb_mem.h> +#include <dev/usb/usbhist.h> -#ifdef USB_DEBUG -#define DPRINTF(x) if (usbdebug) printf x -#define DPRINTFN(n,x) if (usbdebug>(n)) printf x -extern int usbdebug; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif +#define DPRINTF(FMT,A,B,C,D) USBHIST_LOG(usbdebug,FMT,A,B,C,D) +#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(usbdebug,N,FMT,A,B,C,D) #define USB_MEM_SMALL roundup(64, CACHE_LINE_SIZE) #define USB_MEM_CHUNKS 64 @@ -80,9 +73,9 @@ extern int usbdebug; /* This struct is overlayed on free fragments. */ struct usb_frag_dma { - usb_dma_block_t *block; - u_int offs; - LIST_ENTRY(usb_frag_dma) next; + usb_dma_block_t *ufd_block; + u_int ufd_offs; + LIST_ENTRY(usb_frag_dma) ufd_next; }; Static usbd_status usb_block_allocmem(bus_dma_tag_t, size_t, size_t, @@ -122,22 +115,11 @@ usb_block_allocmem(bus_dma_tag_t tag, size_t size, size_t align, usb_dma_block_t *b; int error; - DPRINTFN(5, ("usb_block_allocmem: size=%zu align=%zu\n", size, align)); - - if (size == 0) { -#ifdef DIAGNOSTIC - printf("usb_block_allocmem: called with size==0\n"); -#endif - return USBD_INVAL; - } - -#ifdef DIAGNOSTIC - if (cpu_softintr_p() || cpu_intr_p()) { - printf("usb_block_allocmem: in interrupt context, size=%lu\n", - (unsigned long) size); - } -#endif + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + DPRINTFN(5, "size=%zu align=%zu", size, align, 0, 0); + ASSERT_SLEEPABLE(); + KASSERT(size != 0); KASSERT(mutex_owned(&usb_blk_lock)); /* First check the free list. */ @@ -149,23 +131,18 @@ usb_block_allocmem(bus_dma_tag_t tag, size_t size, size_t align, LIST_REMOVE(b, next); usb_blk_nfree--; *dmap = b; - DPRINTFN(6,("usb_block_allocmem: free list size=%zu\n", - b->size)); - return (USBD_NORMAL_COMPLETION); + DPRINTFN(6, "free list size=%zu", b->size, 0, 0, 0); + return USBD_NORMAL_COMPLETION; } } -#ifdef DIAGNOSTIC - if (cpu_softintr_p() || cpu_intr_p()) { - printf("usb_block_allocmem: in interrupt context, failed\n"); - return (USBD_NOMEM); - } -#endif + DPRINTFN(6, "no free", 0, 0, 0, 0); + mutex_exit(&usb_blk_lock); - DPRINTFN(6, ("usb_block_allocmem: no free\n")); - b = kmem_zalloc(sizeof *b, KM_SLEEP); - if (b == NULL) - return (USBD_NOMEM); + b = kmem_zalloc(sizeof(*b), KM_SLEEP); + if (b == NULL) { + goto fail; + } b->tag = tag; b->size = size; @@ -179,29 +156,29 @@ usb_block_allocmem(bus_dma_tag_t tag, size_t size, size_t align, b->segs = kmem_alloc(b->nsegs * sizeof(*b->segs), KM_SLEEP); if (b->segs == NULL) { - kmem_free(b, sizeof *b); - return USBD_NOMEM; + kmem_free(b, sizeof(*b)); + goto fail; } b->nsegs_alloc = b->nsegs; error = bus_dmamem_alloc(tag, b->size, align, 0, b->segs, b->nsegs, - &b->nsegs, BUS_DMA_NOWAIT); + &b->nsegs, BUS_DMA_WAITOK); if (error) goto free0; error = bus_dmamem_map(tag, b->segs, b->nsegs, b->size, - &b->kaddr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); + &b->kaddr, BUS_DMA_WAITOK|BUS_DMA_COHERENT); if (error) goto free1; error = bus_dmamap_create(tag, b->size, b->nsegs, b->size, - 0, BUS_DMA_NOWAIT, &b->map); + 0, BUS_DMA_WAITOK, &b->map); if (error) goto unmap; error = bus_dmamap_load(tag, b->map, b->kaddr, b->size, NULL, - BUS_DMA_NOWAIT); + BUS_DMA_WAITOK); if (error) goto destroy; @@ -209,8 +186,9 @@ usb_block_allocmem(bus_dma_tag_t tag, size_t size, size_t align, #ifdef USB_FRAG_DMA_WORKAROUND memset(b->kaddr, 0, b->size); #endif + mutex_enter(&usb_blk_lock); - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; destroy: bus_dmamap_destroy(tag, b->map); @@ -220,8 +198,11 @@ usb_block_allocmem(bus_dma_tag_t tag, size_t size, size_t align, bus_dmamem_free(tag, b->segs, b->nsegs); free0: kmem_free(b->segs, b->nsegs_alloc * sizeof(*b->segs)); - kmem_free(b, sizeof *b); - return (USBD_NOMEM); + kmem_free(b, sizeof(*b)); + fail: + mutex_enter(&usb_blk_lock); + + return USBD_NOMEM; } #if 0 @@ -239,7 +220,7 @@ usb_block_real_freemem(usb_dma_block_t *b) bus_dmamem_unmap(b->tag, b->kaddr, b->size); bus_dmamem_free(b->tag, b->segs, b->nsegs); kmem_free(b->segs, b->nsegs_alloc * sizeof(*b->segs)); - kmem_free(b, sizeof *b); + kmem_free(b, sizeof(*b)); } #endif @@ -267,7 +248,8 @@ usb_block_freemem(usb_dma_block_t *b) KASSERT(mutex_owned(&usb_blk_lock)); - DPRINTFN(6, ("usb_block_freemem: size=%zu\n", b->size)); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + DPRINTFN(6, "size=%zu", b->size, 0, 0, 0); #ifdef DEBUG LIST_REMOVE(b, next); #endif @@ -276,16 +258,17 @@ usb_block_freemem(usb_dma_block_t *b) } usbd_status -usb_allocmem(usbd_bus_handle bus, size_t size, size_t align, usb_dma_t *p) +usb_allocmem(struct usbd_bus *bus, size_t size, size_t align, usb_dma_t *p) { + return usb_allocmem_flags(bus, size, align, p, 0); } usbd_status -usb_allocmem_flags(usbd_bus_handle bus, size_t size, size_t align, usb_dma_t *p, +usb_allocmem_flags(struct usbd_bus *bus, size_t size, size_t align, usb_dma_t *p, int flags) { - bus_dma_tag_t tag = bus->dmatag; + bus_dma_tag_t tag = bus->ub_dmatag; usbd_status err; struct usb_frag_dma *f; usb_dma_block_t *b; @@ -293,43 +276,47 @@ usb_allocmem_flags(usbd_bus_handle bus, size_t size, size_t align, usb_dma_t *p, static ONCE_DECL(init_control); bool frag; + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + ASSERT_SLEEPABLE(); + RUN_ONCE(&init_control, usb_mem_init); frag = (flags & USBMALLOC_MULTISEG); /* If the request is large then just use a full block. */ if (size > USB_MEM_SMALL || align > USB_MEM_SMALL) { - DPRINTFN(1, ("usb_allocmem: large alloc %d\n", (int)size)); + DPRINTFN(1, "large alloc %d", size, 0, 0, 0); size = (size + USB_MEM_BLOCK - 1) & ~(USB_MEM_BLOCK - 1); mutex_enter(&usb_blk_lock); - err = usb_block_allocmem(tag, size, align, &p->block, frag); + err = usb_block_allocmem(tag, size, align, &p->udma_block, frag); if (!err) { #ifdef DEBUG - LIST_INSERT_HEAD(&usb_blk_fulllist, p->block, next); + LIST_INSERT_HEAD(&usb_blk_fulllist, p->udma_block, next); #endif - p->block->flags = USB_DMA_FULLBLOCK; - p->offs = 0; + p->udma_block->flags = USB_DMA_FULLBLOCK; + p->udma_offs = 0; } mutex_exit(&usb_blk_lock); - return (err); + return err; } mutex_enter(&usb_blk_lock); /* Check for free fragments. */ - LIST_FOREACH(f, &usb_frag_freelist, next) { - KDASSERTMSG(usb_valid_block_p(f->block, &usb_blk_fraglist), + LIST_FOREACH(f, &usb_frag_freelist, ufd_next) { + KDASSERTMSG(usb_valid_block_p(f->ufd_block, &usb_blk_fraglist), "%s: usb frag %p: unknown block pointer %p", - __func__, f, f->block); - if (f->block->tag == tag) + __func__, f, f->ufd_block); + if (f->ufd_block->tag == tag) break; } if (f == NULL) { - DPRINTFN(1, ("usb_allocmem: adding fragments\n")); + DPRINTFN(1, "adding fragments", 0, 0, 0, 0); err = usb_block_allocmem(tag, USB_MEM_BLOCK, USB_MEM_SMALL, &b, false); if (err) { mutex_exit(&usb_blk_lock); - return (err); + return err; } #ifdef DEBUG LIST_INSERT_HEAD(&usb_blk_fraglist, b, next); @@ -337,59 +324,60 @@ usb_allocmem_flags(usbd_bus_handle bus, size_t size, size_t align, usb_dma_t *p, b->flags = 0; for (i = 0; i < USB_MEM_BLOCK; i += USB_MEM_SMALL) { f = (struct usb_frag_dma *)((char *)b->kaddr + i); - f->block = b; - f->offs = i; - LIST_INSERT_HEAD(&usb_frag_freelist, f, next); + f->ufd_block = b; + f->ufd_offs = i; + LIST_INSERT_HEAD(&usb_frag_freelist, f, ufd_next); #ifdef USB_FRAG_DMA_WORKAROUND i += 1 * USB_MEM_SMALL; #endif } f = LIST_FIRST(&usb_frag_freelist); } - p->block = f->block; - p->offs = f->offs; + p->udma_block = f->ufd_block; + p->udma_offs = f->ufd_offs; #ifdef USB_FRAG_DMA_WORKAROUND p->offs += USB_MEM_SMALL; #endif - p->block->flags &= ~USB_DMA_RESERVE; - LIST_REMOVE(f, next); + LIST_REMOVE(f, ufd_next); mutex_exit(&usb_blk_lock); - DPRINTFN(5, ("usb_allocmem: use frag=%p size=%d\n", f, (int)size)); + DPRINTFN(5, "use frag=%p size=%d", f, size, 0, 0); - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } void -usb_freemem(usbd_bus_handle bus, usb_dma_t *p) +usb_freemem(struct usbd_bus *bus, usb_dma_t *p) { struct usb_frag_dma *f; + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + mutex_enter(&usb_blk_lock); - if (p->block->flags & USB_DMA_FULLBLOCK) { - KDASSERTMSG(usb_valid_block_p(p->block, &usb_blk_fulllist), + if (p->udma_block->flags & USB_DMA_FULLBLOCK) { + KDASSERTMSG(usb_valid_block_p(p->udma_block, &usb_blk_fulllist), "%s: dma %p: invalid block pointer %p", - __func__, p, p->block); - DPRINTFN(1, ("usb_freemem: large free\n")); - usb_block_freemem(p->block); + __func__, p, p->udma_block); + DPRINTFN(1, "large free", 0, 0, 0, 0); + usb_block_freemem(p->udma_block); mutex_exit(&usb_blk_lock); return; } - KDASSERTMSG(usb_valid_block_p(p->block, &usb_blk_fraglist), + KDASSERTMSG(usb_valid_block_p(p->udma_block, &usb_blk_fraglist), "%s: dma %p: invalid block pointer %p", - __func__, p, p->block); + __func__, p, p->udma_block); //usb_syncmem(p, 0, USB_MEM_SMALL, BUS_DMASYNC_POSTREAD); f = KERNADDR(p, 0); #ifdef USB_FRAG_DMA_WORKAROUND f = (void *)((uintptr_t)f - USB_MEM_SMALL); #endif - f->block = p->block; - f->offs = p->offs; + f->ufd_block = p->udma_block; + f->ufd_offs = p->udma_offs; #ifdef USB_FRAG_DMA_WORKAROUND f->offs -= USB_MEM_SMALL; #endif - LIST_INSERT_HEAD(&usb_frag_freelist, f, next); + LIST_INSERT_HEAD(&usb_frag_freelist, f, ufd_next); mutex_exit(&usb_blk_lock); - DPRINTFN(5, ("usb_freemem: frag=%p\n", f)); + DPRINTFN(5, "frag=%p", f, 0, 0, 0); } bus_addr_t @@ -398,156 +386,39 @@ usb_dmaaddr(usb_dma_t *dma, unsigned int offset) unsigned int i; bus_size_t seg_offs; - offset += dma->offs; + offset += dma->udma_offs; - KASSERTMSG(offset < dma->block->size, "offset %d vs %zu", offset, - dma->block->size); + KASSERTMSG(offset < dma->udma_block->size, "offset %d vs %zu", offset, + dma->udma_block->size); - if (dma->block->nsegs == 1) { - KASSERT(dma->block->map->dm_segs[0].ds_len > offset); - return dma->block->map->dm_segs[0].ds_addr + offset; + if (dma->udma_block->nsegs == 1) { + KASSERT(dma->udma_block->map->dm_segs[0].ds_len > offset); + return dma->udma_block->map->dm_segs[0].ds_addr + offset; } - /* Search for a bus_segment_t corresponding to this offset. With no + /* + * Search for a bus_segment_t corresponding to this offset. With no * record of the offset in the map to a particular dma_segment_t, we * have to iterate from the start of the list each time. Could be - * improved */ + * improved + */ seg_offs = 0; - for (i = 0; i < dma->block->nsegs; i++) { - if (seg_offs + dma->block->map->dm_segs[i].ds_len > offset) + for (i = 0; i < dma->udma_block->nsegs; i++) { + if (seg_offs + dma->udma_block->map->dm_segs[i].ds_len > offset) break; - seg_offs += dma->block->map->dm_segs[i].ds_len; + seg_offs += dma->udma_block->map->dm_segs[i].ds_len; } - KASSERT(i != dma->block->nsegs); + KASSERT(i != dma->udma_block->nsegs); offset -= seg_offs; - return dma->block->map->dm_segs[i].ds_addr + offset; + return dma->udma_block->map->dm_segs[i].ds_addr + offset; } void usb_syncmem(usb_dma_t *p, bus_addr_t offset, bus_size_t len, int ops) { - bus_dmamap_sync(p->block->tag, p->block->map, p->offs + offset, - len, ops); -} - - -usbd_status -usb_reserve_allocm(struct usb_dma_reserve *rs, usb_dma_t *dma, u_int32_t size) -{ - int error; - u_long start; - bus_addr_t baddr; - - if (rs->vaddr == 0 || size > USB_MEM_RESERVE) - return USBD_NOMEM; - - dma->block = kmem_zalloc(sizeof *dma->block, KM_SLEEP); - if (dma->block == NULL) { - aprint_error_dev(rs->dv, "%s: failed allocating dma block", - __func__); - goto out0; - } - - dma->block->nsegs = 1; - dma->block->segs = kmem_alloc(dma->block->nsegs * - sizeof(*dma->block->segs), KM_SLEEP); - if (dma->block->segs == NULL) { - aprint_error_dev(rs->dv, "%s: failed allocating 1 dma segment", - __func__); - goto out1; - } - - error = extent_alloc(rs->extent, size, PAGE_SIZE, 0, - EX_NOWAIT, &start); - - if (error != 0) { - aprint_error_dev(rs->dv, "%s: extent_alloc size %u failed " - "(error %d)", __func__, size, error); - goto out2; - } - - baddr = start; - dma->offs = baddr - rs->paddr; - dma->block->flags = USB_DMA_RESERVE; - dma->block->align = PAGE_SIZE; - dma->block->size = size; - dma->block->segs[0] = rs->map->dm_segs[0]; - dma->block->map = rs->map; - dma->block->kaddr = rs->vaddr; - dma->block->tag = rs->dtag; - - return USBD_NORMAL_COMPLETION; -out2: - kmem_free(dma->block->segs, dma->block->nsegs * - sizeof(*dma->block->segs)); -out1: - kmem_free(dma->block, sizeof *dma->block); -out0: - return USBD_NOMEM; -} - -void -usb_reserve_freem(struct usb_dma_reserve *rs, usb_dma_t *dma) -{ - extent_free(rs->extent, - (u_long)(rs->paddr + dma->offs), dma->block->size, 0); - kmem_free(dma->block->segs, dma->block->nsegs * - sizeof(*dma->block->segs)); - kmem_free(dma->block, sizeof *dma->block); -} - -int -usb_setup_reserve(device_t dv, struct usb_dma_reserve *rs, bus_dma_tag_t dtag, - size_t size) -{ - int error, nseg; - bus_dma_segment_t seg; - - rs->dtag = dtag; - rs->size = size; - rs->dv = dv; - - error = bus_dmamem_alloc(dtag, USB_MEM_RESERVE, PAGE_SIZE, 0, - &seg, 1, &nseg, BUS_DMA_NOWAIT); - if (error != 0) - return error; - - error = bus_dmamem_map(dtag, &seg, nseg, USB_MEM_RESERVE, - &rs->vaddr, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); - if (error != 0) - goto freeit; - - error = bus_dmamap_create(dtag, USB_MEM_RESERVE, 1, - USB_MEM_RESERVE, 0, BUS_DMA_NOWAIT, &rs->map); - if (error != 0) - goto unmap; - - error = bus_dmamap_load(dtag, rs->map, rs->vaddr, USB_MEM_RESERVE, - NULL, BUS_DMA_NOWAIT); - if (error != 0) - goto destroy; - - rs->paddr = rs->map->dm_segs[0].ds_addr; - rs->extent = extent_create(device_xname(dv), (u_long)rs->paddr, - (u_long)(rs->paddr + USB_MEM_RESERVE - 1), 0, 0, 0); - if (rs->extent == NULL) { - rs->vaddr = 0; - return ENOMEM; - } - - return 0; - - destroy: - bus_dmamap_destroy(dtag, rs->map); - unmap: - bus_dmamem_unmap(dtag, rs->vaddr, size); - freeit: - bus_dmamem_free(dtag, &seg, nseg); - - rs->vaddr = 0; - - return error; + bus_dmamap_sync(p->udma_block->tag, p->udma_block->map, p->udma_offs + offset, + len, ops); } diff --git a/sys/dev/usb/usb_mem.h b/sys/dev/usb/usb_mem.h index 262bc7cb63a..36a67f15a30 100644 --- a/sys/dev/usb/usb_mem.h +++ b/sys/dev/usb/usb_mem.h @@ -1,4 +1,4 @@ -/* $NetBSD: usb_mem.h,v 1.30 2013/01/23 23:44:30 jmcneill Exp $ */ +/* $NetBSD: usb_mem.h,v 1.31 2016/04/23 10:15:32 skrll Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_mem.h,v 1.9 1999/11/17 22:33:47 n_hibma Exp $ */ /* @@ -34,53 +34,27 @@ typedef struct usb_dma_block { bus_dma_tag_t tag; bus_dmamap_t map; - void *kaddr; - bus_dma_segment_t *segs; - int nsegs; - int nsegs_alloc; - size_t size; - size_t align; + void *kaddr; + bus_dma_segment_t *segs; + int nsegs; + int nsegs_alloc; + size_t size; + size_t align; int flags; #define USB_DMA_FULLBLOCK 0x0001 -#define USB_DMA_RESERVE 0x0002 LIST_ENTRY(usb_dma_block) next; } usb_dma_block_t; #define USBMALLOC_MULTISEG 1 -usbd_status usb_allocmem(usbd_bus_handle, size_t, size_t, usb_dma_t *); -usbd_status usb_allocmem_flags(usbd_bus_handle, size_t, size_t, usb_dma_t *, +usbd_status usb_allocmem(struct usbd_bus *, size_t, size_t, usb_dma_t *); +usbd_status usb_allocmem_flags(struct usbd_bus *, size_t, size_t, usb_dma_t *, int); -void usb_freemem(usbd_bus_handle, usb_dma_t *); -void usb_syncmem(usb_dma_t *, bus_addr_t, bus_size_t, int ops); +void usb_freemem(struct usbd_bus *, usb_dma_t *); +void usb_syncmem(usb_dma_t *, bus_addr_t, bus_size_t, int); bus_addr_t usb_dmaaddr(usb_dma_t *, unsigned int); #define DMAADDR(dma, o) usb_dmaaddr((dma), (o)) #define KERNADDR(dma, o) \ - ((void *)((char *)(dma)->block->kaddr + (dma)->offs + (o))) - -struct extent; - -struct usb_dma_reserve { - bus_dma_tag_t dtag; - bus_dmamap_t map; - void *vaddr; - bus_addr_t paddr; - size_t size; - struct extent *extent; - device_t dv; -}; - -#if defined(_KERNEL_OPT) -#include "opt_usb_mem_reserve.h" -#endif - -#ifndef USB_MEM_RESERVE -#define USB_MEM_RESERVE (256 * 1024) -#endif - -usbd_status usb_reserve_allocm(struct usb_dma_reserve *, usb_dma_t *, - u_int32_t); -int usb_setup_reserve(device_t, struct usb_dma_reserve *, bus_dma_tag_t, size_t); -void usb_reserve_freem(struct usb_dma_reserve *, usb_dma_t *); + ((void *)((char *)(dma)->udma_block->kaddr + (dma)->udma_offs + (o))) diff --git a/sys/dev/usb/usb_quirks.c b/sys/dev/usb/usb_quirks.c index d1645e13d7a..9cccf5816c9 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.83 2015/04/05 09:24:21 skrll Exp $ */ +/* $NetBSD: usb_quirks.c,v 1.84 2016/04/23 10:15:32 skrll Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_quirks.c,v 1.30 2003/01/02 04:15:55 imp Exp $ */ /* @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usb_quirks.c,v 1.83 2015/04/05 09:24:21 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usb_quirks.c,v 1.84 2016/04/23 10:15:32 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -52,9 +52,9 @@ extern int usbdebug; #define ANY 0xffff Static const struct usbd_quirk_entry { - u_int16_t idVendor; - u_int16_t idProduct; - u_int16_t bcdDevice; + uint16_t idVendor; + uint16_t idProduct; + uint16_t bcdDevice; struct usbd_quirks quirks; } usb_quirks[] = { /* Devices which should be ignored by uhid */ @@ -95,9 +95,9 @@ Static const struct usbd_quirk_entry { { USB_VENDOR_MOTOROLA2, USB_PRODUCT_MOTOROLA2_T720C, 0x001, { UQ_ASSUME_CM_OVER_DATA }}, { USB_VENDOR_EICON, USB_PRODUCT_EICON_DIVA852, - 0x100, { UQ_ASSUME_CM_OVER_DATA }}, + 0x100, { UQ_ASSUME_CM_OVER_DATA }}, { USB_VENDOR_SIEMENS2, USB_PRODUCT_SIEMENS2_MC75, - 0x000, { UQ_ASSUME_CM_OVER_DATA }}, + 0x000, { UQ_ASSUME_CM_OVER_DATA }}, { USB_VENDOR_TELEX, USB_PRODUCT_TELEX_MIC1, 0x009, { UQ_AU_NO_FRAC }}, { USB_VENDOR_SILICONPORTALS, USB_PRODUCT_SILICONPORTALS_YAPPHONE, 0x100, { UQ_AU_INP_ASYNC }}, @@ -158,9 +158,9 @@ const struct usbd_quirks * usbd_find_quirk(usb_device_descriptor_t *d) { const struct usbd_quirk_entry *t; - u_int16_t vendor = UGETW(d->idVendor); - u_int16_t product = UGETW(d->idProduct); - u_int16_t revision = UGETW(d->bcdDevice); + uint16_t vendor = UGETW(d->idVendor); + uint16_t product = UGETW(d->idProduct); + uint16_t revision = UGETW(d->bcdDevice); for (t = usb_quirks; t->idVendor != 0; t++) { if (t->idVendor == vendor && @@ -174,5 +174,5 @@ usbd_find_quirk(usb_device_descriptor_t *d) UGETW(d->idVendor), UGETW(d->idProduct), UGETW(d->bcdDevice), t->quirks.uq_flags); #endif - return (&t->quirks); + return &t->quirks; } diff --git a/sys/dev/usb/usb_quirks.h b/sys/dev/usb/usb_quirks.h index dffc712f7f4..f6aafb22310 100644 --- a/sys/dev/usb/usb_quirks.h +++ b/sys/dev/usb/usb_quirks.h @@ -1,4 +1,4 @@ -/* $NetBSD: usb_quirks.h,v 1.26 2010/11/30 11:35:30 phx Exp $ */ +/* $NetBSD: usb_quirks.h,v 1.27 2016/04/23 10:15:32 skrll Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_quirks.h,v 1.9 1999/11/12 23:31:03 n_hibma Exp $ */ /* @@ -32,7 +32,7 @@ */ struct usbd_quirks { - u_int32_t uq_flags; /* Device problems: */ + uint32_t uq_flags; /* Device problems: */ #define UQ_NO_SET_PROTO 0x0001 /* cannot handle SET PROTOCOL. */ #define UQ_SWAP_UNICODE 0x0002 /* has some Unicode strings swapped. */ #define UQ_MS_REVZ 0x0004 /* mouse has Z-axis reversed */ diff --git a/sys/dev/usb/usb_subr.c b/sys/dev/usb/usb_subr.c index 87ec4efe3c1..cc3db52f26b 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.209 2016/04/21 15:42:56 skrll Exp $ */ +/* $NetBSD: usb_subr.c,v 1.210 2016/04/23 10:15:32 skrll Exp $ */ /* $FreeBSD: src/sys/dev/usb/usb_subr.c,v 1.18 1999/11/17 22:33:47 n_hibma Exp $ */ /* @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.209 2016/04/21 15:42:56 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.210 2016/04/23 10:15:32 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_compat_netbsd.h" @@ -44,7 +44,6 @@ __KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.209 2016/04/21 15:42:56 skrll Exp $") #include <sys/systm.h> #include <sys/kernel.h> #include <sys/kmem.h> -#include <sys/malloc.h> #include <sys/device.h> #include <sys/select.h> #include <sys/proc.h> @@ -67,18 +66,14 @@ __KERNEL_RCSID(0, "$NetBSD: usb_subr.c,v 1.209 2016/04/21 15:42:56 skrll Exp $") #define DPRINTF(FMT,A,B,C,D) USBHIST_LOG(usbdebug,FMT,A,B,C,D) #define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(usbdebug,N,FMT,A,B,C,D) -MALLOC_DEFINE(M_USB, "USB", "USB misc. memory"); -MALLOC_DEFINE(M_USBDEV, "USB device", "USB device driver"); -MALLOC_DEFINE(M_USBHC, "USB HC", "USB host controller"); - -Static usbd_status usbd_set_config(usbd_device_handle, int); -Static void usbd_devinfo(usbd_device_handle, int, char *, size_t); -Static void usbd_devinfo_vp(usbd_device_handle, char *, size_t, char *, size_t, +Static usbd_status usbd_set_config(struct usbd_device *, int); +Static void usbd_devinfo(struct usbd_device *, int, char *, size_t); +Static void usbd_devinfo_vp(struct usbd_device *, char *, size_t, char *, size_t, int, int); -Static int usbd_getnewaddr(usbd_bus_handle); +Static int usbd_getnewaddr(struct usbd_bus *); Static int usbd_print(void *, const char *); Static int usbd_ifprint(void *, const char *); -Static void usbd_free_iface_data(usbd_device_handle, int); +Static void usbd_free_iface_data(struct usbd_device *, int); uint32_t usb_cookie_no = 0; @@ -115,21 +110,20 @@ usbd_errstr(usbd_status err) if (err < USBD_ERROR_MAX) { return usbd_error_strs[err]; } else { - snprintf(buffer, sizeof buffer, "%d", err); + snprintf(buffer, sizeof(buffer), "%d", err); return buffer; } } usbd_status -usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid, +usbd_get_string_desc(struct usbd_device *dev, int sindex, int langid, usb_string_descriptor_t *sdesc, int *sizep) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usb_device_request_t req; usbd_status err; int actlen; - USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - req.bmRequestType = UT_READ_DEVICE; req.bRequest = UR_GET_DESCRIPTOR; USETW2(req.wValue, UDESC_STRING, sindex); @@ -138,23 +132,23 @@ usbd_get_string_desc(usbd_device_handle dev, int sindex, int langid, err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT); if (err) - return (err); + return err; if (actlen < 2) - return (USBD_SHORT_XFER); + return USBD_SHORT_XFER; USETW(req.wLength, sdesc->bLength); /* the whole string */ err = usbd_do_request_flags(dev, &req, sdesc, USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT); if (err) - return (err); + return err; if (actlen != sdesc->bLength) { DPRINTF("expected %d, got %d", sdesc->bLength, actlen, 0, 0); } *sizep = actlen; - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } static void @@ -190,7 +184,7 @@ usbd_get_device_string(struct usbd_device *ud, uByte index, char **buf) void usbd_get_device_strings(struct usbd_device *ud) { - usb_device_descriptor_t *udd = &ud->ddesc; + usb_device_descriptor_t *udd = &ud->ud_ddesc; usbd_get_device_string(ud, udd->iManufacturer, &ud->ud_vendor); usbd_get_device_string(ud, udd->iProduct, &ud->ud_product); @@ -199,10 +193,10 @@ usbd_get_device_strings(struct usbd_device *ud) Static void -usbd_devinfo_vp(usbd_device_handle dev, char *v, size_t vl, char *p, +usbd_devinfo_vp(struct usbd_device *dev, char *v, size_t vl, char *p, size_t pl, int usedev, int useencoded) { - usb_device_descriptor_t *udd = &dev->ddesc; + usb_device_descriptor_t *udd = &dev->ud_ddesc; if (dev == NULL) return; @@ -237,14 +231,14 @@ usbd_printBCD(char *cp, size_t l, int bcd) } Static void -usbd_devinfo(usbd_device_handle dev, int showclass, char *cp, size_t l) +usbd_devinfo(struct usbd_device *dev, int showclass, char *cp, size_t l) { - usb_device_descriptor_t *udd = &dev->ddesc; + usb_device_descriptor_t *udd = &dev->ud_ddesc; char *vendor, *product; int bcdDevice, bcdUSB; char *ep; - vendor = malloc(USB_MAX_ENCODED_STRING_LEN * 2, M_USB, M_NOWAIT); + vendor = kmem_alloc(USB_MAX_ENCODED_STRING_LEN * 2, KM_SLEEP); if (vendor == NULL) { *cp = '\0'; return; @@ -265,17 +259,17 @@ usbd_devinfo(usbd_device_handle dev, int showclass, char *cp, size_t l) cp += usbd_printBCD(cp, ep - cp, bcdUSB); *cp++ = '/'; cp += usbd_printBCD(cp, ep - cp, bcdDevice); - cp += snprintf(cp, ep - cp, ", addr %d", dev->address); + cp += snprintf(cp, ep - cp, ", addr %d", dev->ud_addr); *cp = 0; - free(vendor, M_USB); + kmem_free(vendor, USB_MAX_ENCODED_STRING_LEN * 2); } char * -usbd_devinfo_alloc(usbd_device_handle dev, int showclass) +usbd_devinfo_alloc(struct usbd_device *dev, int showclass) { char *devinfop; - devinfop = malloc(DEVINFOSIZE, M_TEMP, M_WAITOK); + devinfop = kmem_alloc(DEVINFOSIZE, KM_SLEEP); usbd_devinfo(dev, showclass, devinfop, DEVINFOSIZE); return devinfop; } @@ -283,49 +277,48 @@ usbd_devinfo_alloc(usbd_device_handle dev, int showclass) void usbd_devinfo_free(char *devinfop) { - free(devinfop, M_TEMP); + kmem_free(devinfop, DEVINFOSIZE); } /* Delay for a certain number of ms */ void -usb_delay_ms_locked(usbd_bus_handle bus, u_int ms, kmutex_t *lock) +usb_delay_ms_locked(struct usbd_bus *bus, u_int ms, kmutex_t *lock) { /* Wait at least two clock ticks so we know the time has passed. */ - if (bus->use_polling || cold) + if (bus->ub_usepolling || cold) delay((ms+1) * 1000); else kpause("usbdly", false, (ms*hz+999)/1000 + 1, lock); } void -usb_delay_ms(usbd_bus_handle bus, u_int ms) +usb_delay_ms(struct usbd_bus *bus, u_int ms) { usb_delay_ms_locked(bus, ms, NULL); } /* Delay given a device handle. */ void -usbd_delay_ms_locked(usbd_device_handle dev, u_int ms, kmutex_t *lock) +usbd_delay_ms_locked(struct usbd_device *dev, u_int ms, kmutex_t *lock) { - usb_delay_ms_locked(dev->bus, ms, lock); + usb_delay_ms_locked(dev->ud_bus, ms, lock); } /* Delay given a device handle. */ void -usbd_delay_ms(usbd_device_handle dev, u_int ms) +usbd_delay_ms(struct usbd_device *dev, u_int ms) { - usb_delay_ms_locked(dev->bus, ms, NULL); + usb_delay_ms_locked(dev->ud_bus, ms, NULL); } usbd_status -usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps) +usbd_reset_port(struct usbd_device *dev, int port, usb_port_status_t *ps) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usb_device_request_t req; usbd_status err; int n; - USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - req.bmRequestType = UT_WRITE_CLASS_OTHER; req.bRequest = UR_SET_FEATURE; USETW(req.wValue, UHF_PORT_RESET); @@ -334,7 +327,7 @@ usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps) err = usbd_do_request(dev, &req, 0); DPRINTFN(1, "port %d reset done, error=%d", port, err, 0, 0); if (err) - return (err); + return err; n = 10; do { /* Wait for device to recover from reset. */ @@ -342,14 +335,14 @@ usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps) err = usbd_get_port_status(dev, port, ps); if (err) { DPRINTF("get status failed %d", err, 0, 0, 0); - return (err); + return err; } /* If the device disappeared, just give up. */ if (!(UGETW(ps->wPortStatus) & UPS_CURRENT_CONNECT_STATUS)) - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0); if (n == 0) - return (USBD_TIMEOUT); + return USBD_TIMEOUT; err = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET); #ifdef USB_DEBUG if (err) @@ -358,19 +351,18 @@ usbd_reset_port(usbd_device_handle dev, int port, usb_port_status_t *ps) /* Wait for the device to recover from reset. */ usbd_delay_ms(dev, USB_PORT_RESET_RECOVERY); - return (err); + return err; } usb_interface_descriptor_t * usbd_find_idesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); char *p = (char *)cd; char *end = p + UGETW(cd->wTotalLength); usb_interface_descriptor_t *d; int curidx, lastidx, curaidx = 0; - USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - for (curidx = lastidx = -1; p < end; ) { d = (usb_interface_descriptor_t *)p; DPRINTFN(4, "idx=%d(%d) altidx=%d(%d)", ifaceidx, curidx, @@ -388,10 +380,10 @@ usbd_find_idesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx) } else curaidx++; if (ifaceidx == curidx && altidx == curaidx) - return (d); + return d; } } - return (NULL); + return NULL; } usb_endpoint_descriptor_t * @@ -406,9 +398,9 @@ usbd_find_edesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx, d = usbd_find_idesc(cd, ifaceidx, altidx); if (d == NULL) - return (NULL); + return NULL; if (endptidx >= d->bNumEndpoints) /* quick exit */ - return (NULL); + return NULL; curidx = -1; for (p = (char *)d + d->bLength; p < end; ) { @@ -417,46 +409,45 @@ usbd_find_edesc(usb_config_descriptor_t *cd, int ifaceidx, int altidx, break; p += e->bLength; if (p <= end && e->bDescriptorType == UDESC_INTERFACE) - return (NULL); + return NULL; if (p <= end && e->bDescriptorType == UDESC_ENDPOINT) { curidx++; if (curidx == endptidx) - return (e); + return e; } } - return (NULL); + return NULL; } usbd_status -usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx) +usbd_fill_iface_data(struct usbd_device *dev, int ifaceidx, int altidx) { - usbd_interface_handle ifc = &dev->ifaces[ifaceidx]; + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + struct usbd_interface *ifc = &dev->ud_ifaces[ifaceidx]; usb_interface_descriptor_t *idesc; char *p, *end; int endpt, nendpt; - USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - DPRINTFN(4, "ifaceidx=%d altidx=%d", ifaceidx, altidx, 0, 0); - idesc = usbd_find_idesc(dev->cdesc, ifaceidx, altidx); + idesc = usbd_find_idesc(dev->ud_cdesc, ifaceidx, altidx); if (idesc == NULL) - return (USBD_INVAL); - ifc->device = dev; - ifc->idesc = idesc; - ifc->index = ifaceidx; - ifc->altindex = altidx; - nendpt = ifc->idesc->bNumEndpoints; + return USBD_INVAL; + ifc->ui_dev = dev; + ifc->ui_idesc = idesc; + ifc->ui_index = ifaceidx; + ifc->ui_altindex = altidx; + nendpt = ifc->ui_idesc->bNumEndpoints; DPRINTFN(4, "found idesc nendpt=%d", nendpt, 0, 0, 0); if (nendpt != 0) { - ifc->endpoints = malloc(nendpt * sizeof(struct usbd_endpoint), - M_USB, M_NOWAIT); - if (ifc->endpoints == NULL) - return (USBD_NOMEM); + ifc->ui_endpoints = kmem_alloc(nendpt * sizeof(struct usbd_endpoint), + KM_SLEEP); + if (ifc->ui_endpoints == NULL) + return USBD_NOMEM; } else - ifc->endpoints = NULL; - ifc->priv = NULL; - p = (char *)ifc->idesc + ifc->idesc->bLength; - end = (char *)dev->cdesc + UGETW(dev->cdesc->wTotalLength); + ifc->ui_endpoints = NULL; + ifc->ui_priv = NULL; + p = (char *)ifc->ui_idesc + ifc->ui_idesc->bLength; + end = (char *)dev->ud_cdesc + UGETW(dev->ud_cdesc->wTotalLength); #define ed ((usb_endpoint_descriptor_t *)p) for (endpt = 0; endpt < nendpt; endpt++) { DPRINTFN(10, "endpt=%d", endpt, 0, 0, 0); @@ -477,8 +468,8 @@ usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx) "out of data"); goto bad; found: - ifc->endpoints[endpt].edesc = ed; - if (dev->speed == USB_SPEED_HIGH) { + ifc->ui_endpoints[endpt].ue_edesc = ed; + if (dev->ud_speed == USB_SPEED_HIGH) { u_int mps; /* Control and bulk endpoints have max packet limits. */ switch (UE_GET_XFERTYPE(ed->bmAttributes)) { @@ -500,97 +491,106 @@ usbd_fill_iface_data(usbd_device_handle dev, int ifaceidx, int altidx) break; } } - ifc->endpoints[endpt].refcnt = 0; - ifc->endpoints[endpt].datatoggle = 0; + ifc->ui_endpoints[endpt].ue_refcnt = 0; + ifc->ui_endpoints[endpt].ue_toggle = 0; p += ed->bLength; } #undef ed - LIST_INIT(&ifc->pipes); - return (USBD_NORMAL_COMPLETION); + LIST_INIT(&ifc->ui_pipes); + return USBD_NORMAL_COMPLETION; bad: - if (ifc->endpoints != NULL) { - free(ifc->endpoints, M_USB); - ifc->endpoints = NULL; + if (ifc->ui_endpoints != NULL) { + kmem_free(ifc->ui_endpoints, nendpt * sizeof(struct usbd_endpoint)); + ifc->ui_endpoints = NULL; } - return (USBD_INVAL); + return USBD_INVAL; } void -usbd_free_iface_data(usbd_device_handle dev, int ifcno) +usbd_free_iface_data(struct usbd_device *dev, int ifcno) { - usbd_interface_handle ifc = &dev->ifaces[ifcno]; - if (ifc->endpoints) - free(ifc->endpoints, M_USB); + struct usbd_interface *ifc = &dev->ud_ifaces[ifcno]; + if (ifc->ui_endpoints) { + int nendpt = ifc->ui_idesc->bNumEndpoints; + size_t sz = nendpt * sizeof(struct usbd_endpoint); + kmem_free(ifc->ui_endpoints, sz); + } } Static usbd_status -usbd_set_config(usbd_device_handle dev, int conf) +usbd_set_config(struct usbd_device *dev, int conf) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usb_device_request_t req; + DPRINTFN(5, "dev %p conf %d", dev, conf, 0, 0); + req.bmRequestType = UT_WRITE_DEVICE; req.bRequest = UR_SET_CONFIG; USETW(req.wValue, conf); USETW(req.wIndex, 0); USETW(req.wLength, 0); - return (usbd_do_request(dev, &req, 0)); + return usbd_do_request(dev, &req, 0); } usbd_status -usbd_set_config_no(usbd_device_handle dev, int no, int msg) +usbd_set_config_no(struct usbd_device *dev, int no, int msg) { - int index; + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usb_config_descriptor_t cd; usbd_status err; - - USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + int index; if (no == USB_UNCONFIG_NO) - return (usbd_set_config_index(dev, USB_UNCONFIG_INDEX, msg)); + return usbd_set_config_index(dev, USB_UNCONFIG_INDEX, msg); DPRINTFN(5, "%d", no, 0, 0, 0); /* Figure out what config index to use. */ - for (index = 0; index < dev->ddesc.bNumConfigurations; index++) { + for (index = 0; index < dev->ud_ddesc.bNumConfigurations; index++) { err = usbd_get_config_desc(dev, index, &cd); if (err) - return (err); + return err; if (cd.bConfigurationValue == no) - return (usbd_set_config_index(dev, index, msg)); + return usbd_set_config_index(dev, index, msg); } - return (USBD_INVAL); + return USBD_INVAL; } usbd_status -usbd_set_config_index(usbd_device_handle dev, int index, int msg) +usbd_set_config_index(struct usbd_device *dev, int index, int msg) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usb_config_descriptor_t cd, *cdp; + usb_bos_descriptor_t bd, *bdp = NULL; usbd_status err; int i, ifcidx, nifc, len, selfpowered, power; - USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - DPRINTFN(5, "dev=%p index=%d", dev, index, 0, 0); - if (index >= dev->ddesc.bNumConfigurations && + if (index >= dev->ud_ddesc.bNumConfigurations && index != USB_UNCONFIG_INDEX) { /* panic? */ printf("usbd_set_config_index: illegal index\n"); - return (USBD_INVAL); + return USBD_INVAL; } /* XXX check that all interfaces are idle */ - if (dev->config != USB_UNCONFIG_NO) { + if (dev->ud_config != USB_UNCONFIG_NO) { DPRINTF("free old config", 0, 0, 0, 0); /* Free all configuration data structures. */ - nifc = dev->cdesc->bNumInterface; + nifc = dev->ud_cdesc->bNumInterface; for (ifcidx = 0; ifcidx < nifc; ifcidx++) usbd_free_iface_data(dev, ifcidx); - free(dev->ifaces, M_USB); - free(dev->cdesc, M_USB); - dev->ifaces = NULL; - dev->cdesc = NULL; - dev->config = USB_UNCONFIG_NO; + kmem_free(dev->ud_ifaces, nifc * sizeof(struct usbd_interface)); + kmem_free(dev->ud_cdesc, UGETW(dev->ud_cdesc->wTotalLength)); + if (dev->ud_bdesc != NULL) + kmem_free(dev->ud_bdesc, + UGETW(dev->ud_bdesc->wTotalLength)); + dev->ud_ifaces = NULL; + dev->ud_cdesc = NULL; + dev->ud_bdesc = NULL; + dev->ud_config = USB_UNCONFIG_NO; } if (index == USB_UNCONFIG_INDEX) { @@ -601,19 +601,19 @@ usbd_set_config_index(usbd_device_handle dev, int index, int msg) DPRINTF("setting config=0 failed, err = %d", err, 0, 0, 0); } - return (err); + return err; } /* Get the short descriptor. */ err = usbd_get_config_desc(dev, index, &cd); if (err) { DPRINTF("get_config_desc=%d", err, 0, 0, 0); - return (err); + return err; } len = UGETW(cd.wTotalLength); - cdp = malloc(len, M_USB, M_NOWAIT); + cdp = kmem_alloc(len, KM_SLEEP); if (cdp == NULL) - return (USBD_NOMEM); + return USBD_NOMEM; /* Get the full descriptor. Try a few times for slow devices. */ for (i = 0; i < 3; i++) { @@ -632,6 +632,35 @@ usbd_set_config_index(usbd_device_handle dev, int index, int msg) goto bad; } + if (USB_IS_SS(dev->ud_speed)) { + /* get short bos desc */ + err = usbd_get_bos_desc(dev, index, &bd); + if (!err) { + int blen = UGETW(bd.wTotalLength); + bdp = kmem_alloc(blen, KM_SLEEP); + if (bdp == NULL) { + err = USBD_NOMEM; + goto bad; + } + + /* Get the full desc */ + for (i = 0; i < 3; i++) { + err = usbd_get_desc(dev, UDESC_BOS, index, blen, + bdp); + if (!err) + break; + usbd_delay_ms(dev, 200); + } + if (err || bdp->bDescriptorType != UDESC_BOS) { + DPRINTF("error %d or bad desc %d", err, + bdp->bDescriptorType, 0, 0); + kmem_free(bdp, blen); + bdp = NULL; + } + } + } + dev->ud_bdesc = bdp; + /* * Figure out if the device is self or bus powered. */ @@ -650,7 +679,7 @@ usbd_set_config_index(usbd_device_handle dev, int index, int msg) selfpowered = !!(cdp->bmAttributes & UC_SELF_POWERED); DPRINTF("addr %d cno=%d attr=0x%02x, selfpowered=%d", - dev->address, cdp->bConfigurationValue, cdp->bmAttributes, + dev->ud_addr, cdp->bConfigurationValue, cdp->bmAttributes, selfpowered); DPRINTF("max power=%d", cdp->bMaxPower * 2, 0, 0, 0); @@ -660,35 +689,35 @@ usbd_set_config_index(usbd_device_handle dev, int index, int msg) if (msg) printf("%s: device addr %d (config %d): " "can't set self powered configuration\n", - device_xname(dev->bus->bdev), dev->address, + device_xname(dev->ud_bus->bdev), dev->ud_addr, cdp->bConfigurationValue); err = USBD_NO_POWER; goto bad; } #endif #ifdef USB_DEBUG - if (dev->powersrc == NULL) { + if (dev->ud_powersrc == NULL) { DPRINTF("No power source?", 0, 0, 0, 0); err = USBD_IOERROR; goto bad; } #endif power = cdp->bMaxPower * 2; - if (power > dev->powersrc->power) { - DPRINTF("power exceeded %d %d", power, dev->powersrc->power, + if (power > dev->ud_powersrc->up_power) { + DPRINTF("power exceeded %d %d", power, dev->ud_powersrc->up_power, 0, 0); /* XXX print nicer message. */ if (msg) printf("%s: device addr %d (config %d) exceeds power " "budget, %d mA > %d mA\n", - device_xname(dev->bus->usbctl), dev->address, + device_xname(dev->ud_bus->ub_usbctl), dev->ud_addr, cdp->bConfigurationValue, - power, dev->powersrc->power); + power, dev->ud_powersrc->up_power); err = USBD_NO_POWER; goto bad; } - dev->power = power; - dev->self_powered = selfpowered; + dev->ud_power = power; + dev->ud_selfpowered = selfpowered; /* Set the actual configuration value. */ DPRINTF("set config %d", cdp->bConfigurationValue, 0, 0, 0); @@ -701,15 +730,15 @@ usbd_set_config_index(usbd_device_handle dev, int index, int msg) /* Allocate and fill interface data. */ nifc = cdp->bNumInterface; - dev->ifaces = malloc(nifc * sizeof(struct usbd_interface), - M_USB, M_NOWAIT); - if (dev->ifaces == NULL) { + dev->ud_ifaces = kmem_alloc(nifc * sizeof(struct usbd_interface), + KM_SLEEP); + if (dev->ud_ifaces == NULL) { err = USBD_NOMEM; goto bad; } DPRINTFN(5, "dev=%p cdesc=%p", dev, cdp, 0, 0); - dev->cdesc = cdp; - dev->config = cdp->bConfigurationValue; + dev->ud_cdesc = cdp; + dev->ud_config = cdp->bConfigurationValue; for (ifcidx = 0; ifcidx < nifc; ifcidx++) { err = usbd_fill_iface_data(dev, ifcidx, 0); if (err) { @@ -719,114 +748,124 @@ usbd_set_config_index(usbd_device_handle dev, int index, int msg) } } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; bad: - free(cdp, M_USB); - return (err); + kmem_free(cdp, len); + if (bdp != NULL) { + kmem_free(bdp, UGETW(bdp->wTotalLength)); + dev->ud_bdesc = NULL; + } + return err; } /* XXX add function for alternate settings */ usbd_status -usbd_setup_pipe(usbd_device_handle dev, usbd_interface_handle iface, - struct usbd_endpoint *ep, int ival, usbd_pipe_handle *pipe) +usbd_setup_pipe(struct usbd_device *dev, struct usbd_interface *iface, + struct usbd_endpoint *ep, int ival, struct usbd_pipe **pipe) { return usbd_setup_pipe_flags(dev, iface, ep, ival, pipe, 0); } usbd_status -usbd_setup_pipe_flags(usbd_device_handle dev, usbd_interface_handle iface, - struct usbd_endpoint *ep, int ival, usbd_pipe_handle *pipe, uint8_t flags) +usbd_setup_pipe_flags(struct usbd_device *dev, struct usbd_interface *iface, + struct usbd_endpoint *ep, int ival, struct usbd_pipe **pipe, uint8_t flags) { - usbd_pipe_handle p; - usbd_status err; - USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + struct usbd_pipe *p; + usbd_status err; - p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT); - DPRINTFN(1, "dev=%p iface=%p ep=%p pipe=%p", dev, iface, ep, p); - if (p == NULL) - return (USBD_NOMEM); - p->device = dev; - p->iface = iface; - p->endpoint = ep; - ep->refcnt++; - p->refcnt = 1; - p->intrxfer = NULL; - p->running = 0; - p->aborting = 0; - p->repeat = 0; - p->interval = ival; - p->flags = flags; - SIMPLEQ_INIT(&p->queue); - err = dev->bus->methods->open_pipe(p); + p = kmem_alloc(dev->ud_bus->ub_pipesize, KM_SLEEP); + DPRINTFN(1, "dev=%p addr=%d iface=%p ep=%p pipe=%p", dev, dev->ud_addr, iface, ep); + if (p == NULL) { + DPRINTFN(1, "(nomem)", 0, 0, 0, 0); + return USBD_NOMEM; + } + p->up_dev = dev; + p->up_iface = iface; + p->up_endpoint = ep; + ep->ue_refcnt++; + p->up_intrxfer = NULL; + p->up_running = 0; + p->up_aborting = 0; + p->up_serialise = true; + p->up_repeat = 0; + p->up_interval = ival; + p->up_flags = flags; + p->up_serialise = true; + SIMPLEQ_INIT(&p->up_queue); + err = dev->ud_bus->ub_methods->ubm_open(p); if (err) { DPRINTF("endpoint=0x%x failed, error=%d", - ep->edesc->bEndpointAddress, err, 0, 0); - free(p, M_USB); - return (err); + ep->ue_edesc->bEndpointAddress, err, 0, 0); + kmem_intr_free(p, dev->ud_bus->ub_pipesize); + return err; } - usb_init_task(&p->async_task, usbd_clear_endpoint_stall_task, p, + + KASSERT(p->up_methods->upm_start || p->up_serialise == false); + + usb_init_task(&p->up_async_task, usbd_clear_endpoint_stall_task, p, USB_TASKQ_MPSAFE); + DPRINTFN(1, "pipe=%p", p, 0, 0, 0); *pipe = p; - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } /* Abort the device control pipe. */ void -usbd_kill_pipe(usbd_pipe_handle pipe) +usbd_kill_pipe(struct usbd_pipe *pipe) { usbd_abort_pipe(pipe); usbd_lock_pipe(pipe); - pipe->methods->close(pipe); + pipe->up_methods->upm_close(pipe); usbd_unlock_pipe(pipe); - usb_rem_task(pipe->device, &pipe->async_task); - pipe->endpoint->refcnt--; - free(pipe, M_USB); + usb_rem_task(pipe->up_dev, &pipe->up_async_task); + pipe->up_endpoint->ue_refcnt--; + kmem_free(pipe, pipe->up_dev->ud_bus->ub_pipesize); } int -usbd_getnewaddr(usbd_bus_handle bus) +usbd_getnewaddr(struct usbd_bus *bus) { int addr; for (addr = 1; addr < USB_MAX_DEVICES; addr++) - if (bus->devices[addr] == NULL) - return (addr); - return (-1); + if (bus->ub_devices[addr] == NULL) + return addr; + return -1; } usbd_status -usbd_attach_roothub(device_t parent, usbd_device_handle dev) +usbd_attach_roothub(device_t parent, struct usbd_device *dev) { struct usb_attach_arg uaa; - usb_device_descriptor_t *dd = &dev->ddesc; + usb_device_descriptor_t *dd = &dev->ud_ddesc; device_t dv; - uaa.device = dev; - uaa.usegeneric = 0; - uaa.port = 0; - uaa.vendor = UGETW(dd->idVendor); - uaa.product = UGETW(dd->idProduct); - uaa.release = UGETW(dd->bcdDevice); - uaa.class = dd->bDeviceClass; - uaa.subclass = dd->bDeviceSubClass; - uaa.proto = dd->bDeviceProtocol; + uaa.uaa_device = dev; + uaa.uaa_usegeneric = 0; + uaa.uaa_port = 0; + uaa.uaa_vendor = UGETW(dd->idVendor); + uaa.uaa_product = UGETW(dd->idProduct); + uaa.uaa_release = UGETW(dd->bcdDevice); + uaa.uaa_class = dd->bDeviceClass; + uaa.uaa_subclass = dd->bDeviceSubClass; + uaa.uaa_proto = dd->bDeviceProtocol; dv = config_found_ia(parent, "usbroothubif", &uaa, 0); if (dv) { - dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT); - if (dev->subdevs == NULL) - return (USBD_NOMEM); - dev->subdevs[0] = dv; - dev->subdevlen = 1; + dev->ud_subdevs = kmem_alloc(sizeof(dv), KM_SLEEP); + if (dev->ud_subdevs == NULL) + return USBD_NOMEM; + dev->ud_subdevs[0] = dv; + dev->ud_subdevlen = 1; } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } static void -usbd_serialnumber(device_t dv, usbd_device_handle dev) +usbd_serialnumber(device_t dv, struct usbd_device *dev) { if (dev->ud_serial) { prop_dictionary_set_cstring(device_properties(dv), @@ -835,28 +874,28 @@ usbd_serialnumber(device_t dv, usbd_device_handle dev) } static usbd_status -usbd_attachwholedevice(device_t parent, usbd_device_handle dev, int port, +usbd_attachwholedevice(device_t parent, struct usbd_device *dev, int port, int usegeneric) { struct usb_attach_arg uaa; - usb_device_descriptor_t *dd = &dev->ddesc; + usb_device_descriptor_t *dd = &dev->ud_ddesc; device_t dv; int dlocs[USBDEVIFCF_NLOCS]; - uaa.device = dev; - uaa.usegeneric = usegeneric; - uaa.port = port; - uaa.vendor = UGETW(dd->idVendor); - uaa.product = UGETW(dd->idProduct); - uaa.release = UGETW(dd->bcdDevice); - uaa.class = dd->bDeviceClass; - uaa.subclass = dd->bDeviceSubClass; - uaa.proto = dd->bDeviceProtocol; - - dlocs[USBDEVIFCF_PORT] = uaa.port; - dlocs[USBDEVIFCF_VENDOR] = uaa.vendor; - dlocs[USBDEVIFCF_PRODUCT] = uaa.product; - dlocs[USBDEVIFCF_RELEASE] = uaa.release; + uaa.uaa_device = dev; + uaa.uaa_usegeneric = usegeneric; + uaa.uaa_port = port; + uaa.uaa_vendor = UGETW(dd->idVendor); + uaa.uaa_product = UGETW(dd->idProduct); + uaa.uaa_release = UGETW(dd->bcdDevice); + uaa.uaa_class = dd->bDeviceClass; + uaa.uaa_subclass = dd->bDeviceSubClass; + uaa.uaa_proto = dd->bDeviceProtocol; + + dlocs[USBDEVIFCF_PORT] = uaa.uaa_port; + dlocs[USBDEVIFCF_VENDOR] = uaa.uaa_vendor; + dlocs[USBDEVIFCF_PRODUCT] = uaa.uaa_product; + dlocs[USBDEVIFCF_RELEASE] = uaa.uaa_release; /* the rest is historical ballast */ dlocs[USBDEVIFCF_CONFIGURATION] = -1; dlocs[USBDEVIFCF_INTERFACE] = -1; @@ -866,79 +905,80 @@ usbd_attachwholedevice(device_t parent, usbd_device_handle dev, int port, config_stdsubmatch); KERNEL_UNLOCK_ONE(NULL); if (dv) { - dev->subdevs = malloc(sizeof dv, M_USB, M_NOWAIT); - if (dev->subdevs == NULL) - return (USBD_NOMEM); - dev->subdevs[0] = dv; - dev->subdevlen = 1; - dev->nifaces_claimed = 1; /* XXX */ + dev->ud_subdevs = kmem_alloc(sizeof(dv), KM_SLEEP); + if (dev->ud_subdevs == NULL) + return USBD_NOMEM; + dev->ud_subdevs[0] = dv; + dev->ud_subdevlen = 1; + dev->ud_nifaces_claimed = 1; /* XXX */ usbd_serialnumber(dv, dev); } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } static usbd_status -usbd_attachinterfaces(device_t parent, usbd_device_handle dev, +usbd_attachinterfaces(device_t parent, struct usbd_device *dev, int port, const int *locators) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); struct usbif_attach_arg uiaa; int ilocs[USBIFIFCF_NLOCS]; - usb_device_descriptor_t *dd = &dev->ddesc; + usb_device_descriptor_t *dd = &dev->ud_ddesc; int nifaces; - usbd_interface_handle *ifaces; + struct usbd_interface **ifaces; int i, j, loc; device_t dv; - USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - - nifaces = dev->cdesc->bNumInterface; - ifaces = malloc(nifaces * sizeof(*ifaces), M_USB, M_NOWAIT|M_ZERO); + nifaces = dev->ud_cdesc->bNumInterface; + ifaces = kmem_zalloc(nifaces * sizeof(*ifaces), KM_SLEEP); if (!ifaces) - return (USBD_NOMEM); + return USBD_NOMEM; for (i = 0; i < nifaces; i++) { - if (!dev->subdevs[i]) { - ifaces[i] = &dev->ifaces[i]; + if (!dev->ud_subdevs[i]) { + ifaces[i] = &dev->ud_ifaces[i]; } DPRINTF("interface %d %p", i, ifaces[i], 0, 0); } - uiaa.device = dev; - uiaa.port = port; - uiaa.vendor = UGETW(dd->idVendor); - uiaa.product = UGETW(dd->idProduct); - uiaa.release = UGETW(dd->bcdDevice); - uiaa.configno = dev->cdesc->bConfigurationValue; - uiaa.ifaces = ifaces; - uiaa.nifaces = nifaces; - ilocs[USBIFIFCF_PORT] = uiaa.port; - ilocs[USBIFIFCF_VENDOR] = uiaa.vendor; - ilocs[USBIFIFCF_PRODUCT] = uiaa.product; - ilocs[USBIFIFCF_RELEASE] = uiaa.release; - ilocs[USBIFIFCF_CONFIGURATION] = uiaa.configno; + + uiaa.uiaa_device = dev; + uiaa.uiaa_port = port; + uiaa.uiaa_vendor = UGETW(dd->idVendor); + uiaa.uiaa_product = UGETW(dd->idProduct); + uiaa.uiaa_release = UGETW(dd->bcdDevice); + uiaa.uiaa_configno = dev->ud_cdesc->bConfigurationValue; + uiaa.uiaa_ifaces = ifaces; + uiaa.uiaa_nifaces = nifaces; + ilocs[USBIFIFCF_PORT] = uiaa.uiaa_port; + ilocs[USBIFIFCF_VENDOR] = uiaa.uiaa_vendor; + ilocs[USBIFIFCF_PRODUCT] = uiaa.uiaa_product; + ilocs[USBIFIFCF_RELEASE] = uiaa.uiaa_release; + ilocs[USBIFIFCF_CONFIGURATION] = uiaa.uiaa_configno; for (i = 0; i < nifaces; i++) { if (!ifaces[i]) { DPRINTF("interface %d claimed", i, 0, 0, 0); continue; /* interface already claimed */ } - uiaa.iface = ifaces[i]; - uiaa.class = ifaces[i]->idesc->bInterfaceClass; - uiaa.subclass = ifaces[i]->idesc->bInterfaceSubClass; - uiaa.proto = ifaces[i]->idesc->bInterfaceProtocol; - uiaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber; + uiaa.uiaa_iface = ifaces[i]; + uiaa.uiaa_class = ifaces[i]->ui_idesc->bInterfaceClass; + uiaa.uiaa_subclass = ifaces[i]->ui_idesc->bInterfaceSubClass; + uiaa.uiaa_proto = ifaces[i]->ui_idesc->bInterfaceProtocol; + uiaa.uiaa_ifaceno = ifaces[i]->ui_idesc->bInterfaceNumber; - DPRINTF("searching for interface %d", i, 0, 0, 0); + DPRINTF("searching for interface %d...", i, 0, 0, 0); DPRINTF("class %x subclass %x proto %x ifaceno %d", - uiaa.class, uiaa.subclass, uiaa.proto, uiaa.ifaceno); - ilocs[USBIFIFCF_INTERFACE] = uiaa.ifaceno; + uiaa.uiaa_class, uiaa.uiaa_subclass, uiaa.uiaa_proto, + uiaa.uiaa_ifaceno); + ilocs[USBIFIFCF_INTERFACE] = uiaa.uiaa_ifaceno; if (locators != NULL) { loc = locators[USBIFIFCF_CONFIGURATION]; if (loc != USBIFIFCF_CONFIGURATION_DEFAULT && - loc != uiaa.configno) + loc != uiaa.uiaa_configno) continue; loc = locators[USBIFIFCF_INTERFACE]; if (loc != USBIFIFCF_INTERFACE_DEFAULT && - loc != uiaa.ifaceno) + loc != uiaa.uiaa_ifaceno) continue; } KERNEL_LOCK(1, NULL); @@ -954,34 +994,34 @@ usbd_attachinterfaces(device_t parent, usbd_device_handle dev, ifaces[i] = NULL; /* account for ifaces claimed by the driver behind our back */ for (j = 0; j < nifaces; j++) { - if (!ifaces[j] && !dev->subdevs[j]) { - DPRINTF("interface %d claimed " - "behind our back", j, 0, 0, 0); - dev->subdevs[j] = dv; - dev->nifaces_claimed++; + + if (!ifaces[j] && !dev->ud_subdevs[j]) { + DPRINTF("interface %d claimed behind our back", + j, 0, 0, 0); + dev->ud_subdevs[j] = dv; + dev->ud_nifaces_claimed++; } } } - free(ifaces, M_USB); - return (USBD_NORMAL_COMPLETION); + kmem_free(ifaces, nifaces * sizeof(*ifaces)); + return USBD_NORMAL_COMPLETION; } usbd_status -usbd_probe_and_attach(device_t parent, usbd_device_handle dev, +usbd_probe_and_attach(device_t parent, struct usbd_device *dev, int port, int addr) { - usb_device_descriptor_t *dd = &dev->ddesc; + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + usb_device_descriptor_t *dd = &dev->ud_ddesc; int confi, nifaces; usbd_status err; - USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - /* First try with device specific drivers. */ DPRINTF("trying device specific drivers", 0, 0, 0, 0); err = usbd_attachwholedevice(parent, dev, port, 0); - if (dev->nifaces_claimed || err) - return (err); + if (dev->ud_nifaces_claimed || err) + return err; DPRINTF("no device specific driver found", 0, 0, 0, 0); DPRINTF("looping over %d configurations", dd->bNumConfigurations, @@ -994,24 +1034,25 @@ usbd_probe_and_attach(device_t parent, usbd_device_handle dev, "error=%d", port, addr, err, 0); printf("%s: port %d, set config at addr %d failed\n", device_xname(parent), port, addr); - return (err); + return err; } - nifaces = dev->cdesc->bNumInterface; - dev->subdevs = malloc(nifaces * sizeof(device_t), M_USB, - M_NOWAIT|M_ZERO); - if (dev->subdevs == NULL) - return (USBD_NOMEM); - dev->subdevlen = nifaces; + nifaces = dev->ud_cdesc->bNumInterface; + dev->ud_subdevs = kmem_zalloc(nifaces * sizeof(device_t), + KM_SLEEP); + if (dev->ud_subdevs == NULL) + return USBD_NOMEM; + dev->ud_subdevlen = nifaces; err = usbd_attachinterfaces(parent, dev, port, NULL); - if (!dev->nifaces_claimed) { - free(dev->subdevs, M_USB); - dev->subdevs = 0; - dev->subdevlen = 0; + if (!dev->ud_nifaces_claimed) { + kmem_free(dev->ud_subdevs, + dev->ud_subdevlen * sizeof(device_t)); + dev->ud_subdevs = 0; + dev->ud_subdevlen = 0; } - if (dev->nifaces_claimed || err) - return (err); + if (dev->ud_nifaces_claimed || err) + return err; } /* No interfaces were attached in any of the configurations. */ @@ -1029,7 +1070,8 @@ usbd_probe_and_attach(device_t parent, usbd_device_handle dev, * fully operational and not harming anyone. */ DPRINTF("generic attach failed", 0, 0, 0, 0); - return (USBD_NORMAL_COMPLETION); + + return USBD_NORMAL_COMPLETION; } /** @@ -1037,7 +1079,7 @@ usbd_probe_and_attach(device_t parent, usbd_device_handle dev, * called before calling this. */ usbd_status -usbd_reattach_device(device_t parent, usbd_device_handle dev, +usbd_reattach_device(device_t parent, struct usbd_device *dev, int port, const int *locators) { int i, loc; @@ -1048,32 +1090,32 @@ usbd_reattach_device(device_t parent, usbd_device_handle dev, return USBD_NORMAL_COMPLETION; loc = locators[USBIFIFCF_VENDOR]; if (loc != USBIFIFCF_VENDOR_DEFAULT && - loc != UGETW(dev->ddesc.idVendor)) + loc != UGETW(dev->ud_ddesc.idVendor)) return USBD_NORMAL_COMPLETION; loc = locators[USBIFIFCF_PRODUCT]; if (loc != USBIFIFCF_PRODUCT_DEFAULT && - loc != UGETW(dev->ddesc.idProduct)) + loc != UGETW(dev->ud_ddesc.idProduct)) return USBD_NORMAL_COMPLETION; loc = locators[USBIFIFCF_RELEASE]; if (loc != USBIFIFCF_RELEASE_DEFAULT && - loc != UGETW(dev->ddesc.bcdDevice)) + loc != UGETW(dev->ud_ddesc.bcdDevice)) return USBD_NORMAL_COMPLETION; } - if (dev->subdevlen == 0) { + if (dev->ud_subdevlen == 0) { /* XXX: check USBIFIFCF_CONFIGURATION and * USBIFIFCF_INTERFACE too */ - return usbd_probe_and_attach(parent, dev, port, dev->address); - } else if (dev->subdevlen != dev->cdesc->bNumInterface) { + return usbd_probe_and_attach(parent, dev, port, dev->ud_addr); + } else if (dev->ud_subdevlen != dev->ud_cdesc->bNumInterface) { /* device-specific or generic driver is already attached. */ return USBD_NORMAL_COMPLETION; } /* Does the device have unconfigured interfaces? */ - for (i = 0; i < dev->subdevlen; i++) { - if (dev->subdevs[i] == NULL) { + for (i = 0; i < dev->ud_subdevlen; i++) { + if (dev->ud_subdevs[i] == NULL) { break; } } - if (i >= dev->subdevlen) + if (i >= dev->ud_subdevlen) return USBD_NORMAL_COMPLETION; return usbd_attachinterfaces(parent, dev, port, locators); } @@ -1085,12 +1127,15 @@ usbd_reattach_device(device_t parent, usbd_device_handle dev, * MaxPacketSize is known by the host) by exactly this length. */ usbd_status -usbd_get_initial_ddesc(usbd_device_handle dev, usb_device_descriptor_t *desc) +usbd_get_initial_ddesc(struct usbd_device *dev, usb_device_descriptor_t *desc) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usb_device_request_t req; char buf[64]; int res, actlen; + DPRINTFN(5, "dev %p", dev, 0, 0, 0); + req.bmRequestType = UT_READ_DEVICE; req.bRequest = UR_GET_DESCRIPTOR; USETW2(req.wValue, UDESC_DEVICE, 0); @@ -1113,10 +1158,11 @@ usbd_get_initial_ddesc(usbd_device_handle dev, usb_device_descriptor_t *desc) * and attach a driver. */ usbd_status -usbd_new_device(device_t parent, usbd_bus_handle bus, int depth, +usbd_new_device(device_t parent, struct usbd_bus* bus, int depth, int speed, int port, struct usbd_port *up) { - usbd_device_handle dev, adev; + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + struct usbd_device *dev, *adev; struct usbd_device *hub; usb_device_descriptor_t *dd; usb_port_status_t ps; @@ -1125,68 +1171,66 @@ usbd_new_device(device_t parent, usbd_bus_handle bus, int depth, int i; int p; - USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - DPRINTF("bus=%p port=%d depth=%d speed=%d", bus, port, depth, speed); - if (bus->methods->new_device != NULL) - return (bus->methods->new_device)(parent, bus, depth, speed, + if (bus->ub_methods->ubm_newdev != NULL) + return (bus->ub_methods->ubm_newdev)(parent, bus, depth, speed, port, up); addr = usbd_getnewaddr(bus); if (addr < 0) { printf("%s: No free USB addresses, new device ignored.\n", - device_xname(bus->usbctl)); - return (USBD_NO_ADDR); + device_xname(bus->ub_usbctl)); + return USBD_NO_ADDR; } - dev = malloc(sizeof *dev, M_USB, M_NOWAIT|M_ZERO); + dev = kmem_zalloc(sizeof(*dev), KM_SLEEP); if (dev == NULL) - return (USBD_NOMEM); + return USBD_NOMEM; - dev->bus = bus; + dev->ud_bus = bus; /* Set up default endpoint handle. */ - dev->def_ep.edesc = &dev->def_ep_desc; + dev->ud_ep0.ue_edesc = &dev->ud_ep0desc; /* Set up default endpoint descriptor. */ - dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE; - dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT; - dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT; - dev->def_ep_desc.bmAttributes = UE_CONTROL; + dev->ud_ep0desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE; + dev->ud_ep0desc.bDescriptorType = UDESC_ENDPOINT; + dev->ud_ep0desc.bEndpointAddress = USB_CONTROL_ENDPOINT; + dev->ud_ep0desc.bmAttributes = UE_CONTROL; /* * temporary, will be fixed after first descriptor fetch * (which uses 64 bytes so it shouldn't be less), * highspeed devices must support 64 byte packets anyway */ if (speed == USB_SPEED_HIGH || speed == USB_SPEED_FULL) - USETW(dev->def_ep_desc.wMaxPacketSize, 64); + USETW(dev->ud_ep0desc.wMaxPacketSize, 64); else - USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET); + USETW(dev->ud_ep0desc.wMaxPacketSize, USB_MAX_IPACKET); - dev->def_ep_desc.bInterval = 0; + dev->ud_ep0desc.bInterval = 0; /* doesn't matter, just don't leave it uninitialized */ - dev->def_ep.datatoggle = 0; + dev->ud_ep0.ue_toggle = 0; - dev->quirks = &usbd_no_quirk; - dev->address = USB_START_ADDR; - dev->ddesc.bMaxPacketSize = 0; - dev->depth = depth; - dev->powersrc = up; - dev->myhub = up->parent; + dev->ud_quirks = &usbd_no_quirk; + dev->ud_addr = USB_START_ADDR; + dev->ud_ddesc.bMaxPacketSize = 0; + dev->ud_depth = depth; + dev->ud_powersrc = up; + dev->ud_myhub = up->up_parent; - up->device = dev; + up->up_dev = dev; /* Locate port on upstream high speed hub */ - for (adev = dev, hub = up->parent; - hub != NULL && hub->speed != USB_SPEED_HIGH; - adev = hub, hub = hub->myhub) + for (adev = dev, hub = up->up_parent; + hub != NULL && hub->ud_speed != USB_SPEED_HIGH; + adev = hub, hub = hub->ud_myhub) ; if (hub) { - for (p = 0; p < hub->hub->hubdesc.bNbrPorts; p++) { - if (hub->hub->ports[p].device == adev) { - dev->myhsport = &hub->hub->ports[p]; + for (p = 0; p < hub->ud_hub->uh_hubdesc.bNbrPorts; p++) { + if (hub->ud_hub->uh_ports[p].up_dev == adev) { + dev->ud_myhsport = &hub->ud_hub->uh_ports[p]; goto found; } } @@ -1194,21 +1238,21 @@ usbd_new_device(device_t parent, usbd_bus_handle bus, int depth, found: DPRINTFN(1, "high speed port %d", p, 0, 0, 0); } else { - dev->myhsport = NULL; + dev->ud_myhsport = NULL; } - dev->speed = speed; - dev->langid = USBD_NOLANG; - dev->cookie.cookie = ++usb_cookie_no; + dev->ud_speed = speed; + dev->ud_langid = USBD_NOLANG; + dev->ud_cookie.cookie = ++usb_cookie_no; /* Establish the default pipe. */ - err = usbd_setup_pipe_flags(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL, - &dev->default_pipe, USBD_MPSAFE); + err = usbd_setup_pipe_flags(dev, 0, &dev->ud_ep0, USBD_DEFAULT_INTERVAL, + &dev->ud_pipe0, USBD_MPSAFE); if (err) { usbd_remove_device(dev, up); - return (err); + return err; } - dd = &dev->ddesc; + dd = &dev->ud_ddesc; /* Try a few times in case the device is slow (i.e. outside specs.) */ for (i = 0; i < 10; i++) { /* Get the first 8 bytes of the device descriptor. */ @@ -1217,18 +1261,18 @@ usbd_new_device(device_t parent, usbd_bus_handle bus, int depth, break; usbd_delay_ms(dev, 200); if ((i & 3) == 3) - usbd_reset_port(up->parent, port, &ps); + usbd_reset_port(up->up_parent, port, &ps); } if (err) { DPRINTF("addr=%d, getting first desc failed: %d", addr, err, 0, 0); usbd_remove_device(dev, up); - return (err); + return err; } /* Windows resets the port here, do likewise */ - if (up->parent) - usbd_reset_port(up->parent, port, &ps); + if (up->up_parent) + usbd_reset_port(up->up_parent, port, &ps); if (speed == USB_SPEED_HIGH) { /* Max packet size must be 64 (sec 5.5.3). */ @@ -1245,27 +1289,27 @@ usbd_new_device(device_t parent, usbd_bus_handle bus, int depth, DPRINTF("adding unit addr=%d, rev=%02x, class=%d, subclass=%d", addr, UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass); DPRINTF("protocol=%d, maxpacket=%d, len=%d, speed=%d", - dd->bDeviceProtocol, dd->bMaxPacketSize, dd->bLength, dev->speed); + dd->bDeviceProtocol, dd->bMaxPacketSize, dd->bLength, dev->ud_speed); if (dd->bDescriptorType != UDESC_DEVICE) { /* Illegal device descriptor */ DPRINTF("illegal descriptor %d", dd->bDescriptorType, 0, 0, 0); usbd_remove_device(dev, up); - return (USBD_INVAL); + return USBD_INVAL; } if (dd->bLength < USB_DEVICE_DESCRIPTOR_SIZE) { DPRINTF("bad length %d", dd->bLength, 0, 0, 0); usbd_remove_device(dev, up); - return (USBD_INVAL); + return USBD_INVAL; } - USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize); + USETW(dev->ud_ep0desc.wMaxPacketSize, dd->bMaxPacketSize); /* Re-establish the default pipe with the new MPS. */ - usbd_kill_pipe(dev->default_pipe); - err = usbd_setup_pipe_flags(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL, - &dev->default_pipe, USBD_MPSAFE); + usbd_kill_pipe(dev->ud_pipe0); + err = usbd_setup_pipe_flags(dev, 0, &dev->ud_ep0, USBD_DEFAULT_INTERVAL, + &dev->ud_pipe0, USBD_MPSAFE); if (err) { DPRINTF("setup default pipe failed err %d", err, 0, 0, 0); usbd_remove_device(dev, up); @@ -1284,13 +1328,13 @@ usbd_new_device(device_t parent, usbd_bus_handle bus, int depth, /* Allow device time to set new address */ usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE); - dev->address = addr; /* new device address now */ - bus->devices[addr] = dev; + dev->ud_addr = addr; /* new device address now */ + bus->ub_devices[addr] = dev; /* Re-establish the default pipe with the new address. */ - usbd_kill_pipe(dev->default_pipe); - err = usbd_setup_pipe_flags(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL, - &dev->default_pipe, USBD_MPSAFE); + usbd_kill_pipe(dev->ud_pipe0); + err = usbd_setup_pipe_flags(dev, 0, &dev->ud_ep0, USBD_DEFAULT_INTERVAL, + &dev->ud_pipe0, USBD_MPSAFE); if (err) { DPRINTF("setup default pipe failed, err = %d", err, 0, 0, 0); usbd_remove_device(dev, up); @@ -1302,12 +1346,12 @@ usbd_new_device(device_t parent, usbd_bus_handle bus, int depth, DPRINTF("addr=%d, getting full desc failed, err = %d", addr, err, 0, 0); usbd_remove_device(dev, up); - return (err); + return err; } /* Assume 100mA bus powered for now. Changed when configured. */ - dev->power = USB_MIN_POWER; - dev->self_powered = 0; + dev->ud_power = USB_MIN_POWER; + dev->ud_selfpowered = 0; DPRINTF("new dev (addr %d), dev=%p, parent=%p", addr, dev, parent, 0); @@ -1318,48 +1362,68 @@ usbd_new_device(device_t parent, usbd_bus_handle bus, int depth, if (port == 0) { /* root hub */ KASSERT(addr == 1); usbd_attach_roothub(parent, dev); - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } err = usbd_probe_and_attach(parent, dev, port, addr); if (err) { usbd_remove_device(dev, up); - return (err); + return err; } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } usbd_status -usbd_reload_device_desc(usbd_device_handle dev) +usbd_reload_device_desc(struct usbd_device *dev) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + usb_device_descriptor_t *udd = &dev->ud_ddesc; usbd_status err; /* Get the full device descriptor. */ - err = usbd_get_device_desc(dev, &dev->ddesc); + err = usbd_get_device_desc(dev, udd); if (err) - return (err); + return err; + + DPRINTFN(15, "bLength %5u", udd->bLength, 0, 0, 0); + DPRINTFN(15, "bDescriptorType %5u", udd->bDescriptorType, 0, 0, 0); + DPRINTFN(15, "bcdUSB %2x.%02x", udd->bcdUSB[1], + udd->bcdUSB[0], 0, 0); + DPRINTFN(15, "bDeviceClass %5u", udd->bDeviceClass, 0, 0, 0); + DPRINTFN(15, "bDeviceSubClass %5u", udd->bDeviceSubClass, 0, 0, 0); + DPRINTFN(15, "bDeviceProtocol %5u", udd->bDeviceProtocol, 0, 0, 0); + DPRINTFN(15, "bMaxPacketSize0 %5u", udd->bMaxPacketSize, 0, 0, 0); + DPRINTFN(15, "idVendor 0x%04x", udd->idVendor, 0, 0, 0); + DPRINTFN(15, "idProduct 0x%04x", udd->idProduct, 0, 0, 0); + DPRINTFN(15, "bcdDevice %2x.%02x", udd->bcdDevice[1], + udd->bcdDevice[0], 0, 0); + DPRINTFN(15, "iManufacturer %5u", udd->iManufacturer, 0, 0, 0); + DPRINTFN(15, "iProduct %5u", udd->iProduct, 0, 0, 0); + DPRINTFN(15, "iSerial %5u", udd->iSerialNumber, 0, 0, 0); + DPRINTFN(15, "bNumConfigurations %5u", udd->bNumConfigurations, 0, 0, + 0); /* Figure out what's wrong with this device. */ - dev->quirks = usbd_find_quirk(&dev->ddesc); + dev->ud_quirks = usbd_find_quirk(udd); - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } void -usbd_remove_device(usbd_device_handle dev, struct usbd_port *up) +usbd_remove_device(struct usbd_device *dev, struct usbd_port *up) { USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - DPRINTF("dev %p", dev, 0, 0, 0); + DPRINTF("dev %p up %p", dev, up, 0, 0); - if (dev->default_pipe != NULL) - usbd_kill_pipe(dev->default_pipe); - up->device = NULL; - dev->bus->devices[dev->address] = NULL; + if (dev->ud_pipe0 != NULL) + usbd_kill_pipe(dev->ud_pipe0); + up->up_dev = NULL; + dev->ud_bus->ub_devices[dev->ud_addr] = NULL; - free(dev, M_USB); + kmem_free(dev, sizeof(*dev)); } int @@ -1370,73 +1434,73 @@ usbd_print(void *aux, const char *pnp) if (pnp) { #define USB_DEVINFO 1024 char *devinfo; - if (!uaa->usegeneric) - return (QUIET); - devinfo = malloc(USB_DEVINFO, M_TEMP, M_WAITOK); - usbd_devinfo(uaa->device, 1, devinfo, USB_DEVINFO); + if (!uaa->uaa_usegeneric) + return QUIET; + devinfo = kmem_alloc(USB_DEVINFO, KM_SLEEP); + usbd_devinfo(uaa->uaa_device, 1, devinfo, USB_DEVINFO); aprint_normal("%s, %s", devinfo, pnp); - free(devinfo, M_TEMP); + kmem_free(devinfo, USB_DEVINFO); } - aprint_normal(" port %d", uaa->port); + aprint_normal(" port %d", uaa->uaa_port); #if 0 /* * It gets very crowded with these locators on the attach line. * They are not really needed since they are printed in the clear * by each driver. */ - if (uaa->vendor != UHUB_UNK_VENDOR) - aprint_normal(" vendor 0x%04x", uaa->vendor); - if (uaa->product != UHUB_UNK_PRODUCT) - aprint_normal(" product 0x%04x", uaa->product); - if (uaa->release != UHUB_UNK_RELEASE) - aprint_normal(" release 0x%04x", uaa->release); + if (uaa->uaa_vendor != UHUB_UNK_VENDOR) + aprint_normal(" vendor 0x%04x", uaa->uaa_vendor); + if (uaa->uaa_product != UHUB_UNK_PRODUCT) + aprint_normal(" product 0x%04x", uaa->uaa_product); + if (uaa->uaa_release != UHUB_UNK_RELEASE) + aprint_normal(" release 0x%04x", uaa->uaa_release); #endif - return (UNCONF); + return UNCONF; } int usbd_ifprint(void *aux, const char *pnp) { - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; if (pnp) - return (QUIET); - aprint_normal(" port %d", uaa->port); - aprint_normal(" configuration %d", uaa->configno); - aprint_normal(" interface %d", uaa->ifaceno); + return QUIET; + aprint_normal(" port %d", uiaa->uiaa_port); + aprint_normal(" configuration %d", uiaa->uiaa_configno); + aprint_normal(" interface %d", uiaa->uiaa_ifaceno); #if 0 /* * It gets very crowded with these locators on the attach line. * They are not really needed since they are printed in the clear * by each driver. */ - if (uaa->vendor != UHUB_UNK_VENDOR) - aprint_normal(" vendor 0x%04x", uaa->vendor); - if (uaa->product != UHUB_UNK_PRODUCT) - aprint_normal(" product 0x%04x", uaa->product); - if (uaa->release != UHUB_UNK_RELEASE) - aprint_normal(" release 0x%04x", uaa->release); + if (uaa->uaa_vendor != UHUB_UNK_VENDOR) + aprint_normal(" vendor 0x%04x", uaa->uaa_vendor); + if (uaa->uaa_product != UHUB_UNK_PRODUCT) + aprint_normal(" product 0x%04x", uaa->uaa_product); + if (uaa->uaa_release != UHUB_UNK_RELEASE) + aprint_normal(" release 0x%04x", uaa->uaa_release); #endif - return (UNCONF); + return UNCONF; } void -usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di, +usbd_fill_deviceinfo(struct usbd_device *dev, struct usb_device_info *di, int usedev) { struct usbd_port *p; int i, j, err, s; - di->udi_bus = device_unit(dev->bus->usbctl); - di->udi_addr = dev->address; - di->udi_cookie = dev->cookie; + di->udi_bus = device_unit(dev->ud_bus->ub_usbctl); + di->udi_addr = dev->ud_addr; + di->udi_cookie = dev->ud_cookie; usbd_devinfo_vp(dev, di->udi_vendor, sizeof(di->udi_vendor), di->udi_product, sizeof(di->udi_product), usedev, 1); usbd_printBCD(di->udi_release, sizeof(di->udi_release), - UGETW(dev->ddesc.bcdDevice)); + UGETW(dev->ud_ddesc.bcdDevice)); if (usedev) { usbd_status uerr = usbd_get_string(dev, - dev->ddesc.iSerialNumber, di->udi_serial); + dev->ud_ddesc.iSerialNumber, di->udi_serial); if (uerr != USBD_NORMAL_COMPLETION) { di->udi_serial[0] = '\0'; } else { @@ -1449,23 +1513,24 @@ usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di, sizeof(di->udi_serial)); } } - di->udi_vendorNo = UGETW(dev->ddesc.idVendor); - di->udi_productNo = UGETW(dev->ddesc.idProduct); - di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice); - di->udi_class = dev->ddesc.bDeviceClass; - di->udi_subclass = dev->ddesc.bDeviceSubClass; - di->udi_protocol = dev->ddesc.bDeviceProtocol; - di->udi_config = dev->config; - di->udi_power = dev->self_powered ? 0 : dev->power; - di->udi_speed = dev->speed; - - if (dev->subdevlen > 0) { - for (i = 0, j = 0; i < dev->subdevlen && + + di->udi_vendorNo = UGETW(dev->ud_ddesc.idVendor); + di->udi_productNo = UGETW(dev->ud_ddesc.idProduct); + di->udi_releaseNo = UGETW(dev->ud_ddesc.bcdDevice); + di->udi_class = dev->ud_ddesc.bDeviceClass; + di->udi_subclass = dev->ud_ddesc.bDeviceSubClass; + di->udi_protocol = dev->ud_ddesc.bDeviceProtocol; + di->udi_config = dev->ud_config; + di->udi_power = dev->ud_selfpowered ? 0 : dev->ud_power; + di->udi_speed = dev->ud_speed; + + if (dev->ud_subdevlen > 0) { + for (i = 0, j = 0; i < dev->ud_subdevlen && j < USB_MAX_DEVNAMES; i++) { - if (!dev->subdevs[i]) + if (!dev->ud_subdevs[i]) continue; strncpy(di->udi_devnames[j], - device_xname(dev->subdevs[i]), USB_MAX_DEVNAMELEN); + device_xname(dev->ud_subdevs[i]), USB_MAX_DEVNAMELEN); di->udi_devnames[j][USB_MAX_DEVNAMELEN-1] = '\0'; j++; } @@ -1475,20 +1540,28 @@ usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di, for (/* j is set */; j < USB_MAX_DEVNAMES; j++) di->udi_devnames[j][0] = 0; /* empty */ - if (dev->hub) { + if (dev->ud_hub) { for (i = 0; i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) && - i < dev->hub->hubdesc.bNbrPorts; + i < dev->ud_hub->uh_hubdesc.bNbrPorts; i++) { - p = &dev->hub->ports[i]; - if (p->device) - err = p->device->address; + p = &dev->ud_hub->uh_ports[i]; + if (p->up_dev) + err = p->up_dev->ud_addr; else { - s = UGETW(p->status.wPortStatus); + s = UGETW(p->up_status.wPortStatus); if (s & UPS_PORT_ENABLED) err = USB_PORT_ENABLED; else if (s & UPS_SUSPEND) err = USB_PORT_SUSPENDED; + /* + * Note: UPS_PORT_POWER_SS is available only + * on 3.x, and UPS_PORT_POWER is available + * only on 2.0 or 1.1. + */ + else if (USB_IS_SS(dev->ud_speed) && + (s & UPS_PORT_POWER_SS)) + err = USB_PORT_POWERED; else if (s & UPS_PORT_POWER) err = USB_PORT_POWERED; else @@ -1496,43 +1569,43 @@ usbd_fill_deviceinfo(usbd_device_handle dev, struct usb_device_info *di, } di->udi_ports[i] = err; } - di->udi_nports = dev->hub->hubdesc.bNbrPorts; + di->udi_nports = dev->ud_hub->uh_hubdesc.bNbrPorts; } else di->udi_nports = 0; } #ifdef COMPAT_30 void -usbd_fill_deviceinfo_old(usbd_device_handle dev, struct usb_device_info_old *di, +usbd_fill_deviceinfo_old(struct usbd_device *dev, struct usb_device_info_old *di, int usedev) { struct usbd_port *p; int i, j, err, s; - di->udi_bus = device_unit(dev->bus->usbctl); - di->udi_addr = dev->address; - di->udi_cookie = dev->cookie; + di->udi_bus = device_unit(dev->ud_bus->ub_usbctl); + di->udi_addr = dev->ud_addr; + di->udi_cookie = dev->ud_cookie; usbd_devinfo_vp(dev, di->udi_vendor, sizeof(di->udi_vendor), di->udi_product, sizeof(di->udi_product), usedev, 0); usbd_printBCD(di->udi_release, sizeof(di->udi_release), - UGETW(dev->ddesc.bcdDevice)); - di->udi_vendorNo = UGETW(dev->ddesc.idVendor); - di->udi_productNo = UGETW(dev->ddesc.idProduct); - di->udi_releaseNo = UGETW(dev->ddesc.bcdDevice); - di->udi_class = dev->ddesc.bDeviceClass; - di->udi_subclass = dev->ddesc.bDeviceSubClass; - di->udi_protocol = dev->ddesc.bDeviceProtocol; - di->udi_config = dev->config; - di->udi_power = dev->self_powered ? 0 : dev->power; - di->udi_speed = dev->speed; - - if (dev->subdevlen > 0) { - for (i = 0, j = 0; i < dev->subdevlen && + UGETW(dev->ud_ddesc.bcdDevice)); + di->udi_vendorNo = UGETW(dev->ud_ddesc.idVendor); + di->udi_productNo = UGETW(dev->ud_ddesc.idProduct); + di->udi_releaseNo = UGETW(dev->ud_ddesc.bcdDevice); + di->udi_class = dev->ud_ddesc.bDeviceClass; + di->udi_subclass = dev->ud_ddesc.bDeviceSubClass; + di->udi_protocol = dev->ud_ddesc.bDeviceProtocol; + di->udi_config = dev->ud_config; + di->udi_power = dev->ud_selfpowered ? 0 : dev->ud_power; + di->udi_speed = dev->ud_speed; + + if (dev->ud_subdevlen > 0) { + for (i = 0, j = 0; i < dev->ud_subdevlen && j < USB_MAX_DEVNAMES; i++) { - if (!dev->subdevs[i]) + if (!dev->ud_subdevs[i]) continue; strncpy(di->udi_devnames[j], - device_xname(dev->subdevs[i]), USB_MAX_DEVNAMELEN); + device_xname(dev->ud_subdevs[i]), USB_MAX_DEVNAMELEN); di->udi_devnames[j][USB_MAX_DEVNAMELEN-1] = '\0'; j++; } @@ -1542,16 +1615,16 @@ usbd_fill_deviceinfo_old(usbd_device_handle dev, struct usb_device_info_old *di, for (/* j is set */; j < USB_MAX_DEVNAMES; j++) di->udi_devnames[j][0] = 0; /* empty */ - if (dev->hub) { + if (dev->ud_hub) { for (i = 0; i < sizeof(di->udi_ports) / sizeof(di->udi_ports[0]) && - i < dev->hub->hubdesc.bNbrPorts; + i < dev->ud_hub->uh_hubdesc.bNbrPorts; i++) { - p = &dev->hub->ports[i]; - if (p->device) - err = p->device->address; + p = &dev->ud_hub->uh_ports[i]; + if (p->up_dev) + err = p->up_dev->ud_addr; else { - s = UGETW(p->status.wPortStatus); + s = UGETW(p->up_status.wPortStatus); if (s & UPS_PORT_ENABLED) err = USB_PORT_ENABLED; else if (s & UPS_SUSPEND) @@ -1563,7 +1636,7 @@ usbd_fill_deviceinfo_old(usbd_device_handle dev, struct usb_device_info_old *di, } di->udi_ports[i] = err; } - di->udi_nports = dev->hub->hubdesc.bNbrPorts; + di->udi_nports = dev->ud_hub->uh_hubdesc.bNbrPorts; } else di->udi_nports = 0; } @@ -1571,23 +1644,27 @@ usbd_fill_deviceinfo_old(usbd_device_handle dev, struct usb_device_info_old *di, void -usb_free_device(usbd_device_handle dev) +usb_free_device(struct usbd_device *dev) { int ifcidx, nifc; - if (dev->default_pipe != NULL) - usbd_kill_pipe(dev->default_pipe); - if (dev->ifaces != NULL) { - nifc = dev->cdesc->bNumInterface; + if (dev->ud_pipe0 != NULL) + usbd_kill_pipe(dev->ud_pipe0); + if (dev->ud_ifaces != NULL) { + nifc = dev->ud_cdesc->bNumInterface; for (ifcidx = 0; ifcidx < nifc; ifcidx++) usbd_free_iface_data(dev, ifcidx); - free(dev->ifaces, M_USB); + kmem_free(dev->ud_ifaces, + nifc * sizeof(struct usbd_interface)); } - if (dev->cdesc != NULL) - free(dev->cdesc, M_USB); - if (dev->subdevlen > 0) { - free(dev->subdevs, M_USB); - dev->subdevlen = 0; + if (dev->ud_cdesc != NULL) + kmem_free(dev->ud_cdesc, UGETW(dev->ud_cdesc->wTotalLength)); + if (dev->ud_bdesc != NULL) + kmem_free(dev->ud_bdesc, UGETW(dev->ud_bdesc->wTotalLength)); + if (dev->ud_subdevlen > 0) { + kmem_free(dev->ud_subdevs, + dev->ud_subdevlen * sizeof(device_t)); + dev->ud_subdevlen = 0; } if (dev->ud_vendor) { kmem_free(dev->ud_vendor, USB_MAX_ENCODED_STRING_LEN); @@ -1598,7 +1675,7 @@ usb_free_device(usbd_device_handle dev) if (dev->ud_serial) { kmem_free(dev->ud_serial, USB_MAX_ENCODED_STRING_LEN); } - free(dev, M_USB); + kmem_free(dev, sizeof(*dev)); } /* @@ -1621,14 +1698,14 @@ usb_free_device(usbd_device_handle dev) int usb_disconnect_port(struct usbd_port *up, device_t parent, int flags) { - usbd_device_handle dev = up->device; + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + struct usbd_device *dev = up->up_dev; device_t subdev; char subdevname[16]; const char *hubname = device_xname(parent); int i, rc; - USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - DPRINTFN(3, "up=%p dev=%p port=%d", up, dev, up->portno, 0); + DPRINTFN(3, "up=%p dev=%p port=%d", up, dev, up->up_portno, 0); if (dev == NULL) { #ifdef DIAGNOSTIC @@ -1637,26 +1714,26 @@ usb_disconnect_port(struct usbd_port *up, device_t parent, int flags) return 0; } - if (dev->subdevlen > 0) { + if (dev->ud_subdevlen > 0) { DPRINTFN(3, "disconnect subdevs", 0, 0, 0, 0); - for (i = 0; i < dev->subdevlen; i++) { - if ((subdev = dev->subdevs[i]) == NULL) + for (i = 0; i < dev->ud_subdevlen; i++) { + if ((subdev = dev->ud_subdevs[i]) == NULL) continue; strlcpy(subdevname, device_xname(subdev), sizeof(subdevname)); if ((rc = config_detach(subdev, flags)) != 0) return rc; printf("%s: at %s", subdevname, hubname); - if (up->portno != 0) - printf(" port %d", up->portno); - printf(" (addr %d) disconnected\n", dev->address); + if (up->up_portno != 0) + printf(" port %d", up->up_portno); + printf(" (addr %d) disconnected\n", dev->ud_addr); } - KASSERT(!dev->nifaces_claimed); + KASSERT(!dev->ud_nifaces_claimed); } usbd_add_dev_event(USB_EVENT_DEVICE_DETACH, dev); - dev->bus->devices[dev->address] = NULL; - up->device = NULL; + dev->ud_bus->ub_devices[dev->ud_addr] = NULL; + up->up_dev = NULL; usb_free_device(dev); return 0; } diff --git a/sys/dev/usb/usbdevices.config b/sys/dev/usb/usbdevices.config index 16738411cfb..a750158fb43 100644 --- a/sys/dev/usb/usbdevices.config +++ b/sys/dev/usb/usbdevices.config @@ -1,4 +1,4 @@ -# $NetBSD: usbdevices.config,v 1.24 2014/03/16 09:34:45 martin Exp $ +# $NetBSD: usbdevices.config,v 1.25 2016/04/23 10:15:32 skrll Exp $ # # This file contains all USB related configuration. # It is suitable for inclusion in a kernel config(5) file. @@ -106,6 +106,10 @@ irframe* at stuirda? ustir* at uhub? port ? irframe* at ustir? +# KingSun/DonShine USB/IrDA Bridge +udsir* at uhub? port ? +irframe* at udsir? + # Windows Media Center IR transceiver irmce* at uhub? port ? cir* at irmce? diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 04f9dd44482..a2cb30b2b8f 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -1,4 +1,4 @@ -$NetBSD: usbdevs,v 1.713 2016/04/19 15:50:24 nonaka Exp $ +$NetBSD: usbdevs,v 1.714 2016/04/23 10:15:32 skrll Exp $ /* * Copyright (c) 1998-2004 The NetBSD Foundation, Inc. diff --git a/sys/dev/usb/usbdevs.h b/sys/dev/usb/usbdevs.h index 1fd8215c903..4f43c3dba9b 100644 --- a/sys/dev/usb/usbdevs.h +++ b/sys/dev/usb/usbdevs.h @@ -1,10 +1,10 @@ -/* $NetBSD: usbdevs.h,v 1.705 2016/04/19 15:51:21 nonaka Exp $ */ +/* $NetBSD: usbdevs.h,v 1.706 2016/04/23 10:15:32 skrll Exp $ */ /* * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. * * generated from: - * NetBSD: usbdevs,v 1.713 2016/04/19 15:50:24 nonaka Exp + * NetBSD: usbdevs,v 1.684.2.6 2016/04/22 13:43:55 skrll Exp */ /* diff --git a/sys/dev/usb/usbdevs_data.h b/sys/dev/usb/usbdevs_data.h index 0d320546ac5..3285ae0ddbf 100644 --- a/sys/dev/usb/usbdevs_data.h +++ b/sys/dev/usb/usbdevs_data.h @@ -1,10 +1,10 @@ -/* $NetBSD: usbdevs_data.h,v 1.706 2016/04/19 15:51:21 nonaka Exp $ */ +/* $NetBSD: usbdevs_data.h,v 1.707 2016/04/23 10:15:32 skrll Exp $ */ /* * THIS FILE AUTOMATICALLY GENERATED. DO NOT EDIT. * * generated from: - * NetBSD: usbdevs,v 1.713 2016/04/19 15:50:24 nonaka Exp + * NetBSD: usbdevs,v 1.684.2.6 2016/04/22 13:43:55 skrll Exp */ /* diff --git a/sys/dev/usb/usbdi.c b/sys/dev/usb/usbdi.c index 3d50996e68e..0ef5651f11b 100644 --- a/sys/dev/usb/usbdi.c +++ b/sys/dev/usb/usbdi.c @@ -1,12 +1,13 @@ -/* $NetBSD: usbdi.c,v 1.168 2015/12/22 22:26:16 skrll Exp $ */ +/* $NetBSD: usbdi.c,v 1.169 2016/04/23 10:15:32 skrll Exp $ */ /* - * Copyright (c) 1998, 2012 The NetBSD Foundation, Inc. + * Copyright (c) 1998, 2012, 2015 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Lennart Augustsson (lennart@augustsson.net) at - * Carlstedt Research & Technology and Matthew R. Green (mrg@eterna.com.au). + * Carlstedt Research & Technology, Matthew R. Green (mrg@eterna.com.au), + * and Nick Hudson. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,18 +32,19 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.168 2015/12/22 22:26:16 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.169 2016/04/23 10:15:32 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" #include "opt_compat_netbsd.h" +#include "usb_dma.h" #endif #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/device.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/proc.h> #include <sys/bus.h> #include <sys/cpu.h> @@ -60,10 +62,14 @@ __KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.168 2015/12/22 22:26:16 skrll Exp $"); extern int usbdebug; -Static usbd_status usbd_ar_pipe(usbd_pipe_handle); -Static void usbd_start_next(usbd_pipe_handle); +Static usbd_status usbd_ar_pipe(struct usbd_pipe *); +Static void usbd_start_next(struct usbd_pipe *); Static usbd_status usbd_open_pipe_ival - (usbd_interface_handle, u_int8_t, u_int8_t, usbd_pipe_handle *, int); + (struct usbd_interface *, uint8_t, uint8_t, struct usbd_pipe **, int); +static void *usbd_alloc_buffer(struct usbd_xfer *, uint32_t); +static void usbd_free_buffer(struct usbd_xfer *); +static struct usbd_xfer *usbd_alloc_xfer(struct usbd_device *, unsigned int); +static usbd_status usbd_free_xfer(struct usbd_xfer *); #if defined(USB_DEBUG) void @@ -71,13 +77,13 @@ usbd_dump_iface(struct usbd_interface *iface) { USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - USBHIST_LOG(usbdebug, "iface %p\n", iface, 0, 0, 0); + USBHIST_LOG(usbdebug, "iface %p", iface, 0, 0, 0); if (iface == NULL) return; USBHIST_LOG(usbdebug, " device = %p idesc = %p index = %d", - iface->device, iface->idesc, iface->index, 0); + iface->ui_dev, iface->ui_idesc, iface->ui_index, 0); USBHIST_LOG(usbdebug, " altindex=%d priv=%p", - iface->altindex, iface->priv, 0, 0); + iface->ui_altindex, iface->ui_priv, 0, 0); } void @@ -89,12 +95,12 @@ usbd_dump_device(struct usbd_device *dev) if (dev == NULL) return; USBHIST_LOG(usbdebug, " bus = %p default_pipe = %p", - dev->bus, dev->default_pipe, 0, 0); + dev->ud_bus, dev->ud_pipe0, 0, 0); USBHIST_LOG(usbdebug, " address = %d config = %d depth = %d ", - dev->address, dev->config, dev->depth, 0); + dev->ud_addr, dev->ud_config, dev->ud_depth, 0); USBHIST_LOG(usbdebug, " speed = %d self_powered = %d " "power = %d langid = %d", - dev->speed, dev->self_powered, dev->power, dev->langid); + dev->ud_speed, dev->ud_selfpowered, dev->ud_power, dev->ud_langid); } void @@ -106,57 +112,57 @@ usbd_dump_endpoint(struct usbd_endpoint *endp) if (endp == NULL) return; USBHIST_LOG(usbdebug, " edesc = %p refcnt = %d", - endp->edesc, endp->refcnt, 0, 0); - if (endp->edesc) + endp->ue_edesc, endp->ue_refcnt, 0, 0); + if (endp->ue_edesc) USBHIST_LOG(usbdebug, " bEndpointAddress=0x%02x", - endp->edesc->bEndpointAddress, 0, 0, 0); + endp->ue_edesc->bEndpointAddress, 0, 0, 0); } void -usbd_dump_queue(usbd_pipe_handle pipe) +usbd_dump_queue(struct usbd_pipe *pipe) { - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; USBHIST_FUNC(); USBHIST_CALLED(usbdebug); USBHIST_LOG(usbdebug, "pipe = %p", pipe, 0, 0, 0); - SIMPLEQ_FOREACH(xfer, &pipe->queue, next) { + SIMPLEQ_FOREACH(xfer, &pipe->up_queue, ux_next) { USBHIST_LOG(usbdebug, " xfer = %p", xfer, 0, 0, 0); } } void -usbd_dump_pipe(usbd_pipe_handle pipe) +usbd_dump_pipe(struct usbd_pipe *pipe) { USBHIST_FUNC(); USBHIST_CALLED(usbdebug); USBHIST_LOG(usbdebug, "pipe = %p", pipe, 0, 0, 0); if (pipe == NULL) return; - usbd_dump_iface(pipe->iface); - usbd_dump_device(pipe->device); - usbd_dump_endpoint(pipe->endpoint); + usbd_dump_iface(pipe->up_iface); + usbd_dump_device(pipe->up_dev); + usbd_dump_endpoint(pipe->up_endpoint); USBHIST_LOG(usbdebug, "(usbd_dump_pipe)", 0, 0, 0, 0); - USBHIST_LOG(usbdebug, " refcnt = %d running = %d aborting = %d", - pipe->refcnt, pipe->running, pipe->aborting, 0); + USBHIST_LOG(usbdebug, " running = %d aborting = %d", + pipe->up_running, pipe->up_aborting, 0, 0); USBHIST_LOG(usbdebug, " intrxfer = %p, repeat = %d, interval = %d", - pipe->intrxfer, pipe->repeat, pipe->interval, 0); + pipe->up_intrxfer, pipe->up_repeat, pipe->up_interval, 0); } #endif usbd_status -usbd_open_pipe(usbd_interface_handle iface, u_int8_t address, - u_int8_t flags, usbd_pipe_handle *pipe) +usbd_open_pipe(struct usbd_interface *iface, uint8_t address, + uint8_t flags, struct usbd_pipe **pipe) { return (usbd_open_pipe_ival(iface, address, flags, pipe, USBD_DEFAULT_INTERVAL)); } usbd_status -usbd_open_pipe_ival(usbd_interface_handle iface, u_int8_t address, - u_int8_t flags, usbd_pipe_handle *pipe, int ival) +usbd_open_pipe_ival(struct usbd_interface *iface, uint8_t address, + uint8_t flags, struct usbd_pipe **pipe, int ival) { - usbd_pipe_handle p; + struct usbd_pipe *p; struct usbd_endpoint *ep; usbd_status err; int i; @@ -166,34 +172,34 @@ usbd_open_pipe_ival(usbd_interface_handle iface, u_int8_t address, USBHIST_LOG(usbdebug, "iface = %p address = 0x%x flags = 0x%x", iface, address, flags, 0); - for (i = 0; i < iface->idesc->bNumEndpoints; i++) { - ep = &iface->endpoints[i]; - if (ep->edesc == NULL) - return (USBD_IOERROR); - if (ep->edesc->bEndpointAddress == address) + for (i = 0; i < iface->ui_idesc->bNumEndpoints; i++) { + ep = &iface->ui_endpoints[i]; + if (ep->ue_edesc == NULL) + return USBD_IOERROR; + if (ep->ue_edesc->bEndpointAddress == address) goto found; } - return (USBD_BAD_ADDRESS); + return USBD_BAD_ADDRESS; found: - if ((flags & USBD_EXCLUSIVE_USE) && ep->refcnt != 0) - return (USBD_IN_USE); - err = usbd_setup_pipe_flags(iface->device, iface, ep, ival, &p, flags); + if ((flags & USBD_EXCLUSIVE_USE) && ep->ue_refcnt != 0) + return USBD_IN_USE; + err = usbd_setup_pipe_flags(iface->ui_dev, iface, ep, ival, &p, flags); if (err) - return (err); - LIST_INSERT_HEAD(&iface->pipes, p, next); + return err; + LIST_INSERT_HEAD(&iface->ui_pipes, p, up_next); *pipe = p; - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } usbd_status -usbd_open_pipe_intr(usbd_interface_handle iface, u_int8_t address, - u_int8_t flags, usbd_pipe_handle *pipe, - usbd_private_handle priv, void *buffer, u_int32_t len, +usbd_open_pipe_intr(struct usbd_interface *iface, uint8_t address, + uint8_t flags, struct usbd_pipe **pipe, + void *priv, void *buffer, uint32_t len, usbd_callback cb, int ival) { usbd_status err; - usbd_xfer_handle xfer; - usbd_pipe_handle ipipe; + struct usbd_xfer *xfer; + struct usbd_pipe *ipipe; USBHIST_FUNC(); USBHIST_CALLED(usbdebug); @@ -204,68 +210,67 @@ usbd_open_pipe_intr(usbd_interface_handle iface, u_int8_t address, USBD_EXCLUSIVE_USE | (flags & USBD_MPSAFE), &ipipe, ival); if (err) - return (err); - xfer = usbd_alloc_xfer(iface->device); - if (xfer == NULL) { - err = USBD_NOMEM; + return err; + err = usbd_create_xfer(ipipe, len, flags, 0, &xfer); + if (err) goto bad1; - } - usbd_setup_xfer(xfer, ipipe, priv, buffer, len, flags, - USBD_NO_TIMEOUT, cb); - ipipe->intrxfer = xfer; - ipipe->repeat = 1; + + usbd_setup_xfer(xfer, priv, buffer, len, flags, USBD_NO_TIMEOUT, cb); + ipipe->up_intrxfer = xfer; + ipipe->up_repeat = 1; err = usbd_transfer(xfer); *pipe = ipipe; if (err != USBD_IN_PROGRESS) - goto bad2; - return (USBD_NORMAL_COMPLETION); + goto bad3; + return USBD_NORMAL_COMPLETION; - bad2: - ipipe->intrxfer = NULL; - ipipe->repeat = 0; - usbd_free_xfer(xfer); + bad3: + ipipe->up_intrxfer = NULL; + ipipe->up_repeat = 0; + + usbd_destroy_xfer(xfer); bad1: usbd_close_pipe(ipipe); - return (err); + return err; } usbd_status -usbd_close_pipe(usbd_pipe_handle pipe) +usbd_close_pipe(struct usbd_pipe *pipe) { - USBHIST_FUNC(); USBHIST_CALLED(usbdebug); -#ifdef DIAGNOSTIC - if (pipe == NULL) { - USBHIST_LOG(usbdebug, "pipe == NULL", 0, 0, 0, 0); - return (USBD_NORMAL_COMPLETION); - } -#endif + KASSERT(pipe != NULL); usbd_lock_pipe(pipe); - if (--pipe->refcnt != 0) { - usbd_unlock_pipe(pipe); - return (USBD_NORMAL_COMPLETION); + + if (!SIMPLEQ_EMPTY(&pipe->up_queue)) { + printf("WARNING: pipe closed with active xfers on addr %d\n", + pipe->up_dev->ud_addr); + usbd_ar_pipe(pipe); } - if (! SIMPLEQ_EMPTY(&pipe->queue)) { - usbd_unlock_pipe(pipe); - return (USBD_PENDING_REQUESTS); + + KASSERT(SIMPLEQ_EMPTY(&pipe->up_queue)); + + LIST_REMOVE(pipe, up_next); + pipe->up_endpoint->ue_refcnt--; + + if (pipe->up_intrxfer != NULL) { + usbd_unlock_pipe(pipe); + usbd_destroy_xfer(pipe->up_intrxfer); + usbd_lock_pipe(pipe); } - LIST_REMOVE(pipe, next); - pipe->endpoint->refcnt--; - pipe->methods->close(pipe); + + pipe->up_methods->upm_close(pipe); usbd_unlock_pipe(pipe); - if (pipe->intrxfer != NULL) - usbd_free_xfer(pipe->intrxfer); - free(pipe, M_USB); - return (USBD_NORMAL_COMPLETION); + kmem_free(pipe, pipe->up_dev->ud_bus->ub_pipesize); + + return USBD_NORMAL_COMPLETION; } usbd_status -usbd_transfer(usbd_xfer_handle xfer) +usbd_transfer(struct usbd_xfer *xfer) { - usbd_pipe_handle pipe = xfer->pipe; - usb_dma_t *dmap = &xfer->dmabuf; + struct usbd_pipe *pipe = xfer->ux_pipe; usbd_status err; unsigned int size, flags; @@ -273,305 +278,379 @@ usbd_transfer(usbd_xfer_handle xfer) USBHIST_LOG(usbdebug, "xfer = %p, flags = %#x, pipe = %p, running = %d", - xfer, xfer->flags, pipe, pipe->running); + xfer, xfer->ux_flags, pipe, pipe->up_running); #ifdef USB_DEBUG if (usbdebug > 5) usbd_dump_queue(pipe); #endif - xfer->done = 0; + xfer->ux_done = 0; - if (pipe->aborting) { + if (pipe->up_aborting) { USBHIST_LOG(usbdebug, "<- done xfer %p, aborting", xfer, 0, 0, 0); - return (USBD_CANCELLED); + return USBD_CANCELLED; } - 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; + KASSERT(xfer->ux_length == 0 || xfer->ux_buf != NULL); -#ifdef DIAGNOSTIC - if (xfer->rqflags & URQ_AUTO_DMABUF) - printf("usbd_transfer: has old buffer!\n"); -#endif - err = bus->methods->allocm(bus, dmap, size); - if (err) { - USBHIST_LOG(usbdebug, - "<- done xfer %p, no mem", xfer, 0, 0, 0); - return (err); - } - xfer->rqflags |= URQ_AUTO_DMABUF; - } + size = xfer->ux_length; + flags = xfer->ux_flags; - flags = xfer->flags; + if (size != 0) { + /* + * Use the xfer buffer if none specified in transfer setup. + * isoc transfers always use the xfer buffer, i.e. + * ux_buffer is always NULL for isoc. + */ + if (xfer->ux_buffer == NULL) { + xfer->ux_buffer = xfer->ux_buf; + } - /* Copy data if going out. */ - if (!(flags & USBD_NO_COPY) && size != 0 && !usbd_xfer_isread(xfer)) - memcpy(KERNADDR(dmap, 0), xfer->buffer, size); + /* + * If not using the xfer buffer copy data to the + * xfer buffer for OUT transfers of >0 length + */ + if (xfer->ux_buffer != xfer->ux_buf) { + KASSERT(xfer->ux_buf); + if (!usbd_xfer_isread(xfer)) { + memcpy(xfer->ux_buf, xfer->ux_buffer, size); + } + } + } /* xfer is not valid after the transfer method unless synchronous */ - err = pipe->methods->transfer(xfer); + err = pipe->up_methods->upm_transfer(xfer); USBHIST_LOG(usbdebug, "<- done transfer %p, err = %d", xfer, err, 0, 0); if (err != USBD_IN_PROGRESS && err) { - /* The transfer has not been queued, so free buffer. */ - if (xfer->rqflags & URQ_AUTO_DMABUF) { - struct usbd_bus *bus = pipe->device->bus; - - bus->methods->freem(bus, &xfer->dmabuf); - xfer->rqflags &= ~URQ_AUTO_DMABUF; - } /* * The transfer made it onto the pipe queue, but didn't get * accepted by the HCD for some reason. It needs removing * from the pipe queue. */ usbd_lock_pipe(pipe); - SIMPLEQ_REMOVE_HEAD(&pipe->queue, next); - usbd_start_next(pipe); + SIMPLEQ_REMOVE_HEAD(&pipe->up_queue, ux_next); + if (pipe->up_serialise) + usbd_start_next(pipe); usbd_unlock_pipe(pipe); } if (!(flags & USBD_SYNCHRONOUS)) { USBHIST_LOG(usbdebug, "<- done xfer %p, not sync (err %d)", xfer, err, 0, 0); - return (err); + return err; } if (err != USBD_IN_PROGRESS) { - USBHIST_LOG(usbdebug, "<- done xfer %p, not in progress " - "(err %d)", xfer, err, 0, 0); - return (err); + USBHIST_LOG(usbdebug, "<- done xfer %p, err %d (complete/error)", xfer, + err, 0, 0); + return err; } /* Sync transfer, wait for completion. */ usbd_lock_pipe(pipe); - while (!xfer->done) { - if (pipe->device->bus->use_polling) + while (!xfer->ux_done) { + if (pipe->up_dev->ud_bus->ub_usepolling) panic("usbd_transfer: not done"); USBHIST_LOG(usbdebug, "<- sleeping on xfer %p", xfer, 0, 0, 0); err = 0; if ((flags & USBD_SYNCHRONOUS_SIG) != 0) { - err = cv_wait_sig(&xfer->cv, pipe->device->bus->lock); + err = cv_wait_sig(&xfer->ux_cv, pipe->up_dev->ud_bus->ub_lock); } else { - cv_wait(&xfer->cv, pipe->device->bus->lock); + cv_wait(&xfer->ux_cv, pipe->up_dev->ud_bus->ub_lock); } if (err) { - if (!xfer->done) - pipe->methods->abort(xfer); + if (!xfer->ux_done) + pipe->up_methods->upm_abort(xfer); break; } } usbd_unlock_pipe(pipe); - return (xfer->status); + return xfer->ux_status; } /* Like usbd_transfer(), but waits for completion. */ usbd_status -usbd_sync_transfer(usbd_xfer_handle xfer) +usbd_sync_transfer(struct usbd_xfer *xfer) { - xfer->flags |= USBD_SYNCHRONOUS; - return (usbd_transfer(xfer)); + xfer->ux_flags |= USBD_SYNCHRONOUS; + return usbd_transfer(xfer); } /* Like usbd_transfer(), but waits for completion and listens for signals. */ usbd_status -usbd_sync_transfer_sig(usbd_xfer_handle xfer) +usbd_sync_transfer_sig(struct usbd_xfer *xfer) { - xfer->flags |= USBD_SYNCHRONOUS | USBD_SYNCHRONOUS_SIG; - return (usbd_transfer(xfer)); + xfer->ux_flags |= USBD_SYNCHRONOUS | USBD_SYNCHRONOUS_SIG; + return usbd_transfer(xfer); } -void * -usbd_alloc_buffer(usbd_xfer_handle xfer, u_int32_t size) +static void * +usbd_alloc_buffer(struct usbd_xfer *xfer, uint32_t size) { - struct usbd_bus *bus = xfer->device->bus; - usbd_status err; + KASSERT(xfer->ux_buf == NULL); + KASSERT(size != 0); -#ifdef DIAGNOSTIC - if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF)) - printf("usbd_alloc_buffer: xfer already has a buffer\n"); + xfer->ux_bufsize = 0; +#if NUSB_DMA > 0 + struct usbd_bus *bus = xfer->ux_bus; + + if (bus->ub_usedma) { + usb_dma_t *dmap = &xfer->ux_dmabuf; + + int err = usb_allocmem_flags(bus, size, 0, dmap, bus->ub_dmaflags); + if (err) { + return NULL; + } + xfer->ux_buf = KERNADDR(&xfer->ux_dmabuf, 0); + xfer->ux_bufsize = size; + + return xfer->ux_buf; + } #endif - err = bus->methods->allocm(bus, &xfer->dmabuf, size); - if (err) - return (NULL); - xfer->rqflags |= URQ_DEV_DMABUF; - return (KERNADDR(&xfer->dmabuf, 0)); + KASSERT(xfer->ux_bus->ub_usedma == false); + xfer->ux_buf = kmem_alloc(size, KM_SLEEP); + + if (xfer->ux_buf != NULL) { + xfer->ux_bufsize = size; + } + + return xfer->ux_buf; } -void -usbd_free_buffer(usbd_xfer_handle xfer) +static void +usbd_free_buffer(struct usbd_xfer *xfer) { -#ifdef DIAGNOSTIC - if (!(xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))) { - printf("usbd_free_buffer: no buffer\n"); + KASSERT(xfer->ux_buf != NULL); + KASSERT(xfer->ux_bufsize != 0); + + void *buf = xfer->ux_buf; + uint32_t size = xfer->ux_bufsize; + + xfer->ux_buf = NULL; + xfer->ux_bufsize = 0; + +#if NUSB_DMA > 0 + struct usbd_bus *bus = xfer->ux_bus; + + if (bus->ub_usedma) { + usb_dma_t *dmap = &xfer->ux_dmabuf; + + usb_freemem(bus, dmap); return; } #endif - xfer->rqflags &= ~(URQ_DEV_DMABUF | URQ_AUTO_DMABUF); - xfer->device->bus->methods->freem(xfer->device->bus, &xfer->dmabuf); + KASSERT(xfer->ux_bus->ub_usedma == false); + + kmem_free(buf, size); } void * -usbd_get_buffer(usbd_xfer_handle xfer) +usbd_get_buffer(struct usbd_xfer *xfer) +{ + return xfer->ux_buf; +} + +struct usbd_pipe * +usbd_get_pipe0(struct usbd_device *dev) { - if (!(xfer->rqflags & URQ_DEV_DMABUF)) - return (NULL); - return (KERNADDR(&xfer->dmabuf, 0)); + + return dev->ud_pipe0; } -usbd_xfer_handle -usbd_alloc_xfer(usbd_device_handle dev) +static struct usbd_xfer * +usbd_alloc_xfer(struct usbd_device *dev, unsigned int nframes) { - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - xfer = dev->bus->methods->allocx(dev->bus); + ASSERT_SLEEPABLE(); + + xfer = dev->ud_bus->ub_methods->ubm_allocx(dev->ud_bus, nframes); if (xfer == NULL) - return (NULL); - xfer->device = dev; - callout_init(&xfer->timeout_handle, CALLOUT_MPSAFE); - cv_init(&xfer->cv, "usbxfer"); - cv_init(&xfer->hccv, "usbhcxfer"); + return NULL; + xfer->ux_bus = dev->ud_bus; + callout_init(&xfer->ux_callout, CALLOUT_MPSAFE); + cv_init(&xfer->ux_cv, "usbxfer"); + cv_init(&xfer->ux_hccv, "usbhcxfer"); USBHIST_LOG(usbdebug, "returns %p", xfer, 0, 0, 0); - return (xfer); + return xfer; } -usbd_status -usbd_free_xfer(usbd_xfer_handle xfer) +static usbd_status +usbd_free_xfer(struct usbd_xfer *xfer) { USBHIST_FUNC(); USBHIST_CALLED(usbdebug); USBHIST_LOG(usbdebug, "%p", xfer, 0, 0, 0); - if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF)) + if (xfer->ux_buf) { usbd_free_buffer(xfer); + } #if defined(DIAGNOSTIC) - if (callout_pending(&xfer->timeout_handle)) { - callout_stop(&xfer->timeout_handle); + if (callout_pending(&xfer->ux_callout)) { + callout_stop(&xfer->ux_callout); printf("usbd_free_xfer: timeout_handle pending\n"); } #endif - cv_destroy(&xfer->cv); - cv_destroy(&xfer->hccv); - xfer->device->bus->methods->freex(xfer->device->bus, xfer); - return (USBD_NORMAL_COMPLETION); + cv_destroy(&xfer->ux_cv); + cv_destroy(&xfer->ux_hccv); + xfer->ux_bus->ub_methods->ubm_freex(xfer->ux_bus, xfer); + return USBD_NORMAL_COMPLETION; +} + +int +usbd_create_xfer(struct usbd_pipe *pipe, size_t len, unsigned int flags, + unsigned int nframes, struct usbd_xfer **xp) +{ + KASSERT(xp != NULL); + void *buf; + + struct usbd_xfer *xfer = usbd_alloc_xfer(pipe->up_dev, nframes); + if (xfer == NULL) + return ENOMEM; + + if (len) { + buf = usbd_alloc_buffer(xfer, len); + if (!buf) { + usbd_free_xfer(xfer); + return ENOMEM; + } + } + xfer->ux_pipe = pipe; + xfer->ux_flags = flags; + xfer->ux_nframes = nframes; + xfer->ux_methods = pipe->up_methods; + + if (xfer->ux_methods->upm_init) { + int err = xfer->ux_methods->upm_init(xfer); + if (err) { + if (buf) + usbd_free_buffer(xfer); + usbd_free_xfer(xfer); + return err; + } + } + + *xp = xfer; + return 0; } void -usbd_setup_xfer(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 callback) +usbd_destroy_xfer(struct usbd_xfer *xfer) { - 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; + + if (xfer->ux_methods->upm_fini) { + xfer->ux_methods->upm_fini(xfer); + } + + usbd_free_xfer(xfer); } void -usbd_setup_default_xfer(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 callback) +usbd_setup_xfer(struct usbd_xfer *xfer, void *priv, void *buffer, + uint32_t length, uint16_t flags, uint32_t timeout, usbd_callback callback) { - 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; + KASSERT(xfer->ux_pipe); + + xfer->ux_priv = priv; + xfer->ux_buffer = buffer; + xfer->ux_length = length; + xfer->ux_actlen = 0; + xfer->ux_flags = flags; + xfer->ux_timeout = timeout; + xfer->ux_status = USBD_NOT_STARTED; + xfer->ux_callback = callback; + xfer->ux_rqflags &= ~URQ_REQUEST; + xfer->ux_nframes = 0; } void -usbd_setup_isoc_xfer(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) +usbd_setup_default_xfer(struct usbd_xfer *xfer, struct usbd_device *dev, + void *priv, uint32_t timeout, usb_device_request_t *req, void *buffer, + uint32_t length, uint16_t flags, usbd_callback callback) { - 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; + KASSERT(xfer->ux_pipe == dev->ud_pipe0); + + xfer->ux_priv = priv; + xfer->ux_buffer = buffer; + xfer->ux_length = length; + xfer->ux_actlen = 0; + xfer->ux_flags = flags; + xfer->ux_timeout = timeout; + xfer->ux_status = USBD_NOT_STARTED; + xfer->ux_callback = callback; + xfer->ux_request = *req; + xfer->ux_rqflags |= URQ_REQUEST; + xfer->ux_nframes = 0; } void -usbd_get_xfer_status(usbd_xfer_handle xfer, usbd_private_handle *priv, - void **buffer, u_int32_t *count, usbd_status *status) +usbd_setup_isoc_xfer(struct usbd_xfer *xfer, void *priv, uint16_t *frlengths, + uint32_t nframes, uint16_t flags, usbd_callback callback) +{ + xfer->ux_priv = priv; + xfer->ux_buffer = NULL; + xfer->ux_length = 0; + xfer->ux_actlen = 0; + xfer->ux_flags = flags; + xfer->ux_timeout = USBD_NO_TIMEOUT; + xfer->ux_status = USBD_NOT_STARTED; + xfer->ux_callback = callback; + xfer->ux_rqflags &= ~URQ_REQUEST; + xfer->ux_frlengths = frlengths; + xfer->ux_nframes = nframes; +} + +void +usbd_get_xfer_status(struct usbd_xfer *xfer, void **priv, + void **buffer, uint32_t *count, usbd_status *status) { if (priv != NULL) - *priv = xfer->priv; + *priv = xfer->ux_priv; if (buffer != NULL) - *buffer = xfer->buffer; + *buffer = xfer->ux_buffer; if (count != NULL) - *count = xfer->actlen; + *count = xfer->ux_actlen; if (status != NULL) - *status = xfer->status; + *status = xfer->ux_status; } usb_config_descriptor_t * -usbd_get_config_descriptor(usbd_device_handle dev) +usbd_get_config_descriptor(struct usbd_device *dev) { -#ifdef DIAGNOSTIC - if (dev == NULL) { - printf("usbd_get_config_descriptor: dev == NULL\n"); - return (NULL); - } -#endif - return (dev->cdesc); + KASSERT(dev != NULL); + + return dev->ud_cdesc; } usb_interface_descriptor_t * -usbd_get_interface_descriptor(usbd_interface_handle iface) +usbd_get_interface_descriptor(struct usbd_interface *iface) { -#ifdef DIAGNOSTIC - if (iface == NULL) { - printf("usbd_get_interface_descriptor: dev == NULL\n"); - return (NULL); - } -#endif - return (iface->idesc); + KASSERT(iface != NULL); + + return iface->ui_idesc; } usb_device_descriptor_t * -usbd_get_device_descriptor(usbd_device_handle dev) +usbd_get_device_descriptor(struct usbd_device *dev) { - return (&dev->ddesc); + KASSERT(dev != NULL); + + return &dev->ud_ddesc; } usb_endpoint_descriptor_t * -usbd_interface2endpoint_descriptor(usbd_interface_handle iface, u_int8_t index) +usbd_interface2endpoint_descriptor(struct usbd_interface *iface, uint8_t index) { - if (index >= iface->idesc->bNumEndpoints) - return (NULL); - return (iface->endpoints[index].edesc); + + if (index >= iface->ui_idesc->bNumEndpoints) + return NULL; + return iface->ui_endpoints[index].ue_edesc; } /* Some drivers may wish to abort requests on the default pipe, * @@ -579,31 +658,26 @@ usbd_interface2endpoint_descriptor(usbd_interface_handle iface, u_int8_t index) usbd_status usbd_abort_default_pipe(struct usbd_device *device) { - - return usbd_abort_pipe(device->default_pipe); + return usbd_abort_pipe(device->ud_pipe0); } usbd_status -usbd_abort_pipe(usbd_pipe_handle pipe) +usbd_abort_pipe(struct usbd_pipe *pipe) { usbd_status err; -#ifdef DIAGNOSTIC - if (pipe == NULL) { - printf("usbd_abort_pipe: pipe==NULL\n"); - return (USBD_NORMAL_COMPLETION); - } -#endif + KASSERT(pipe != NULL); + usbd_lock_pipe(pipe); err = usbd_ar_pipe(pipe); usbd_unlock_pipe(pipe); - return (err); + return err; } usbd_status -usbd_clear_endpoint_stall(usbd_pipe_handle pipe) +usbd_clear_endpoint_stall(struct usbd_pipe *pipe) { - usbd_device_handle dev = pipe->device; + struct usbd_device *dev = pipe->up_dev; usb_device_request_t req; usbd_status err; @@ -613,12 +687,12 @@ usbd_clear_endpoint_stall(usbd_pipe_handle pipe) * Clearing en endpoint stall resets the endpoint toggle, so * do the same to the HC toggle. */ - pipe->methods->cleartoggle(pipe); + pipe->up_methods->upm_cleartoggle(pipe); req.bmRequestType = UT_WRITE_ENDPOINT; req.bRequest = UR_CLEAR_FEATURE; USETW(req.wValue, UF_ENDPOINT_HALT); - USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress); + USETW(req.wIndex, pipe->up_endpoint->ue_edesc->bEndpointAddress); USETW(req.wLength, 0); err = usbd_do_request(dev, &req, 0); #if 0 @@ -628,119 +702,123 @@ XXX should we do this? /* XXX activate pipe */ } #endif - return (err); + return err; } void usbd_clear_endpoint_stall_task(void *arg) { - usbd_pipe_handle pipe = arg; - usbd_device_handle dev = pipe->device; + struct usbd_pipe *pipe = arg; + struct usbd_device *dev = pipe->up_dev; usb_device_request_t req; - pipe->methods->cleartoggle(pipe); + pipe->up_methods->upm_cleartoggle(pipe); req.bmRequestType = UT_WRITE_ENDPOINT; req.bRequest = UR_CLEAR_FEATURE; USETW(req.wValue, UF_ENDPOINT_HALT); - USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress); + USETW(req.wIndex, pipe->up_endpoint->ue_edesc->bEndpointAddress); USETW(req.wLength, 0); (void)usbd_do_request(dev, &req, 0); } void -usbd_clear_endpoint_stall_async(usbd_pipe_handle pipe) +usbd_clear_endpoint_stall_async(struct usbd_pipe *pipe) { - - usb_add_task(pipe->device, &pipe->async_task, USB_TASKQ_DRIVER); + usb_add_task(pipe->up_dev, &pipe->up_async_task, USB_TASKQ_DRIVER); } void -usbd_clear_endpoint_toggle(usbd_pipe_handle pipe) +usbd_clear_endpoint_toggle(struct usbd_pipe *pipe) { - pipe->methods->cleartoggle(pipe); + + pipe->up_methods->upm_cleartoggle(pipe); } usbd_status -usbd_endpoint_count(usbd_interface_handle iface, u_int8_t *count) +usbd_endpoint_count(struct usbd_interface *iface, uint8_t *count) { -#ifdef DIAGNOSTIC - if (iface == NULL || iface->idesc == NULL) { - printf("usbd_endpoint_count: NULL pointer\n"); - return (USBD_INVAL); - } -#endif - *count = iface->idesc->bNumEndpoints; - return (USBD_NORMAL_COMPLETION); + KASSERT(iface != NULL); + KASSERT(iface->ui_idesc != NULL); + + *count = iface->ui_idesc->bNumEndpoints; + return USBD_NORMAL_COMPLETION; } usbd_status -usbd_interface_count(usbd_device_handle dev, u_int8_t *count) +usbd_interface_count(struct usbd_device *dev, uint8_t *count) { - if (dev->cdesc == NULL) - return (USBD_NOT_CONFIGURED); - *count = dev->cdesc->bNumInterface; - return (USBD_NORMAL_COMPLETION); + + if (dev->ud_cdesc == NULL) + return USBD_NOT_CONFIGURED; + *count = dev->ud_cdesc->bNumInterface; + return USBD_NORMAL_COMPLETION; } void -usbd_interface2device_handle(usbd_interface_handle iface, - usbd_device_handle *dev) +usbd_interface2device_handle(struct usbd_interface *iface, + struct usbd_device **dev) { - *dev = iface->device; + + *dev = iface->ui_dev; } usbd_status -usbd_device2interface_handle(usbd_device_handle dev, - u_int8_t ifaceno, usbd_interface_handle *iface) +usbd_device2interface_handle(struct usbd_device *dev, + uint8_t ifaceno, struct usbd_interface **iface) { - if (dev->cdesc == NULL) - return (USBD_NOT_CONFIGURED); - if (ifaceno >= dev->cdesc->bNumInterface) - return (USBD_INVAL); - *iface = &dev->ifaces[ifaceno]; - return (USBD_NORMAL_COMPLETION); + + if (dev->ud_cdesc == NULL) + return USBD_NOT_CONFIGURED; + if (ifaceno >= dev->ud_cdesc->bNumInterface) + return USBD_INVAL; + *iface = &dev->ud_ifaces[ifaceno]; + return USBD_NORMAL_COMPLETION; } -usbd_device_handle -usbd_pipe2device_handle(usbd_pipe_handle pipe) +struct usbd_device * +usbd_pipe2device_handle(struct usbd_pipe *pipe) { - return (pipe->device); + KASSERT(pipe != NULL); + + return pipe->up_dev; } /* XXXX use altno */ usbd_status -usbd_set_interface(usbd_interface_handle iface, int altidx) +usbd_set_interface(struct usbd_interface *iface, int altidx) { usb_device_request_t req; usbd_status err; void *endpoints; - if (LIST_FIRST(&iface->pipes) != 0) - return (USBD_IN_USE); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + if (LIST_FIRST(&iface->ui_pipes) != NULL) + return USBD_IN_USE; - endpoints = iface->endpoints; - err = usbd_fill_iface_data(iface->device, iface->index, altidx); + endpoints = iface->ui_endpoints; + int nendpt = iface->ui_idesc->bNumEndpoints; + USBHIST_LOG(usbdebug, "iface %p endpoints = %p nendpt", iface, + endpoints, iface->ui_idesc->bNumEndpoints, 0); + err = usbd_fill_iface_data(iface->ui_dev, iface->ui_index, altidx); if (err) - return (err); + return err; /* new setting works, we can free old endpoints */ - if (endpoints != NULL) - free(endpoints, M_USB); - -#ifdef DIAGNOSTIC - if (iface->idesc == NULL) { - printf("usbd_set_interface: NULL pointer\n"); - return (USBD_INVAL); + if (endpoints != NULL) { + USBHIST_LOG(usbdebug, "iface %p endpoints = %p nendpt", iface, + endpoints, nendpt, 0); + kmem_free(endpoints, nendpt * sizeof(struct usbd_endpoint)); } -#endif + KASSERT(iface->ui_idesc != NULL); req.bmRequestType = UT_WRITE_INTERFACE; req.bRequest = UR_SET_INTERFACE; - USETW(req.wValue, iface->idesc->bAlternateSetting); - USETW(req.wIndex, iface->idesc->bInterfaceNumber); + USETW(req.wValue, iface->ui_idesc->bAlternateSetting); + USETW(req.wIndex, iface->ui_idesc->bInterfaceNumber); USETW(req.wLength, 0); - return (usbd_do_request(iface->device, &req, 0)); + return usbd_do_request(iface->ui_dev, &req, 0); } int @@ -758,380 +836,284 @@ usbd_get_no_alts(usb_config_descriptor_t *cdesc, int ifaceno) d->bInterfaceNumber == ifaceno) n++; } - return (n); + return n; } int -usbd_get_interface_altindex(usbd_interface_handle iface) +usbd_get_interface_altindex(struct usbd_interface *iface) { - return (iface->altindex); + return iface->ui_altindex; } usbd_status -usbd_get_interface(usbd_interface_handle iface, u_int8_t *aiface) +usbd_get_interface(struct usbd_interface *iface, uint8_t *aiface) { usb_device_request_t req; req.bmRequestType = UT_READ_INTERFACE; req.bRequest = UR_GET_INTERFACE; USETW(req.wValue, 0); - USETW(req.wIndex, iface->idesc->bInterfaceNumber); + USETW(req.wIndex, iface->ui_idesc->bInterfaceNumber); USETW(req.wLength, 1); - return (usbd_do_request(iface->device, &req, aiface)); + return usbd_do_request(iface->ui_dev, &req, aiface); } /*** Internal routines ***/ /* Dequeue all pipe operations, called at splusb(). */ Static usbd_status -usbd_ar_pipe(usbd_pipe_handle pipe) +usbd_ar_pipe(struct usbd_pipe *pipe) { - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - KASSERT(mutex_owned(pipe->device->bus->lock)); + KASSERT(mutex_owned(pipe->up_dev->ud_bus->ub_lock)); USBHIST_LOG(usbdebug, "pipe = %p", pipe, 0, 0, 0); #ifdef USB_DEBUG if (usbdebug > 5) usbd_dump_queue(pipe); #endif - pipe->repeat = 0; - pipe->aborting = 1; - while ((xfer = SIMPLEQ_FIRST(&pipe->queue)) != NULL) { + pipe->up_repeat = 0; + pipe->up_aborting = 1; + while ((xfer = SIMPLEQ_FIRST(&pipe->up_queue)) != NULL) { USBHIST_LOG(usbdebug, "pipe = %p xfer = %p (methods = %p)", - pipe, xfer, pipe->methods, 0); + pipe, xfer, pipe->up_methods, 0); /* Make the HC abort it (and invoke the callback). */ - pipe->methods->abort(xfer); + pipe->up_methods->upm_abort(xfer); /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */ } - pipe->aborting = 0; - return (USBD_NORMAL_COMPLETION); + pipe->up_aborting = 0; + return USBD_NORMAL_COMPLETION; } /* Called with USB lock held. */ void -usb_transfer_complete(usbd_xfer_handle xfer) +usb_transfer_complete(struct usbd_xfer *xfer) { - usbd_pipe_handle pipe = xfer->pipe; - usb_dma_t *dmap = &xfer->dmabuf; - int sync = xfer->flags & USBD_SYNCHRONOUS; - int erred = xfer->status == USBD_CANCELLED || - xfer->status == USBD_TIMEOUT; - int polling = pipe->device->bus->use_polling; - int repeat; + struct usbd_pipe *pipe = xfer->ux_pipe; + struct usbd_bus *bus = pipe->up_dev->ud_bus; + int sync = xfer->ux_flags & USBD_SYNCHRONOUS; + int erred = + xfer->ux_status == USBD_CANCELLED || + xfer->ux_status == USBD_TIMEOUT; + int polling = bus->ub_usepolling; + int repeat = pipe->up_repeat; USBHIST_FUNC(); USBHIST_CALLED(usbdebug); USBHIST_LOG(usbdebug, "pipe = %p xfer = %p status = %d actlen = %d", - pipe, xfer, xfer->status, xfer->actlen); - - KASSERT(polling || mutex_owned(pipe->device->bus->lock)); + pipe, xfer, xfer->ux_status, xfer->ux_actlen); -#ifdef DIAGNOSTIC - if (xfer->busy_free != XFER_ONQU) { - printf("usb_transfer_complete: xfer=%p not queued 0x%08x\n", - xfer, xfer->busy_free); - } -#endif + KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock)); + KASSERT(xfer->ux_state == XFER_ONQU); + KASSERT(pipe != NULL); -#ifdef DIAGNOSTIC - if (pipe == NULL) { - printf("usb_transfer_complete: pipe==0, xfer=%p\n", xfer); - return; - } -#endif - repeat = pipe->repeat; /* XXXX */ if (polling) - pipe->running = 0; - - if (!(xfer->flags & USBD_NO_COPY) && xfer->actlen != 0 && - usbd_xfer_isread(xfer)) { - if (xfer->actlen > xfer->length) { -#ifdef DIAGNOSTIC - printf("%s: actlen (%d) > len (%d)\n", __func__, - xfer->actlen, xfer->length); -#endif - xfer->actlen = xfer->length; - } - memcpy(xfer->buffer, KERNADDR(dmap, 0), xfer->actlen); - } - - /* 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); - xfer->rqflags &= ~URQ_AUTO_DMABUF; - } - } + pipe->up_running = 0; if (!repeat) { /* Remove request from queue. */ - KASSERTMSG(!SIMPLEQ_EMPTY(&pipe->queue), + KASSERTMSG(!SIMPLEQ_EMPTY(&pipe->up_queue), "pipe %p is empty, but xfer %p wants to complete", pipe, xfer); + KASSERTMSG(xfer == SIMPLEQ_FIRST(&pipe->up_queue), + "xfer %p is not start of queue (%p is at start)", xfer, + SIMPLEQ_FIRST(&pipe->up_queue)); + #ifdef DIAGNOSTIC - if (xfer != SIMPLEQ_FIRST(&pipe->queue)) - printf("%s: bad dequeue %p != %p\n", __func__, - xfer, SIMPLEQ_FIRST(&pipe->queue)); - xfer->busy_free = XFER_BUSY; + xfer->ux_state = XFER_BUSY; #endif - SIMPLEQ_REMOVE_HEAD(&pipe->queue, next); + SIMPLEQ_REMOVE_HEAD(&pipe->up_queue, ux_next); } USBHIST_LOG(usbdebug, "xfer %p: repeat %d new head = %p", - xfer, repeat, SIMPLEQ_FIRST(&pipe->queue), 0); + xfer, repeat, SIMPLEQ_FIRST(&pipe->up_queue), 0); /* Count completed transfers. */ - ++pipe->device->bus->stats.uds_requests - [pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE]; + ++pipe->up_dev->ud_bus->ub_stats.uds_requests + [pipe->up_endpoint->ue_edesc->bmAttributes & UE_XFERTYPE]; - xfer->done = 1; - if (!xfer->status && xfer->actlen < xfer->length && - !(xfer->flags & USBD_SHORT_XFER_OK)) { + xfer->ux_done = 1; + if (!xfer->ux_status && xfer->ux_actlen < xfer->ux_length && + !(xfer->ux_flags & USBD_SHORT_XFER_OK)) { USBHIST_LOG(usbdebug, "short transfer %d < %d", - xfer->actlen, xfer->length, 0, 0); - xfer->status = USBD_SHORT_XFER; + xfer->ux_actlen, xfer->ux_length, 0, 0); + xfer->ux_status = USBD_SHORT_XFER; } - if (repeat) { - USBHIST_LOG(usbdebug, "xfer %p doing callback %p status %x", - xfer, xfer->callback, xfer->status, 0); - if (xfer->callback) { - if (!polling) - mutex_exit(pipe->device->bus->lock); - - if (!(pipe->flags & USBD_MPSAFE)) - KERNEL_LOCK(1, curlwp); - xfer->callback(xfer, xfer->priv, xfer->status); - USBHIST_LOG(usbdebug, "xfer %p doing done %p", xfer, - pipe->methods->done, 0, 0); - if (!(pipe->flags & USBD_MPSAFE)) - KERNEL_UNLOCK_ONE(curlwp); - - if (!polling) - mutex_enter(pipe->device->bus->lock); - } - pipe->methods->done(xfer); - } else { - USBHIST_LOG(usbdebug, "xfer %p doing done %p", xfer, - pipe->methods->done, 0, 0); - pipe->methods->done(xfer); - USBHIST_LOG(usbdebug, "xfer %p doing callback %p status %x", - xfer, xfer->callback, xfer->status, 0); - if (xfer->callback) { - if (!polling) - mutex_exit(pipe->device->bus->lock); - - if (!(pipe->flags & USBD_MPSAFE)) - KERNEL_LOCK(1, curlwp); - xfer->callback(xfer, xfer->priv, xfer->status); - if (!(pipe->flags & USBD_MPSAFE)) - KERNEL_UNLOCK_ONE(curlwp); - - if (!polling) - mutex_enter(pipe->device->bus->lock); + USBHIST_LOG(usbdebug, "xfer %p doing done %p", xfer, + pipe->up_methods->upm_done, 0, 0); + pipe->up_methods->upm_done(xfer); + + if (xfer->ux_length != 0 && xfer->ux_buffer != xfer->ux_buf) { + KDASSERTMSG(xfer->ux_actlen <= xfer->ux_length, + "actlen %d length %d",xfer->ux_actlen, xfer->ux_length); + + /* Only if IN transfer */ + if (usbd_xfer_isread(xfer)) { + memcpy(xfer->ux_buffer, xfer->ux_buf, xfer->ux_actlen); } } + USBHIST_LOG(usbdebug, "xfer %p doing callback %p status %d", + xfer, xfer->ux_callback, xfer->ux_status, 0); + + if (xfer->ux_callback) { + if (!polling) + mutex_exit(pipe->up_dev->ud_bus->ub_lock); + + if (!(pipe->up_flags & USBD_MPSAFE)) + KERNEL_LOCK(1, curlwp); + + xfer->ux_callback(xfer, xfer->ux_priv, xfer->ux_status); + + if (!(pipe->up_flags & USBD_MPSAFE)) + KERNEL_UNLOCK_ONE(curlwp); + + if (!polling) + mutex_enter(pipe->up_dev->ud_bus->ub_lock); + } + if (sync && !polling) { USBHIST_LOG(usbdebug, "<- done xfer %p, wakeup", xfer, 0, 0, 0); - cv_broadcast(&xfer->cv); + cv_broadcast(&xfer->ux_cv); } - if (!repeat) { + if (repeat) { + xfer->ux_actlen = 0; + xfer->ux_status = USBD_NOT_STARTED; + } else { /* XXX should we stop the queue on all errors? */ - if (erred && pipe->iface != NULL) /* not control pipe */ - pipe->running = 0; - else - usbd_start_next(pipe); + if (erred && pipe->up_iface != NULL) /* not control pipe */ + pipe->up_running = 0; } + if (pipe->up_running && pipe->up_serialise) + usbd_start_next(pipe); } /* Called with USB lock held. */ usbd_status -usb_insert_transfer(usbd_xfer_handle xfer) +usb_insert_transfer(struct usbd_xfer *xfer) { - usbd_pipe_handle pipe = xfer->pipe; + struct usbd_pipe *pipe = xfer->ux_pipe; usbd_status err; USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - USBHIST_LOG(usbdebug, "pipe = %p running = %d timeout = %d", - pipe, pipe->running, xfer->timeout, 0); + USBHIST_LOG(usbdebug, "xfer = %p pipe = %p running = %d timeout = %d", + xfer, pipe, pipe->up_running, xfer->ux_timeout); - KASSERT(mutex_owned(pipe->device->bus->lock)); + KASSERT(mutex_owned(pipe->up_dev->ud_bus->ub_lock)); + KASSERT(xfer->ux_state == XFER_BUSY); #ifdef DIAGNOSTIC - if (xfer->busy_free != XFER_BUSY) { - USBHIST_LOG(usbdebug, "<- done, xfer %p not busy", xfer, 0, 0, - 0); - printf("usb_insert_transfer: xfer=%p not busy 0x%08x\n", - xfer, xfer->busy_free); - return (USBD_INVAL); - } - xfer->busy_free = XFER_ONQU; + xfer->ux_state = XFER_ONQU; #endif - SIMPLEQ_INSERT_TAIL(&pipe->queue, xfer, next); - if (pipe->running) + SIMPLEQ_INSERT_TAIL(&pipe->up_queue, xfer, ux_next); + if (pipe->up_running && pipe->up_serialise) err = USBD_IN_PROGRESS; else { - pipe->running = 1; + pipe->up_running = 1; err = USBD_NORMAL_COMPLETION; } USBHIST_LOG(usbdebug, "<- done xfer %p, err %d", xfer, err, 0, 0); - return (err); + return err; } /* Called with USB lock held. */ void -usbd_start_next(usbd_pipe_handle pipe) +usbd_start_next(struct usbd_pipe *pipe) { - usbd_xfer_handle xfer; + struct usbd_xfer *xfer; usbd_status err; USBHIST_FUNC(); USBHIST_CALLED(usbdebug); -#ifdef DIAGNOSTIC - if (pipe == NULL) { - printf("usbd_start_next: pipe == NULL\n"); - return; - } - if (pipe->methods == NULL || pipe->methods->start == NULL) { - printf("usbd_start_next: pipe=%p no start method\n", pipe); - return; - } -#endif + KASSERT(pipe != NULL); + KASSERT(pipe->up_methods != NULL); + KASSERT(pipe->up_methods->upm_start != NULL); + KASSERT(pipe->up_serialise == true); - int polling = pipe->device->bus->use_polling; - KASSERT(polling || mutex_owned(pipe->device->bus->lock)); + int polling = pipe->up_dev->ud_bus->ub_usepolling; + KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock)); /* Get next request in queue. */ - xfer = SIMPLEQ_FIRST(&pipe->queue); + xfer = SIMPLEQ_FIRST(&pipe->up_queue); USBHIST_LOG(usbdebug, "pipe = %p, xfer = %p", pipe, xfer, 0, 0); if (xfer == NULL) { - pipe->running = 0; + pipe->up_running = 0; } else { if (!polling) - mutex_exit(pipe->device->bus->lock); - err = pipe->methods->start(xfer); + mutex_exit(pipe->up_dev->ud_bus->ub_lock); + err = pipe->up_methods->upm_start(xfer); if (!polling) - mutex_enter(pipe->device->bus->lock); + mutex_enter(pipe->up_dev->ud_bus->ub_lock); if (err != USBD_IN_PROGRESS) { USBHIST_LOG(usbdebug, "error = %d", err, 0, 0, 0); - pipe->running = 0; + pipe->up_running = 0; /* XXX do what? */ } } - KASSERT(polling || mutex_owned(pipe->device->bus->lock)); + KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock)); } usbd_status -usbd_do_request(usbd_device_handle dev, usb_device_request_t *req, void *data) +usbd_do_request(struct usbd_device *dev, usb_device_request_t *req, void *data) { - return (usbd_do_request_flags(dev, req, data, 0, 0, - USBD_DEFAULT_TIMEOUT)); -} -usbd_status -usbd_do_request_flags(usbd_device_handle dev, usb_device_request_t *req, - void *data, u_int16_t flags, int *actlen, u_int32_t timo) -{ - return (usbd_do_request_flags_pipe(dev, dev->default_pipe, req, - data, flags, actlen, timo)); + return usbd_do_request_flags(dev, req, data, 0, 0, + USBD_DEFAULT_TIMEOUT); } usbd_status -usbd_do_request_flags_pipe(usbd_device_handle dev, usbd_pipe_handle pipe, - usb_device_request_t *req, void *data, u_int16_t flags, int *actlen, - u_int32_t timeout) +usbd_do_request_flags(struct usbd_device *dev, usb_device_request_t *req, + void *data, uint16_t flags, int *actlen, uint32_t timeout) { - usbd_xfer_handle xfer; + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + struct usbd_xfer *xfer; usbd_status err; - USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + ASSERT_SLEEPABLE(); -#ifdef DIAGNOSTIC - if (cpu_intr_p() || cpu_softintr_p()) { - USBHIST_LOG(usbdebug, "not in process context", 0, 0, 0, 0); - return (USBD_INVAL); - } -#endif + size_t len = UGETW(req->wLength); + int error = usbd_create_xfer(dev->ud_pipe0, len, 0, 0, &xfer); + if (error) + return error; - xfer = usbd_alloc_xfer(dev); - if (xfer == NULL) - return (USBD_NOMEM); - usbd_setup_default_xfer(xfer, dev, 0, timeout, req, - data, UGETW(req->wLength), flags, 0); - xfer->pipe = pipe; + usbd_setup_default_xfer(xfer, dev, 0, timeout, req, data, + UGETW(req->wLength), flags, NULL); + KASSERT(xfer->ux_pipe == dev->ud_pipe0); err = usbd_sync_transfer(xfer); #if defined(USB_DEBUG) || defined(DIAGNOSTIC) - if (xfer->actlen > xfer->length) { + if (xfer->ux_actlen > xfer->ux_length) { USBHIST_LOG(usbdebug, "overrun addr = %d type = 0x%02x", - dev->address, xfer->request.bmRequestType, 0, 0); + dev->ud_addr, xfer->ux_request.bmRequestType, 0, 0); USBHIST_LOG(usbdebug, " req = 0x%02x val = %d index = %d", - xfer->request.bRequest, UGETW(xfer->request.wValue), - UGETW(xfer->request.wIndex), 0); + xfer->ux_request.bRequest, UGETW(xfer->ux_request.wValue), + UGETW(xfer->ux_request.wIndex), 0); USBHIST_LOG(usbdebug, " rlen = %d length = %d actlen = %d", - UGETW(xfer->request.wLength), - xfer->length, xfer->actlen, 0); + UGETW(xfer->ux_request.wLength), + xfer->ux_length, xfer->ux_actlen, 0); } #endif 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 - * any halt condition. - */ - usb_device_request_t treq; - usb_status_t status; - u_int16_t s; - 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_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, - &treq, &status,sizeof(usb_status_t), - 0, 0); - nerr = usbd_sync_transfer(xfer); - if (nerr) - goto bad; - s = UGETW(status.wStatus); - USBHIST_LOG(usbdebug, "status = 0x%04x", s, 0, 0, 0); - if (!(s & UES_HALT)) - goto bad; - treq.bmRequestType = UT_WRITE_ENDPOINT; - treq.bRequest = UR_CLEAR_FEATURE; - USETW(treq.wValue, UF_ENDPOINT_HALT); - USETW(treq.wIndex, 0); - USETW(treq.wLength, 0); - usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, - &treq, &status, 0, 0, 0); - nerr = usbd_sync_transfer(xfer); - if (nerr) - goto bad; - } + *actlen = xfer->ux_actlen; + + usbd_destroy_xfer(xfer); - bad: if (err) { USBHIST_LOG(usbdebug, "returning err = %d", err, 0, 0, 0); } - usbd_free_xfer(xfer); - return (err); + return err; } const struct usbd_quirks * -usbd_get_quirks(usbd_device_handle dev) +usbd_get_quirks(struct usbd_device *dev) { #ifdef DIAGNOSTIC if (dev == NULL) { @@ -1139,7 +1121,7 @@ usbd_get_quirks(usbd_device_handle dev) return 0; } #endif - return (dev->quirks); + return dev->ud_quirks; } /* XXX do periodic free() of free list */ @@ -1148,47 +1130,47 @@ usbd_get_quirks(usbd_device_handle dev) * Called from keyboard driver when in polling mode. */ void -usbd_dopoll(usbd_interface_handle iface) +usbd_dopoll(struct usbd_interface *iface) { - iface->device->bus->methods->do_poll(iface->device->bus); + iface->ui_dev->ud_bus->ub_methods->ubm_dopoll(iface->ui_dev->ud_bus); } /* - * XXX use this more??? use_polling it touched manually all over + * XXX use this more??? ub_usepolling it touched manually all over */ void -usbd_set_polling(usbd_device_handle dev, int on) +usbd_set_polling(struct usbd_device *dev, int on) { if (on) - dev->bus->use_polling++; + dev->ud_bus->ub_usepolling++; else - dev->bus->use_polling--; + dev->ud_bus->ub_usepolling--; /* Kick the host controller when switching modes */ - mutex_enter(dev->bus->lock); - (*dev->bus->methods->soft_intr)(dev->bus); - mutex_exit(dev->bus->lock); + mutex_enter(dev->ud_bus->ub_lock); + dev->ud_bus->ub_methods->ubm_softint(dev->ud_bus); + mutex_exit(dev->ud_bus->ub_lock); } usb_endpoint_descriptor_t * -usbd_get_endpoint_descriptor(usbd_interface_handle iface, u_int8_t address) +usbd_get_endpoint_descriptor(struct usbd_interface *iface, uint8_t address) { struct usbd_endpoint *ep; int i; - for (i = 0; i < iface->idesc->bNumEndpoints; i++) { - ep = &iface->endpoints[i]; - if (ep->edesc->bEndpointAddress == address) - return (iface->endpoints[i].edesc); + for (i = 0; i < iface->ui_idesc->bNumEndpoints; i++) { + ep = &iface->ui_endpoints[i]; + if (ep->ue_edesc->bEndpointAddress == address) + return iface->ui_endpoints[i].ue_edesc; } - return (NULL); + return NULL; } /* * usbd_ratecheck() can limit the number of error messages that occurs. * When a device is unplugged it may take up to 0.25s for the hub driver - * to notice it. If the driver continuosly tries to do I/O operations + * to notice it. If the driver continuously tries to do I/O operations * this can generate a large number of messages. */ int @@ -1196,7 +1178,7 @@ usbd_ratecheck(struct timeval *last) { static struct timeval errinterval = { 0, 250000 }; /* 0.25 s*/ - return (ratecheck(last, &errinterval)); + return ratecheck(last, &errinterval); } /* @@ -1205,26 +1187,26 @@ usbd_ratecheck(struct timeval *last) */ const struct usb_devno * usb_match_device(const struct usb_devno *tbl, u_int nentries, u_int sz, - u_int16_t vendor, u_int16_t product) + uint16_t vendor, uint16_t product) { while (nentries-- > 0) { - u_int16_t tproduct = tbl->ud_product; + uint16_t tproduct = tbl->ud_product; if (tbl->ud_vendor == vendor && (tproduct == product || tproduct == USB_PRODUCT_ANY)) - return (tbl); + return tbl; tbl = (const struct usb_devno *)((const char *)tbl + sz); } - return (NULL); + return NULL; } void -usb_desc_iter_init(usbd_device_handle dev, usbd_desc_iter_t *iter) +usb_desc_iter_init(struct usbd_device *dev, usbd_desc_iter_t *iter) { const usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev); - iter->cur = (const uByte *)cd; - iter->end = (const uByte *)cd + UGETW(cd->wTotalLength); + iter->cur = (const uByte *)cd; + iter->end = (const uByte *)cd + UGETW(cd->wTotalLength); } const usb_descriptor_t * @@ -1251,19 +1233,19 @@ usb_desc_iter_next(usbd_desc_iter_t *iter) } usbd_status -usbd_get_string(usbd_device_handle dev, int si, char *buf) +usbd_get_string(struct usbd_device *dev, int si, char *buf) { return usbd_get_string0(dev, si, buf, 1); } usbd_status -usbd_get_string0(usbd_device_handle dev, int si, char *buf, int unicode) +usbd_get_string0(struct usbd_device *dev, int si, char *buf, int unicode) { - int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE; + int swap = dev->ud_quirks->uq_flags & UQ_SWAP_UNICODE; usb_string_descriptor_t us; char *s; int i, n; - u_int16_t c; + uint16_t c; usbd_status err; int size; @@ -1271,25 +1253,25 @@ usbd_get_string0(usbd_device_handle dev, int si, char *buf, int unicode) buf[0] = '\0'; if (si == 0) - return (USBD_INVAL); - if (dev->quirks->uq_flags & UQ_NO_STRINGS) - return (USBD_STALLED); - if (dev->langid == USBD_NOLANG) { + return USBD_INVAL; + if (dev->ud_quirks->uq_flags & UQ_NO_STRINGS) + return USBD_STALLED; + if (dev->ud_langid == USBD_NOLANG) { /* Set up default language */ err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us, &size); if (err || size < 4) { USBHIST_LOG(usbdebug, "getting lang failed, using 0", 0, 0, 0, 0); - dev->langid = 0; /* Well, just pick something then */ + dev->ud_langid = 0; /* Well, just pick something then */ } else { /* Pick the first language as the default. */ - dev->langid = UGETW(us.bString[0]); + dev->ud_langid = UGETW(us.bString[0]); } } - err = usbd_get_string_desc(dev, si, dev->langid, &us, &size); + err = usbd_get_string_desc(dev, si, dev->ud_langid, &us, &size); if (err) - return (err); + return err; s = buf; n = size / 2 - 1; if (unicode) { @@ -1312,5 +1294,5 @@ usbd_get_string0(usbd_device_handle dev, int si, char *buf, int unicode) *s++ = 0; } #endif - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } diff --git a/sys/dev/usb/usbdi.h b/sys/dev/usb/usbdi.h index 161ea2d32fd..612f7197284 100644 --- a/sys/dev/usb/usbdi.h +++ b/sys/dev/usb/usbdi.h @@ -1,4 +1,4 @@ -/* $NetBSD: usbdi.h,v 1.90 2014/07/17 18:42:37 riastradh Exp $ */ +/* $NetBSD: usbdi.h,v 1.91 2016/04/23 10:15:32 skrll Exp $ */ /* $FreeBSD: src/sys/dev/usb/usbdi.h,v 1.18 1999/11/17 22:33:49 n_hibma Exp $ */ /* @@ -34,12 +34,11 @@ #ifndef _USBDI_H_ #define _USBDI_H_ -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_xfer *usbd_xfer_handle; -typedef void *usbd_private_handle; +struct usbd_bus; +struct usbd_device; +struct usbd_interface; +struct usbd_pipe; +struct usbd_xfer; typedef enum { /* keep in sync with usbd_error_strs */ USBD_NORMAL_COMPLETION = 0, /* must be 0 */ @@ -66,18 +65,16 @@ typedef enum { /* keep in sync with usbd_error_strs */ USBD_ERROR_MAX /* must be last */ } usbd_status; -typedef void (*usbd_callback)(usbd_xfer_handle, usbd_private_handle, - usbd_status); +typedef void (*usbd_callback)(struct usbd_xfer *, void *, usbd_status); + +/* Use default (specified by ep. desc.) interval on interrupt pipe */ +#define USBD_DEFAULT_INTERVAL (-1) /* Open flags */ #define USBD_EXCLUSIVE_USE 0x01 #define USBD_MPSAFE 0x80 -/* Use default (specified by ep. desc.) interval on interrupt pipe */ -#define USBD_DEFAULT_INTERVAL (-1) - /* 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_FORCE_SHORT_XFER 0x08 /* force last short packet on write */ @@ -90,103 +87,112 @@ typedef void (*usbd_callback)(usbd_xfer_handle, usbd_private_handle, #define DEVINFOSIZE 1024 -usbd_status usbd_open_pipe(usbd_interface_handle, u_int8_t, - u_int8_t, usbd_pipe_handle *); -usbd_status usbd_close_pipe(usbd_pipe_handle); -usbd_status usbd_transfer(usbd_xfer_handle); -usbd_xfer_handle usbd_alloc_xfer(usbd_device_handle); -usbd_status usbd_free_xfer(usbd_xfer_handle); -void usbd_setup_xfer(usbd_xfer_handle, usbd_pipe_handle, - usbd_private_handle, void *, - u_int32_t, u_int16_t, u_int32_t, - usbd_callback); -void usbd_setup_default_xfer(usbd_xfer_handle, usbd_device_handle, - usbd_private_handle, u_int32_t, - usb_device_request_t *, void *, - u_int32_t, u_int16_t, usbd_callback); -void usbd_setup_isoc_xfer(usbd_xfer_handle, usbd_pipe_handle, - usbd_private_handle, u_int16_t *, - u_int32_t, u_int16_t, usbd_callback); -void usbd_get_xfer_status(usbd_xfer_handle, usbd_private_handle *, - void **, u_int32_t *, usbd_status *); +usbd_status usbd_open_pipe_intr(struct usbd_interface *, uint8_t, uint8_t, + struct usbd_pipe **, void *, void *, uint32_t, usbd_callback, int); +usbd_status usbd_open_pipe(struct usbd_interface *, uint8_t, uint8_t, + struct usbd_pipe **); +usbd_status usbd_close_pipe(struct usbd_pipe *); + +usbd_status usbd_transfer(struct usbd_xfer *); + +void *usbd_get_buffer(struct usbd_xfer *); +struct usbd_pipe *usbd_get_pipe0(struct usbd_device *); + +int usbd_create_xfer(struct usbd_pipe *, size_t, unsigned int, unsigned int, + struct usbd_xfer **); +void usbd_destroy_xfer(struct usbd_xfer *); + +void usbd_setup_xfer(struct usbd_xfer *, void *, void *, + uint32_t, uint16_t, uint32_t, usbd_callback); + +void usbd_setup_default_xfer(struct usbd_xfer *, struct usbd_device *, + void *, uint32_t, usb_device_request_t *, void *, + uint32_t, uint16_t, usbd_callback); + +void usbd_setup_isoc_xfer(struct usbd_xfer *, void *, uint16_t *, + uint32_t, uint16_t, usbd_callback); + +void usbd_get_xfer_status(struct usbd_xfer *, void **, + void **, uint32_t *, usbd_status *); + usb_endpoint_descriptor_t *usbd_interface2endpoint_descriptor - (usbd_interface_handle, u_int8_t); -usbd_status usbd_abort_pipe(usbd_pipe_handle); -usbd_status usbd_abort_default_pipe(usbd_device_handle); -usbd_status usbd_clear_endpoint_stall(usbd_pipe_handle); -void usbd_clear_endpoint_stall_async(usbd_pipe_handle); -void usbd_clear_endpoint_toggle(usbd_pipe_handle); -usbd_status usbd_endpoint_count(usbd_interface_handle, u_int8_t *); -usbd_status usbd_interface_count(usbd_device_handle, u_int8_t *); -void usbd_interface2device_handle(usbd_interface_handle, - usbd_device_handle *); -usbd_status usbd_device2interface_handle(usbd_device_handle, - u_int8_t, usbd_interface_handle *); - -usbd_device_handle usbd_pipe2device_handle(usbd_pipe_handle); -void *usbd_alloc_buffer(usbd_xfer_handle, u_int32_t); -void usbd_free_buffer(usbd_xfer_handle); -void *usbd_get_buffer(usbd_xfer_handle); -usbd_status usbd_sync_transfer(usbd_xfer_handle); -usbd_status usbd_sync_transfer_sig(usbd_xfer_handle); -usbd_status usbd_open_pipe_intr(usbd_interface_handle, u_int8_t, - u_int8_t, usbd_pipe_handle *, - usbd_private_handle, void *, - u_int32_t, usbd_callback, int); -usbd_status usbd_do_request(usbd_device_handle, usb_device_request_t *, void *); -usbd_status usbd_do_request_async(usbd_device_handle, - usb_device_request_t *, void *); -usbd_status usbd_do_request_flags(usbd_device_handle, usb_device_request_t *, - void *, u_int16_t, int*, u_int32_t); -usbd_status usbd_do_request_flags_pipe(usbd_device_handle, usbd_pipe_handle, - usb_device_request_t *, void *, u_int16_t, int *, u_int32_t); -usb_interface_descriptor_t *usbd_get_interface_descriptor - (usbd_interface_handle); -usb_config_descriptor_t *usbd_get_config_descriptor(usbd_device_handle); -usb_device_descriptor_t *usbd_get_device_descriptor(usbd_device_handle); -usbd_status usbd_set_interface(usbd_interface_handle, int); + (struct usbd_interface *, uint8_t); + +usbd_status usbd_abort_pipe(struct usbd_pipe *); +usbd_status usbd_abort_default_pipe(struct usbd_device *); + +usbd_status usbd_clear_endpoint_stall(struct usbd_pipe *); +void usbd_clear_endpoint_stall_async(struct usbd_pipe *); + +void usbd_clear_endpoint_toggle(struct usbd_pipe *); +usbd_status usbd_endpoint_count(struct usbd_interface *, uint8_t *); + +usbd_status usbd_interface_count(struct usbd_device *, uint8_t *); + +void usbd_interface2device_handle(struct usbd_interface *, struct usbd_device **); +usbd_status usbd_device2interface_handle(struct usbd_device *, + uint8_t, struct usbd_interface **); + +struct usbd_device *usbd_pipe2device_handle(struct usbd_pipe *); + +usbd_status usbd_sync_transfer(struct usbd_xfer *); +usbd_status usbd_sync_transfer_sig(struct usbd_xfer *); + +usbd_status usbd_do_request(struct usbd_device *, usb_device_request_t *, void *); +usbd_status usbd_do_request_flags(struct usbd_device *, usb_device_request_t *, + void *, uint16_t, int *, uint32_t); + +usb_interface_descriptor_t * + usbd_get_interface_descriptor(struct usbd_interface *); +usb_endpoint_descriptor_t * + usbd_get_endpoint_descriptor(struct usbd_interface *, uint8_t); + +usb_config_descriptor_t *usbd_get_config_descriptor(struct usbd_device *); +usb_device_descriptor_t *usbd_get_device_descriptor(struct usbd_device *); + +usbd_status usbd_set_interface(struct usbd_interface *, int); +usbd_status usbd_get_interface(struct usbd_interface *, uint8_t *); + int usbd_get_no_alts(usb_config_descriptor_t *, int); -usbd_status usbd_get_interface(usbd_interface_handle, u_int8_t *); -void usbd_fill_deviceinfo(usbd_device_handle, struct usb_device_info *, int); + +void usbd_fill_deviceinfo(struct usbd_device *, struct usb_device_info *, int); #ifdef COMPAT_30 -void usbd_fill_deviceinfo_old(usbd_device_handle, struct usb_device_info_old *, +void usbd_fill_deviceinfo_old(struct usbd_device *, struct usb_device_info_old *, int); #endif -int usbd_get_interface_altindex(usbd_interface_handle); +int usbd_get_interface_altindex(struct usbd_interface *); usb_interface_descriptor_t *usbd_find_idesc(usb_config_descriptor_t *, - int, int); + int, int); usb_endpoint_descriptor_t *usbd_find_edesc(usb_config_descriptor_t *, - int, int, int); + int, int, int); -void usbd_dopoll(usbd_interface_handle); -void usbd_set_polling(usbd_device_handle, int); +void usbd_dopoll(struct usbd_interface *); +void usbd_set_polling(struct usbd_device *, int); const char *usbd_errstr(usbd_status); -void usbd_add_dev_event(int, usbd_device_handle); -void usbd_add_drv_event(int, usbd_device_handle, device_t); +void usbd_add_dev_event(int, struct usbd_device *); +void usbd_add_drv_event(int, struct usbd_device *, device_t); -char *usbd_devinfo_alloc(usbd_device_handle, int); +char *usbd_devinfo_alloc(struct usbd_device *, int); void usbd_devinfo_free(char *); -const struct usbd_quirks *usbd_get_quirks(usbd_device_handle); -usb_endpoint_descriptor_t *usbd_get_endpoint_descriptor - (usbd_interface_handle, u_int8_t); +const struct usbd_quirks *usbd_get_quirks(struct usbd_device *); -usbd_status usbd_reload_device_desc(usbd_device_handle); +usbd_status usbd_reload_device_desc(struct usbd_device *); int usbd_ratecheck(struct timeval *); -usbd_status usbd_get_string(usbd_device_handle, int, char *); -usbd_status usbd_get_string0(usbd_device_handle, int, char *, int); +usbd_status usbd_get_string(struct usbd_device *, int, char *); +usbd_status usbd_get_string0(struct usbd_device *, int, char *, int); /* An iterator for descriptors. */ typedef struct { const uByte *cur; const uByte *end; } usbd_desc_iter_t; -void usb_desc_iter_init(usbd_device_handle, usbd_desc_iter_t *); +void usb_desc_iter_init(struct usbd_device *, usbd_desc_iter_t *); const usb_descriptor_t *usb_desc_iter_next(usbd_desc_iter_t *); /* Used to clear endpoint stalls from the softint */ @@ -211,49 +217,53 @@ struct usb_task { #define USB_TASKQ_NAMES {"usbtask-hc", "usbtask-dr"} #define USB_TASKQ_MPSAFE 0x80 -void usb_add_task(usbd_device_handle, struct usb_task *, int); -void usb_rem_task(usbd_device_handle, struct usb_task *); +void usb_add_task(struct usbd_device *, struct usb_task *, int); +void usb_rem_task(struct usbd_device *, struct usb_task *); #define usb_init_task(t, f, a, fl) ((t)->fun = (f), (t)->arg = (a), (t)->queue = USB_NUM_TASKQS, (t)->flags = (fl)) struct usb_devno { - u_int16_t ud_vendor; - u_int16_t ud_product; + uint16_t ud_vendor; + uint16_t ud_product; }; const struct usb_devno *usb_match_device(const struct usb_devno *, - u_int, u_int, u_int16_t, u_int16_t); + u_int, u_int, uint16_t, uint16_t); #define usb_lookup(tbl, vendor, product) \ - usb_match_device((const struct usb_devno *)(tbl), sizeof (tbl) / sizeof ((tbl)[0]), sizeof ((tbl)[0]), (vendor), (product)) + usb_match_device((const struct usb_devno *)(tbl), sizeof(tbl) / sizeof((tbl)[0]), sizeof((tbl)[0]), (vendor), (product)) #define USB_PRODUCT_ANY 0xffff /* NetBSD attachment information */ /* Attach data */ struct usb_attach_arg { - int port; - int vendor; - int product; - int release; - usbd_device_handle device; /* current device */ - int class, subclass, proto; - int usegeneric; + int uaa_port; + int uaa_vendor; + int uaa_product; + int uaa_release; + struct usbd_device * uaa_device; /* current device */ + int uaa_class; + int uaa_subclass; + int uaa_proto; + int uaa_usegeneric; }; struct usbif_attach_arg { - int port; - int configno; - int ifaceno; - int vendor; - int product; - int release; - usbd_device_handle device; /* current device */ - - usbd_interface_handle iface; /* current interface */ - int class, subclass, proto; + int uiaa_port; + int uiaa_configno; + int uiaa_ifaceno; + int uiaa_vendor; + int uiaa_product; + int uiaa_release; + struct usbd_device * uiaa_device; /* current device */ + + struct usbd_interface * uiaa_iface; /* current interface */ + int uiaa_class; + int uiaa_subclass; + int uiaa_proto; /* XXX need accounting for interfaces not matched to */ - usbd_interface_handle *ifaces; /* all interfaces */ - int nifaces; /* number of interfaces */ + struct usbd_interface **uiaa_ifaces; /* all interfaces */ + int uiaa_nifaces; /* number of interfaces */ }; /* Match codes. */ @@ -289,5 +299,6 @@ struct usbif_attach_arg { #define splhardusb splvm #define IPL_SOFTUSB IPL_SOFTNET #define IPL_USB IPL_VM +#define SOFTINT_USB SOFTINT_NET #endif /* _USBDI_H_ */ diff --git a/sys/dev/usb/usbdi_util.c b/sys/dev/usb/usbdi_util.c index 667e7442082..ac2b6f0e388 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.64 2015/03/27 12:46:51 skrll Exp $ */ +/* $NetBSD: usbdi_util.c,v 1.65 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998, 2012 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usbdi_util.c,v 1.64 2015/03/27 12:46:51 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usbdi_util.c,v 1.65 2016/04/23 10:15:32 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -40,7 +40,7 @@ __KERNEL_RCSID(0, "$NetBSD: usbdi_util.c,v 1.64 2015/03/27 12:46:51 skrll Exp $" #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/proc.h> #include <sys/device.h> #include <sys/bus.h> @@ -52,96 +52,97 @@ __KERNEL_RCSID(0, "$NetBSD: usbdi_util.c,v 1.64 2015/03/27 12:46:51 skrll Exp $" #include <dev/usb/usbdi_util.h> #include <dev/usb/usbhist.h> -#ifdef USB_DEBUG -#define DPRINTF(x) if (usbdebug) printf x -#define DPRINTFN(n,x) if (usbdebug>(n)) printf x -extern int usbdebug; -#else -#define DPRINTF(x) -#define DPRINTFN(n,x) -#endif +#define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(usbdebug,1,FMT,A,B,C,D) +#define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(usbdebug,N,FMT,A,B,C,D) usbd_status -usbd_get_desc(usbd_device_handle dev, int type, int index, int len, void *desc) +usbd_get_desc(struct usbd_device *dev, int type, int index, int len, void *desc) { usb_device_request_t req; - DPRINTFN(3,("usbd_get_desc: type=%d, index=%d, len=%d\n", - type, index, len)); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + DPRINTFN(3,"type=%d, index=%d, len=%d", type, index, len, 0); req.bmRequestType = UT_READ_DEVICE; req.bRequest = UR_GET_DESCRIPTOR; USETW2(req.wValue, type, index); USETW(req.wIndex, 0); USETW(req.wLength, len); - return (usbd_do_request(dev, &req, desc)); + return usbd_do_request(dev, &req, desc); } usbd_status -usbd_get_config_desc(usbd_device_handle dev, int confidx, +usbd_get_config_desc(struct usbd_device *dev, int confidx, usb_config_descriptor_t *d) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usbd_status err; - DPRINTFN(3,("usbd_get_config_desc: confidx=%d\n", confidx)); + DPRINTFN(3, "confidx=%d", confidx, 0, 0, 0); err = usbd_get_desc(dev, UDESC_CONFIG, confidx, USB_CONFIG_DESCRIPTOR_SIZE, d); if (err) - return (err); + return err; if (d->bDescriptorType != UDESC_CONFIG) { - DPRINTFN(-1,("usbd_get_config_desc: confidx=%d, bad desc " - "len=%d type=%d\n", - confidx, d->bLength, d->bDescriptorType)); - return (USBD_INVAL); + DPRINTFN(1, "confidx=%d, bad desc len=%d type=%d", + confidx, d->bLength, d->bDescriptorType, 0); + return USBD_INVAL; } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } usbd_status -usbd_get_config_desc_full(usbd_device_handle dev, int conf, void *d, int size) +usbd_get_config_desc_full(struct usbd_device *dev, int conf, void *d, int size) { - DPRINTFN(3,("usbd_get_config_desc_full: conf=%d\n", conf)); - return (usbd_get_desc(dev, UDESC_CONFIG, conf, size, d)); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + DPRINTFN(3, "conf=%d", conf, 0, 0, 0); + return usbd_get_desc(dev, UDESC_CONFIG, conf, size, d); } usbd_status -usbd_get_bos_desc(usbd_device_handle dev, int confidx, +usbd_get_bos_desc(struct usbd_device *dev, int confidx, usb_bos_descriptor_t *d) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usbd_status err; - DPRINTFN(3,("usbd_get_bos_desc: confidx=%d\n", confidx)); + DPRINTFN(3, "confidx=%d", confidx, 0, 0, 0); err = usbd_get_desc(dev, UDESC_BOS, confidx, USB_BOS_DESCRIPTOR_SIZE, d); if (err) return (err); if (d->bDescriptorType != UDESC_BOS) { - DPRINTFN(-1,("usbd_get_bos_desc: confidx=%d, bad desc " - "len=%d type=%d\n", - confidx, d->bLength, d->bDescriptorType)); - return (USBD_INVAL); + DPRINTFN(1, "confidx=%d, bad desc len=%d type=%d", + confidx, d->bLength, d->bDescriptorType, 0); + return USBD_INVAL; } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } usbd_status -usbd_get_bos_desc_full(usbd_device_handle dev, int conf, void *d, int size) +usbd_get_bos_desc_full(struct usbd_device *dev, int conf, void *d, int size) { - DPRINTFN(3,("usbd_get_bos_desc_full: conf=%d\n", conf)); - return (usbd_get_desc(dev, UDESC_BOS, conf, size, d)); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + DPRINTFN(3, "conf=%d", conf, 0, 0, 0); + return usbd_get_desc(dev, UDESC_BOS, conf, size, d); } usbd_status -usbd_get_device_desc(usbd_device_handle dev, usb_device_descriptor_t *d) +usbd_get_device_desc(struct usbd_device *dev, usb_device_descriptor_t *d) { - DPRINTFN(3,("usbd_get_device_desc:\n")); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + return (usbd_get_desc(dev, UDESC_DEVICE, 0, USB_DEVICE_DESCRIPTOR_SIZE, d)); } usbd_status -usbd_get_device_status(usbd_device_handle dev, usb_status_t *st) +usbd_get_device_status(struct usbd_device *dev, usb_status_t *st) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usb_device_request_t req; req.bmRequestType = UT_READ_DEVICE; @@ -149,27 +150,31 @@ usbd_get_device_status(usbd_device_handle dev, usb_status_t *st) USETW(req.wValue, 0); USETW(req.wIndex, 0); USETW(req.wLength, sizeof(usb_status_t)); - return (usbd_do_request(dev, &req, st)); + return usbd_do_request(dev, &req, st); } usbd_status -usbd_get_hub_status(usbd_device_handle dev, usb_hub_status_t *st) +usbd_get_hub_status(struct usbd_device *dev, usb_hub_status_t *st) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usb_device_request_t req; + DPRINTF("dev %p", dev, 0, 0, 0); req.bmRequestType = UT_READ_CLASS_DEVICE; req.bRequest = UR_GET_STATUS; USETW(req.wValue, 0); USETW(req.wIndex, 0); USETW(req.wLength, sizeof(usb_hub_status_t)); - return (usbd_do_request(dev, &req, st)); + return usbd_do_request(dev, &req, st); } usbd_status -usbd_set_address(usbd_device_handle dev, int addr) +usbd_set_address(struct usbd_device *dev, int addr) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usb_device_request_t req; + DPRINTF("dev %p addr %d", dev, addr, 0, 0); req.bmRequestType = UT_WRITE_DEVICE; req.bRequest = UR_SET_ADDRESS; USETW(req.wValue, addr); @@ -179,194 +184,262 @@ usbd_set_address(usbd_device_handle dev, int addr) } usbd_status -usbd_get_port_status(usbd_device_handle dev, int port, usb_port_status_t *ps) +usbd_get_port_status(struct usbd_device *dev, int port, usb_port_status_t *ps) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usb_device_request_t req; + DPRINTF("dev %p port %d", dev, port, 0, 0); req.bmRequestType = UT_READ_CLASS_OTHER; req.bRequest = UR_GET_STATUS; USETW(req.wValue, 0); USETW(req.wIndex, port); - USETW(req.wLength, sizeof *ps); - return (usbd_do_request(dev, &req, ps)); + USETW(req.wLength, sizeof(*ps)); + return usbd_do_request(dev, &req, ps); +} + +/* USB 3.1 10.16.2.6, 10.16.2.6.3 */ +usbd_status +usbd_get_port_status_ext(struct usbd_device *dev, int port, + usb_port_status_ext_t *pse) +{ + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + usb_device_request_t req; + + DPRINTF("dev %p port %d", dev, port, 0, 0); + req.bmRequestType = UT_READ_CLASS_OTHER; + req.bRequest = UR_GET_STATUS; + USETW2(req.wValue, 0, UR_PST_EXT_PORT_STATUS); + USETW(req.wIndex, port); + USETW(req.wLength, sizeof(*pse)); + return (usbd_do_request(dev, &req, pse)); } usbd_status -usbd_clear_hub_feature(usbd_device_handle dev, int sel) +usbd_clear_hub_feature(struct usbd_device *dev, int sel) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usb_device_request_t req; + DPRINTF("dev %p sel %d", dev, sel, 0, 0); req.bmRequestType = UT_WRITE_CLASS_DEVICE; req.bRequest = UR_CLEAR_FEATURE; USETW(req.wValue, sel); USETW(req.wIndex, 0); USETW(req.wLength, 0); - return (usbd_do_request(dev, &req, 0)); + return usbd_do_request(dev, &req, 0); } usbd_status -usbd_set_hub_feature(usbd_device_handle dev, int sel) +usbd_set_hub_feature(struct usbd_device *dev, int sel) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usb_device_request_t req; + DPRINTF("dev %p sel %d", dev, sel, 0, 0); req.bmRequestType = UT_WRITE_CLASS_DEVICE; req.bRequest = UR_SET_FEATURE; USETW(req.wValue, sel); USETW(req.wIndex, 0); USETW(req.wLength, 0); - return (usbd_do_request(dev, &req, 0)); + return usbd_do_request(dev, &req, 0); } usbd_status -usbd_clear_port_feature(usbd_device_handle dev, int port, int sel) +usbd_clear_port_feature(struct usbd_device *dev, int port, int sel) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usb_device_request_t req; + DPRINTF("dev %p port %d sel %d", dev, port, sel, 0); req.bmRequestType = UT_WRITE_CLASS_OTHER; req.bRequest = UR_CLEAR_FEATURE; USETW(req.wValue, sel); USETW(req.wIndex, port); USETW(req.wLength, 0); - return (usbd_do_request(dev, &req, 0)); + return usbd_do_request(dev, &req, 0); } usbd_status -usbd_set_port_feature(usbd_device_handle dev, int port, int sel) +usbd_set_port_feature(struct usbd_device *dev, int port, int sel) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usb_device_request_t req; + DPRINTF("dev %p port %d sel %d", dev, sel, 0, 0); req.bmRequestType = UT_WRITE_CLASS_OTHER; req.bRequest = UR_SET_FEATURE; USETW(req.wValue, sel); USETW(req.wIndex, port); USETW(req.wLength, 0); - return (usbd_do_request(dev, &req, 0)); + return usbd_do_request(dev, &req, 0); } usbd_status -usbd_get_protocol(usbd_interface_handle iface, u_int8_t *report) +usbd_set_port_u1_timeout(struct usbd_device *dev, int port, int timeout) +{ + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + usb_device_request_t req; + + DPRINTF("dev %p port %d timeout %d", dev, port, timeout, 0); + req.bmRequestType = UT_WRITE_CLASS_OTHER; + req.bRequest = UR_SET_FEATURE; + USETW(req.wValue, UHF_PORT_U1_TIMEOUT); + USETW2(req.wIndex, timeout, port); + USETW(req.wLength, 0); + return usbd_do_request(dev, &req, 0); +} + +usbd_status +usbd_set_port_u2_timeout(struct usbd_device *dev, int port, int timeout) +{ + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + usb_device_request_t req; + + DPRINTF("dev %p port %d timeout %d", dev, port, timeout, 0); + req.bmRequestType = UT_WRITE_CLASS_OTHER; + req.bRequest = UR_SET_FEATURE; + USETW(req.wValue, UHF_PORT_U2_TIMEOUT); + USETW2(req.wIndex, timeout, port); + USETW(req.wLength, 0); + return usbd_do_request(dev, &req, 0); +} + +usbd_status +usbd_get_protocol(struct usbd_interface *iface, uint8_t *report) { usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface); - usbd_device_handle dev; + struct usbd_device *dev; usb_device_request_t req; - DPRINTFN(4, ("usbd_get_protocol: iface=%p, endpt=%d\n", - iface, id->bInterfaceNumber)); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + DPRINTFN(4, "iface=%p, endpt=%d", iface, id->bInterfaceNumber, 0, 0); if (id == NULL) - return (USBD_IOERROR); + return USBD_IOERROR; usbd_interface2device_handle(iface, &dev); req.bmRequestType = UT_READ_CLASS_INTERFACE; req.bRequest = UR_GET_PROTOCOL; USETW(req.wValue, 0); USETW(req.wIndex, id->bInterfaceNumber); USETW(req.wLength, 1); - return (usbd_do_request(dev, &req, report)); + return usbd_do_request(dev, &req, report); } usbd_status -usbd_set_protocol(usbd_interface_handle iface, int report) +usbd_set_protocol(struct usbd_interface *iface, int report) { usb_interface_descriptor_t *id = usbd_get_interface_descriptor(iface); - usbd_device_handle dev; + struct usbd_device *dev; usb_device_request_t req; - DPRINTFN(4, ("usbd_set_protocol: iface=%p, report=%d, endpt=%d\n", - iface, report, id->bInterfaceNumber)); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + DPRINTFN(4, "iface=%p, report=%d, endpt=%d", iface, report, + id->bInterfaceNumber, 0); if (id == NULL) - return (USBD_IOERROR); + return USBD_IOERROR; usbd_interface2device_handle(iface, &dev); req.bmRequestType = UT_WRITE_CLASS_INTERFACE; req.bRequest = UR_SET_PROTOCOL; USETW(req.wValue, report); USETW(req.wIndex, id->bInterfaceNumber); USETW(req.wLength, 0); - return (usbd_do_request(dev, &req, 0)); + return usbd_do_request(dev, &req, 0); } usbd_status -usbd_set_report(usbd_interface_handle iface, int type, int id, void *data, +usbd_set_report(struct usbd_interface *iface, int type, int id, void *data, int len) { usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface); - usbd_device_handle dev; + struct usbd_device *dev; usb_device_request_t req; - DPRINTFN(4, ("usbd_set_report: len=%d\n", len)); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + DPRINTFN(4, "len=%d", len, 0, 0, 0); if (ifd == NULL) - return (USBD_IOERROR); + return USBD_IOERROR; usbd_interface2device_handle(iface, &dev); req.bmRequestType = UT_WRITE_CLASS_INTERFACE; req.bRequest = UR_SET_REPORT; USETW2(req.wValue, type, id); USETW(req.wIndex, ifd->bInterfaceNumber); USETW(req.wLength, len); - return (usbd_do_request(dev, &req, data)); + return usbd_do_request(dev, &req, data); } usbd_status -usbd_get_report(usbd_interface_handle iface, int type, int id, void *data, +usbd_get_report(struct usbd_interface *iface, int type, int id, void *data, int len) { usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface); - usbd_device_handle dev; + struct usbd_device *dev; usb_device_request_t req; - DPRINTFN(4, ("usbd_get_report: len=%d\n", len)); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + DPRINTFN(4, "len=%d", len, 0, 0, 0); if (ifd == NULL) - return (USBD_IOERROR); + return USBD_IOERROR; usbd_interface2device_handle(iface, &dev); req.bmRequestType = UT_READ_CLASS_INTERFACE; req.bRequest = UR_GET_REPORT; USETW2(req.wValue, type, id); USETW(req.wIndex, ifd->bInterfaceNumber); USETW(req.wLength, len); - return (usbd_do_request(dev, &req, data)); + return usbd_do_request(dev, &req, data); } usbd_status -usbd_set_idle(usbd_interface_handle iface, int duration, int id) +usbd_set_idle(struct usbd_interface *iface, int duration, int id) { usb_interface_descriptor_t *ifd = usbd_get_interface_descriptor(iface); - usbd_device_handle dev; + struct usbd_device *dev; usb_device_request_t req; - DPRINTFN(4, ("usbd_set_idle: %d %d\n", duration, id)); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + DPRINTFN(4, "duration %d id %d", duration, id, 0, 0); if (ifd == NULL) - return (USBD_IOERROR); + return USBD_IOERROR; usbd_interface2device_handle(iface, &dev); req.bmRequestType = UT_WRITE_CLASS_INTERFACE; req.bRequest = UR_SET_IDLE; USETW2(req.wValue, duration, id); USETW(req.wIndex, ifd->bInterfaceNumber); USETW(req.wLength, 0); - return (usbd_do_request(dev, &req, 0)); + return usbd_do_request(dev, &req, 0); } usbd_status -usbd_get_report_descriptor(usbd_device_handle dev, int ifcno, +usbd_get_report_descriptor(struct usbd_device *dev, int ifcno, int size, void *d) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usb_device_request_t req; + DPRINTF("dev %p ifcno %d size %d", dev, ifcno, size, 0); req.bmRequestType = UT_READ_INTERFACE; req.bRequest = UR_GET_DESCRIPTOR; USETW2(req.wValue, UDESC_REPORT, 0); /* report id should be 0 */ USETW(req.wIndex, ifcno); USETW(req.wLength, size); - return (usbd_do_request(dev, &req, d)); + return usbd_do_request(dev, &req, d); } usb_hid_descriptor_t * -usbd_get_hid_descriptor(usbd_interface_handle ifc) +usbd_get_hid_descriptor(struct usbd_interface *ifc) { usb_interface_descriptor_t *idesc = usbd_get_interface_descriptor(ifc); - usbd_device_handle dev; + struct usbd_device *dev; usb_config_descriptor_t *cdesc; usb_hid_descriptor_t *hd; char *p, *end; if (idesc == NULL) - return (NULL); + return NULL; usbd_interface2device_handle(ifc, &dev); cdesc = usbd_get_config_descriptor(dev); @@ -376,142 +449,147 @@ usbd_get_hid_descriptor(usbd_interface_handle ifc) for (; p < end; p += hd->bLength) { hd = (usb_hid_descriptor_t *)p; if (p + hd->bLength <= end && hd->bDescriptorType == UDESC_HID) - return (hd); + return hd; if (hd->bDescriptorType == UDESC_INTERFACE) break; } - return (NULL); + return NULL; } usbd_status -usbd_read_report_desc(usbd_interface_handle ifc, void **descp, int *sizep, - struct malloc_type * mem) +usbd_read_report_desc(struct usbd_interface *ifc, void **descp, int *sizep) { usb_interface_descriptor_t *id; usb_hid_descriptor_t *hid; - usbd_device_handle dev; + struct usbd_device *dev; usbd_status err; usbd_interface2device_handle(ifc, &dev); id = usbd_get_interface_descriptor(ifc); if (id == NULL) - return (USBD_INVAL); + return USBD_INVAL; hid = usbd_get_hid_descriptor(ifc); if (hid == NULL) - return (USBD_IOERROR); + return USBD_IOERROR; *sizep = UGETW(hid->descrs[0].wDescriptorLength); - *descp = malloc(*sizep, mem, M_NOWAIT); + *descp = kmem_alloc(*sizep, KM_SLEEP); if (*descp == NULL) - return (USBD_NOMEM); + return USBD_NOMEM; err = usbd_get_report_descriptor(dev, id->bInterfaceNumber, *sizep, *descp); if (err) { - free(*descp, mem); + kmem_free(*descp, *sizep); *descp = NULL; - return (err); + return err; } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } usbd_status -usbd_get_config(usbd_device_handle dev, u_int8_t *conf) +usbd_get_config(struct usbd_device *dev, uint8_t *conf) { + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); usb_device_request_t req; + DPRINTF("dev %p", dev, 0, 0, 0); req.bmRequestType = UT_READ_DEVICE; req.bRequest = UR_GET_CONFIG; USETW(req.wValue, 0); USETW(req.wIndex, 0); USETW(req.wLength, 1); - return (usbd_do_request(dev, &req, conf)); + return usbd_do_request(dev, &req, conf); } usbd_status -usbd_bulk_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe, - u_int16_t flags, u_int32_t timeout, void *buf, - u_int32_t *size, const char *lbl) +usbd_bulk_transfer(struct usbd_xfer *xfer, struct usbd_pipe *pipe, + uint16_t flags, uint32_t timeout, void *buf, uint32_t *size) { usbd_status err; USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - usbd_setup_xfer(xfer, pipe, 0, buf, *size, flags, timeout, NULL); - DPRINTFN(1, ("usbd_bulk_transfer: start transfer %d bytes\n", *size)); + usbd_setup_xfer(xfer, 0, buf, *size, flags, timeout, NULL); + DPRINTFN(1, "start transfer %d bytes", *size, 0, 0, 0); err = usbd_sync_transfer_sig(xfer); usbd_get_xfer_status(xfer, NULL, NULL, size, NULL); - DPRINTFN(1,("usbd_bulk_transfer: transferred %d\n", *size)); + DPRINTFN(1, "transferred %d", *size, 0, 0, 0); if (err) { - DPRINTF(("usbd_bulk_transfer: error=%d\n", err)); usbd_clear_endpoint_stall(pipe); } - USBHIST_LOG(usbdebug, "<- done err %d", xfer, err, 0, 0); + USBHIST_LOG(usbdebug, "<- done xfer %p err %d", xfer, err, 0, 0); - return (err); + return err; } usbd_status -usbd_intr_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe, - u_int16_t flags, u_int32_t timeout, void *buf, - u_int32_t *size, const char *lbl) +usbd_intr_transfer(struct usbd_xfer *xfer, struct usbd_pipe *pipe, + uint16_t flags, uint32_t timeout, void *buf, uint32_t *size) { usbd_status err; USBHIST_FUNC(); USBHIST_CALLED(usbdebug); - usbd_setup_xfer(xfer, pipe, 0, buf, *size, flags, timeout, NULL); + usbd_setup_xfer(xfer, 0, buf, *size, flags, timeout, NULL); - DPRINTFN(1, ("usbd_intr_transfer: start transfer %d bytes\n", *size)); + DPRINTFN(1, "start transfer %d bytes", *size, 0, 0, 0); err = usbd_sync_transfer_sig(xfer); usbd_get_xfer_status(xfer, NULL, NULL, size, NULL); - DPRINTFN(1,("usbd_intr_transfer: transferred %d\n", *size)); + DPRINTFN(1, "transferred %d", *size, 0, 0, 0); if (err) { - DPRINTF(("usbd_intr_transfer: error=%d\n", err)); usbd_clear_endpoint_stall(pipe); } - USBHIST_LOG(usbdebug, "<- done err %d", xfer, err, 0, 0); + USBHIST_LOG(usbdebug, "<- done xfer %p err %d", xfer, err, 0, 0); - return (err); + return err; } void usb_detach_wait(device_t dv, kcondvar_t *cv, kmutex_t *lock) { - DPRINTF(("usb_detach_wait: waiting for %s\n", device_xname(dv))); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + DPRINTFN(1, "waiting for dv %p", dv, 0, 0, 0); if (cv_timedwait(cv, lock, hz * 60)) // dv, PZERO, "usbdet", hz * 60 printf("usb_detach_wait: %s didn't detach\n", - device_xname(dv)); - DPRINTF(("usb_detach_wait: %s done\n", device_xname(dv))); + device_xname(dv)); + DPRINTFN(1, "done", 0, 0, 0, 0); } void usb_detach_broadcast(device_t dv, kcondvar_t *cv) { - DPRINTF(("usb_detach_broadcast: for %s\n", device_xname(dv))); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + DPRINTFN(1, "for dv %p", dv, 0, 0, 0); cv_broadcast(cv); } void usb_detach_waitold(device_t dv) { - DPRINTF(("usb_detach_waitold: waiting for %s\n", device_xname(dv))); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + DPRINTFN(1, "waiting for dv %p", dv, 0, 0, 0); if (tsleep(dv, PZERO, "usbdet", hz * 60)) /* XXXSMP ok */ printf("usb_detach_waitold: %s didn't detach\n", - device_xname(dv)); - DPRINTF(("usb_detach_waitold: %s done\n", device_xname(dv))); + device_xname(dv)); + DPRINTFN(1, "done", 0, 0, 0, 0); } void usb_detach_wakeupold(device_t dv) { - DPRINTF(("usb_detach_wakeupold: for %s\n", device_xname(dv))); + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + DPRINTFN(1, "for dv %p", dv, 0, 0, 0); wakeup(dv); /* XXXSMP ok */ } const usb_cdc_descriptor_t * -usb_find_desc(usbd_device_handle dev, int type, int subtype) +usb_find_desc(struct usbd_device *dev, int type, int subtype) { usbd_desc_iter_t iter; const usb_cdc_descriptor_t *desc; @@ -529,7 +607,7 @@ usb_find_desc(usbd_device_handle dev, int type, int subtype) /* same as usb_find_desc(), but searches only in the specified interface. */ const usb_cdc_descriptor_t * -usb_find_desc_if(usbd_device_handle dev, int type, int subtype, +usb_find_desc_if(struct usbd_device *dev, int type, int subtype, usb_interface_descriptor_t *id) { usbd_desc_iter_t iter; diff --git a/sys/dev/usb/usbdi_util.h b/sys/dev/usb/usbdi_util.h index 3dd3cd6a0f6..413bbc242bf 100644 --- a/sys/dev/usb/usbdi_util.h +++ b/sys/dev/usb/usbdi_util.h @@ -1,4 +1,4 @@ -/* $NetBSD: usbdi_util.h,v 1.46 2015/03/27 12:46:51 skrll Exp $ */ +/* $NetBSD: usbdi_util.h,v 1.47 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998, 2004 The NetBSD Foundation, Inc. @@ -35,53 +35,55 @@ #include <dev/usb/usbhid.h> -usbd_status usbd_get_desc(usbd_device_handle dev, int type, - int index, int len, void *desc); -usbd_status usbd_get_config_desc(usbd_device_handle, int, +usbd_status usbd_get_desc(struct usbd_device *, int, + int, int, void *); +usbd_status usbd_get_config_desc(struct usbd_device *, int, usb_config_descriptor_t *); -usbd_status usbd_get_config_desc_full(usbd_device_handle, int, void *, int); -usbd_status usbd_get_bos_desc(usbd_device_handle, int, +usbd_status usbd_get_config_desc_full(struct usbd_device *, int, void *, int); +usbd_status usbd_get_bos_desc(struct usbd_device *, int, usb_bos_descriptor_t *); -usbd_status usbd_get_bos_desc_full(usbd_device_handle, int, void *, int); -usbd_status usbd_get_device_desc(usbd_device_handle dev, - usb_device_descriptor_t *d); -usbd_status usbd_set_address(usbd_device_handle dev, int addr); -usbd_status usbd_get_port_status(usbd_device_handle, +usbd_status usbd_get_bos_desc_full(struct usbd_device *, int, void *, int); +usbd_status usbd_get_device_desc(struct usbd_device *, + usb_device_descriptor_t *); +usbd_status usbd_set_address(struct usbd_device *, int); +usbd_status usbd_get_port_status(struct usbd_device *, int, usb_port_status_t *); -usbd_status usbd_set_hub_feature(usbd_device_handle dev, int); -usbd_status usbd_clear_hub_feature(usbd_device_handle, int); -usbd_status usbd_set_port_feature(usbd_device_handle dev, int, int); -usbd_status usbd_clear_port_feature(usbd_device_handle, int, int); -usbd_status usbd_get_device_status(usbd_device_handle, usb_status_t *); -usbd_status usbd_get_hub_status(usbd_device_handle, usb_hub_status_t *); -usbd_status usbd_get_protocol(usbd_interface_handle dev, u_int8_t *report); -usbd_status usbd_set_protocol(usbd_interface_handle dev, int report); -usbd_status usbd_get_report_descriptor(usbd_device_handle dev, int ifcno, - int size, void *d); -usb_hid_descriptor_t *usbd_get_hid_descriptor(usbd_interface_handle ifc); -usbd_status usbd_set_report(usbd_interface_handle iface, int type, int id, - void *data,int len); -usbd_status usbd_get_report(usbd_interface_handle iface, int type, int id, - void *data, int len); -usbd_status usbd_set_idle(usbd_interface_handle iface, int duration,int id); -usbd_status usbd_read_report_desc(usbd_interface_handle ifc, void **descp, - int *sizep, struct malloc_type *mem); -usbd_status usbd_get_config(usbd_device_handle dev, u_int8_t *conf); -usbd_status usbd_get_string_desc(usbd_device_handle dev, int sindex, - int langid,usb_string_descriptor_t *sdesc, - int *sizep); +usbd_status usbd_get_port_status_ext(struct usbd_device *, + int, usb_port_status_ext_t *); +usbd_status usbd_set_hub_feature(struct usbd_device *, int); +usbd_status usbd_clear_hub_feature(struct usbd_device *, int); +usbd_status usbd_set_port_feature(struct usbd_device *, int, int); +usbd_status usbd_clear_port_feature(struct usbd_device *, int, int); +usbd_status usbd_set_port_u1_timeout(struct usbd_device *, int, int); +usbd_status usbd_set_port_u2_timeout(struct usbd_device *, int, int); +usbd_status usbd_get_device_status(struct usbd_device *, usb_status_t *); +usbd_status usbd_get_hub_status(struct usbd_device *, usb_hub_status_t *); +usbd_status usbd_get_protocol(struct usbd_interface *, uint8_t *); +usbd_status usbd_set_protocol(struct usbd_interface *, int); +usbd_status usbd_get_report_descriptor(struct usbd_device *, int, + int, void *); +usb_hid_descriptor_t *usbd_get_hid_descriptor(struct usbd_interface *); +usbd_status usbd_set_report(struct usbd_interface *, int, int, + void *, int); +usbd_status usbd_get_report(struct usbd_interface *, int, int, + void *, int); +usbd_status usbd_set_idle(struct usbd_interface *, int, int); +usbd_status usbd_read_report_desc(struct usbd_interface *, void **, + int *); +usbd_status usbd_get_config(struct usbd_device *, uint8_t *); +usbd_status usbd_get_string_desc(struct usbd_device *, int, + int, usb_string_descriptor_t *, + int *); -usbd_status usbd_set_config_no(usbd_device_handle, int, int); -usbd_status usbd_set_config_index(usbd_device_handle, int, int); +usbd_status usbd_set_config_no(struct usbd_device *, int, int); +usbd_status usbd_set_config_index(struct usbd_device *, int, int); -usbd_status usbd_bulk_transfer(usbd_xfer_handle, usbd_pipe_handle, - u_int16_t, u_int32_t, void *, - u_int32_t *, const char *); +usbd_status usbd_bulk_transfer(struct usbd_xfer *, struct usbd_pipe *, + uint16_t, uint32_t, void *, uint32_t *); -usbd_status usbd_intr_transfer(usbd_xfer_handle, usbd_pipe_handle, - u_int16_t, u_int32_t, void *, - u_int32_t *, const char *); +usbd_status usbd_intr_transfer(struct usbd_xfer *, struct usbd_pipe *, + uint16_t, uint32_t, void *, uint32_t *); void usb_detach_waitold(device_t); void usb_detach_wakeupold(device_t); @@ -99,11 +101,11 @@ typedef struct { uByte bDescriptorSubtype; } UPACKED usb_cdc_descriptor_t; -const usb_cdc_descriptor_t *usb_find_desc(usbd_device_handle dev, int type, - int subtype); -const usb_cdc_descriptor_t *usb_find_desc_if(usbd_device_handle dev, int type, - int subtype, - usb_interface_descriptor_t *id); +const usb_cdc_descriptor_t *usb_find_desc(struct usbd_device *, int, + int); +const usb_cdc_descriptor_t *usb_find_desc_if(struct usbd_device *, int, + int, + usb_interface_descriptor_t *); #define USBD_CDCSUBTYPE_ANY (~0) #endif /* _USBDI_UTIL_H_ */ diff --git a/sys/dev/usb/usbdivar.h b/sys/dev/usb/usbdivar.h index ecc16e24d78..6468f380940 100644 --- a/sys/dev/usb/usbdivar.h +++ b/sys/dev/usb/usbdivar.h @@ -1,4 +1,4 @@ -/* $NetBSD: usbdivar.h,v 1.112 2016/02/16 07:51:13 skrll Exp $ */ +/* $NetBSD: usbdivar.h,v 1.113 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 1998, 2012 The NetBSD Foundation, Inc. @@ -38,26 +38,25 @@ * List of hardware interface methods, and whether the lock is held * when each is called by this module: * - * BUS METHOD LOCK NOTES + * BUS METHOD LOCK NOTES * ----------------------- ------- ------------------------- - * open_pipe - might want to take lock? - * soft_intr x - * do_poll - might want to take lock? - * allocm - - * freem - - * allocx - - * freex - - * get_lock - Called at attach time - * new_device + * ubm_open - might want to take lock? + * ubm_softint x + * ubm_dopoll - might want to take lock? + * ubm_allocx - + * ubm_freex - + * ubm_getlock - Called at attach time + * ubm_newdev - Will take lock + ubm_rhctrl * - * PIPE METHOD LOCK NOTES + * PIPE METHOD LOCK NOTES * ----------------------- ------- ------------------------- - * transfer - - * start - might want to take lock? - * abort x - * close x - * cleartoggle - - * done x + * upm_transfer - + * upm_start - might want to take lock? + * upm_abort x + * upm_close x + * upm_cleartoggle - + * upm_done x * * The above semantics are likely to change. Little performance * evaluation has been done on this code and the locking strategy. @@ -77,8 +76,8 @@ /* From usb_mem.h */ struct usb_dma_block; typedef struct { - struct usb_dma_block *block; - u_int offs; + struct usb_dma_block *udma_block; + u_int udma_offs; } usb_dma_t; struct usbd_xfer; @@ -86,75 +85,65 @@ struct usbd_pipe; struct usbd_port; struct usbd_endpoint { - usb_endpoint_descriptor_t *edesc; - int refcnt; - int datatoggle; + usb_endpoint_descriptor_t *ue_edesc; + int ue_refcnt; + int ue_toggle; }; struct usbd_bus_methods { - usbd_status (*open_pipe)(struct usbd_pipe *pipe); - void (*soft_intr)(void *); - void (*do_poll)(struct usbd_bus *); - usbd_status (*allocm)(struct usbd_bus *, usb_dma_t *, - u_int32_t bufsize); - void (*freem)(struct usbd_bus *, usb_dma_t *); - struct usbd_xfer * (*allocx)(struct usbd_bus *); - void (*freex)(struct usbd_bus *, struct usbd_xfer *); - void (*get_lock)(struct usbd_bus *, kmutex_t **); - usbd_status (*new_device)(device_t, usbd_bus_handle, int, + usbd_status (*ubm_open)(struct usbd_pipe *); + void (*ubm_softint)(void *); + void (*ubm_dopoll)(struct usbd_bus *); + struct usbd_xfer *(*ubm_allocx)(struct usbd_bus *, unsigned int); + void (*ubm_freex)(struct usbd_bus *, struct usbd_xfer *); + void (*ubm_getlock)(struct usbd_bus *, kmutex_t **); + usbd_status (*ubm_newdev)(device_t, struct usbd_bus *, int, int, int, struct usbd_port *); + + int (*ubm_rhctrl)(struct usbd_bus *, + usb_device_request_t *, void *, int); }; struct usbd_pipe_methods { - usbd_status (*transfer)(usbd_xfer_handle xfer); - usbd_status (*start)(usbd_xfer_handle xfer); - void (*abort)(usbd_xfer_handle xfer); - void (*close)(usbd_pipe_handle pipe); - void (*cleartoggle)(usbd_pipe_handle pipe); - void (*done)(usbd_xfer_handle xfer); + int (*upm_init)(struct usbd_xfer *); + void (*upm_fini)(struct usbd_xfer *); + usbd_status (*upm_transfer)(struct usbd_xfer *); + usbd_status (*upm_start)(struct usbd_xfer *); + void (*upm_abort)(struct usbd_xfer *); + void (*upm_close)(struct usbd_pipe *); + void (*upm_cleartoggle)(struct usbd_pipe *); + void (*upm_done)(struct usbd_xfer *); }; struct usbd_tt { - struct usbd_hub *hub; + struct usbd_hub *utt_hub; }; struct usbd_port { - usb_port_status_t status; - u_int16_t power; /* mA of current on port */ - u_int8_t portno; - u_int8_t restartcnt; + usb_port_status_t up_status; + uint16_t up_power; /* mA of current on port */ + uint8_t up_portno; + uint8_t up_restartcnt; #define USBD_RESTART_MAX 5 - u_int8_t reattach; - struct usbd_device *device; /* Connected device */ - struct usbd_device *parent; /* The ports hub */ - struct usbd_tt *tt; /* Transaction translator (if any) */ + uint8_t up_reattach; + struct usbd_device *up_dev; /* Connected device */ + struct usbd_device *up_parent; /* The ports hub */ + struct usbd_tt *up_tt; /* Transaction translator (if any) */ }; struct usbd_hub { - usbd_status (*explore)(usbd_device_handle hub); - void *hubsoftc; - usb_hub_descriptor_t hubdesc; - struct usbd_port ports[1]; + usbd_status (*uh_explore)(struct usbd_device *hub); + void *uh_hubsoftc; + usb_hub_descriptor_t uh_hubdesc; + struct usbd_port uh_ports[1]; }; /*****/ struct usbd_bus { /* Filled by HC driver */ - void *hci_private; - const struct usbd_bus_methods *methods; - u_int32_t pipe_size; /* size of a pipe struct */ - /* Filled by usb driver */ - kmutex_t *lock; - struct usbd_device *root_hub; - usbd_device_handle devices[USB_MAX_DEVICES]; - kcondvar_t needs_explore_cv; - char needs_explore;/* a hub a signalled a change */ - char use_polling; - device_t usbctl; - struct usb_device_stats stats; - u_int no_intrs; - int usbrev; /* USB revision */ + void *ub_hcpriv; + int ub_revision; /* USB revision */ #define USBREV_UNKNOWN 0 #define USBREV_PRE_1_0 1 #define USBREV_1_0 2 @@ -163,36 +152,57 @@ struct usbd_bus { #define USBREV_3_0 5 #define USBREV_STR { "unknown", "pre 1.0", "1.0", "1.1", "2.0", "3.0" } - void *soft; /* soft interrupt cookie */ - bus_dma_tag_t dmatag; /* DMA tag */ + const struct usbd_bus_methods + *ub_methods; + uint32_t ub_pipesize; /* size of a pipe struct */ + bool ub_usedma; /* Does this HC support DMA */ + int ub_dmaflags; + bus_dma_tag_t ub_dmatag; /* DMA tag */ + + /* Filled by usb driver */ + kmutex_t *ub_lock; + struct usbd_device *ub_roothub; + uint8_t ub_rhaddr; /* roothub address */ + uint8_t ub_rhconf; /* roothub configuration */ + struct usbd_device *ub_devices[USB_MAX_DEVICES]; + kcondvar_t ub_needsexplore_cv; + char ub_needsexplore;/* a hub a signalled a change */ + char ub_usepolling; + device_t ub_usbctl; + struct usb_device_stats ub_stats; + + void *ub_soft; /* soft interrupt cookie */ }; struct usbd_device { - struct usbd_bus *bus; /* our controller */ - struct usbd_pipe *default_pipe; /* pipe 0 */ - u_int8_t address; /* device addess */ - u_int8_t config; /* current configuration # */ - u_int8_t depth; /* distance from root hub */ - u_int8_t speed; /* low/full/high speed */ - u_int8_t self_powered; /* flag for self powered */ - u_int16_t power; /* mA the device uses */ - int16_t langid; /* language for strings */ + struct usbd_bus *ud_bus; /* our controller */ + struct usbd_pipe *ud_pipe0; /* pipe 0 */ + uint8_t ud_addr; /* device addess */ + uint8_t ud_config; /* current configuration # */ + uint8_t ud_depth; /* distance from root hub */ + uint8_t ud_speed; /* low/full/high speed */ + uint8_t ud_selfpowered; /* flag for self powered */ + uint16_t ud_power; /* mA the device uses */ + int16_t ud_langid; /* language for strings */ #define USBD_NOLANG (-1) - usb_event_cookie_t cookie; /* unique connection id */ - struct usbd_port *powersrc; /* upstream hub port, or 0 */ - struct usbd_device *myhub; /* upstream hub */ - struct usbd_port *myhsport; /* closest high speed port */ - struct usbd_endpoint def_ep; /* for pipe 0 */ - usb_endpoint_descriptor_t def_ep_desc; /* for pipe 0 */ - struct usbd_interface *ifaces; /* array of all interfaces */ - usb_device_descriptor_t ddesc; /* device descriptor */ - usb_config_descriptor_t *cdesc; /* full config descr */ - const struct usbd_quirks *quirks; /* device quirks, always set */ - struct usbd_hub *hub; /* only if this is a hub */ - int subdevlen; /* array length of following */ - device_t *subdevs; /* sub-devices */ - int nifaces_claimed; /* number of ifaces in use */ - void *hci_private; + usb_event_cookie_t ud_cookie; /* unique connection id */ + struct usbd_port *ud_powersrc; /* upstream hub port, or 0 */ + struct usbd_device *ud_myhub; /* upstream hub */ + struct usbd_port *ud_myhsport; /* closest high speed port */ + struct usbd_endpoint ud_ep0; /* for pipe 0 */ + usb_endpoint_descriptor_t + ud_ep0desc; /* for pipe 0 */ + struct usbd_interface *ud_ifaces; /* array of all interfaces */ + usb_device_descriptor_t ud_ddesc; /* device descriptor */ + usb_config_descriptor_t *ud_cdesc; /* full config descr */ + usb_bos_descriptor_t *ud_bdesc; /* full BOS descr */ + const struct usbd_quirks + *ud_quirks; /* device quirks, always set */ + struct usbd_hub *ud_hub; /* only if this is a hub */ + int ud_subdevlen; /* array length of following */ + device_t *ud_subdevs; /* sub-devices */ + int ud_nifaces_claimed; /* number of ifaces in use */ + void *ud_hcpriv; char *ud_serial; /* serial number, can be NULL */ char *ud_vendor; /* vendor string, can be NULL */ @@ -200,145 +210,151 @@ struct usbd_device { }; struct usbd_interface { - struct usbd_device *device; - usb_interface_descriptor_t *idesc; - int index; - int altindex; - struct usbd_endpoint *endpoints; - void *priv; - LIST_HEAD(, usbd_pipe) pipes; + struct usbd_device *ui_dev; + usb_interface_descriptor_t + *ui_idesc; + int ui_index; + int ui_altindex; + struct usbd_endpoint *ui_endpoints; + void *ui_priv; + LIST_HEAD(, usbd_pipe) ui_pipes; }; struct usbd_pipe { - struct usbd_interface *iface; - struct usbd_device *device; - struct usbd_endpoint *endpoint; - int refcnt; - char running; - char aborting; - SIMPLEQ_HEAD(, usbd_xfer) queue; - LIST_ENTRY(usbd_pipe) next; - struct usb_task async_task; - - usbd_xfer_handle intrxfer; /* used for repeating requests */ - char repeat; - int interval; - uint8_t flags; + struct usbd_interface *up_iface; + struct usbd_device *up_dev; + struct usbd_endpoint *up_endpoint; + char up_running; + char up_aborting; + bool up_serialise; + SIMPLEQ_HEAD(, usbd_xfer) + up_queue; + LIST_ENTRY(usbd_pipe) up_next; + struct usb_task up_async_task; + + struct usbd_xfer *up_intrxfer; /* used for repeating requests */ + char up_repeat; + int up_interval; + uint8_t up_flags; /* Filled by HC driver. */ - const struct usbd_pipe_methods *methods; + const struct usbd_pipe_methods + *up_methods; }; struct usbd_xfer { - struct usbd_pipe *pipe; - void *priv; - void *buffer; - kcondvar_t cv; - u_int32_t length; - u_int32_t actlen; - u_int16_t flags; - u_int32_t timeout; - usbd_status status; - usbd_callback callback; - volatile u_int8_t done; - u_int8_t busy_free; /* used for DIAGNOSTIC */ + struct usbd_pipe *ux_pipe; + void *ux_priv; + void *ux_buffer; + kcondvar_t ux_cv; + uint32_t ux_length; + uint32_t ux_actlen; + uint16_t ux_flags; + uint32_t ux_timeout; + usbd_status ux_status; + usbd_callback ux_callback; + volatile uint8_t ux_done; + uint8_t ux_state; /* used for DIAGNOSTIC */ #define XFER_FREE 0x46 #define XFER_BUSY 0x55 #define XFER_ONQU 0x9e /* For control pipe */ - usb_device_request_t request; + usb_device_request_t ux_request; /* For isoc */ - u_int16_t *frlengths; - int nframes; + uint16_t *ux_frlengths; + int ux_nframes; + + const struct usbd_pipe_methods *ux_methods; - /* For memory allocation */ - struct usbd_device *device; - usb_dma_t dmabuf; + /* For memory allocation and softc */ + struct usbd_bus *ux_bus; + usb_dma_t ux_dmabuf; + void *ux_buf; + uint32_t ux_bufsize; - u_int8_t rqflags; + uint8_t ux_rqflags; #define URQ_REQUEST 0x01 -#define URQ_AUTO_DMABUF 0x10 -#define URQ_DEV_DMABUF 0x20 - SIMPLEQ_ENTRY(usbd_xfer) next; + SIMPLEQ_ENTRY(usbd_xfer) + ux_next; - void *hcpriv; /* private use by the HC driver */ - u_int8_t hcflags; /* private use by the HC driver */ + void *ux_hcpriv; /* private use by the HC driver */ + uint8_t ux_hcflags; /* private use by the HC driver */ #define UXFER_ABORTING 0x01 /* xfer is aborting. */ #define UXFER_ABORTWAIT 0x02 /* abort completion is being awaited. */ - kcondvar_t hccv; /* private use by the HC driver */ + kcondvar_t ux_hccv; /* private use by the HC driver */ - struct callout timeout_handle; + struct callout ux_callout; }; void usbd_init(void); void usbd_finish(void); -#if defined(USB_DEBUG) || defined(EHCI_DEBUG) || defined(OHCI_DEBUG) -void usbd_dump_iface(struct usbd_interface *iface); -void usbd_dump_device(struct usbd_device *dev); -void usbd_dump_endpoint(struct usbd_endpoint *endp); -void usbd_dump_queue(usbd_pipe_handle pipe); -void usbd_dump_pipe(usbd_pipe_handle pipe); +#if defined(USB_DEBUG) +void usbd_dump_iface(struct usbd_interface *); +void usbd_dump_device(struct usbd_device *); +void usbd_dump_endpoint(struct usbd_endpoint *); +void usbd_dump_queue(struct usbd_pipe *); +void usbd_dump_pipe(struct usbd_pipe *); #endif /* Routines from usb_subr.c */ int usbctlprint(void *, const char *); void usbd_get_device_strings(struct usbd_device *); -void usb_delay_ms_locked(usbd_bus_handle, u_int, kmutex_t *); -void usb_delay_ms(usbd_bus_handle, u_int); -void usbd_delay_ms_locked(usbd_device_handle, u_int, kmutex_t *); -void usbd_delay_ms(usbd_device_handle, u_int); -usbd_status usbd_reset_port(usbd_device_handle, int, usb_port_status_t *); -usbd_status usbd_setup_pipe(usbd_device_handle dev, - usbd_interface_handle iface, +void usb_delay_ms_locked(struct usbd_bus *, u_int, kmutex_t *); +void usb_delay_ms(struct usbd_bus *, u_int); +void usbd_delay_ms_locked(struct usbd_device *, u_int, kmutex_t *); +void usbd_delay_ms(struct usbd_device *, u_int); +usbd_status usbd_reset_port(struct usbd_device *, int, usb_port_status_t *); +usbd_status usbd_setup_pipe(struct usbd_device *, + struct usbd_interface *, struct usbd_endpoint *, int, - usbd_pipe_handle *pipe); -usbd_status usbd_setup_pipe_flags(usbd_device_handle dev, - usbd_interface_handle iface, + struct usbd_pipe **); +usbd_status usbd_setup_pipe_flags(struct usbd_device *, + struct usbd_interface *, struct usbd_endpoint *, int, - usbd_pipe_handle *pipe, - uint8_t flags); -usbd_status usbd_new_device(device_t, usbd_bus_handle, int, int, int, + struct usbd_pipe **, + uint8_t); +usbd_status usbd_new_device(device_t, struct usbd_bus *, int, int, int, struct usbd_port *); -usbd_status usbd_reattach_device(device_t, usbd_device_handle, +usbd_status usbd_reattach_device(device_t, struct usbd_device *, int, const int *); -void usbd_remove_device(usbd_device_handle, struct usbd_port *); +void usbd_remove_device(struct usbd_device *, struct usbd_port *); int usbd_printBCD(char *, size_t, int); -usbd_status usbd_fill_iface_data(usbd_device_handle, int, int); -void usb_free_device(usbd_device_handle); +usbd_status usbd_fill_iface_data(struct usbd_device *, int, int); +void usb_free_device(struct usbd_device *); -usbd_status usb_insert_transfer(usbd_xfer_handle); -void usb_transfer_complete(usbd_xfer_handle); +usbd_status usb_insert_transfer(struct usbd_xfer *); +void usb_transfer_complete(struct usbd_xfer *); int usb_disconnect_port(struct usbd_port *, device_t, int); -void usbd_kill_pipe(usbd_pipe_handle); -usbd_status usbd_attach_roothub(device_t, usbd_device_handle); -usbd_status usbd_probe_and_attach(device_t, usbd_device_handle, int, int); -usbd_status usbd_get_initial_ddesc(usbd_device_handle, +void usbd_kill_pipe(struct usbd_pipe *); +usbd_status usbd_attach_roothub(device_t, struct usbd_device *); +usbd_status usbd_probe_and_attach(device_t, struct usbd_device *, int, int); +usbd_status usbd_get_initial_ddesc(struct usbd_device *, usb_device_descriptor_t *); /* Routines from usb.c */ -void usb_needs_explore(usbd_device_handle); -void usb_needs_reattach(usbd_device_handle); +void usb_needs_explore(struct usbd_device *); +void usb_needs_reattach(struct usbd_device *); void usb_schedsoftintr(struct usbd_bus *); static inline int usbd_xfer_isread(struct usbd_xfer *xfer) { - if (xfer->rqflags & URQ_REQUEST) - return xfer->request.bmRequestType & UT_READ; + if (xfer->ux_rqflags & URQ_REQUEST) + return xfer->ux_request.bmRequestType & UT_READ; - return xfer->pipe->endpoint->edesc->bEndpointAddress & - UE_DIR_IN; + return xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress & + UE_DIR_IN; } /* * These macros reflect the current locking scheme. They might change. */ -#define usbd_lock_pipe(p) mutex_enter((p)->device->bus->lock) -#define usbd_unlock_pipe(p) mutex_exit((p)->device->bus->lock) +#define usbd_lock_pipe(p) mutex_enter((p)->up_dev->ud_bus->ub_lock) +#define usbd_unlock_pipe(p) mutex_exit((p)->up_dev->ud_bus->ub_lock) diff --git a/sys/dev/usb/usbhid.h b/sys/dev/usb/usbhid.h index 1cb7a079373..9e01308b233 100644 --- a/sys/dev/usb/usbhid.h +++ b/sys/dev/usb/usbhid.h @@ -1,4 +1,4 @@ -/* $NetBSD: usbhid.h,v 1.15 2016/01/23 01:15:23 dholland Exp $ */ +/* $NetBSD: usbhid.h,v 1.16 2016/04/23 10:15:32 skrll Exp $ */ /* $FreeBSD: src/sys/dev/usb/usbhid.h,v 1.7 1999/11/17 22:33:51 n_hibma Exp $ */ /* diff --git a/sys/dev/usb/usbhist.h b/sys/dev/usb/usbhist.h index 762db639275..4e6b1b2fbfa 100644 --- a/sys/dev/usb/usbhist.h +++ b/sys/dev/usb/usbhist.h @@ -1,4 +1,4 @@ -/* $NetBSD: usbhist.h,v 1.3 2015/10/29 00:15:48 mrg Exp $ */ +/* $NetBSD: usbhist.h,v 1.4 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2012 Matthew R. Green @@ -58,6 +58,11 @@ extern int usbdebug; KERNHIST_LOG(usbhist,FMT,A,B,C,D); \ } \ } while (0) +#define USBHIST_LOGM(NAME,N,FMT,A,B,C,D) do { \ + if ((NAME) & (N)) { \ + KERNHIST_LOG(usbhist,FMT,A,B,C,D); \ + } \ +} while (0) #define USBHIST_LOG(NAME,FMT,A,B,C,D) USBHIST_LOGN(NAME,1,FMT,A,B,C,D) #define USBHIST_CALLED(NAME) do { \ if ((NAME) != 0) { \ @@ -76,6 +81,7 @@ USBHIST_DECL(usbhist); #define USBHIST_INIT_STATIC(NAME,BUF) #define USBHIST_LINK_STATIC(NAME) #define USBHIST_LOGN(N,NAME,FMT,A,B,C,D) do { } while(0) +#define USBHIST_LOGM(N,NAME,FMT,A,B,C,D) do { } while(0) #define USBHIST_LOG(NAME,FMT,A,B,C,D) do { } while(0) #define USBHIST_CALLED(NAME) #define USBHIST_FUNC() diff --git a/sys/dev/usb/usbroothub.c b/sys/dev/usb/usbroothub.c new file mode 100644 index 00000000000..6860038ac89 --- /dev/null +++ b/sys/dev/usb/usbroothub.c @@ -0,0 +1,491 @@ +/* $NetBSD: usbroothub.c,v 1.2 2016/04/23 10:15:32 skrll Exp $ */ + +/*- + * Copyright (c) 1998, 2004, 2011, 2012 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Lennart Augustsson (lennart@augustsson.net) at + * Carlstedt Research & Technology, Jared D. McNeill (jmcneill@invisible.ca), + * Matthew R. Green (mrg@eterna.com.au) and Nick Hudson. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Copyright (c) 2008 + * Matthias Drochner. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include <dev/usb/usb.h> +#include <dev/usb/usbdi.h> +#include <dev/usb/usbdivar.h> +#include <dev/usb/usbroothub.h> +#include <dev/usb/usbhist.h> + +extern int usbdebug; + +/* helper functions for USB root hub emulation */ + +static usbd_status roothub_ctrl_transfer(struct usbd_xfer *); +static usbd_status roothub_ctrl_start(struct usbd_xfer *); +static void roothub_ctrl_abort(struct usbd_xfer *); +static void roothub_ctrl_close(struct usbd_pipe *); +static void roothub_ctrl_done(struct usbd_xfer *); +static void roothub_noop(struct usbd_pipe *pipe); + +const struct usbd_pipe_methods roothub_ctrl_methods = { + .upm_transfer = roothub_ctrl_transfer, + .upm_start = roothub_ctrl_start, + .upm_abort = roothub_ctrl_abort, + .upm_close = roothub_ctrl_close, + .upm_cleartoggle = roothub_noop, + .upm_done = roothub_ctrl_done, +}; + +int +usb_makestrdesc(usb_string_descriptor_t *p, int l, const char *s) +{ + int i; + + if (l == 0) + return 0; + p->bLength = 2 * strlen(s) + 2; + if (l == 1) + return 1; + p->bDescriptorType = UDESC_STRING; + l -= 2; + /* poor man's utf-16le conversion */ + for (i = 0; s[i] && l > 1; i++, l -= 2) + USETW2(p->bString[i], 0, s[i]); + return 2 * i + 2; +} + +int +usb_makelangtbl(usb_string_descriptor_t *p, int l) +{ + + if (l == 0) + return 0; + p->bLength = 4; + if (l == 1) + return 1; + p->bDescriptorType = UDESC_STRING; + if (l < 4) + return 2; + USETW(p->bString[0], 0x0409); /* english/US */ + return 4; +} + +/* + * Data structures and routines to emulate the root hub. + */ +static const usb_device_descriptor_t usbroothub_devd1 = { + .bLength = sizeof(usb_device_descriptor_t), + .bDescriptorType = UDESC_DEVICE, + .bcdUSB = {0x00, 0x01}, + .bDeviceClass = UDCLASS_HUB, + .bDeviceSubClass = UDSUBCLASS_HUB, + .bDeviceProtocol = UDPROTO_FSHUB, + .bMaxPacketSize = 64, + .idVendor = {0}, + .idProduct = {0}, + .bcdDevice = {0x00, 0x01}, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 0, + .bNumConfigurations = 1 +}; + +static const struct usb_roothub_descriptors usbroothub_confd1 = { + .urh_confd = { + .bLength = USB_CONFIG_DESCRIPTOR_SIZE, + .bDescriptorType = UDESC_CONFIG, + .wTotalLength = USETWD(sizeof(usbroothub_confd1)), + .bNumInterface = 1, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = UC_ATTR_MBO | UC_SELF_POWERED, + .bMaxPower = 0, + }, + .urh_ifcd = { + .bLength = USB_INTERFACE_DESCRIPTOR_SIZE, + .bDescriptorType = UDESC_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = UICLASS_HUB, + .bInterfaceSubClass = UISUBCLASS_HUB, + .bInterfaceProtocol = UIPROTO_FSHUB, + .iInterface = 0 + }, + .urh_endpd = { + .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE, + .bDescriptorType = UDESC_ENDPOINT, + .bEndpointAddress = UE_DIR_IN | USBROOTHUB_INTR_ENDPT, + .bmAttributes = UE_INTERRUPT, + .wMaxPacketSize = USETWD(8), /* max packet */ + .bInterval = 255, + }, +}; + +static const usb_device_descriptor_t usbroothub_devd2 = { + .bLength = sizeof(usb_device_descriptor_t), + .bDescriptorType = UDESC_DEVICE, + .bcdUSB = {0x00, 0x02}, + .bDeviceClass = UDCLASS_HUB, + .bDeviceSubClass = UDSUBCLASS_HUB, + .bDeviceProtocol = UDPROTO_HSHUBSTT, + .bMaxPacketSize = 64, + .idVendor = {0}, + .idProduct = {0}, + .bcdDevice = {0x00, 0x01}, + .iManufacturer = 1, + .iProduct = 2, + .iSerialNumber = 0, + .bNumConfigurations = 1 +}; + +static const usb_device_qualifier_t usbroothub_odevd2 = { + .bLength = USB_DEVICE_QUALIFIER_SIZE, + .bDescriptorType = UDESC_DEVICE_QUALIFIER, + .bcdUSB = {0x00, 0x02}, + .bDeviceClass = UDCLASS_HUB, + .bDeviceSubClass = UDSUBCLASS_HUB, + .bDeviceProtocol = UDPROTO_FSHUB, + .bMaxPacketSize0 = 64, + .bNumConfigurations = 1, +}; + +static const struct usb_roothub_descriptors usbroothub_confd2 = { + .urh_confd = { + .bLength = USB_CONFIG_DESCRIPTOR_SIZE, + .bDescriptorType = UDESC_CONFIG, + .wTotalLength = USETWD(sizeof(usbroothub_confd2)), + .bNumInterface = 1, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = UC_ATTR_MBO | UC_SELF_POWERED, + .bMaxPower = 0, + }, + .urh_ifcd = { + .bLength = USB_INTERFACE_DESCRIPTOR_SIZE, + .bDescriptorType = UDESC_INTERFACE, + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 1, + .bInterfaceClass = UICLASS_HUB, + .bInterfaceSubClass = UISUBCLASS_HUB, + .bInterfaceProtocol = UIPROTO_HSHUBSTT, + .iInterface = 0 + }, + .urh_endpd = { + .bLength = USB_ENDPOINT_DESCRIPTOR_SIZE, + .bDescriptorType = UDESC_ENDPOINT, + .bEndpointAddress = UE_DIR_IN | USBROOTHUB_INTR_ENDPT, + .bmAttributes = UE_INTERRUPT, + .wMaxPacketSize = USETWD(8), /* max packet */ + .bInterval = 12, + }, +}; + +static const usb_hub_descriptor_t usbroothub_hubd = { + .bDescLength = USB_HUB_DESCRIPTOR_SIZE, + .bDescriptorType = UDESC_HUB, + .bNbrPorts = 1, + .wHubCharacteristics = USETWD(UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL), + .bPwrOn2PwrGood = 50, + .bHubContrCurrent = 0, + .DeviceRemovable = {0}, /* port is removable */ +}; + +/* + * Simulate a hardware hub by handling all the necessary requests. + */ +usbd_status +roothub_ctrl_transfer(struct usbd_xfer *xfer) +{ + struct usbd_pipe *pipe = xfer->ux_pipe; + struct usbd_bus *bus = pipe->up_dev->ud_bus; + usbd_status err; + + /* Insert last in queue. */ + mutex_enter(bus->ub_lock); + err = usb_insert_transfer(xfer); + mutex_exit(bus->ub_lock); + if (err) + return err; + + /* Pipe isn't running, start first */ + return roothub_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); +} + +static usbd_status +roothub_ctrl_start(struct usbd_xfer *xfer) +{ + struct usbd_pipe *pipe = xfer->ux_pipe; + struct usbd_bus *bus = pipe->up_dev->ud_bus; + usb_device_request_t *req; + usbd_status err = USBD_IOERROR; /* XXX STALL? */ + uint16_t len, value; + int buflen, actlen; + void *buf; + + USBHIST_FUNC(); USBHIST_CALLED(usbdebug); + + KASSERT(xfer->ux_rqflags & URQ_REQUEST); + req = &xfer->ux_request; + + USBHIST_LOG(usbdebug, "type=%#2x request=%#2x", req->bmRequestType, + req->bRequest, 0, 0); + + len = UGETW(req->wLength); + value = UGETW(req->wValue); + + buf = len ? usbd_get_buffer(xfer) : NULL; + buflen = 0; + +#define C(x,y) ((x) | ((y) << 8)) + switch (C(req->bRequest, req->bmRequestType)) { + case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE): + case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE): + case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT): + /* + * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops + * for the integrated root hub. + */ + break; + case C(UR_GET_CONFIG, UT_READ_DEVICE): + if (len > 0) { + uint8_t *out = buf; + + *out = bus->ub_rhconf; + buflen = sizeof(*out); + } + break; + case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): + USBHIST_LOG(usbdebug, "wValue=%#4x", value, 0, 0, 0); + + if (len == 0) + break; + switch (value) { + case C(0, UDESC_DEVICE): + if (bus->ub_revision == USBREV_2_0) { + buflen = min(len, sizeof(usbroothub_devd2)); + memcpy(buf, &usbroothub_devd2, buflen); + } else { + buflen = min(len, sizeof(usbroothub_devd1)); + memcpy(buf, &usbroothub_devd1, buflen); + } + break; + case C(0, UDESC_CONFIG): + if (bus->ub_revision == USBREV_2_0) { + buflen = min(len, sizeof(usbroothub_confd2)); + memcpy(buf, &usbroothub_confd2, buflen); + } else { + buflen = min(len, sizeof(usbroothub_confd1)); + memcpy(buf, &usbroothub_confd1, buflen); + } + break; + case C(0, UDESC_DEVICE_QUALIFIER): + if (bus->ub_revision == USBREV_2_0) { + /* + * We can't really operate at another speed, + * but the spec says we need this descriptor. + */ + buflen = min(len, sizeof(usbroothub_odevd2)); + memcpy(buf, &usbroothub_odevd2, buflen); + } else + goto fail; + break; + case C(0, UDESC_OTHER_SPEED_CONFIGURATION): + if (bus->ub_revision == USBREV_2_0) { + struct usb_roothub_descriptors confd; + + /* + * We can't really operate at another speed, + * but the spec says we need this descriptor. + */ + buflen = min(len, sizeof(usbroothub_confd2)); + memcpy(&confd, &usbroothub_confd2, buflen); + confd.urh_confd.bDescriptorType = + UDESC_OTHER_SPEED_CONFIGURATION; + memcpy(buf, &confd, buflen); + } else + goto fail; + break; +#define sd ((usb_string_descriptor_t *)buf) + case C(0, UDESC_STRING): + /* Language table */ + buflen = usb_makelangtbl(sd, len); + break; + case C(1, UDESC_STRING): + /* Vendor */ + buflen = usb_makestrdesc(sd, len, "NetBSD"); + break; + case C(2, UDESC_STRING): + /* Product */ + buflen = usb_makestrdesc(sd, len, "Root hub"); + break; +#undef sd + default: + /* Default to error */ + buflen = -1; + } + break; + case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE): + buflen = min(len, sizeof(usbroothub_hubd)); + memcpy(buf, &usbroothub_hubd, buflen); + break; + case C(UR_GET_INTERFACE, UT_READ_INTERFACE): + /* Get Interface, 9.4.4 */ + if (len > 0) { + uint8_t *out = buf; + + *out = 0; + buflen = sizeof(*out); + } + break; + case C(UR_GET_STATUS, UT_READ_DEVICE): + /* Get Status from device, 9.4.5 */ + if (len > 1) { + usb_status_t *out = buf; + + USETW(out->wStatus, UDS_SELF_POWERED); + buflen = sizeof(*out); + } + break; + case C(UR_GET_STATUS, UT_READ_INTERFACE): + case C(UR_GET_STATUS, UT_READ_ENDPOINT): + /* Get Status from interface, endpoint, 9.4.5 */ + if (len > 1) { + usb_status_t *out = buf; + + USETW(out->wStatus, 0); + buflen = sizeof(*out); + } + break; + case C(UR_SET_ADDRESS, UT_WRITE_DEVICE): + /* Set Address, 9.4.6 */ + USBHIST_LOG(usbdebug, "UR_SET_ADDRESS, UT_WRITE_DEVICE: addr %d", + value, 0, 0, 0); + if (value >= USB_MAX_DEVICES) { + goto fail; + } + bus->ub_rhaddr = value; + break; + case C(UR_SET_CONFIG, UT_WRITE_DEVICE): + /* Set Configuration, 9.4.7 */ + if (value != 0 && value != 1) { + goto fail; + } + bus->ub_rhconf = value; + break; + case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE): + /* Set Descriptor, 9.4.8, not supported */ + break; + case C(UR_SET_FEATURE, UT_WRITE_DEVICE): + case C(UR_SET_FEATURE, UT_WRITE_INTERFACE): + case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT): + /* Set Feature, 9.4.9, not supported */ + goto fail; + case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE): + /* Set Interface, 9.4.10, not supported */ + break; + case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT): + /* Synch Frame, 9.4.11, not supported */ + break; + default: + /* Default to error */ + buflen = -1; + break; + } + + actlen = bus->ub_methods->ubm_rhctrl(bus, req, buf, buflen); + USBHIST_LOG(usbdebug, "xfer %p buflen %d actlen %d", xfer, buflen, + actlen, 0); + if (actlen < 0) + goto fail; + + xfer->ux_actlen = actlen; + err = USBD_NORMAL_COMPLETION; + + fail: + USBHIST_LOG(usbdebug, "xfer %p err %d", xfer, err, 0, 0); + + xfer->ux_status = err; + mutex_enter(bus->ub_lock); + usb_transfer_complete(xfer); + mutex_exit(bus->ub_lock); + + return USBD_NORMAL_COMPLETION; +} + +/* Abort a root control request. */ +Static void +roothub_ctrl_abort(struct usbd_xfer *xfer) +{ + + /* Nothing to do, all transfers are synchronous. */ +} + +/* Close the root pipe. */ +Static void +roothub_ctrl_close(struct usbd_pipe *pipe) +{ + + /* Nothing to do. */ +} + +Static void +roothub_ctrl_done(struct usbd_xfer *xfer) +{ + + /* Nothing to do. */ +} + +static void +roothub_noop(struct usbd_pipe *pipe) +{ + +} diff --git a/sys/dev/usb/usbroothub.h b/sys/dev/usb/usbroothub.h new file mode 100644 index 00000000000..a9e566ef411 --- /dev/null +++ b/sys/dev/usb/usbroothub.h @@ -0,0 +1,43 @@ +/* $NetBSD: usbroothub.h,v 1.2 2016/04/23 10:15:32 skrll Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Nick Hudson + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +int usb_makestrdesc(usb_string_descriptor_t *, int, const char *); +int usb_makelangtbl(usb_string_descriptor_t *, int); + +struct usb_roothub_descriptors { + usb_config_descriptor_t urh_confd; + usb_interface_descriptor_t urh_ifcd; + usb_endpoint_descriptor_t urh_endpd; +}; + +#define USBROOTHUB_INTR_ENDPT 1 + +extern const struct usbd_pipe_methods roothub_ctrl_methods; diff --git a/sys/dev/usb/usbroothub_subr.c b/sys/dev/usb/usbroothub_subr.c deleted file mode 100644 index 34948342c92..00000000000 --- a/sys/dev/usb/usbroothub_subr.c +++ /dev/null @@ -1,66 +0,0 @@ -/* $NetBSD: usbroothub_subr.c,v 1.3 2015/11/19 00:40:43 christos Exp $ */ - -/* - * Copyright (c) 2008 - * Matthias Drochner. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include <dev/usb/usb.h> -#include <dev/usb/usbroothub_subr.h> - -/* helper functions for USB root hub emulation */ - -int -usb_makestrdesc(usb_string_descriptor_t *p, int l, const char *s) -{ - int i; - - if (l == 0) - return (0); - p->bLength = 2 * strlen(s) + 2; - if (l == 1) - return (1); - p->bDescriptorType = UDESC_STRING; - l -= 2; - /* poor man's utf-16le conversion */ - for (i = 0; s[i] && l > 1; i++, l -= 2) - USETW2(p->bString[i], 0, s[i]); - return (2 * i + 2); -} - -int -usb_makelangtbl(usb_string_descriptor_t *p, int l) -{ - - if (l == 0) - return (0); - p->bLength = 4; - if (l == 1) - return (1); - p->bDescriptorType = UDESC_STRING; - if (l < 4) - return (2); - USETW(p->bString[0], 0x0409); /* english/US */ - return (4); -} diff --git a/sys/dev/usb/usbroothub_subr.h b/sys/dev/usb/usbroothub_subr.h deleted file mode 100644 index 4da254ed109..00000000000 --- a/sys/dev/usb/usbroothub_subr.h +++ /dev/null @@ -1,4 +0,0 @@ -/* $NetBSD: usbroothub_subr.h,v 1.3 2015/11/19 00:40:43 christos Exp $ */ - -int usb_makestrdesc(usb_string_descriptor_t *, int, const char *); -int usb_makelangtbl(usb_string_descriptor_t *, int); diff --git a/sys/dev/usb/uscanner.c b/sys/dev/usb/uscanner.c index 59c33f68982..1e8e9bd3f4d 100644 --- a/sys/dev/usb/uscanner.c +++ b/sys/dev/usb/uscanner.c @@ -1,4 +1,4 @@ -/* $NetBSD: uscanner.c,v 1.75 2014/07/25 08:10:39 dholland Exp $ */ +/* $NetBSD: uscanner.c,v 1.76 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -32,12 +32,12 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uscanner.c,v 1.75 2014/07/25 08:10:39 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uscanner.c,v 1.76 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/device.h> #include <sys/file.h> #include <sys/select.h> @@ -204,21 +204,21 @@ static const struct uscan_info uscanner_devs[] = { struct uscanner_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device *sc_udev; + struct usbd_interface *sc_iface; u_int sc_dev_flags; - usbd_pipe_handle sc_bulkin_pipe; + struct usbd_pipe *sc_bulkin_pipe; int sc_bulkin; - usbd_xfer_handle sc_bulkin_xfer; + struct usbd_xfer *sc_bulkin_xfer; void *sc_bulkin_buffer; int sc_bulkin_bufferlen; int sc_bulkin_datalen; - usbd_pipe_handle sc_bulkout_pipe; + struct usbd_pipe *sc_bulkout_pipe; int sc_bulkout; - usbd_xfer_handle sc_bulkout_xfer; + struct usbd_xfer *sc_bulkout_xfer; void *sc_bulkout_buffer; int sc_bulkout_bufferlen; int sc_bulkout_datalen; @@ -268,16 +268,16 @@ int uscanner_activate(device_t, enum devact); extern struct cfdriver uscanner_cd; CFATTACH_DECL_NEW(uscanner, sizeof(struct uscanner_softc), uscanner_match, uscanner_attach, uscanner_detach, uscanner_activate); -int +int uscanner_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (uscanner_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return uscanner_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } -void +void uscanner_attach(device_t parent, device_t self, void *aux) { struct uscanner_softc *sc = device_private(self); @@ -293,15 +293,15 @@ uscanner_attach(device_t parent, device_t self, void *aux) aprint_naive("\n"); aprint_normal("\n"); - devinfop = usbd_devinfo_alloc(uaa->device, 0); + devinfop = usbd_devinfo_alloc(uaa->uaa_device, 0); aprint_normal_dev(self, "%s\n", devinfop); usbd_devinfo_free(devinfop); - sc->sc_dev_flags = uscanner_lookup(uaa->vendor, uaa->product)->flags; + sc->sc_dev_flags = uscanner_lookup(uaa->uaa_vendor, uaa->uaa_product)->flags; - sc->sc_udev = uaa->device; + sc->sc_udev = uaa->uaa_device; - err = usbd_set_config_no(uaa->device, 1, 1); /* XXX */ + err = usbd_set_config_no(uaa->uaa_device, 1, 1); /* XXX */ if (err) { aprint_error_dev(self, "failed to set configuration" ", err=%s\n", usbd_errstr(err)); @@ -336,7 +336,7 @@ uscanner_attach(device_t parent, device_t self, void *aux) ed_bulkin = ed; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) { - ed_bulkout = ed; + ed_bulkout = ed; } if (ed_bulkin && ed_bulkout) /* found all we need */ @@ -377,17 +377,13 @@ uscanneropen(dev_t dev, int flag, int mode, flag, mode, unit)); if (sc->sc_dying) - return (ENXIO); + return ENXIO; if (sc->sc_state & USCANNER_OPEN) - return (EBUSY); + return EBUSY; sc->sc_state |= USCANNER_OPEN; - sc->sc_bulkin_buffer = malloc(USCANNER_BUFFERSIZE, M_USBDEV, M_WAITOK); - sc->sc_bulkout_buffer = malloc(USCANNER_BUFFERSIZE, M_USBDEV, M_WAITOK); - /* No need to check buffers for NULL since we have WAITOK */ - sc->sc_bulkin_bufferlen = USCANNER_BUFFERSIZE; sc->sc_bulkout_bufferlen = USCANNER_BUFFERSIZE; @@ -399,7 +395,7 @@ uscanneropen(dev_t dev, int flag, int mode, printf("%s: cannot open bulk-in pipe (addr %d)\n", device_xname(sc->sc_dev), sc->sc_bulkin); uscanner_do_close(sc); - return (EIO); + return EIO; } } if (sc->sc_bulkout_pipe == NULL) { @@ -409,22 +405,27 @@ uscanneropen(dev_t dev, int flag, int mode, printf("%s: cannot open bulk-out pipe (addr %d)\n", device_xname(sc->sc_dev), sc->sc_bulkout); uscanner_do_close(sc); - return (EIO); + return EIO; } } - sc->sc_bulkin_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_bulkin_xfer == NULL) { + int error = usbd_create_xfer(sc->sc_bulkin_pipe, USCANNER_BUFFERSIZE, + USBD_SHORT_XFER_OK, 0, &sc->sc_bulkin_xfer); + if (error) { uscanner_do_close(sc); - return (ENOMEM); + return error; } - sc->sc_bulkout_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_bulkout_xfer == NULL) { + sc->sc_bulkin_buffer = usbd_get_buffer(sc->sc_bulkin_xfer); + + error = usbd_create_xfer(sc->sc_bulkout_pipe, USCANNER_BUFFERSIZE, 0, + 0, &sc->sc_bulkout_xfer); + if (error) { uscanner_do_close(sc); - return (ENOMEM); + return error; } + sc->sc_bulkout_buffer = usbd_get_buffer(sc->sc_bulkout_xfer); - return (0); /* success */ + return 0; /* success */ } int @@ -441,46 +442,49 @@ uscannerclose(dev_t dev, int flag, int mode, #ifdef DIAGNOSTIC if (!(sc->sc_state & USCANNER_OPEN)) { printf("uscannerclose: not open\n"); - return (EINVAL); + return EINVAL; } #endif uscanner_do_close(sc); - return (0); + return 0; } void uscanner_do_close(struct uscanner_softc *sc) { - if (sc->sc_bulkin_xfer) { - usbd_free_xfer(sc->sc_bulkin_xfer); - sc->sc_bulkin_xfer = NULL; - } - if (sc->sc_bulkout_xfer) { - usbd_free_xfer(sc->sc_bulkout_xfer); - sc->sc_bulkout_xfer = NULL; - } - if (!(sc->sc_dev_flags & USC_KEEP_OPEN)) { if (sc->sc_bulkin_pipe != NULL) { usbd_abort_pipe(sc->sc_bulkin_pipe); + } + if (sc->sc_bulkout_pipe != NULL) { + usbd_abort_pipe(sc->sc_bulkout_pipe); + } + if (sc->sc_bulkin_xfer) { + usbd_destroy_xfer(sc->sc_bulkin_xfer); + sc->sc_bulkin_xfer = NULL; + } + if (sc->sc_bulkout_xfer) { + usbd_destroy_xfer(sc->sc_bulkout_xfer); + sc->sc_bulkout_xfer = NULL; + } + if (sc->sc_bulkin_pipe != NULL) { usbd_close_pipe(sc->sc_bulkin_pipe); sc->sc_bulkin_pipe = NULL; } if (sc->sc_bulkout_pipe != NULL) { - usbd_abort_pipe(sc->sc_bulkout_pipe); usbd_close_pipe(sc->sc_bulkout_pipe); sc->sc_bulkout_pipe = NULL; } } if (sc->sc_bulkin_buffer) { - free(sc->sc_bulkin_buffer, M_USBDEV); + kmem_free(sc->sc_bulkin_buffer, sc->sc_bulkin_bufferlen); sc->sc_bulkin_buffer = NULL; } if (sc->sc_bulkout_buffer) { - free(sc->sc_bulkout_buffer, M_USBDEV); + kmem_free(sc->sc_bulkout_buffer, sc->sc_bulkin_bufferlen); sc->sc_bulkout_buffer = NULL; } @@ -490,24 +494,21 @@ uscanner_do_close(struct uscanner_softc *sc) Static int uscanner_do_read(struct uscanner_softc *sc, struct uio *uio, int flag) { - u_int32_t n, tn; + uint32_t n, tn; usbd_status err; int error = 0; DPRINTFN(5, ("%s: uscannerread\n", device_xname(sc->sc_dev))); if (sc->sc_dying) - return (EIO); + return EIO; while ((n = min(sc->sc_bulkin_bufferlen, uio->uio_resid)) != 0) { DPRINTFN(1, ("uscannerread: start transfer %d bytes\n",n)); tn = n; - err = usbd_bulk_transfer( - sc->sc_bulkin_xfer, sc->sc_bulkin_pipe, - USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, - sc->sc_bulkin_buffer, &tn, - "uscnrb"); + err = usbd_bulk_transfer(sc->sc_bulkin_xfer, sc->sc_bulkin_pipe, + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, sc->sc_bulkin_buffer, &tn); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; @@ -523,7 +524,7 @@ uscanner_do_read(struct uscanner_softc *sc, struct uio *uio, int flag) break; } - return (error); + return error; } int @@ -539,31 +540,29 @@ uscannerread(dev_t dev, struct uio *uio, int flag) if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); - return (error); + return error; } Static int uscanner_do_write(struct uscanner_softc *sc, struct uio *uio, int flag) { - u_int32_t n; + uint32_t n; int error = 0; usbd_status err; DPRINTFN(5, ("%s: uscanner_do_write\n", device_xname(sc->sc_dev))); if (sc->sc_dying) - return (EIO); + return EIO; while ((n = min(sc->sc_bulkout_bufferlen, uio->uio_resid)) != 0) { error = uiomove(sc->sc_bulkout_buffer, n, uio); if (error) break; DPRINTFN(1, ("uscanner_do_write: transfer %d bytes\n", n)); - err = usbd_bulk_transfer( - sc->sc_bulkout_xfer, sc->sc_bulkout_pipe, - 0, USBD_NO_TIMEOUT, - sc->sc_bulkout_buffer, &n, - "uscnwb"); + err = usbd_bulk_transfer(sc->sc_bulkout_xfer, + sc->sc_bulkout_pipe, 0, USBD_NO_TIMEOUT, + sc->sc_bulkout_buffer, &n); if (err) { if (err == USBD_INTERRUPTED) error = EINTR; @@ -573,7 +572,7 @@ uscanner_do_write(struct uscanner_softc *sc, struct uio *uio, int flag) } } - return (error); + return error; } int @@ -588,7 +587,7 @@ uscannerwrite(dev_t dev, struct uio *uio, int flag) error = uscanner_do_write(sc, uio, flag); if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); - return (error); + return error; } int @@ -605,7 +604,7 @@ uscanner_activate(device_t self, enum devact act) } } -int +int uscanner_detach(device_t self, int flags) { struct uscanner_softc *sc = device_private(self); @@ -641,7 +640,7 @@ uscanner_detach(device_t self, int flags) sc->sc_dev); seldestroy(&sc->sc_selq); - return (0); + return 0; } int @@ -653,7 +652,7 @@ uscannerpoll(dev_t dev, int events, struct lwp *l) sc = device_lookup_private(&uscanner_cd, USCANNERUNIT(dev)); if (sc->sc_dying) - return (POLLHUP); + return POLLHUP; /* * We have no easy way of determining if a read will @@ -663,7 +662,7 @@ uscannerpoll(dev_t dev, int events, struct lwp *l) revents |= events & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM); - return (revents); + return revents; } static void @@ -686,7 +685,7 @@ uscannerkqfilter(dev_t dev, struct knote *kn) sc = device_lookup_private(&uscanner_cd, USCANNERUNIT(dev)); if (sc->sc_dying) - return (ENXIO); + return ENXIO; switch (kn->kn_filter) { case EVFILT_READ: @@ -701,19 +700,19 @@ uscannerkqfilter(dev_t dev, struct knote *kn) break; default: - return (EINVAL); + return EINVAL; } kn->kn_hook = sc; SLIST_INSERT_HEAD(klist, kn, kn_selnext); - return (0); + return 0; } int uscannerioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l) { - return (EINVAL); + return EINVAL; } diff --git a/sys/dev/usb/uslsa.c b/sys/dev/usb/uslsa.c index 1cbf43b0bec..74f5885eb6e 100644 --- a/sys/dev/usb/uslsa.c +++ b/sys/dev/usb/uslsa.c @@ -1,4 +1,4 @@ -/* $NetBSD: uslsa.c,v 1.19 2014/03/10 19:55:18 reinoud Exp $ */ +/* $NetBSD: uslsa.c,v 1.20 2016/04/23 10:15:32 skrll Exp $ */ /* from ugensa.c */ @@ -58,7 +58,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uslsa.c,v 1.19 2014/03/10 19:55:18 reinoud Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uslsa.c,v 1.20 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -89,8 +89,8 @@ int uslsadebug = 0; struct uslsa_softc { device_t sc_dev; /* base device */ device_t sc_subdev; /* ucom device */ - usbd_device_handle sc_udev; /* usb device */ - usbd_interface_handle sc_iface; /* interface */ + struct usbd_device * sc_udev; /* usb device */ + struct usbd_interface * sc_iface; /* interface */ uint8_t sc_ifnum; /* interface number */ bool sc_dying; /* disconnecting */ }; @@ -108,14 +108,14 @@ static int uslsa_request_set(struct uslsa_softc *, uint8_t, uint16_t); static int uslsa_set_flow(struct uslsa_softc *, tcflag_t, tcflag_t); static const struct ucom_methods uslsa_methods = { - uslsa_get_status, - uslsa_set, - uslsa_param, - uslsa_ioctl, - uslsa_open, - uslsa_close, - NULL, - NULL, + .ucom_get_status = uslsa_get_status, + .ucom_set = uslsa_set, + .ucom_param = uslsa_param, + .ucom_ioctl = uslsa_ioctl, + .ucom_open = uslsa_open, + .ucom_close = uslsa_close, + .ucom_read = NULL, + .ucom_write = NULL, }; #define USLSA_CONFIG_INDEX 0 @@ -154,11 +154,9 @@ CFATTACH_DECL2_NEW(uslsa, sizeof(struct uslsa_softc), uslsa_match, static int uslsa_match(device_t parent, cfdata_t match, void *aux) { - const struct usbif_attach_arg *uaa; + const struct usbif_attach_arg *uiaa = aux; - uaa = aux; - - if (usb_lookup(uslsa_devs, uaa->vendor, uaa->product) != NULL) { + if (usb_lookup(uslsa_devs, uiaa->uiaa_vendor, uiaa->uiaa_product) != NULL) { return UMATCH_VENDOR_PRODUCT; } else { return UMATCH_NONE; @@ -169,19 +167,18 @@ static void uslsa_attach(device_t parent, device_t self, void *aux) { struct uslsa_softc *sc; - const struct usbif_attach_arg *uaa; + const struct usbif_attach_arg *uiaa = aux; const usb_interface_descriptor_t *id; const usb_endpoint_descriptor_t *ed; char *devinfop; - struct ucom_attach_args uca; + struct ucom_attach_args ucaa; int i; sc = device_private(self); - uaa = aux; sc->sc_dev = self; - sc->sc_udev = uaa->device; - sc->sc_iface = uaa->iface; + sc->sc_udev = uiaa->uiaa_device; + sc->sc_iface = uiaa->uiaa_iface; aprint_naive("\n"); aprint_normal("\n"); @@ -194,21 +191,21 @@ uslsa_attach(device_t parent, device_t self, void *aux) sc->sc_ifnum = id->bInterfaceNumber; - uca.info = "Silicon Labs CP210x"; - uca.portno = UCOM_UNK_PORTNO; - uca.ibufsize = USLSA_BUFSIZE; - uca.obufsize = USLSA_BUFSIZE; - uca.ibufsizepad = USLSA_BUFSIZE; - uca.opkthdrlen = 0; - uca.device = sc->sc_udev; - uca.iface = sc->sc_iface; - uca.methods = &uslsa_methods; - uca.arg = sc; + ucaa.ucaa_info = "Silicon Labs CP210x"; + ucaa.ucaa_portno = UCOM_UNK_PORTNO; + ucaa.ucaa_ibufsize = USLSA_BUFSIZE; + ucaa.ucaa_obufsize = USLSA_BUFSIZE; + ucaa.ucaa_ibufsizepad = USLSA_BUFSIZE; + ucaa.ucaa_opkthdrlen = 0; + ucaa.ucaa_device = sc->sc_udev; + ucaa.ucaa_iface = sc->sc_iface; + ucaa.ucaa_methods = &uslsa_methods; + ucaa.ucaa_arg = sc; usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); - uca.bulkin = uca.bulkout = -1; + ucaa.ucaa_bulkin = ucaa.ucaa_bulkout = -1; for (i = 0; i < id->bNumEndpoints; i++) { int addr, dir, attr; @@ -223,22 +220,22 @@ uslsa_attach(device_t parent, device_t self, void *aux) dir = UE_GET_DIR(ed->bEndpointAddress); attr = ed->bmAttributes & UE_XFERTYPE; if (dir == UE_DIR_IN && attr == UE_BULK) { - uca.bulkin = addr; + ucaa.ucaa_bulkin = addr; } else if (dir == UE_DIR_OUT && attr == UE_BULK) { - uca.bulkout = addr; + ucaa.ucaa_bulkout = addr; } else { aprint_error_dev(self, "unexpected endpoint\n"); } } aprint_debug_dev(sc->sc_dev, "EPs: in=%#x out=%#x\n", - uca.bulkin, uca.bulkout); - if ((uca.bulkin == -1) || (uca.bulkout == -1)) { + ucaa.ucaa_bulkin, ucaa.ucaa_bulkout); + if ((ucaa.ucaa_bulkin == -1) || (ucaa.ucaa_bulkout == -1)) { aprint_error_dev(self, "could not find endpoints\n"); sc->sc_dying = true; return; } - sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &uca, + sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &ucaa, ucomprint, ucomsubmatch); return; diff --git a/sys/dev/usb/usscanner.c b/sys/dev/usb/usscanner.c index 565a2e9913d..d82257aa6a1 100644 --- a/sys/dev/usb/usscanner.c +++ b/sys/dev/usb/usscanner.c @@ -1,4 +1,4 @@ -/* $NetBSD: usscanner.c,v 1.38 2013/09/15 19:27:22 martin Exp $ */ +/* $NetBSD: usscanner.c,v 1.39 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -47,14 +47,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: usscanner.c,v 1.38 2013/09/15 19:27:22 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: usscanner.c,v 1.39 2016/04/23 10:15:32 skrll Exp $"); #include "scsibus.h" #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/lwp.h> -#include <sys/malloc.h> #include <sys/device.h> #include <sys/conf.h> #include <sys/buf.h> @@ -94,24 +93,26 @@ int usscannerdebug = 0; struct usscanner_softc { device_t sc_dev; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device *sc_udev; + struct usbd_interface *sc_iface; int sc_in_addr; - usbd_pipe_handle sc_in_pipe; + struct usbd_pipe *sc_in_pipe; int sc_intr_addr; - usbd_pipe_handle sc_intr_pipe; - usbd_xfer_handle sc_intr_xfer; + struct usbd_pipe *sc_intr_pipe; + struct usbd_xfer *sc_intr_xfer; u_char sc_status; int sc_out_addr; - usbd_pipe_handle sc_out_pipe; + struct usbd_pipe *sc_out_pipe; - usbd_xfer_handle sc_cmd_xfer; + struct usbd_xfer *sc_cmd_xfer; void *sc_cmd_buffer; - usbd_xfer_handle sc_data_xfer; - void *sc_data_buffer; + struct usbd_xfer *sc_datain_xfer; + void *sc_datain_buffer; + struct usbd_xfer *sc_dataout_xfer; + void *sc_dataout_buffer; int sc_state; #define UAS_IDLE 0 @@ -133,13 +134,13 @@ struct usscanner_softc { }; -Static void usscanner_cleanup(struct usscanner_softc *sc); -Static void usscanner_scsipi_request(struct scsipi_channel *chan, - scsipi_adapter_req_t req, void *arg); -Static void usscanner_scsipi_minphys(struct buf *bp); -Static void usscanner_done(struct usscanner_softc *sc); -Static void usscanner_sense(struct usscanner_softc *sc); -typedef void callback(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void usscanner_cleanup(struct usscanner_softc *); +Static void usscanner_scsipi_request(struct scsipi_channel *, + scsipi_adapter_req_t, void *); +Static void usscanner_scsipi_minphys(struct buf *); +Static void usscanner_done(struct usscanner_softc *); +Static void usscanner_sense(struct usscanner_softc *); +typedef void callback(struct usbd_xfer *, void *, usbd_status); Static callback usscanner_intr_cb; Static callback usscanner_cmd_cb; Static callback usscanner_data_cb; @@ -156,32 +157,33 @@ CFATTACH_DECL2_NEW(usscanner, sizeof(struct usscanner_softc), usscanner_match, usscanner_attach, usscanner_detach, usscanner_activate, NULL, usscanner_childdet); -int +int usscanner_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; DPRINTFN(50,("usscanner_match\n")); - if (uaa->vendor == USB_VENDOR_HP && - uaa->product == USB_PRODUCT_HP_5300C) - return (UMATCH_VENDOR_PRODUCT); + if (uaa->uaa_vendor == USB_VENDOR_HP && + uaa->uaa_product == USB_PRODUCT_HP_5300C) + return UMATCH_VENDOR_PRODUCT; else - return (UMATCH_NONE); + return UMATCH_NONE; } -void +void usscanner_attach(device_t parent, device_t self, void *aux) { struct usscanner_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface; + struct usbd_device * dev = uaa->uaa_device; + struct usbd_interface * iface; char *devinfop; usbd_status err; usb_endpoint_descriptor_t *ed; - u_int8_t epcount; + uint8_t epcount; int i; + int error; DPRINTFN(10,("usscanner_attach: sc=%p\n", sc)); @@ -263,44 +265,45 @@ usscanner_attach(device_t parent, device_t self, void *aux) return; } - sc->sc_cmd_xfer = usbd_alloc_xfer(uaa->device); - if (sc->sc_cmd_xfer == NULL) { - aprint_error_dev(self, "alloc cmd xfer failed, err=%d\n", err); + /* XXX too big */ + error = usbd_create_xfer(sc->sc_out_pipe, USSCANNER_MAX_TRANSFER_SIZE, + 0, 0, &sc->sc_cmd_xfer); + if (error) { + aprint_error_dev(self, "alloc cmd xfer failed, error=%d\n", + error); usscanner_cleanup(sc); return; } - /* XXX too big */ - sc->sc_cmd_buffer = usbd_alloc_buffer(sc->sc_cmd_xfer, - USSCANNER_MAX_TRANSFER_SIZE); - if (sc->sc_cmd_buffer == NULL) { - aprint_error_dev(self, "alloc cmd buffer failed, err=%d\n", - err); + sc->sc_cmd_buffer = usbd_get_buffer(sc->sc_cmd_xfer); + + error = usbd_create_xfer(sc->sc_intr_pipe, 1, USBD_SHORT_XFER_OK, + 0, &sc->sc_intr_xfer); + if (error) { + aprint_error_dev(self, "alloc intr xfer failed, error=%d\n", + error); usscanner_cleanup(sc); return; } - sc->sc_intr_xfer = usbd_alloc_xfer (uaa->device); - if (sc->sc_intr_xfer == NULL) { - aprint_error_dev(self, "alloc intr xfer failed, err=%d\n", err); - usscanner_cleanup(sc); - return; - } - - sc->sc_data_xfer = usbd_alloc_xfer(uaa->device); - if (sc->sc_data_xfer == NULL) { - aprint_error_dev(self, "alloc data xfer failed, err=%d\n", err); + error = usbd_create_xfer(sc->sc_in_pipe, USSCANNER_MAX_TRANSFER_SIZE, + USBD_SHORT_XFER_OK, 0, &sc->sc_datain_xfer); + if (error) { + aprint_error_dev(self, "alloc data xfer failed, error=%d\n", + error); usscanner_cleanup(sc); return; } - sc->sc_data_buffer = usbd_alloc_buffer(sc->sc_data_xfer, - USSCANNER_MAX_TRANSFER_SIZE); - if (sc->sc_data_buffer == NULL) { - aprint_error_dev(self, "alloc data buffer failed, err=%d\n", - err); + sc->sc_datain_buffer = usbd_get_buffer(sc->sc_datain_xfer); + + error = usbd_create_xfer(sc->sc_out_pipe, USSCANNER_MAX_TRANSFER_SIZE, + USBD_SHORT_XFER_OK, 0, &sc->sc_dataout_xfer); + if (error) { + aprint_error_dev(self, "alloc data xfer failed, err=%d\n", err); usscanner_cleanup(sc); return; } + sc->sc_dataout_buffer = usbd_get_buffer(sc->sc_dataout_xfer); /* * Fill in the adapter. @@ -353,7 +356,7 @@ usscanner_childdet(device_t self, device_t child) sc->sc_child = NULL; } -int +int usscanner_detach(device_t self, int flags) { struct usscanner_softc *sc = device_private(self); @@ -385,12 +388,24 @@ usscanner_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - return (rv); + return rv; } Static void usscanner_cleanup(struct usscanner_softc *sc) { + if (sc->sc_cmd_xfer != NULL) { + usbd_destroy_xfer(sc->sc_cmd_xfer); + sc->sc_cmd_xfer = NULL; + } + if (sc->sc_datain_xfer != NULL) { + usbd_destroy_xfer(sc->sc_datain_xfer); + sc->sc_datain_xfer = NULL; + } + if (sc->sc_dataout_xfer != NULL) { + usbd_destroy_xfer(sc->sc_dataout_xfer); + sc->sc_dataout_xfer = NULL; + } if (sc->sc_in_pipe != NULL) { usbd_close_pipe(sc->sc_in_pipe); sc->sc_in_pipe = NULL; @@ -403,14 +418,6 @@ usscanner_cleanup(struct usscanner_softc *sc) usbd_close_pipe(sc->sc_out_pipe); sc->sc_out_pipe = NULL; } - if (sc->sc_cmd_xfer != NULL) { - usbd_free_xfer(sc->sc_cmd_xfer); - sc->sc_cmd_xfer = NULL; - } - if (sc->sc_data_xfer != NULL) { - usbd_free_xfer(sc->sc_data_xfer); - sc->sc_data_xfer = NULL; - } } int @@ -447,12 +454,13 @@ usscanner_sense(struct usscanner_softc *sc) memset(&sense_cmd, 0, sizeof(sense_cmd)); sense_cmd.opcode = SCSI_REQUEST_SENSE; sense_cmd.byte2 = periph->periph_lun << SCSI_CMD_LUN_SHIFT; - sense_cmd.length = sizeof xs->sense; + sense_cmd.length = sizeof(xs->sense); sc->sc_state = UAS_SENSECMD; - memcpy(sc->sc_cmd_buffer, &sense_cmd, sizeof sense_cmd); - usbd_setup_xfer(sc->sc_cmd_xfer, sc->sc_out_pipe, sc, sc->sc_cmd_buffer, - sizeof sense_cmd, USBD_NO_COPY, USSCANNER_TIMEOUT, + memcpy(sc->sc_cmd_buffer, &sense_cmd, sizeof(sense_cmd)); + + usbd_setup_xfer(sc->sc_cmd_xfer, sc, sc->sc_cmd_buffer, + sizeof(sense_cmd), 0, USSCANNER_TIMEOUT, usscanner_sensecmd_cb); err = usbd_transfer(sc->sc_cmd_xfer); if (err == USBD_IN_PROGRESS) @@ -463,7 +471,7 @@ usscanner_sense(struct usscanner_softc *sc) } Static void -usscanner_intr_cb(usbd_xfer_handle xfer, usbd_private_handle priv, +usscanner_intr_cb(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct usscanner_softc *sc = priv; @@ -491,12 +499,12 @@ usscanner_intr_cb(usbd_xfer_handle xfer, usbd_private_handle priv, } Static void -usscanner_data_cb(usbd_xfer_handle xfer, usbd_private_handle priv, +usscanner_data_cb(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct usscanner_softc *sc = priv; struct scsipi_xfer *xs = sc->sc_xs; - u_int32_t len; + uint32_t len; DPRINTFN(10, ("usscanner_data_cb status=%d\n", status)); @@ -512,8 +520,6 @@ usscanner_data_cb(usbd_xfer_handle xfer, usbd_private_handle priv, switch (status) { case USBD_NORMAL_COMPLETION: - if (xs->xs_control & XS_CTL_DATA_IN) - memcpy(xs->data, sc->sc_data_buffer, len); xs->error = XS_NOERROR; break; case USBD_TIMEOUT: @@ -533,12 +539,12 @@ usscanner_data_cb(usbd_xfer_handle xfer, usbd_private_handle priv, } Static void -usscanner_sensedata_cb(usbd_xfer_handle xfer, usbd_private_handle priv, +usscanner_sensedata_cb(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct usscanner_softc *sc = priv; struct scsipi_xfer *xs = sc->sc_xs; - u_int32_t len; + uint32_t len; DPRINTFN(10, ("usscanner_sensedata_cb status=%d\n", status)); @@ -552,8 +558,8 @@ usscanner_sensedata_cb(usbd_xfer_handle xfer, usbd_private_handle priv, switch (status) { case USBD_NORMAL_COMPLETION: - memcpy(&xs->sense, sc->sc_data_buffer, len); - if (len < sizeof xs->sense) + memcpy(&xs->sense, sc->sc_datain_buffer, len); + if (len < sizeof(xs->sense)) xs->error = XS_SHORTSENSE; break; case USBD_TIMEOUT: @@ -578,9 +584,8 @@ usscanner_done(struct usscanner_softc *sc) DPRINTFN(10,("usscanner_done: error=%d\n", sc->sc_xs->error)); sc->sc_state = UAS_STATUS; - usbd_setup_xfer(sc->sc_intr_xfer, sc->sc_intr_pipe, sc, &sc->sc_status, - 1, USBD_SHORT_XFER_OK | USBD_NO_COPY, - USSCANNER_TIMEOUT, usscanner_intr_cb); + usbd_setup_xfer(sc->sc_intr_xfer, sc, &sc->sc_status, 1, + USBD_SHORT_XFER_OK, USSCANNER_TIMEOUT, usscanner_intr_cb); err = usbd_transfer(sc->sc_intr_xfer); if (err == USBD_IN_PROGRESS) return; @@ -588,7 +593,7 @@ usscanner_done(struct usscanner_softc *sc) } Static void -usscanner_sensecmd_cb(usbd_xfer_handle xfer, usbd_private_handle priv, +usscanner_sensecmd_cb(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct usscanner_softc *sc = priv; @@ -620,11 +625,10 @@ usscanner_sensecmd_cb(usbd_xfer_handle xfer, usbd_private_handle priv, } sc->sc_state = UAS_SENSEDATA; - usbd_setup_xfer(sc->sc_data_xfer, sc->sc_in_pipe, sc, - sc->sc_data_buffer, - sizeof xs->sense, USBD_SHORT_XFER_OK | USBD_NO_COPY, + usbd_setup_xfer(sc->sc_datain_xfer, sc, sc->sc_datain_buffer, + sizeof(xs->sense), USBD_SHORT_XFER_OK, USSCANNER_TIMEOUT, usscanner_sensedata_cb); - err = usbd_transfer(sc->sc_data_xfer); + err = usbd_transfer(sc->sc_datain_xfer); if (err == USBD_IN_PROGRESS) return; xs->error = XS_DRIVER_STUFFUP; @@ -633,12 +637,12 @@ usscanner_sensecmd_cb(usbd_xfer_handle xfer, usbd_private_handle priv, } Static void -usscanner_cmd_cb(usbd_xfer_handle xfer, usbd_private_handle priv, +usscanner_cmd_cb(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct usscanner_softc *sc = priv; struct scsipi_xfer *xs = sc->sc_xs; - usbd_pipe_handle pipe; + struct usbd_xfer *dxfer; usbd_status err; DPRINTFN(10, ("usscanner_cmd_cb status=%d\n", status)); @@ -676,18 +680,16 @@ usscanner_cmd_cb(usbd_xfer_handle xfer, usbd_private_handle priv, if (xs->xs_control & XS_CTL_DATA_IN) { DPRINTFN(4, ("usscanner_cmd_cb: data in len=%d\n", xs->datalen)); - pipe = sc->sc_in_pipe; + dxfer = sc->sc_datain_xfer; } else { DPRINTFN(4, ("usscanner_cmd_cb: data out len=%d\n", xs->datalen)); - memcpy(sc->sc_data_buffer, xs->data, xs->datalen); - pipe = sc->sc_out_pipe; + dxfer = sc->sc_dataout_xfer; } sc->sc_state = UAS_DATA; - usbd_setup_xfer(sc->sc_data_xfer, pipe, sc, sc->sc_data_buffer, - xs->datalen, USBD_SHORT_XFER_OK | USBD_NO_COPY, - xs->timeout, usscanner_data_cb); - err = usbd_transfer(sc->sc_data_xfer); + usbd_setup_xfer(dxfer, sc, xs->data, xs->datalen, + USBD_SHORT_XFER_OK, xs->timeout, usscanner_data_cb); + err = usbd_transfer(dxfer); if (err == USBD_IN_PROGRESS) return; xs->error = XS_DRIVER_STUFFUP; @@ -750,9 +752,8 @@ usscanner_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, sc->sc_state = UAS_CMD; sc->sc_xs = xs; memcpy(sc->sc_cmd_buffer, xs->cmd, xs->cmdlen); - usbd_setup_xfer(sc->sc_cmd_xfer, sc->sc_out_pipe, sc, - sc->sc_cmd_buffer, xs->cmdlen, USBD_NO_COPY, - USSCANNER_TIMEOUT, usscanner_cmd_cb); + usbd_setup_xfer(sc->sc_cmd_xfer, sc, sc->sc_cmd_buffer, + xs->cmdlen, 0, USSCANNER_TIMEOUT, usscanner_cmd_cb); err = usbd_transfer(sc->sc_cmd_xfer); if (err != USBD_IN_PROGRESS) { xs->error = XS_DRIVER_STUFFUP; diff --git a/sys/dev/usb/ustir.c b/sys/dev/usb/ustir.c index 15a006ee353..63c49a337e5 100644 --- a/sys/dev/usb/ustir.c +++ b/sys/dev/usb/ustir.c @@ -1,4 +1,4 @@ -/* $NetBSD: ustir.c,v 1.33 2013/05/27 16:23:20 kiyohara Exp $ */ +/* $NetBSD: ustir.c,v 1.34 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -30,13 +30,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ustir.c,v 1.33 2013/05/27 16:23:20 kiyohara Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ustir.c,v 1.34 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> #include <sys/device.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/conf.h> #include <sys/file.h> #include <sys/poll.h> @@ -90,17 +90,17 @@ Static struct ustir_speedrec const ustir_speeds[USTIR_NSPEEDS] = { struct ustir_softc { device_t sc_dev; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; + struct usbd_device *sc_udev; + struct usbd_interface *sc_iface; - u_int8_t *sc_ur_buf; /* Unencapsulated frame */ + uint8_t *sc_ur_buf; /* Unencapsulated frame */ u_int sc_ur_framelen; - u_int8_t *sc_rd_buf; /* Raw incoming data stream */ + uint8_t *sc_rd_buf; /* Raw incoming data stream */ size_t sc_rd_index; int sc_rd_addr; - usbd_pipe_handle sc_rd_pipe; - usbd_xfer_handle sc_rd_xfer; + struct usbd_pipe *sc_rd_pipe; + struct usbd_xfer *sc_rd_xfer; u_int sc_rd_count; int sc_rd_readinprogress; u_int sc_rd_expectdataticks; @@ -109,11 +109,11 @@ struct ustir_softc { struct lwp *sc_thread; struct selinfo sc_rd_sel; - u_int8_t *sc_wr_buf; + uint8_t *sc_wr_buf; int sc_wr_addr; int sc_wr_stalewrite; - usbd_xfer_handle sc_wr_xfer; - usbd_pipe_handle sc_wr_pipe; + struct usbd_xfer *sc_wr_xfer; + struct usbd_pipe *sc_wr_pipe; struct selinfo sc_wr_sel; enum { @@ -138,19 +138,19 @@ struct ustir_softc { #define USTIR_WR_TIMEOUT 200 -Static int ustir_activate(device_t self, enum devact act); -Static int ustir_open(void *h, int flag, int mode, struct lwp *l); -Static int ustir_close(void *h, int flag, int mode, struct lwp *l); -Static int ustir_read(void *h, struct uio *uio, int flag); -Static int ustir_write(void *h, struct uio *uio, int flag); -Static int ustir_set_params(void *h, struct irda_params *params); -Static int ustir_get_speeds(void *h, int *speeds); -Static int ustir_get_turnarounds(void *h, int *times); -Static int ustir_poll(void *h, int events, struct lwp *l); -Static int ustir_kqfilter(void *h, struct knote *kn); +Static int ustir_activate(device_t, enum devact); +Static int ustir_open(void *, int, int, struct lwp *); +Static int ustir_close(void *, int, int, struct lwp *); +Static int ustir_read(void *, struct uio *, int); +Static int ustir_write(void *, struct uio *, int); +Static int ustir_set_params(void *, struct irda_params *); +Static int ustir_get_speeds(void *, int *); +Static int ustir_get_turnarounds(void *, int *); +Static int ustir_poll(void *, int, struct lwp *); +Static int ustir_kqfilter(void *, struct knote *); #ifdef USTIR_DEBUG_IOCTLS -Static int ustir_ioctl(void *h, u_long cmd, void *addr, int flag, struct lwp *l); +Static int ustir_ioctl(void *, u_long, void *, int, struct lwp *); #endif Static struct irframe_methods const ustir_methods = { @@ -162,13 +162,13 @@ Static struct irframe_methods const ustir_methods = { #endif }; -Static void ustir_rd_cb(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void ustir_rd_cb(struct usbd_xfer *, void *, usbd_status); Static usbd_status ustir_start_read(struct ustir_softc *); Static void ustir_periodic(struct ustir_softc *); Static void ustir_thread(void *); static usbd_status -ustir_read_reg(struct ustir_softc *sc, unsigned int reg, u_int8_t *data) +ustir_read_reg(struct ustir_softc *sc, unsigned int reg, uint8_t *data) { usb_device_request_t req; @@ -182,7 +182,7 @@ ustir_read_reg(struct ustir_softc *sc, unsigned int reg, u_int8_t *data) } static usbd_status -ustir_write_reg(struct ustir_softc *sc, unsigned int reg, u_int8_t data) +ustir_write_reg(struct ustir_softc *sc, unsigned int reg, uint8_t data) { usb_device_request_t req; @@ -197,7 +197,7 @@ ustir_write_reg(struct ustir_softc *sc, unsigned int reg, u_int8_t data) #ifdef USTIR_DEBUG static void -ustir_dumpdata(u_int8_t const *data, size_t dlen, char const *desc) +ustir_dumpdata(uint8_t const *data, size_t dlen, char const *desc) { size_t bdindex; printf("%s: (%lx)", desc, (unsigned long)dlen); @@ -216,30 +216,30 @@ extern struct cfdriver ustir_cd; CFATTACH_DECL2_NEW(ustir, sizeof(struct ustir_softc), ustir_match, ustir_attach, ustir_detach, ustir_activate, NULL, ustir_childdet); -int +int ustir_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; DPRINTFN(50,("ustir_match\n")); - if (uaa->vendor == USB_VENDOR_SIGMATEL && - uaa->product == USB_PRODUCT_SIGMATEL_IRDA) + if (uaa->uaa_vendor == USB_VENDOR_SIGMATEL && + uaa->uaa_product == USB_PRODUCT_SIGMATEL_IRDA) return UMATCH_VENDOR_PRODUCT; return UMATCH_NONE; } -void +void ustir_attach(device_t parent, device_t self, void *aux) { struct ustir_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface; + struct usbd_device *dev = uaa->uaa_device; + struct usbd_interface *iface; char *devinfop; usb_endpoint_descriptor_t *ed; - u_int8_t epcount; + uint8_t epcount; int i; struct ir_attach_args ia; @@ -312,7 +312,7 @@ ustir_childdet(device_t self, device_t child) sc->sc_child = NULL; } -int +int ustir_detach(device_t self, int flags) { struct ustir_softc *sc = device_private(self); @@ -331,11 +331,25 @@ ustir_detach(device_t self, int flags) /* Abort all pipes. Causes processes waiting for transfer to wake. */ if (sc->sc_rd_pipe != NULL) { usbd_abort_pipe(sc->sc_rd_pipe); + } + if (sc->sc_wr_pipe != NULL) { + usbd_abort_pipe(sc->sc_wr_pipe); + } + if (sc->sc_rd_xfer != NULL) { + usbd_destroy_xfer(sc->sc_rd_xfer); + sc->sc_rd_xfer = NULL; + sc->sc_rd_buf = NULL; + } + if (sc->sc_wr_xfer != NULL) { + usbd_destroy_xfer(sc->sc_wr_xfer); + sc->sc_wr_xfer = NULL; + sc->sc_wr_buf = NULL; + } + if (sc->sc_rd_pipe != NULL) { usbd_close_pipe(sc->sc_rd_pipe); sc->sc_rd_pipe = NULL; } if (sc->sc_wr_pipe != NULL) { - usbd_abort_pipe(sc->sc_wr_pipe); usbd_close_pipe(sc->sc_wr_pipe); sc->sc_wr_pipe = NULL; } @@ -366,7 +380,7 @@ static int deframe_rd_ur(struct ustir_softc *sc) { while (sc->sc_rd_index < sc->sc_rd_count) { - u_int8_t const *buf; + uint8_t const *buf; size_t buflen; enum frameresult fresult; @@ -428,7 +442,7 @@ ustir_periodic(struct ustir_softc *sc) if (sc->sc_direction == udir_output || sc->sc_direction == udir_stalled) { usbd_status err; - u_int8_t regval; + uint8_t regval; DPRINTFN(60, ("%s: reading status register\n", __func__)); @@ -537,11 +551,11 @@ ustir_thread(void *arg) } Static void -ustir_rd_cb(usbd_xfer_handle xfer, usbd_private_handle priv, +ustir_rd_cb(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct ustir_softc *sc = priv; - u_int32_t size; + uint32_t size; DPRINTFN(60, ("%s: sc=%p\n", __func__, sc)); @@ -648,10 +662,9 @@ ustir_start_read(struct ustir_softc *sc) usbd_clear_endpoint_stall(sc->sc_rd_pipe); } - usbd_setup_xfer(sc->sc_rd_xfer, sc->sc_rd_pipe, sc, sc->sc_rd_buf, - sc->sc_params.maxsize, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, ustir_rd_cb); + usbd_setup_xfer(sc->sc_rd_xfer, sc, sc->sc_rd_buf, + sc->sc_params.maxsize, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, + ustir_rd_cb); err = usbd_transfer(sc->sc_rd_xfer); if (err != USBD_IN_PROGRESS) { DPRINTFN(0, ("%s: err=%d\n", __func__, (int)err)); @@ -695,29 +708,20 @@ ustir_open(void *h, int flag, int mode, error = EIO; goto bad2; } - sc->sc_rd_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_rd_xfer == NULL) { - error = ENOMEM; + error = usbd_create_xfer(sc->sc_rd_pipe, IRDA_MAX_FRAME_SIZE, + USBD_SHORT_XFER_OK, 0, &sc->sc_rd_xfer); + if (error) goto bad3; - } - sc->sc_wr_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_wr_xfer == NULL) { - error = ENOMEM; + sc->sc_rd_buf = usbd_get_buffer(sc->sc_rd_xfer); + + error = usbd_create_xfer(sc->sc_wr_pipe, + IRDA_MAX_FRAME_SIZE + STIR_OUTPUT_HEADER_SIZE, + USBD_FORCE_SHORT_XFER, 0, &sc->sc_wr_xfer); + if (error) goto bad4; - } - sc->sc_rd_buf = usbd_alloc_buffer(sc->sc_rd_xfer, - IRDA_MAX_FRAME_SIZE); - if (sc->sc_rd_buf == NULL) { - error = ENOMEM; - goto bad5; - } - sc->sc_wr_buf = usbd_alloc_buffer(sc->sc_wr_xfer, - IRDA_MAX_FRAME_SIZE + STIR_OUTPUT_HEADER_SIZE); - if (sc->sc_wr_buf == NULL) { - error = ENOMEM; - goto bad5; - } - sc->sc_ur_buf = malloc(IRDA_MAX_FRAME_SIZE, M_USBDEV, M_NOWAIT); + sc->sc_wr_buf = usbd_get_buffer(sc->sc_wr_xfer); + + sc->sc_ur_buf = kmem_alloc(IRDA_MAX_FRAME_SIZE, KM_SLEEP); if (sc->sc_ur_buf == NULL) { error = ENOMEM; goto bad5; @@ -751,10 +755,10 @@ ustir_open(void *h, int flag, int mode, return 0; bad5: - usbd_free_xfer(sc->sc_wr_xfer); + usbd_destroy_xfer(sc->sc_wr_xfer); sc->sc_wr_xfer = NULL; bad4: - usbd_free_xfer(sc->sc_rd_xfer); + usbd_destroy_xfer(sc->sc_rd_xfer); sc->sc_rd_xfer = NULL; bad3: usbd_close_pipe(sc->sc_wr_pipe); @@ -787,28 +791,34 @@ ustir_close(void *h, int flag, int mode, if (sc->sc_rd_pipe != NULL) { usbd_abort_pipe(sc->sc_rd_pipe); - usbd_close_pipe(sc->sc_rd_pipe); sc->sc_rd_pipe = NULL; } if (sc->sc_wr_pipe != NULL) { usbd_abort_pipe(sc->sc_wr_pipe); - usbd_close_pipe(sc->sc_wr_pipe); sc->sc_wr_pipe = NULL; } if (sc->sc_rd_xfer != NULL) { - usbd_free_xfer(sc->sc_rd_xfer); + usbd_destroy_xfer(sc->sc_rd_xfer); sc->sc_rd_xfer = NULL; sc->sc_rd_buf = NULL; } if (sc->sc_wr_xfer != NULL) { - usbd_free_xfer(sc->sc_wr_xfer); + usbd_destroy_xfer(sc->sc_wr_xfer); sc->sc_wr_xfer = NULL; sc->sc_wr_buf = NULL; } if (sc->sc_ur_buf != NULL) { - free(sc->sc_ur_buf, M_USBDEV); + kmem_free(sc->sc_ur_buf, IRDA_MAX_FRAME_SIZE); sc->sc_ur_buf = NULL; } + if (sc->sc_rd_pipe != NULL) { + usbd_close_pipe(sc->sc_rd_pipe); + sc->sc_rd_pipe = NULL; + } + if (sc->sc_wr_pipe != NULL) { + usbd_close_pipe(sc->sc_wr_pipe); + sc->sc_wr_pipe = NULL; + } if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); @@ -892,9 +902,9 @@ ustir_write(void *h, struct uio *uio, int flag) { struct ustir_softc *sc = h; usbd_status err; - u_int32_t wrlen; + uint32_t wrlen; int error, sirlength; - u_int8_t *wrbuf; + uint8_t *wrbuf; int s; DPRINTFN(1,("%s: sc=%p\n", __func__, sc)); @@ -966,7 +976,7 @@ ustir_write(void *h, struct uio *uio, int flag) if (sirlength < 0) { error = -sirlength; } else { - u_int32_t btlen; + uint32_t btlen; DPRINTFN(1, ("%s: transfer %u bytes\n", __func__, (unsigned int)wrlen)); @@ -984,9 +994,7 @@ ustir_write(void *h, struct uio *uio, int flag) #endif err = usbd_bulk_transfer(sc->sc_wr_xfer, sc->sc_wr_pipe, - USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - USTIR_WR_TIMEOUT, - wrbuf, &btlen, "ustiwr"); + USBD_FORCE_SHORT_XFER, USTIR_WR_TIMEOUT, wrbuf, &btlen); DPRINTFN(2, ("%s: err=%d\n", __func__, err)); if (err != USBD_NORMAL_COMPLETION) { if (err == USBD_INTERRUPTED) @@ -1058,7 +1066,7 @@ filt_ustirread(struct knote *kn, long hint) struct ustir_softc *sc = kn->kn_hook; kn->kn_data = sc->sc_ur_framelen; - return (kn->kn_data > 0); + return kn->kn_data > 0; } static void @@ -1079,7 +1087,7 @@ filt_ustirwrite(struct knote *kn, long hint) struct ustir_softc *sc = kn->kn_hook; kn->kn_data = 0; - return (sc->sc_direction != udir_input); + return sc->sc_direction != udir_input; } static const struct filterops ustirread_filtops = @@ -1104,7 +1112,7 @@ ustir_kqfilter(void *h, struct knote *kn) kn->kn_fop = &ustirwrite_filtops; break; default: - return (EINVAL); + return EINVAL; } kn->kn_hook = sc; @@ -1113,7 +1121,7 @@ ustir_kqfilter(void *h, struct knote *kn) SLIST_INSERT_HEAD(klist, kn, kn_selnext); splx(s); - return (0); + return 0; } #ifdef USTIR_DEBUG_IOCTLS @@ -1123,7 +1131,7 @@ Static int ustir_ioctl(void *h, u_long cmd, void *addr, int flag, struct lwp *l) int error; unsigned int regnum; usbd_status err; - u_int8_t regdata; + uint8_t regdata; if (sc->sc_dying) return EIO; @@ -1235,8 +1243,8 @@ ustir_set_params(void *h, struct irda_params *p) if (speedblk != NULL) { usbd_status err; - u_int8_t regmode; - u_int8_t regbrate; + uint8_t regmode; + uint8_t regbrate; sc->sc_speedrec = speedblk; diff --git a/sys/dev/usb/uthum.c b/sys/dev/usb/uthum.c index 8ffe8f7c90d..7ebdb7bd299 100644 --- a/sys/dev/usb/uthum.c +++ b/sys/dev/usb/uthum.c @@ -1,4 +1,4 @@ -/* $NetBSD: uthum.c,v 1.10 2013/01/05 23:34:21 christos Exp $ */ +/* $NetBSD: uthum.c,v 1.11 2016/04/23 10:15:32 skrll Exp $ */ /* $OpenBSD: uthum.c,v 1.6 2010/01/03 18:43:02 deraadt Exp $ */ /* @@ -22,13 +22,12 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uthum.c,v 1.10 2013/01/05 23:34:21 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uthum.c,v 1.11 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/proc.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> #include <sys/device.h> #include <sys/conf.h> @@ -72,7 +71,7 @@ static uint8_t cmd_end[8] = struct uthum_softc { struct uhidev sc_hdev; - usbd_device_handle sc_udev; + struct usbd_device * sc_udev; u_char sc_dying; uint16_t sc_flag; int sc_sensortype; @@ -118,20 +117,18 @@ CFATTACH_DECL_NEW(uthum, sizeof(struct uthum_softc), uthum_match, uthum_attach, int uthum_match(device_t parent, cfdata_t match, void *aux) { - struct usb_attach_arg *uaa = aux; - struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa; + struct uhidev_attach_arg *uha = aux; - return (uthum_lookup(uha->uaa->vendor, uha->uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return uthum_lookup(uha->uiaa->uiaa_vendor, uha->uiaa->uiaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } void uthum_attach(device_t parent, device_t self, void *aux) { struct uthum_softc *sc = device_private(self); - struct usb_attach_arg *uaa = aux; - struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa; - usbd_device_handle dev = uha->parent->sc_udev; + struct uhidev_attach_arg *uha = aux; + struct usbd_device *dev = uha->parent->sc_udev; int size, repid; void *desc; @@ -230,7 +227,7 @@ uthum_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_hdev.sc_dev); - return (rv); + return rv; } int @@ -243,7 +240,7 @@ uthum_activate(device_t self, enum devact act) sc->sc_dying = 1; break; } - return (0); + return 0; } void @@ -264,19 +261,19 @@ uthum_read_data(struct uthum_softc *sc, uint8_t target_cmd, uint8_t *buf, return 0; /* issue query */ - bzero(cmdbuf, sizeof(cmdbuf)); + memset(cmdbuf, 0, sizeof(cmdbuf)); memcpy(cmdbuf, cmd_start, sizeof(cmd_start)); if (uhidev_set_report(&sc->sc_hdev, UHID_OUTPUT_REPORT, cmdbuf, sc->sc_olen)) return EIO; - bzero(cmdbuf, sizeof(cmdbuf)); + memset(cmdbuf, 0, sizeof(cmdbuf)); cmdbuf[0] = target_cmd; if (uhidev_set_report(&sc->sc_hdev, UHID_OUTPUT_REPORT, cmdbuf, sc->sc_olen)) return EIO; - bzero(cmdbuf, sizeof(cmdbuf)); + memset(cmdbuf, 0, sizeof(cmdbuf)); for (i = 0; i < 7; i++) { if (uhidev_set_report(&sc->sc_hdev, UHID_OUTPUT_REPORT, cmdbuf, sc->sc_olen)) diff --git a/sys/dev/usb/utoppy.c b/sys/dev/usb/utoppy.c index 13d24209221..0cc5daf7f96 100644 --- a/sys/dev/usb/utoppy.c +++ b/sys/dev/usb/utoppy.c @@ -1,4 +1,4 @@ -/* $NetBSD: utoppy.c,v 1.24 2014/07/25 08:10:39 dholland Exp $ */ +/* $NetBSD: utoppy.c,v 1.25 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2006 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: utoppy.c,v 1.24 2014/07/25 08:10:39 dholland Exp $"); +__KERNEL_RCSID(0, "$NetBSD: utoppy.c,v 1.25 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -38,7 +38,6 @@ __KERNEL_RCSID(0, "$NetBSD: utoppy.c,v 1.24 2014/07/25 08:10:39 dholland Exp $") #include <sys/kernel.h> #include <sys/fcntl.h> #include <sys/device.h> -#include <sys/malloc.h> #include <sys/ioctl.h> #include <sys/uio.h> #include <sys/conf.h> @@ -126,8 +125,8 @@ enum utoppy_state { struct utoppy_softc { device_t sc_dev; - usbd_device_handle sc_udev; /* device */ - usbd_interface_handle sc_iface; /* interface */ + struct usbd_device *sc_udev; /* device */ + struct usbd_interface *sc_iface; /* interface */ int sc_dying; int sc_refcnt; @@ -135,16 +134,16 @@ struct utoppy_softc { u_int sc_turbo_mode; int sc_out; - usbd_pipe_handle sc_out_pipe; /* bulk out pipe */ - usbd_xfer_handle sc_out_xfer; + struct usbd_pipe *sc_out_pipe; /* bulk out pipe */ + struct usbd_xfer *sc_out_xfer; void *sc_out_buf; void *sc_out_data; uint64_t sc_wr_offset; uint64_t sc_wr_size; int sc_in; - usbd_pipe_handle sc_in_pipe; /* bulk in pipe */ - usbd_xfer_handle sc_in_xfer; + struct usbd_pipe *sc_in_pipe; /* bulk in pipe */ + struct usbd_xfer *sc_in_xfer; void *sc_in_buf; void *sc_in_data; size_t sc_in_len; @@ -202,28 +201,28 @@ int utoppy_activate(device_t, enum devact); extern struct cfdriver utoppy_cd; CFATTACH_DECL_NEW(utoppy, sizeof(struct utoppy_softc), utoppy_match, utoppy_attach, utoppy_detach, utoppy_activate); -int +int utoppy_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - if (uaa->vendor == USB_VENDOR_TOPFIELD && - uaa->product == USB_PRODUCT_TOPFIELD_TF5000PVR) - return (UMATCH_VENDOR_PRODUCT); + if (uaa->uaa_vendor == USB_VENDOR_TOPFIELD && + uaa->uaa_product == USB_PRODUCT_TOPFIELD_TF5000PVR) + return UMATCH_VENDOR_PRODUCT; - return (UMATCH_NONE); + return UMATCH_NONE; } -void +void utoppy_attach(device_t parent, device_t self, void *aux) { struct utoppy_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface; + struct usbd_device *dev = uaa->uaa_device; + struct usbd_interface *iface; usb_endpoint_descriptor_t *ed; char *devinfop; - u_int8_t epcount; + uint8_t epcount; int i; sc->sc_dev = self; @@ -282,39 +281,52 @@ utoppy_attach(device_t parent, device_t self, void *aux) sc->sc_iface = iface; sc->sc_udev = dev; - sc->sc_out_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_out_xfer == NULL) { - aprint_error_dev(self, "could not allocate bulk out xfer\n"); - goto fail0; + sc->sc_out_pipe = NULL; + sc->sc_in_pipe = NULL; + + if (usbd_open_pipe(sc->sc_iface, sc->sc_out, 0, &sc->sc_out_pipe)) { + DPRINTF(UTOPPY_DBG_OPEN, ("%s: usbd_open_pipe(OUT) failed\n", + device_xname(sc->sc_dev))); + aprint_error_dev(self, "could not open OUT pipe\n"); + sc->sc_dying = 1; + return; } - sc->sc_out_buf = usbd_alloc_buffer(sc->sc_out_xfer, UTOPPY_FRAG_SIZE); - if (sc->sc_out_buf == NULL) { - aprint_error_dev(self, "could not allocate bulk out buffer\n"); - goto fail1; + if (usbd_open_pipe(sc->sc_iface, sc->sc_in, 0, &sc->sc_in_pipe)) { + DPRINTF(UTOPPY_DBG_OPEN, ("%s: usbd_open_pipe(IN) failed\n", + device_xname(sc->sc_dev))); + aprint_error_dev(self, "could not open IN pipe\n"); + + usbd_close_pipe(sc->sc_out_pipe); + sc->sc_out_pipe = NULL; + sc->sc_dying = 1; + return; } - sc->sc_in_xfer = usbd_alloc_xfer(sc->sc_udev); - if (sc->sc_in_xfer == NULL) { + int error; + error = usbd_create_xfer(sc->sc_out_pipe, UTOPPY_FRAG_SIZE, 0, 0, + &sc->sc_out_xfer); + if (error) { + aprint_error_dev(self, "could not allocate bulk out xfer\n"); + goto fail0; + } + + error = usbd_create_xfer(sc->sc_in_pipe, UTOPPY_FRAG_SIZE, + USBD_SHORT_XFER_OK, 0, &sc->sc_in_xfer); + if (error) { aprint_error_dev(self, "could not allocate bulk in xfer\n"); goto fail1; } - sc->sc_in_buf = usbd_alloc_buffer(sc->sc_in_xfer, UTOPPY_FRAG_SIZE); - if (sc->sc_in_buf == NULL) { - aprint_error_dev(self, "could not allocate bulk in buffer\n"); - goto fail2; - } + sc->sc_out_buf = usbd_get_buffer(sc->sc_out_xfer); + sc->sc_in_buf = usbd_get_buffer(sc->sc_in_xfer); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); return; - fail2: usbd_free_xfer(sc->sc_in_xfer); - sc->sc_in_xfer = NULL; - - fail1: usbd_free_xfer(sc->sc_out_xfer); + fail1: usbd_destroy_xfer(sc->sc_out_xfer); sc->sc_out_xfer = NULL; fail0: sc->sc_dying = 1; @@ -335,7 +347,7 @@ utoppy_activate(device_t self, enum devact act) } } -int +int utoppy_detach(device_t self, int flags) { struct utoppy_softc *sc = device_private(self); @@ -349,9 +361,14 @@ utoppy_detach(device_t self, int flags) usbd_abort_pipe(sc->sc_in_pipe); if (sc->sc_in_xfer != NULL) - usbd_free_xfer(sc->sc_in_xfer); + usbd_destroy_xfer(sc->sc_in_xfer); if (sc->sc_out_xfer != NULL) - usbd_free_xfer(sc->sc_out_xfer); + usbd_destroy_xfer(sc->sc_out_xfer); + + if (sc->sc_out_pipe != NULL) + usbd_close_pipe(sc->sc_out_pipe); + if (sc->sc_in_pipe != NULL) + usbd_close_pipe(sc->sc_in_pipe); s = splusb(); if (--sc->sc_refcnt >= 0) @@ -368,7 +385,7 @@ utoppy_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - return (0); + return 0; } static const uint16_t utoppy_crc16_lookup[] = { @@ -436,8 +453,8 @@ utoppy_usbd_status2errno(usbd_status err) { if (err >= USBD_ERROR_MAX) - return (EFAULT); - return (utoppy_usbdstatus_lookup[err]); + return EFAULT; + return utoppy_usbdstatus_lookup[err]; } #ifdef UTOPPY_DEBUG @@ -470,7 +487,7 @@ utoppy_state_string(enum utoppy_state state) break; } - return (str); + return str; } static void @@ -523,18 +540,17 @@ utoppy_dump_packet(const void *b, size_t len) #endif static usbd_status -utoppy_bulk_transfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe, - u_int16_t flags, u_int32_t timeout, void *buf, u_int32_t *size, - const char *lbl) +utoppy_bulk_transfer(struct usbd_xfer *xfer, struct usbd_pipe *pipe, + uint16_t flags, uint32_t timeout, void *buf, uint32_t *size) { usbd_status err; - usbd_setup_xfer(xfer, pipe, 0, buf, *size, flags, timeout, NULL); + usbd_setup_xfer(xfer, 0, buf, *size, flags, timeout, NULL); err = usbd_sync_transfer_sig(xfer); usbd_get_xfer_status(xfer, NULL, NULL, size, NULL); - return (err); + return err; } static int @@ -562,7 +578,7 @@ utoppy_send_packet(struct utoppy_softc *sc, uint16_t cmd, uint32_t timeout) if (len >= UTOPPY_BSIZE) { DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: " "packet too big (%d)\n", device_xname(sc->sc_dev), (int)len)); - return (EINVAL); + return EINVAL; } h->h_len = htole16(dlen + UTOPPY_HEADER_SIZE); @@ -614,8 +630,7 @@ utoppy_send_packet(struct utoppy_softc *sc, uint16_t cmd, uint32_t timeout) memcpy(sc->sc_out_buf, data, thislen); err = utoppy_bulk_transfer(sc->sc_out_xfer, sc->sc_out_pipe, - USBD_NO_COPY, timeout, sc->sc_out_buf, &thislen, - "utoppytx"); + 0, timeout, sc->sc_out_buf, &thislen); if (thislen != min(len, UTOPPY_FRAG_SIZE)) { DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: " @@ -632,7 +647,7 @@ utoppy_send_packet(struct utoppy_softc *sc, uint16_t cmd, uint32_t timeout) DPRINTF(UTOPPY_DBG_SEND_PACKET, ("%s: utoppy_send_packet: " "usbd_bulk_transfer() returned %d.\n", device_xname(sc->sc_dev),err)); - return (err ? utoppy_usbd_status2errno(err) : 0); + return err ? utoppy_usbd_status2errno(err) : 0; } static int @@ -655,8 +670,8 @@ utoppy_recv_packet(struct utoppy_softc *sc, uint16_t *respp, uint32_t timeout) requested = thislen = min(bytesleft, UTOPPY_FRAG_SIZE); err = utoppy_bulk_transfer(sc->sc_in_xfer, sc->sc_in_pipe, - USBD_NO_COPY | USBD_SHORT_XFER_OK, timeout, sc->sc_in_buf, - &thislen, "utoppyrx"); + USBD_SHORT_XFER_OK, timeout, sc->sc_in_buf, + &thislen); DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: " "usbd_bulk_transfer() returned %d, thislen %d, data %p\n", @@ -672,7 +687,7 @@ utoppy_recv_packet(struct utoppy_softc *sc, uint16_t *respp, uint32_t timeout) } while (err == 0 && bytesleft && thislen == requested); if (err) - return (utoppy_usbd_status2errno(err)); + return utoppy_usbd_status2errno(err); h = sc->sc_in_data; @@ -684,7 +699,7 @@ utoppy_recv_packet(struct utoppy_softc *sc, uint16_t *respp, uint32_t timeout) DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: utoppy_recv_packet: bad " " length (len %d, h_len %d)\n", device_xname(sc->sc_dev), (int)len, le16toh(h->h_len))); - return (EIO); + return EIO; } len = h->h_len = le16toh(h->h_len); @@ -708,7 +723,7 @@ utoppy_recv_packet(struct utoppy_softc *sc, uint16_t *respp, uint32_t timeout) DPRINTF(UTOPPY_DBG_RECV_PACKET, ("%s: " "utoppy_recv_packet: failed to ACK file data: %d\n", device_xname(sc->sc_dev), err)); - return (err); + return err; } } @@ -750,7 +765,7 @@ utoppy_recv_packet(struct utoppy_softc *sc, uint16_t *respp, uint32_t timeout) (int)len, crc, h->h_crc)); DDUMP_PACKET(h, len); - return ((crc == h->h_crc) ? 0 : EBADMSG); + return (crc == h->h_crc) ? 0 : EBADMSG; } static __inline void * @@ -758,7 +773,7 @@ utoppy_current_ptr(void *b) { struct utoppy_header *h = b; - return (&h->h_data[h->h_len]); + return &h->h_data[h->h_len]; } static __inline void @@ -854,10 +869,10 @@ utoppy_add_path(struct utoppy_softc *sc, const char *path, int putlen) err, (int)len)); if (err) - return (err); + return err; if (len < 2) - return (EINVAL); + return EINVAL; /* * copyinstr(9) has already copied the terminating NUL character, @@ -885,7 +900,7 @@ utoppy_add_path(struct utoppy_softc *sc, const char *path, int putlen) DPRINTF(UTOPPY_DBG_ADDPATH, ("utoppy_add_path: final len %d\n", (u_int)len)); - return (0); + return 0; } static __inline int @@ -894,13 +909,13 @@ utoppy_get_8(struct utoppy_softc *sc, uint8_t *vp) uint8_t *p; if (sc->sc_in_len < sizeof(*vp)) - return (1); + return 1; p = UTOPPY_IN_DATA(sc); *vp = *p; sc->sc_in_offset += sizeof(*vp); sc->sc_in_len -= sizeof(*vp); - return (0); + return 0; } static __inline int @@ -910,7 +925,7 @@ utoppy_get_16(struct utoppy_softc *sc, uint16_t *vp) uint8_t *p; if (sc->sc_in_len < sizeof(v)) - return (1); + return 1; p = UTOPPY_IN_DATA(sc); v = *p++; @@ -918,7 +933,7 @@ utoppy_get_16(struct utoppy_softc *sc, uint16_t *vp) *vp = v; sc->sc_in_offset += sizeof(v); sc->sc_in_len -= sizeof(v); - return (0); + return 0; } static __inline int @@ -928,7 +943,7 @@ utoppy_get_32(struct utoppy_softc *sc, uint32_t *vp) uint8_t *p; if (sc->sc_in_len < sizeof(v)) - return (1); + return 1; p = UTOPPY_IN_DATA(sc); v = *p++; @@ -938,7 +953,7 @@ utoppy_get_32(struct utoppy_softc *sc, uint32_t *vp) *vp = v; sc->sc_in_offset += sizeof(v); sc->sc_in_len -= sizeof(v); - return (0); + return 0; } static __inline int @@ -948,7 +963,7 @@ utoppy_get_64(struct utoppy_softc *sc, uint64_t *vp) uint8_t *p; if (sc->sc_in_len < sizeof(v)) - return (1); + return 1; p = UTOPPY_IN_DATA(sc); v = *p++; @@ -962,7 +977,7 @@ utoppy_get_64(struct utoppy_softc *sc, uint64_t *vp) *vp = v; sc->sc_in_offset += sizeof(v); sc->sc_in_len -= sizeof(v); - return (0); + return 0; } static __inline int @@ -971,14 +986,14 @@ utoppy_get_string(struct utoppy_softc *sc, char *str, size_t len) char *p; if (sc->sc_in_len < len) - return (1); + return 1; memset(str, 0, len); p = UTOPPY_IN_DATA(sc); strncpy(str, p, len); sc->sc_in_offset += len; sc->sc_in_len -= len; - return (0); + return 0; } static int @@ -989,7 +1004,7 @@ utoppy_command(struct utoppy_softc *sc, uint16_t cmd, int timeout, err = utoppy_send_packet(sc, cmd, timeout); if (err) - return (err); + return err; err = utoppy_recv_packet(sc, presp, timeout); if (err == EBADMSG) { @@ -997,7 +1012,7 @@ utoppy_command(struct utoppy_softc *sc, uint16_t cmd, int timeout, utoppy_send_packet(sc, UTOPPY_RESP_ERROR, timeout); } - return (err); + return err; } static int @@ -1009,11 +1024,11 @@ utoppy_timestamp_decode(struct utoppy_softc *sc, time_t *tp) if (utoppy_get_16(sc, &mjd) || utoppy_get_8(sc, &hour) || utoppy_get_8(sc, &minute) || utoppy_get_8(sc, &sec)) - return (1); + return 1; if (mjd == 0xffffu && hour == 0xffu && minute == 0xffu && sec == 0xffu){ *tp = 0; - return (0); + return 0; } rv = (mjd < UTOPPY_MJD_1970) ? UTOPPY_MJD_1970 : (uint32_t) mjd; @@ -1027,7 +1042,7 @@ utoppy_timestamp_decode(struct utoppy_softc *sc, time_t *tp) rv += sec; *tp = (time_t)rv; - return (0); + return 0; } static void @@ -1061,9 +1076,9 @@ utoppy_turbo_mode(struct utoppy_softc *sc, int state) err = utoppy_command(sc, UTOPPY_CMD_TURBO, UTOPPY_SHORT_TIMEOUT, &r); if (err) - return (err); + return err; - return ((r == UTOPPY_RESP_SUCCESS) ? 0 : EIO); + return (r == UTOPPY_RESP_SUCCESS) ? 0 : EIO; } static int @@ -1076,9 +1091,9 @@ utoppy_check_ready(struct utoppy_softc *sc) err = utoppy_command(sc, UTOPPY_CMD_READY, UTOPPY_LONG_TIMEOUT, &r); if (err) - return (err); + return err; - return ((r == UTOPPY_RESP_SUCCESS) ? 0 : EIO); + return (r == UTOPPY_RESP_SUCCESS) ? 0 : EIO; } static int @@ -1101,7 +1116,7 @@ utoppy_cancel(struct utoppy_softc *sc) } if (err) - return (err); + return err; /* * Make sure turbo mode is off, otherwise the Toppy will not @@ -1110,7 +1125,7 @@ utoppy_cancel(struct utoppy_softc *sc) (void) utoppy_turbo_mode(sc, 0); sc->sc_state = UTOPPY_STATE_IDLE; - return (0); + return 0; } static int @@ -1123,20 +1138,20 @@ utoppy_stats(struct utoppy_softc *sc, struct utoppy_stats *us) UTOPPY_OUT_INIT(sc); err = utoppy_command(sc, UTOPPY_CMD_STATS, UTOPPY_LONG_TIMEOUT, &r); if (err) - return (err); + return err; if (r != UTOPPY_RESP_STATS_DATA) - return (EIO); + return EIO; if (utoppy_get_32(sc, &hsize) || utoppy_get_32(sc, &hfree)) - return (EIO); + return EIO; us->us_hdd_size = hsize; us->us_hdd_size *= 1024; us->us_hdd_free = hfree; us->us_hdd_free *= 1024; - return (0); + return 0; } static int @@ -1162,7 +1177,7 @@ utoppy_readdir_next(struct utoppy_softc *sc) UTOPPY_LONG_TIMEOUT); } utoppy_cancel(sc); - return (err); + return err; } DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_next: " @@ -1182,7 +1197,7 @@ utoppy_readdir_next(struct utoppy_softc *sc) "utoppy_send_packet(ACK) returned %d\n", device_xname(sc->sc_dev), err)); utoppy_cancel(sc); - return (err); + return err; } sc->sc_state = UTOPPY_STATE_READDIR; sc->sc_in_offset = 0; @@ -1203,10 +1218,10 @@ utoppy_readdir_next(struct utoppy_softc *sc) "bad response: 0x%x\n", device_xname(sc->sc_dev), resp)); sc->sc_state = UTOPPY_STATE_IDLE; sc->sc_in_len = 0; - return (EIO); + return EIO; } - return (0); + return 0; } static size_t @@ -1223,7 +1238,7 @@ utoppy_readdir_decode(struct utoppy_softc *sc, struct utoppy_dirent *ud) utoppy_get_32(sc, &ud->ud_attributes)) { DPRINTF(UTOPPY_DBG_READDIR, ("%s: utoppy_readdir_decode: no " "more to decode\n", device_xname(sc->sc_dev))); - return (0); + return 0; } switch (ftype) { @@ -1244,7 +1259,7 @@ utoppy_readdir_decode(struct utoppy_softc *sc, struct utoppy_dirent *ud) ((ftype == UTOPPY_FTYPE_FILE) ? "FILE" : "UNKNOWN"), ud->ud_path, ud->ud_size, (u_long)ud->ud_mtime, ud->ud_attributes)); - return (1); + return 1; } static int @@ -1260,7 +1275,7 @@ utoppy_readfile_next(struct utoppy_softc *sc) "utoppy_recv_packet() returned %d\n", device_xname(sc->sc_dev), err)); utoppy_cancel(sc); - return (err); + return err; } switch (resp) { @@ -1274,7 +1289,7 @@ utoppy_readfile_next(struct utoppy_softc *sc) "utoppy_send_packet(UTOPPY_CMD_ACK) returned %d\n", device_xname(sc->sc_dev), err)); utoppy_cancel(sc); - return (err); + return err; } sc->sc_in_len = 0; @@ -1289,7 +1304,7 @@ utoppy_readfile_next(struct utoppy_softc *sc) "UTOPPY_RESP_FILE_DATA did not provide offset\n", device_xname(sc->sc_dev))); utoppy_cancel(sc); - return (EBADMSG); + return EBADMSG; } DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: " @@ -1317,10 +1332,10 @@ utoppy_readfile_next(struct utoppy_softc *sc) DPRINTF(UTOPPY_DBG_READ, ("%s: utoppy_readfile_next: bad " "response code 0x%0x\n", device_xname(sc->sc_dev), resp)); utoppy_cancel(sc); - return (EIO); + return EIO; } - return (0); + return 0; } int @@ -1335,12 +1350,12 @@ utoppyopen(dev_t dev, int flag, int mode, return ENXIO; if (sc == NULL || sc->sc_iface == NULL || sc->sc_dying) - return (ENXIO); + return ENXIO; if (sc->sc_state != UTOPPY_STATE_CLOSED) { DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: already open\n", device_xname(sc->sc_dev))); - return (EBUSY); + return EBUSY; } DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: opening...\n", @@ -1349,34 +1364,15 @@ utoppyopen(dev_t dev, int flag, int mode, sc->sc_refcnt++; sc->sc_state = UTOPPY_STATE_OPENING; sc->sc_turbo_mode = 0; - sc->sc_out_pipe = NULL; - sc->sc_in_pipe = NULL; - - if (usbd_open_pipe(sc->sc_iface, sc->sc_out, 0, &sc->sc_out_pipe)) { - DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: usbd_open_pipe(OUT) " - "failed\n", device_xname(sc->sc_dev))); - error = EIO; - goto done; - } - - if (usbd_open_pipe(sc->sc_iface, sc->sc_in, 0, &sc->sc_in_pipe)) { - DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: usbd_open_pipe(IN) " - "failed\n", device_xname(sc->sc_dev))); - error = EIO; - usbd_close_pipe(sc->sc_out_pipe); - sc->sc_out_pipe = NULL; - goto done; - } - - sc->sc_out_data = malloc(UTOPPY_BSIZE + 1, M_DEVBUF, M_WAITOK); + sc->sc_out_data = kmem_alloc(UTOPPY_BSIZE + 1, KM_SLEEP); if (sc->sc_out_data == NULL) { error = ENOMEM; goto error; } - sc->sc_in_data = malloc(UTOPPY_BSIZE + 1, M_DEVBUF, M_WAITOK); + sc->sc_in_data = kmem_alloc(UTOPPY_BSIZE + 1, KM_SLEEP); if (sc->sc_in_data == NULL) { - free(sc->sc_out_data, M_DEVBUF); + kmem_free(sc->sc_out_data, UTOPPY_BSIZE + 1); sc->sc_out_data = NULL; error = ENOMEM; goto error; @@ -1388,16 +1384,9 @@ utoppyopen(dev_t dev, int flag, int mode, if ((error = utoppy_check_ready(sc)) != 0) { DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: utoppy_check_ready()" " returned %d\n", device_xname(sc->sc_dev), error)); - error: - usbd_abort_pipe(sc->sc_out_pipe); - usbd_close_pipe(sc->sc_out_pipe); - sc->sc_out_pipe = NULL; - usbd_abort_pipe(sc->sc_in_pipe); - usbd_close_pipe(sc->sc_in_pipe); - sc->sc_in_pipe = NULL; } - done: + error: sc->sc_state = error ? UTOPPY_STATE_CLOSED : UTOPPY_STATE_IDLE; DPRINTF(UTOPPY_DBG_OPEN, ("%s: utoppyopen: done. error %d, new state " @@ -1407,7 +1396,7 @@ utoppyopen(dev_t dev, int flag, int mode, if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); - return (error); + return error; } int @@ -1427,7 +1416,7 @@ utoppyclose(dev_t dev, int flag, int mode, DPRINTF(UTOPPY_DBG_CLOSE, ("%s: utoppyclose: not properly open:" " %s\n", device_xname(sc->sc_dev), utoppy_state_string(sc->sc_state))); - return (0); + return 0; } if (sc->sc_out_data) @@ -1436,26 +1425,22 @@ utoppyclose(dev_t dev, int flag, int mode, if (sc->sc_out_pipe != NULL) { if ((err = usbd_abort_pipe(sc->sc_out_pipe)) != 0) printf("usbd_abort_pipe(OUT) returned %d\n", err); - if ((err = usbd_close_pipe(sc->sc_out_pipe)) != 0) - printf("usbd_close_pipe(OUT) returned %d\n", err); sc->sc_out_pipe = NULL; } if (sc->sc_in_pipe != NULL) { if ((err = usbd_abort_pipe(sc->sc_in_pipe)) != 0) printf("usbd_abort_pipe(IN) returned %d\n", err); - if ((err = usbd_close_pipe(sc->sc_in_pipe)) != 0) - printf("usbd_close_pipe(IN) returned %d\n", err); sc->sc_in_pipe = NULL; } if (sc->sc_out_data) { - free(sc->sc_out_data, M_DEVBUF); + kmem_free(sc->sc_out_data, UTOPPY_BSIZE + 1); sc->sc_out_data = NULL; } if (sc->sc_in_data) { - free(sc->sc_in_data, M_DEVBUF); + kmem_free(sc->sc_in_data, UTOPPY_BSIZE + 1); sc->sc_in_data = NULL; } @@ -1464,7 +1449,7 @@ utoppyclose(dev_t dev, int flag, int mode, DPRINTF(UTOPPY_DBG_CLOSE, ("%s: utoppyclose: done.\n", device_xname(sc->sc_dev))); - return (0); + return 0; } int @@ -1478,7 +1463,7 @@ utoppyread(dev_t dev, struct uio *uio, int flags) sc = device_lookup_private(&utoppy_cd, UTOPPYUNIT(dev)); if (sc->sc_dying) - return (EIO); + return EIO; sc->sc_refcnt++; @@ -1494,7 +1479,7 @@ utoppyread(dev_t dev, struct uio *uio, int flags) err = utoppy_readdir_next(sc); else if ((err = uiomove(&ud, sizeof(ud), uio)) != 0) - utoppy_cancel(sc); + utoppy_cancel(sc); } break; @@ -1545,7 +1530,7 @@ utoppyread(dev_t dev, struct uio *uio, int flags) if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); - return (err); + return err; } int @@ -1559,17 +1544,17 @@ utoppywrite(dev_t dev, struct uio *uio, int flags) sc = device_lookup_private(&utoppy_cd, UTOPPYUNIT(dev)); if (sc->sc_dying) - return (EIO); + return EIO; switch(sc->sc_state) { case UTOPPY_STATE_WRITEFILE: break; case UTOPPY_STATE_IDLE: - return (0); + return 0; default: - return (EIO); + return EIO; } sc->sc_refcnt++; @@ -1648,7 +1633,7 @@ utoppywrite(dev_t dev, struct uio *uio, int flags) if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); - return (err); + return err; } int @@ -1666,7 +1651,7 @@ utoppyioctl(dev_t dev, u_long cmd, void *data, int flag, sc = device_lookup_private(&utoppy_cd, UTOPPYUNIT(dev)); if (sc->sc_dying) - return (EIO); + return EIO; DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: cmd 0x%08lx, state '%s'\n", device_xname(sc->sc_dev), cmd, utoppy_state_string(sc->sc_state))); @@ -1674,7 +1659,7 @@ utoppyioctl(dev_t dev, u_long cmd, void *data, int flag, if (sc->sc_state != UTOPPY_STATE_IDLE && cmd != UTOPPYIOCANCEL) { DPRINTF(UTOPPY_DBG_IOCTL, ("%s: utoppyioctl: still busy.\n", device_xname(sc->sc_dev))); - return (EBUSY); + return EBUSY; } sc->sc_refcnt++; @@ -1913,5 +1898,5 @@ utoppyioctl(dev_t dev, u_long cmd, void *data, int flag, if (--sc->sc_refcnt < 0) usb_detach_wakeupold(sc->sc_dev); - return (err); + return err; } diff --git a/sys/dev/usb/uts.c b/sys/dev/usb/uts.c index 2376ad68d47..d542f1284d8 100644 --- a/sys/dev/usb/uts.c +++ b/sys/dev/usb/uts.c @@ -1,4 +1,4 @@ -/* $NetBSD: uts.c,v 1.3 2013/01/05 23:34:21 christos Exp $ */ +/* $NetBSD: uts.c,v 1.4 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2012 The NetBSD Foundation, Inc. @@ -34,12 +34,11 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uts.c,v 1.3 2013/01/05 23:34:21 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uts.c,v 1.4 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> #include <sys/device.h> #include <sys/ioctl.h> #include <sys/vnode.h> @@ -79,7 +78,7 @@ struct uts_softc { int flags; /* device configuration */ #define UTS_ABS 0x1 /* absolute position */ - u_int32_t sc_buttons; /* touchscreen button status */ + uint32_t sc_buttons; /* touchscreen button status */ device_t sc_wsmousedev; struct tpcalib_softc sc_tpcalib; /* calibration */ struct wsmouse_calibcoords sc_calibcoords; @@ -89,7 +88,7 @@ struct uts_softc { #define TSCREEN_FLAGS_MASK (HIO_CONST|HIO_RELATIVE) -Static void uts_intr(struct uhidev *addr, void *ibuf, u_int len); +Static void uts_intr(struct uhidev *, void *, u_int); Static int uts_enable(void *); Static void uts_disable(void *); @@ -137,7 +136,7 @@ uts_attach(device_t parent, device_t self, void *aux) struct wsmousedev_attach_args a; int size; void *desc; - u_int32_t flags; + uint32_t flags; struct hid_data * d; struct hid_item item; @@ -353,7 +352,7 @@ uts_intr(struct uhidev *addr, void *ibuf, u_int len) { struct uts_softc *sc = (struct uts_softc *)addr; int dx, dy, dz; - u_int32_t buttons = 0; + uint32_t buttons = 0; int flags, s; DPRINTFN(5,("uts_intr: len=%d\n", len)); diff --git a/sys/dev/usb/uvideo.c b/sys/dev/usb/uvideo.c index 9593ea89534..6586d2faa69 100644 --- a/sys/dev/usb/uvideo.c +++ b/sys/dev/usb/uvideo.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvideo.c,v 1.41 2014/09/12 16:40:38 skrll Exp $ */ +/* $NetBSD: uvideo.c,v 1.42 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2008 Patrick Mahoney @@ -42,7 +42,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvideo.c,v 1.41 2014/09/12 16:40:38 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvideo.c,v 1.42 2016/04/23 10:15:32 skrll Exp $"); #ifdef _KERNEL_OPT #include "opt_usb.h" @@ -55,7 +55,6 @@ __KERNEL_RCSID(0, "$NetBSD: uvideo.c,v 1.41 2014/09/12 16:40:38 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -/* #include <sys/malloc.h> */ #include <sys/kmem.h> #include <sys/device.h> #include <sys/ioctl.h> @@ -183,14 +182,14 @@ struct uvideo_stream; struct uvideo_isoc { struct uvideo_isoc_xfer *i_ix; struct uvideo_stream *i_vs; - usbd_xfer_handle i_xfer; + struct usbd_xfer *i_xfer; uint8_t *i_buf; uint16_t *i_frlengths; }; struct uvideo_isoc_xfer { uint8_t ix_endpt; - usbd_pipe_handle ix_pipe; + struct usbd_pipe *ix_pipe; struct uvideo_isoc ix_i[UVIDEO_NXFERS]; uint32_t ix_nframes; uint32_t ix_uframe_len; @@ -200,8 +199,8 @@ struct uvideo_isoc_xfer { struct uvideo_bulk_xfer { uint8_t bx_endpt; - usbd_pipe_handle bx_pipe; - usbd_xfer_handle bx_xfer; + struct usbd_pipe *bx_pipe; + struct usbd_xfer *bx_xfer; uint8_t *bx_buffer; int bx_buflen; bool bx_running; @@ -211,7 +210,7 @@ struct uvideo_bulk_xfer { struct uvideo_stream { struct uvideo_softc *vs_parent; - usbd_interface_handle vs_iface; + struct usbd_interface *vs_iface; uint8_t vs_ifaceno; uint8_t vs_subtype; /* input or output */ uint16_t vs_probelen; /* length of probe and @@ -241,8 +240,8 @@ SLIST_HEAD(uvideo_stream_list, uvideo_stream); struct uvideo_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; /* device */ - usbd_interface_handle sc_iface; /* interface handle */ + struct usbd_device *sc_udev; /* device */ + struct usbd_interface *sc_iface; /* interface handle */ int sc_ifaceno; /* interface number */ char *sc_devname; @@ -324,14 +323,14 @@ static struct uvideo_format * uvideo_stream_guess_format( enum video_pixel_format, uint32_t, uint32_t); static struct uvideo_stream * uvideo_stream_alloc(void); static usbd_status uvideo_stream_init( - struct uvideo_stream *stream, - struct uvideo_softc *sc, - const usb_interface_descriptor_t *ifdesc, - uint8_t idx); + struct uvideo_stream *, + struct uvideo_softc *, + const usb_interface_descriptor_t *, + uint8_t); static usbd_status uvideo_stream_init_desc( struct uvideo_stream *, - const usb_interface_descriptor_t *ifdesc, - usbd_desc_iter_t *iter); + const usb_interface_descriptor_t *, + usbd_desc_iter_t *); static usbd_status uvideo_stream_init_frame_based_format( struct uvideo_stream *, const uvideo_descriptor_t *, @@ -344,8 +343,8 @@ static usbd_status uvideo_stream_recv_process(struct uvideo_stream *, uint8_t *, uint32_t); static usbd_status uvideo_stream_recv_isoc_start(struct uvideo_stream *); static usbd_status uvideo_stream_recv_isoc_start1(struct uvideo_isoc *); -static void uvideo_stream_recv_isoc_complete(usbd_xfer_handle, - usbd_private_handle, +static void uvideo_stream_recv_isoc_complete(struct usbd_xfer *, + void *, usbd_status); static void uvideo_stream_recv_bulk_transfer(void *); @@ -470,14 +469,14 @@ static void print_vs_format_dv_descriptor( int uvideo_match(device_t parent, cfdata_t match, void *aux) { - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; /* TODO: May need to change in the future to work with * Interface Association Descriptor. */ /* Trigger on the Video Control Interface which must be present */ - if (uaa->class == UICLASS_VIDEO && - uaa->subclass == UISUBCLASS_VIDEOCONTROL) + if (uiaa->uiaa_class == UICLASS_VIDEO && + uiaa->uiaa_subclass == UISUBCLASS_VIDEOCONTROL) return UMATCH_IFACECLASS_IFACESUBCLASS; return UMATCH_NONE; @@ -487,7 +486,7 @@ void uvideo_attach(device_t parent, device_t self, void *aux) { struct uvideo_softc *sc = device_private(self); - struct usbif_attach_arg *uaa = aux; + struct usbif_attach_arg *uiaa = aux; usbd_desc_iter_t iter; const usb_interface_descriptor_t *ifdesc; struct uvideo_stream *vs; @@ -496,19 +495,19 @@ uvideo_attach(device_t parent, device_t self, void *aux) sc->sc_dev = self; - sc->sc_devname = usbd_devinfo_alloc(uaa->device, 0); + sc->sc_devname = usbd_devinfo_alloc(uiaa->uiaa_device, 0); aprint_naive("\n"); aprint_normal(": %s\n", sc->sc_devname); - sc->sc_udev = uaa->device; - sc->sc_iface = uaa->iface; - sc->sc_ifaceno = uaa->ifaceno; + sc->sc_udev = uiaa->uiaa_device; + sc->sc_iface = uiaa->uiaa_iface; + sc->sc_ifaceno = uiaa->uiaa_ifaceno; sc->sc_dying = 0; sc->sc_state = UVIDEO_STATE_CLOSED; SLIST_INIT(&sc->sc_stream_list); snprintf(sc->sc_businfo, sizeof(sc->sc_businfo), "usb:%08x", - sc->sc_udev->cookie.cookie); + sc->sc_udev->ud_cookie.cookie); #ifdef UVIDEO_DEBUG /* Debugging dump of descriptors. TODO: move this to userspace @@ -762,7 +761,7 @@ uvideo_stream_guess_format(struct uvideo_stream *vs, static struct uvideo_stream * uvideo_stream_alloc(void) { - return (kmem_alloc(sizeof(struct uvideo_stream), KM_NOSLEEP)); + return kmem_alloc(sizeof(struct uvideo_stream), KM_NOSLEEP); } @@ -1468,6 +1467,7 @@ uvideo_stream_start_xfer(struct uvideo_stream *vs) uint32_t uframe_len; /* bytes per usb frame (TODO: or microframe?) */ uint32_t nframes; /* number of usb frames (TODO: or microframs?) */ int i, ret; + int error; struct uvideo_alternate *alt, *alt_maybe; usbd_status err; @@ -1477,23 +1477,6 @@ uvideo_stream_start_xfer(struct uvideo_stream *vs) ret = 0; bx = &vs->vs_xfer.bulk; - bx->bx_xfer = usbd_alloc_xfer(sc->sc_udev); - if (bx->bx_xfer == NULL) { - DPRINTF(("uvideo: couldn't allocate xfer\n")); - return ENOMEM; - } - DPRINTF(("uvideo: xfer %p\n", bx->bx_xfer)); - - bx->bx_buflen = vs->vs_max_payload_size; - - DPRINTF(("uvideo: allocating %u byte buffer\n", bx->bx_buflen)); - bx->bx_buffer = usbd_alloc_buffer(bx->bx_xfer, bx->bx_buflen); - - if (bx->bx_buffer == NULL) { - DPRINTF(("uvideo: couldn't allocate buffer\n")); - return ENOMEM; - } - err = usbd_open_pipe(vs->vs_iface, bx->bx_endpt, 0, &bx->bx_pipe); if (err != USBD_NORMAL_COMPLETION) { @@ -1503,6 +1486,17 @@ uvideo_stream_start_xfer(struct uvideo_stream *vs) } DPRINTF(("uvideo: pipe %p\n", bx->bx_pipe)); + error = usbd_create_xfer(bx->bx_pipe, vs->vs_max_payload_size, + USBD_SHORT_XFER_OK, 0, &bx->bx_xfer); + if (error) { + DPRINTF(("uvideo: couldn't allocate xfer\n")); + return error; + } + DPRINTF(("uvideo: xfer %p\n", bx->bx_xfer)); + + bx->bx_buflen = vs->vs_max_payload_size; + bx->bx_buffer = usbd_get_buffer(bx->bx_xfer); + mutex_enter(&bx->bx_lock); if (bx->bx_running == false) { bx->bx_running = true; @@ -1603,23 +1597,16 @@ uvideo_stream_start_xfer(struct uvideo_stream *vs) for (i = 0; i < UVIDEO_NXFERS; i++) { struct uvideo_isoc *isoc = &ix->ix_i[i]; - isoc->i_xfer = usbd_alloc_xfer(sc->sc_udev); - if (isoc->i_xfer == NULL) { - DPRINTF(("uvideo: failed to alloc xfer: %s" - " (%d)\n", - usbd_errstr(err), err)); - return ENOMEM; + error = usbd_create_xfer(ix->ix_pipe, + nframes * uframe_len, 0, ix->ix_nframes, + &isoc->i_xfer); + if (error) { + DPRINTF(("uvideo: " + "couldn't allocate xfer (%d)\n", error)); + return error; } - isoc->i_buf = usbd_alloc_buffer(isoc->i_xfer, - nframes * uframe_len); - - if (isoc->i_buf == NULL) { - DPRINTF(("uvideo: failed to alloc buf: %s" - " (%d)\n", - usbd_errstr(err), err)); - return ENOMEM; - } + isoc->i_buf = usbd_get_buffer(isoc->i_xfer); } uvideo_stream_recv_isoc_start(vs); @@ -1658,15 +1645,18 @@ uvideo_stream_stop_xfer(struct uvideo_stream *vs) if (bx->bx_pipe) { usbd_abort_pipe(bx->bx_pipe); - usbd_close_pipe(bx->bx_pipe); - bx->bx_pipe = NULL; } if (bx->bx_xfer) { - usbd_free_xfer(bx->bx_xfer); + usbd_destroy_xfer(bx->bx_xfer); bx->bx_xfer = NULL; } + if (bx->bx_pipe) { + usbd_close_pipe(bx->bx_pipe); + bx->bx_pipe = NULL; + } + DPRINTF(("uvideo_stream_stop_xfer: UE_BULK: done\n")); return 0; @@ -1674,15 +1664,12 @@ uvideo_stream_stop_xfer(struct uvideo_stream *vs) ix = &vs->vs_xfer.isoc; if (ix->ix_pipe != NULL) { usbd_abort_pipe(ix->ix_pipe); - usbd_close_pipe(ix->ix_pipe); - ix->ix_pipe = NULL; } for (i = 0; i < UVIDEO_NXFERS; i++) { struct uvideo_isoc *isoc = &ix->ix_i[i]; if (isoc->i_xfer != NULL) { - usbd_free_buffer(isoc->i_xfer); - usbd_free_xfer(isoc->i_xfer); + usbd_destroy_xfer(isoc->i_xfer); isoc->i_xfer = NULL; } @@ -1694,6 +1681,10 @@ uvideo_stream_stop_xfer(struct uvideo_stream *vs) } } + if (ix->ix_pipe != NULL) { + usbd_close_pipe(ix->ix_pipe); + ix->ix_pipe = NULL; + } /* Give it some time to settle */ usbd_delay_ms(vs->vs_parent->sc_udev, 1000); @@ -1741,11 +1732,10 @@ uvideo_stream_recv_isoc_start1(struct uvideo_isoc *isoc) isoc->i_frlengths[i] = ix->ix_uframe_len; usbd_setup_isoc_xfer(isoc->i_xfer, - ix->ix_pipe, isoc, isoc->i_frlengths, ix->ix_nframes, - USBD_NO_COPY | USBD_SHORT_XFER_OK, + USBD_SHORT_XFER_OK, uvideo_stream_recv_isoc_complete); err = usbd_transfer(isoc->i_xfer); @@ -1791,8 +1781,8 @@ uvideo_stream_recv_process(struct uvideo_stream *vs, uint8_t *buf, uint32_t len) /* Callback on completion of usb isoc transfer */ static void -uvideo_stream_recv_isoc_complete(usbd_xfer_handle xfer, - usbd_private_handle priv, +uvideo_stream_recv_isoc_complete(struct usbd_xfer *xfer, + void *priv, usbd_status status) { struct uvideo_stream *vs; @@ -1853,9 +1843,8 @@ uvideo_stream_recv_bulk_transfer(void *addr) while (bx->bx_running) { len = bx->bx_buflen; err = usbd_bulk_transfer(bx->bx_xfer, bx->bx_pipe, - USBD_SHORT_XFER_OK | USBD_NO_COPY, - USBD_NO_TIMEOUT, - bx->bx_buffer, &len, "uvideorb"); + USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, + bx->bx_buffer, &len); if (err == USBD_NORMAL_COMPLETION) { uvideo_stream_recv_process(vs, bx->bx_buffer, len); @@ -3021,7 +3010,7 @@ usb_desc_iter_next_non_interface(usbd_desc_iter_t *iter) if ((desc = usb_desc_iter_peek_next(iter)) != NULL && desc->bDescriptorType != UDESC_INTERFACE) { - return (usb_desc_iter_next(iter)); + return usb_desc_iter_next(iter); } else { return NULL; } @@ -3068,5 +3057,5 @@ usb_guid_cmp(const usb_guid_t *uguid, const guid_t *guid) else if (guid->data3 < UGETW(uguid->data3)) return -1; - return (memcmp(guid->data4, uguid->data4, 8)); + return memcmp(guid->data4, uguid->data4, 8); } diff --git a/sys/dev/usb/uvisor.c b/sys/dev/usb/uvisor.c index 9dbf9b4bf45..68334e41096 100644 --- a/sys/dev/usb/uvisor.c +++ b/sys/dev/usb/uvisor.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvisor.c,v 1.45 2011/12/23 00:51:49 jakllsch Exp $ */ +/* $NetBSD: uvisor.c,v 1.46 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvisor.c,v 1.45 2011/12/23 00:51:49 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvisor.c,v 1.46 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -130,13 +130,13 @@ struct uvisor_palm_connection_info { struct uvisor_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; /* device */ - usbd_interface_handle sc_iface; /* interface */ + struct usbd_device * sc_udev; /* device */ + struct usbd_interface * sc_iface; /* interface */ device_t sc_subdevs[UVISOR_MAX_CONN]; int sc_numcon; - u_int16_t sc_flags; + uint16_t sc_flags; u_char sc_dying; }; @@ -149,19 +149,19 @@ Static void uvisor_close(void *, int); struct ucom_methods uvisor_methods = { - NULL, - NULL, - NULL, - NULL, - NULL, - uvisor_close, - NULL, - NULL, + .ucom_param = NULL, + .ucom_ioctl = NULL, + .ucom_open = NULL, + .ucom_close = uvisor_close, + .ucom_read = NULL, + .ucom_write = NULL, + .ucom_get_status = NULL, + .ucom_set = NULL, }; struct uvisor_type { struct usb_devno uv_dev; - u_int16_t uv_flags; + uint16_t uv_flags; #define PALM4 0x0001 #define VISOR 0x0002 @@ -198,25 +198,25 @@ extern struct cfdriver uvisor_cd; CFATTACH_DECL2_NEW(uvisor, sizeof(struct uvisor_softc), uvisor_match, uvisor_attach, uvisor_detach, uvisor_activate, NULL, uvisor_childdet); -int +int uvisor_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; DPRINTFN(20,("uvisor: vendor=0x%x, product=0x%x\n", - uaa->vendor, uaa->product)); + uaa->uaa_vendor, uaa->uaa_product)); - return (uvisor_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return uvisor_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } -void +void uvisor_attach(device_t parent, device_t self, void *aux) { struct uvisor_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; - usbd_interface_handle iface; + struct usbd_device *dev = uaa->uaa_device; + struct usbd_interface *iface; usb_interface_descriptor_t *id; struct uvisor_connection_info coninfo; struct uvisor_palm_connection_info palmconinfo; @@ -225,7 +225,7 @@ uvisor_attach(device_t parent, device_t self, void *aux) const char *devname = device_xname(self); int i, j, hasin, hasout, port; usbd_status err; - struct ucom_attach_args uca; + struct ucom_attach_args ucaa; DPRINTFN(10,("\nuvisor_attach: sc=%p\n", sc)); @@ -253,7 +253,7 @@ uvisor_attach(device_t parent, device_t self, void *aux) goto bad; } - sc->sc_flags = uvisor_lookup(uaa->vendor, uaa->product)->uv_flags; + sc->sc_flags = uvisor_lookup(uaa->uaa_vendor, uaa->uaa_product)->uv_flags; if ((sc->sc_flags & (VISOR | PALM4)) == 0) { aprint_error_dev(self, @@ -266,14 +266,14 @@ uvisor_attach(device_t parent, device_t self, void *aux) sc->sc_udev = dev; sc->sc_iface = iface; - uca.ibufsize = UVISORIBUFSIZE; - uca.obufsize = UVISOROBUFSIZE; - uca.ibufsizepad = UVISORIBUFSIZE; - uca.opkthdrlen = 0; - uca.device = dev; - uca.iface = iface; - uca.methods = &uvisor_methods; - uca.arg = sc; + ucaa.ucaa_ibufsize = UVISORIBUFSIZE; + ucaa.ucaa_obufsize = UVISOROBUFSIZE; + ucaa.ucaa_ibufsizepad = UVISORIBUFSIZE; + ucaa.ucaa_opkthdrlen = 0; + ucaa.ucaa_device = dev; + ucaa.ucaa_iface = iface; + ucaa.ucaa_methods = &uvisor_methods; + ucaa.ucaa_arg = sc; err = uvisor_init(sc, &coninfo, &palmconinfo); if (err) { @@ -293,25 +293,25 @@ uvisor_attach(device_t parent, device_t self, void *aux) for (i = 0; i < sc->sc_numcon; ++i) { switch (coninfo.connections[i].port_function_id) { case UVISOR_FUNCTION_GENERIC: - uca.info = "Generic"; + ucaa.ucaa_info = "Generic"; break; case UVISOR_FUNCTION_DEBUGGER: - uca.info = "Debugger"; + ucaa.ucaa_info = "Debugger"; break; case UVISOR_FUNCTION_HOTSYNC: - uca.info = "HotSync"; + ucaa.ucaa_info = "HotSync"; break; case UVISOR_FUNCTION_REMOTE_FILE_SYS: - uca.info = "Remote File System"; + ucaa.ucaa_info = "Remote File System"; break; default: - uca.info = "unknown"; + ucaa.ucaa_info = "unknown"; break; } port = coninfo.connections[i].port; - uca.portno = port; - uca.bulkin = port | UE_DIR_IN; - uca.bulkout = port | UE_DIR_OUT; + ucaa.ucaa_portno = port; + ucaa.ucaa_bulkin = port | UE_DIR_IN; + ucaa.ucaa_bulkout = port | UE_DIR_OUT; /* Verify that endpoints exist. */ hasin = 0; hasout = 0; @@ -330,7 +330,7 @@ uvisor_attach(device_t parent, device_t self, void *aux) } if (hasin == 1 && hasout == 1) sc->sc_subdevs[i] = config_found_sm_loc(self, - "ucombus", NULL, &uca, + "ucombus", NULL, &ucaa, ucomprint, ucomsubmatch); else aprint_error_dev(self, @@ -348,21 +348,21 @@ uvisor_attach(device_t parent, device_t self, void *aux) /* * XXX this should copy out 4-char string from the * XXX port_function_id, but where would the string go? - * XXX uca.info is a const char *, not an array. + * XXX ucaa.ucaa_info is a const char *, not an array. */ - uca.info = "sync"; - uca.portno = i; + ucaa.ucaa_info = "sync"; + ucaa.ucaa_portno = i; if (palmconinfo.endpoint_numbers_different) { port = palmconinfo.connections[i].end_point_info; - uca.bulkin = (port >> 4) | UE_DIR_IN; - uca.bulkout = (port & 0xf) | UE_DIR_OUT; + ucaa.ucaa_bulkin = (port >> 4) | UE_DIR_IN; + ucaa.ucaa_bulkout = (port & 0xf) | UE_DIR_OUT; } else { port = palmconinfo.connections[i].port; - uca.bulkin = port | UE_DIR_IN; - uca.bulkout = port | UE_DIR_OUT; + ucaa.ucaa_bulkin = port | UE_DIR_IN; + ucaa.ucaa_bulkout = port | UE_DIR_OUT; } sc->sc_subdevs[i] = config_found_sm_loc(self, "ucombus", - NULL, &uca, ucomprint, ucomsubmatch); + NULL, &ucaa, ucomprint, ucomsubmatch); } @@ -423,7 +423,7 @@ uvisor_detach(device_t self, int flags) sc->sc_dev); - return (rv); + return rv; } usbd_status @@ -445,7 +445,7 @@ uvisor_init(struct uvisor_softc *sc, struct uvisor_connection_info *ci, err = usbd_do_request_flags(sc->sc_udev, &req, ci, USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT); if (err) - return (err); + return err; } if (sc->sc_flags & PALM4) { @@ -458,7 +458,7 @@ uvisor_init(struct uvisor_softc *sc, struct uvisor_connection_info *ci, err = usbd_do_request_flags(sc->sc_udev, &req, cpi, USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT); if (err) - return (err); + return err; } DPRINTF(("uvisor_init: getting available bytes\n")); @@ -466,14 +466,14 @@ uvisor_init(struct uvisor_softc *sc, struct uvisor_connection_info *ci, req.bRequest = UVISOR_REQUEST_BYTES_AVAILABLE; USETW(req.wValue, 0); USETW(req.wIndex, 5); - USETW(req.wLength, sizeof avail); + USETW(req.wLength, sizeof(avail)); err = usbd_do_request(sc->sc_udev, &req, &avail); if (err) - return (err); + return err; DPRINTF(("uvisor_init: avail=%d\n", UGETW(avail))); DPRINTF(("uvisor_init: done\n")); - return (err); + return err; } void diff --git a/sys/dev/usb/uvscom.c b/sys/dev/usb/uvscom.c index 210938d23fc..34d432b6867 100644 --- a/sys/dev/usb/uvscom.c +++ b/sys/dev/usb/uvscom.c @@ -1,4 +1,4 @@ -/* $NetBSD: uvscom.c,v 1.28 2012/02/24 06:48:28 mrg Exp $ */ +/* $NetBSD: uvscom.c,v 1.29 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2001-2002, Shunsuke Akiyama <akiyama@jp.FreeBSD.org>. * All rights reserved. @@ -35,12 +35,12 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uvscom.c,v 1.28 2012/02/24 06:48:28 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uvscom.c,v 1.29 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/fcntl.h> #include <sys/conf.h> #include <sys/tty.h> @@ -136,13 +136,13 @@ static int uvscomdebug = 1; struct uvscom_softc { device_t sc_dev; /* base device */ - usbd_device_handle sc_udev; /* USB device */ - usbd_interface_handle sc_iface; /* interface */ + struct usbd_device * sc_udev; /* USB device */ + struct usbd_interface * sc_iface; /* interface */ int sc_iface_number;/* interface number */ - usbd_interface_handle sc_intr_iface; /* interrupt interface */ + struct usbd_interface * sc_intr_iface; /* interrupt interface */ int sc_intr_number; /* interrupt number */ - usbd_pipe_handle sc_intr_pipe; /* interrupt pipe */ + struct usbd_pipe * sc_intr_pipe; /* interrupt pipe */ u_char *sc_intr_buf; /* interrupt buffer */ int sc_isize; @@ -179,20 +179,20 @@ Static void uvscom_rts(struct uvscom_softc *, int); Static void uvscom_break(struct uvscom_softc *, int); Static void uvscom_set(void *, int, int, int); -Static void uvscom_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); +Static void uvscom_intr(struct usbd_xfer *, void *, usbd_status); Static int uvscom_param(void *, int, struct termios *); Static int uvscom_open(void *, int); Static void uvscom_close(void *, int); struct ucom_methods uvscom_methods = { - uvscom_get_status, - uvscom_set, - uvscom_param, - NULL, /* uvscom_ioctl, TODO */ - uvscom_open, - uvscom_close, - NULL, - NULL + .ucom_get_status = uvscom_get_status, + .ucom_set = uvscom_set, + .ucom_param = uvscom_param, + .ucom_ioctl = NULL, /* TODO */ + .ucom_open = uvscom_open, + .ucom_close = uvscom_close, + .ucom_read = NULL, + .ucom_write = NULL }; static const struct usb_devno uvscom_devs [] = { @@ -218,28 +218,28 @@ extern struct cfdriver uvscom_cd; CFATTACH_DECL2_NEW(uvscom, sizeof(struct uvscom_softc), uvscom_match, uvscom_attach, uvscom_detach, uvscom_activate, NULL, uvscom_childdet); -int +int uvscom_match(device_t parent, cfdata_t match, void *aux) { struct usb_attach_arg *uaa = aux; - return (uvscom_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return uvscom_lookup(uaa->uaa_vendor, uaa->uaa_product) != NULL ? + UMATCH_VENDOR_PRODUCT : UMATCH_NONE; } -void +void uvscom_attach(device_t parent, device_t self, void *aux) { struct uvscom_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; + struct usbd_device *dev = uaa->uaa_device; usb_config_descriptor_t *cdesc; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; char *devinfop; usbd_status err; int i; - struct ucom_attach_args uca; + struct ucom_attach_args ucaa; aprint_naive("\n"); aprint_normal("\n"); @@ -254,7 +254,7 @@ uvscom_attach(device_t parent, device_t self, void *aux) DPRINTF(("uvscom attach: sc = %p\n", sc)); /* initialize endpoints */ - uca.bulkin = uca.bulkout = -1; + ucaa.ucaa_bulkin = ucaa.ucaa_bulkout = -1; sc->sc_intr_number = -1; sc->sc_intr_pipe = NULL; @@ -302,10 +302,10 @@ uvscom_attach(device_t parent, device_t self, void *aux) if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - uca.bulkin = ed->bEndpointAddress; + ucaa.ucaa_bulkin = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) { - uca.bulkout = ed->bEndpointAddress; + ucaa.ucaa_bulkout = ed->bEndpointAddress; } else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && UE_GET_XFERTYPE(ed->bmAttributes) == UE_INTERRUPT) { sc->sc_intr_number = ed->bEndpointAddress; @@ -313,12 +313,12 @@ uvscom_attach(device_t parent, device_t self, void *aux) } } - if (uca.bulkin == -1) { + if (ucaa.ucaa_bulkin == -1) { aprint_error_dev(self, "Could not find data bulk in\n"); sc->sc_dying = 1; return; } - if (uca.bulkout == -1) { + if (ucaa.ucaa_bulkout == -1) { aprint_error_dev(self, "Could not find data bulk out\n"); sc->sc_dying = 1; return; @@ -332,17 +332,17 @@ uvscom_attach(device_t parent, device_t self, void *aux) sc->sc_dtr = sc->sc_rts = 0; sc->sc_lcr = UVSCOM_LINE_INIT; - uca.portno = UCOM_UNK_PORTNO; - /* bulkin, bulkout set above */ - uca.ibufsize = UVSCOMIBUFSIZE; - uca.obufsize = UVSCOMOBUFSIZE; - uca.ibufsizepad = UVSCOMIBUFSIZE; - uca.opkthdrlen = 0; - uca.device = dev; - uca.iface = sc->sc_iface; - uca.methods = &uvscom_methods; - uca.arg = sc; - uca.info = NULL; + ucaa.ucaa_portno = UCOM_UNK_PORTNO; + /* ucaa_bulkin, ucaa_bulkout set above */ + ucaa.ucaa_ibufsize = UVSCOMIBUFSIZE; + ucaa.ucaa_obufsize = UVSCOMOBUFSIZE; + ucaa.ucaa_ibufsizepad = UVSCOMIBUFSIZE; + ucaa.ucaa_opkthdrlen = 0; + ucaa.ucaa_device = dev; + ucaa.ucaa_iface = sc->sc_iface; + ucaa.ucaa_methods = &uvscom_methods; + ucaa.ucaa_arg = sc; + ucaa.ucaa_info = NULL; err = uvscom_reset(sc); @@ -353,14 +353,14 @@ uvscom_attach(device_t parent, device_t self, void *aux) } DPRINTF(("uvscom: in = 0x%x out = 0x%x intr = 0x%x\n", - uca.bulkin, uca.bulkout, sc->sc_intr_number)); + ucaa.ucaa_bulkin, ucaa.ucaa_bulkout, sc->sc_intr_number)); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); DPRINTF(("uplcom: in=0x%x out=0x%x intr=0x%x\n", - uca.bulkin, uca.bulkout, sc->sc_intr_number )); - sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &uca, + ucaa.ucaa_bulkin, ucaa.ucaa_bulkout, sc->sc_intr_number )); + sc->sc_subdev = config_found_sm_loc(self, "ucombus", NULL, &ucaa, ucomprint, ucomsubmatch); return; @@ -375,7 +375,7 @@ uvscom_childdet(device_t self, device_t child) sc->sc_subdev = NULL; } -int +int uvscom_detach(device_t self, int flags) { struct uvscom_softc *sc = device_private(self); @@ -388,7 +388,7 @@ uvscom_detach(device_t self, int flags) if (sc->sc_intr_pipe != NULL) { usbd_abort_pipe(sc->sc_intr_pipe); usbd_close_pipe(sc->sc_intr_pipe); - free(sc->sc_intr_buf, M_USBDEV); + kmem_free(sc->sc_intr_buf, sc->sc_isize); sc->sc_intr_pipe = NULL; } @@ -399,7 +399,7 @@ uvscom_detach(device_t self, int flags) usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - return (rv); + return rv; } int @@ -435,13 +435,13 @@ uvscom_readstat(struct uvscom_softc *sc) if (err) { aprint_error_dev(sc->sc_dev, "uvscom_readstat: %s\n", usbd_errstr(err)); - return (err); + return err; } DPRINTF(("%s: uvscom_readstat: r = %d\n", device_xname(sc->sc_dev), r)); - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } Static usbd_status @@ -462,10 +462,10 @@ uvscom_shutdown(struct uvscom_softc *sc) if (err) { aprint_error_dev(sc->sc_dev, "uvscom_shutdown: %s\n", usbd_errstr(err)); - return (err); + return err; } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } Static usbd_status @@ -473,7 +473,7 @@ uvscom_reset(struct uvscom_softc *sc) { DPRINTF(("%s: uvscom_reset\n", device_xname(sc->sc_dev))); - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } Static usbd_status @@ -481,7 +481,7 @@ uvscom_set_crtscts(struct uvscom_softc *sc) { DPRINTF(("%s: uvscom_set_crtscts\n", device_xname(sc->sc_dev))); - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } Static usbd_status @@ -503,10 +503,10 @@ uvscom_set_line(struct uvscom_softc *sc, uint16_t line) if (err) { aprint_error_dev(sc->sc_dev, "uvscom_set_line: %s\n", usbd_errstr(err)); - return (err); + return err; } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } Static usbd_status @@ -528,7 +528,7 @@ uvscom_set_line_coding(struct uvscom_softc *sc, uint16_t lsp, uint16_t ls) if (err) { aprint_error_dev(sc->sc_dev, "uvscom_set_line_coding: %s\n", usbd_errstr(err)); - return (err); + return err; } req.bmRequestType = UT_WRITE_VENDOR_DEVICE; @@ -541,10 +541,10 @@ uvscom_set_line_coding(struct uvscom_softc *sc, uint16_t lsp, uint16_t ls) if (err) { aprint_error_dev(sc->sc_dev, "uvscom_set_line_coding: %s\n", usbd_errstr(err)); - return (err); + return err; } - return (USBD_NORMAL_COMPLETION); + return USBD_NORMAL_COMPLETION; } Static void @@ -663,7 +663,7 @@ uvscom_param(void *addr, int portno, struct termios *t) lsp = UVSCOM_SPEED_115200BPS; break; default: - return (EIO); + return EIO; } if (ISSET(t->c_cflag, CSTOPB)) @@ -693,20 +693,20 @@ uvscom_param(void *addr, int portno, struct termios *t) SET(ls, UVSCOM_DATA_BIT_8); break; default: - return (EIO); + return EIO; } err = uvscom_set_line_coding(sc, lsp, ls); if (err) - return (EIO); + return EIO; if (ISSET(t->c_cflag, CRTSCTS)) { err = uvscom_set_crtscts(sc); if (err) - return (EIO); + return EIO; } - return (0); + return 0; } Static int @@ -717,7 +717,7 @@ uvscom_open(void *addr, int portno) int i; if (sc->sc_dying) - return (EIO); + return EIO; DPRINTF(("uvscom_open: sc = %p\n", sc)); @@ -730,10 +730,10 @@ uvscom_open(void *addr, int portno) if (err) { DPRINTF(("%s: uvscom_open: readstat faild\n", device_xname(sc->sc_dev))); - return (EIO); + return EIO; } - sc->sc_intr_buf = malloc(sc->sc_isize, M_USBDEV, M_WAITOK); + sc->sc_intr_buf = kmem_alloc(sc->sc_isize, KM_SLEEP); err = usbd_open_pipe_intr(sc->sc_iface, sc->sc_intr_number, USBD_SHORT_XFER_OK, @@ -747,7 +747,7 @@ uvscom_open(void *addr, int portno) aprint_error_dev(sc->sc_dev, "cannot open interrupt pipe (addr %d)\n", sc->sc_intr_number); - return (EIO); + return EIO; } } else { DPRINTF(("uvscom_open: did not open interrupt pipe.\n")); @@ -764,18 +764,18 @@ uvscom_open(void *addr, int portno) if (i == 0) { DPRINTF(("%s: unit is not ready\n", device_xname(sc->sc_dev))); - return (EIO); + return EIO; } /* check PC card was inserted */ if (ISSET(sc->sc_usr, UVSCOM_NOCARD)) { DPRINTF(("%s: no card\n", device_xname(sc->sc_dev))); - return (EIO); + return EIO; } } - return (0); + return 0; } Static void @@ -802,13 +802,13 @@ uvscom_close(void *addr, int portno) aprint_error_dev(sc->sc_dev, "lose interrupt pipe failed: %s\n", usbd_errstr(err)); - free(sc->sc_intr_buf, M_USBDEV); + kmem_free(sc->sc_intr_buf, sc->sc_isize); sc->sc_intr_pipe = NULL; } } Static void -uvscom_intr(usbd_xfer_handle xfer, usbd_private_handle priv, +uvscom_intr(struct usbd_xfer *xfer, void *priv, usbd_status status) { struct uvscom_softc *sc = priv; diff --git a/sys/dev/usb/uyap.c b/sys/dev/usb/uyap.c index 4db277117a5..8bbcf59906f 100644 --- a/sys/dev/usb/uyap.c +++ b/sys/dev/usb/uyap.c @@ -1,4 +1,4 @@ -/* $NetBSD: uyap.c,v 1.19 2011/12/23 00:51:50 jakllsch Exp $ */ +/* $NetBSD: uyap.c,v 1.20 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uyap.c,v 1.19 2011/12/23 00:51:50 jakllsch Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uyap.c,v 1.20 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -66,8 +66,8 @@ uyap_match(device_t parent, cfdata_t match, void *aux) struct usb_attach_arg *uaa = aux; /* Match the boot device. */ - if (uaa->vendor == USB_VENDOR_SILICONPORTALS && - uaa->product == USB_PRODUCT_SILICONPORTALS_YAPPH_NF) + if (uaa->uaa_vendor == USB_VENDOR_SILICONPORTALS && + uaa->uaa_product == USB_PRODUCT_SILICONPORTALS_YAPPH_NF) return (UMATCH_VENDOR_PRODUCT); return (UMATCH_NONE); @@ -78,7 +78,7 @@ uyap_attach(device_t parent, device_t self, void *aux) { struct uyap_softc *sc = device_private(self); struct usb_attach_arg *uaa = aux; - usbd_device_handle dev = uaa->device; + struct usbd_device *dev = uaa->uaa_device; usbd_status err; char *devinfop; diff --git a/sys/dev/usb/uyap_firmware.h b/sys/dev/usb/uyap_firmware.h index 956ff519412..7b1223c88ae 100644 --- a/sys/dev/usb/uyap_firmware.h +++ b/sys/dev/usb/uyap_firmware.h @@ -1,4 +1,4 @@ -/* $NetBSD: uyap_firmware.h,v 1.7 2009/08/18 11:08:37 drochner Exp $ */ +/* $NetBSD: uyap_firmware.h,v 1.8 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2000 The NetBSD Foundation, Inc. @@ -28,7 +28,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ -#define UC (const u_int8_t *) +#define UC (const uint8_t *) {0x10,0x146C, UC"\xC2\x00\x90\x7F\xA5\xE0\x54\x18\xFF\x13\x13\x13\x54\x1F\x44\x50"}, {0x10,0x147C, diff --git a/sys/dev/usb/uyurex.c b/sys/dev/usb/uyurex.c index acbba24d0a1..9cba89ce7ae 100644 --- a/sys/dev/usb/uyurex.c +++ b/sys/dev/usb/uyurex.c @@ -1,4 +1,4 @@ -/* $NetBSD: uyurex.c,v 1.10 2015/03/07 20:20:55 mrg Exp $ */ +/* $NetBSD: uyurex.c,v 1.11 2016/04/23 10:15:32 skrll Exp $ */ /* $OpenBSD: uyurex.c,v 1.3 2010/03/04 03:47:22 deraadt Exp $ */ /* @@ -22,13 +22,13 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: uyurex.c,v 1.10 2015/03/07 20:20:55 mrg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: uyurex.c,v 1.11 2016/04/23 10:15:32 skrll Exp $"); #include <sys/param.h> #include <sys/proc.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/malloc.h> +#include <sys/kmem.h> #include <sys/device.h> #include <sys/conf.h> #include <sys/envsys.h> @@ -65,7 +65,7 @@ int uyurexdebug = 0; struct uyurex_softc { struct uhidev sc_hdev; - usbd_device_handle sc_udev; + struct usbd_device * sc_udev; u_char sc_dying; uint16_t sc_flag; @@ -113,25 +113,23 @@ extern struct cfdriver uyurex_cd; CFATTACH_DECL_NEW(uyurex, sizeof(struct uyurex_softc), uyurex_match, uyurex_attach, uyurex_detach, uyurex_activate); -int +int uyurex_match(device_t parent, cfdata_t match, void *aux) { - struct usb_attach_arg *uaa = aux; - struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa; + struct uhidev_attach_arg *uha = aux; - if (uyurex_lookup(uha->uaa->vendor, uha->uaa->product) == NULL) + if (uyurex_lookup(uha->uiaa->uiaa_vendor, uha->uiaa->uiaa_product) == NULL) return UMATCH_NONE; return (UMATCH_VENDOR_PRODUCT); } -void +void uyurex_attach(device_t parent, device_t self, void *aux) { struct uyurex_softc *sc = device_private(self); - struct usb_attach_arg *uaa = aux; - struct uhidev_attach_arg *uha = (struct uhidev_attach_arg *)uaa; - usbd_device_handle dev = uha->parent->sc_udev; + struct uhidev_attach_arg *uha = aux; + struct usbd_device *dev = uha->parent->sc_udev; int size, repid, err; void *desc; @@ -159,7 +157,7 @@ uyurex_attach(device_t parent, device_t self, void *aux) aprint_error_dev(self, "uyurex_open: uhidev_open %d\n", err); return; } - sc->sc_ibuf = malloc(sc->sc_ilen, M_USBDEV, M_WAITOK); + sc->sc_ibuf = kmem_alloc(sc->sc_ilen, KM_SLEEP); usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_hdev.sc_dev); @@ -202,7 +200,7 @@ uyurex_attach(device_t parent, device_t self, void *aux) uyurex_set_mode(sc, 0); } -int +int uyurex_detach(device_t self, int flags) { struct uyurex_softc *sc = device_private(self); @@ -215,7 +213,7 @@ uyurex_detach(device_t self, int flags) sysmon_envsys_unregister(sc->sc_sme); if (sc->sc_ibuf != NULL) { - free(sc->sc_ibuf, M_USBDEV); + kmem_free(sc->sc_ibuf, sc->sc_ilen); sc->sc_ibuf = NULL; } diff --git a/sys/dev/usb/x1input_rdesc.h b/sys/dev/usb/x1input_rdesc.h index fb6a67f7986..cddb236ff19 100644 --- a/sys/dev/usb/x1input_rdesc.h +++ b/sys/dev/usb/x1input_rdesc.h @@ -1,4 +1,4 @@ -/* $NetBSD: x1input_rdesc.h,v 1.1 2015/02/08 19:22:45 jmcneill Exp $ */ +/* $NetBSD: x1input_rdesc.h,v 1.2 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (C) 2014 Loic Nageleisen @@ -14,7 +14,7 @@ * * Neither the name of the copyright holders nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -27,10 +27,10 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#define USBIF_IS_X1INPUT(uaa) \ - ((uaa)->class == UICLASS_VENDOR && \ - (uaa)->subclass == 0x47 && \ - (uaa)->proto == 0xd0) +#define USBIF_IS_X1INPUT(uiaa) \ + ((uiaa)->uiaa_class == UICLASS_VENDOR && \ + (uiaa)->uiaa_subclass == 0x47 && \ + (uiaa)->uiaa_proto == 0xd0) static const uByte uhid_x1input_report_descr[] = { 0x05, 0x01, // Usage Page (Generic Desktop) diff --git a/sys/dev/usb/xhci.c b/sys/dev/usb/xhci.c index 4375eb846e2..76ac1a6deb5 100644 --- a/sys/dev/usb/xhci.c +++ b/sys/dev/usb/xhci.c @@ -1,4 +1,4 @@ -/* $NetBSD: xhci.c,v 1.33 2016/01/06 22:12:49 skrll Exp $ */ +/* $NetBSD: xhci.c,v 1.34 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2013 Jonathan A. Kollasch @@ -26,8 +26,17 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + * USB rev 3.1 specification + * http://www.usb.org/developers/docs/usb_31_040315.zip + * USB rev 2.0 specification + * http://www.usb.org/developers/docs/usb20_docs/usb_20_031815.zip + * xHCI rev 1.1 specification + * http://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/extensible-host-controler-interface-usb-xhci.pdf + */ + #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.33 2016/01/06 22:12:49 skrll Exp $"); +__KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.34 2016/04/23 10:15:32 skrll Exp $"); #include "opt_usb.h" @@ -35,7 +44,6 @@ __KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.33 2016/01/06 22:12:49 skrll Exp $"); #include <sys/systm.h> #include <sys/kernel.h> #include <sys/kmem.h> -#include <sys/malloc.h> #include <sys/device.h> #include <sys/select.h> #include <sys/proc.h> @@ -51,19 +59,20 @@ __KERNEL_RCSID(0, "$NetBSD: xhci.c,v 1.33 2016/01/06 22:12:49 skrll Exp $"); #include <dev/usb/usb.h> #include <dev/usb/usbdi.h> #include <dev/usb/usbdivar.h> +#include <dev/usb/usbdi_util.h> #include <dev/usb/usbhist.h> #include <dev/usb/usb_mem.h> #include <dev/usb/usb_quirks.h> #include <dev/usb/xhcireg.h> #include <dev/usb/xhcivar.h> -#include <dev/usb/usbroothub_subr.h> +#include <dev/usb/usbroothub.h> #ifdef USB_DEBUG #ifndef XHCI_DEBUG #define xhcidebug 0 -#else +#else /* !XHCI_DEBUG */ static int xhcidebug = 0; SYSCTL_SETUP(sysctl_hw_xhci_setup, "sysctl hw.xhci setup") @@ -93,7 +102,7 @@ fail: aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); } -#endif /* XHCI_DEBUG */ +#endif /* !XHCI_DEBUG */ #endif /* USB_DEBUG */ #define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(xhcidebug,N,FMT,A,B,C,D) @@ -107,150 +116,151 @@ fail: struct xhci_pipe { struct usbd_pipe xp_pipe; + struct usb_task xp_async_task; }; -#define XHCI_INTR_ENDPT 1 #define XHCI_COMMAND_RING_TRBS 256 #define XHCI_EVENT_RING_TRBS 256 #define XHCI_EVENT_RING_SEGMENTS 1 #define XHCI_TRB_3_ED_BIT XHCI_TRB_3_ISP_BIT -static usbd_status xhci_open(usbd_pipe_handle); +static usbd_status xhci_open(struct usbd_pipe *); +static void xhci_close_pipe(struct usbd_pipe *); static int xhci_intr1(struct xhci_softc * const); static void xhci_softintr(void *); static void xhci_poll(struct usbd_bus *); -static usbd_status xhci_allocm(struct usbd_bus *, usb_dma_t *, uint32_t); -static void xhci_freem(struct usbd_bus *, usb_dma_t *); -static usbd_xfer_handle xhci_allocx(struct usbd_bus *); -static void xhci_freex(struct usbd_bus *, usbd_xfer_handle); +static struct usbd_xfer *xhci_allocx(struct usbd_bus *, unsigned int); +static void xhci_freex(struct usbd_bus *, struct usbd_xfer *); static void xhci_get_lock(struct usbd_bus *, kmutex_t **); -static usbd_status xhci_new_device(device_t, usbd_bus_handle, int, int, int, +static usbd_status xhci_new_device(device_t, struct usbd_bus *, int, int, int, struct usbd_port *); +static int xhci_roothub_ctrl(struct usbd_bus *, usb_device_request_t *, + void *, int); -static usbd_status xhci_configure_endpoint(usbd_pipe_handle); -static usbd_status xhci_unconfigure_endpoint(usbd_pipe_handle); -static usbd_status xhci_reset_endpoint(usbd_pipe_handle); -//static usbd_status xhci_stop_endpoint(usbd_pipe_handle); +static usbd_status xhci_configure_endpoint(struct usbd_pipe *); +//static usbd_status xhci_unconfigure_endpoint(struct usbd_pipe *); +static usbd_status xhci_reset_endpoint(struct usbd_pipe *); +static usbd_status xhci_stop_endpoint(struct usbd_pipe *); -static usbd_status xhci_set_dequeue(usbd_pipe_handle); +static usbd_status xhci_set_dequeue(struct usbd_pipe *); static usbd_status xhci_do_command(struct xhci_softc * const, struct xhci_trb * const, int); -static usbd_status xhci_init_slot(struct xhci_softc * const, uint32_t, - int, int, int, int); +static usbd_status xhci_do_command_locked(struct xhci_softc * const, + struct xhci_trb * const, int); +static usbd_status xhci_init_slot(struct usbd_device *, uint32_t, uint32_t, int); static usbd_status xhci_enable_slot(struct xhci_softc * const, uint8_t * const); +static usbd_status xhci_disable_slot(struct xhci_softc * const, uint8_t); static usbd_status xhci_address_device(struct xhci_softc * const, uint64_t, uint8_t, bool); +static void xhci_set_dcba(struct xhci_softc * const, uint64_t, int); static usbd_status xhci_update_ep0_mps(struct xhci_softc * const, struct xhci_slot * const, u_int); static usbd_status xhci_ring_init(struct xhci_softc * const, struct xhci_ring * const, size_t, size_t); static void xhci_ring_free(struct xhci_softc * const, struct xhci_ring * const); -static void xhci_noop(usbd_pipe_handle); - -static usbd_status xhci_root_ctrl_transfer(usbd_xfer_handle); -static usbd_status xhci_root_ctrl_start(usbd_xfer_handle); -static void xhci_root_ctrl_abort(usbd_xfer_handle); -static void xhci_root_ctrl_close(usbd_pipe_handle); -static void xhci_root_ctrl_done(usbd_xfer_handle); - -static usbd_status xhci_root_intr_transfer(usbd_xfer_handle); -static usbd_status xhci_root_intr_start(usbd_xfer_handle); -static void xhci_root_intr_abort(usbd_xfer_handle); -static void xhci_root_intr_close(usbd_pipe_handle); -static void xhci_root_intr_done(usbd_xfer_handle); - -static usbd_status xhci_device_ctrl_transfer(usbd_xfer_handle); -static usbd_status xhci_device_ctrl_start(usbd_xfer_handle); -static void xhci_device_ctrl_abort(usbd_xfer_handle); -static void xhci_device_ctrl_close(usbd_pipe_handle); -static void xhci_device_ctrl_done(usbd_xfer_handle); - -static usbd_status xhci_device_intr_transfer(usbd_xfer_handle); -static usbd_status xhci_device_intr_start(usbd_xfer_handle); -static void xhci_device_intr_abort(usbd_xfer_handle); -static void xhci_device_intr_close(usbd_pipe_handle); -static void xhci_device_intr_done(usbd_xfer_handle); - -static usbd_status xhci_device_bulk_transfer(usbd_xfer_handle); -static usbd_status xhci_device_bulk_start(usbd_xfer_handle); -static void xhci_device_bulk_abort(usbd_xfer_handle); -static void xhci_device_bulk_close(usbd_pipe_handle); -static void xhci_device_bulk_done(usbd_xfer_handle); +static void xhci_noop(struct usbd_pipe *); + +static usbd_status xhci_root_intr_transfer(struct usbd_xfer *); +static usbd_status xhci_root_intr_start(struct usbd_xfer *); +static void xhci_root_intr_abort(struct usbd_xfer *); +static void xhci_root_intr_close(struct usbd_pipe *); +static void xhci_root_intr_done(struct usbd_xfer *); + +static usbd_status xhci_device_ctrl_transfer(struct usbd_xfer *); +static usbd_status xhci_device_ctrl_start(struct usbd_xfer *); +static void xhci_device_ctrl_abort(struct usbd_xfer *); +static void xhci_device_ctrl_close(struct usbd_pipe *); +static void xhci_device_ctrl_done(struct usbd_xfer *); + +static usbd_status xhci_device_intr_transfer(struct usbd_xfer *); +static usbd_status xhci_device_intr_start(struct usbd_xfer *); +static void xhci_device_intr_abort(struct usbd_xfer *); +static void xhci_device_intr_close(struct usbd_pipe *); +static void xhci_device_intr_done(struct usbd_xfer *); + +static usbd_status xhci_device_bulk_transfer(struct usbd_xfer *); +static usbd_status xhci_device_bulk_start(struct usbd_xfer *); +static void xhci_device_bulk_abort(struct usbd_xfer *); +static void xhci_device_bulk_close(struct usbd_pipe *); +static void xhci_device_bulk_done(struct usbd_xfer *); static void xhci_timeout(void *); static void xhci_timeout_task(void *); static const struct usbd_bus_methods xhci_bus_methods = { - .open_pipe = xhci_open, - .soft_intr = xhci_softintr, - .do_poll = xhci_poll, - .allocm = xhci_allocm, - .freem = xhci_freem, - .allocx = xhci_allocx, - .freex = xhci_freex, - .get_lock = xhci_get_lock, - .new_device = xhci_new_device, -}; - -static const struct usbd_pipe_methods xhci_root_ctrl_methods = { - .transfer = xhci_root_ctrl_transfer, - .start = xhci_root_ctrl_start, - .abort = xhci_root_ctrl_abort, - .close = xhci_root_ctrl_close, - .cleartoggle = xhci_noop, - .done = xhci_root_ctrl_done, + .ubm_open = xhci_open, + .ubm_softint = xhci_softintr, + .ubm_dopoll = xhci_poll, + .ubm_allocx = xhci_allocx, + .ubm_freex = xhci_freex, + .ubm_getlock = xhci_get_lock, + .ubm_newdev = xhci_new_device, + .ubm_rhctrl = xhci_roothub_ctrl, }; static const struct usbd_pipe_methods xhci_root_intr_methods = { - .transfer = xhci_root_intr_transfer, - .start = xhci_root_intr_start, - .abort = xhci_root_intr_abort, - .close = xhci_root_intr_close, - .cleartoggle = xhci_noop, - .done = xhci_root_intr_done, + .upm_transfer = xhci_root_intr_transfer, + .upm_start = xhci_root_intr_start, + .upm_abort = xhci_root_intr_abort, + .upm_close = xhci_root_intr_close, + .upm_cleartoggle = xhci_noop, + .upm_done = xhci_root_intr_done, }; static const struct usbd_pipe_methods xhci_device_ctrl_methods = { - .transfer = xhci_device_ctrl_transfer, - .start = xhci_device_ctrl_start, - .abort = xhci_device_ctrl_abort, - .close = xhci_device_ctrl_close, - .cleartoggle = xhci_noop, - .done = xhci_device_ctrl_done, + .upm_transfer = xhci_device_ctrl_transfer, + .upm_start = xhci_device_ctrl_start, + .upm_abort = xhci_device_ctrl_abort, + .upm_close = xhci_device_ctrl_close, + .upm_cleartoggle = xhci_noop, + .upm_done = xhci_device_ctrl_done, }; static const struct usbd_pipe_methods xhci_device_isoc_methods = { - .cleartoggle = xhci_noop, + .upm_cleartoggle = xhci_noop, }; static const struct usbd_pipe_methods xhci_device_bulk_methods = { - .transfer = xhci_device_bulk_transfer, - .start = xhci_device_bulk_start, - .abort = xhci_device_bulk_abort, - .close = xhci_device_bulk_close, - .cleartoggle = xhci_noop, - .done = xhci_device_bulk_done, + .upm_transfer = xhci_device_bulk_transfer, + .upm_start = xhci_device_bulk_start, + .upm_abort = xhci_device_bulk_abort, + .upm_close = xhci_device_bulk_close, + .upm_cleartoggle = xhci_noop, + .upm_done = xhci_device_bulk_done, }; static const struct usbd_pipe_methods xhci_device_intr_methods = { - .transfer = xhci_device_intr_transfer, - .start = xhci_device_intr_start, - .abort = xhci_device_intr_abort, - .close = xhci_device_intr_close, - .cleartoggle = xhci_noop, - .done = xhci_device_intr_done, + .upm_transfer = xhci_device_intr_transfer, + .upm_start = xhci_device_intr_start, + .upm_abort = xhci_device_intr_abort, + .upm_close = xhci_device_intr_close, + .upm_cleartoggle = xhci_noop, + .upm_done = xhci_device_intr_done, }; static inline uint32_t +xhci_read_1(const struct xhci_softc * const sc, bus_size_t offset) +{ + return bus_space_read_1(sc->sc_iot, sc->sc_ioh, offset); +} + +static inline uint32_t xhci_read_4(const struct xhci_softc * const sc, bus_size_t offset) { return bus_space_read_4(sc->sc_iot, sc->sc_ioh, offset); } +static inline void +xhci_write_1(const struct xhci_softc * const sc, bus_size_t offset, + uint32_t value) +{ + bus_space_write_1(sc->sc_iot, sc->sc_ioh, offset, value); +} + #if 0 /* unused */ static inline void xhci_write_4(const struct xhci_softc * const sc, bus_size_t offset, @@ -392,7 +402,7 @@ xhci_db_write_4(const struct xhci_softc * const sc, bus_size_t offset, static inline uint8_t xhci_ep_get_type(usb_endpoint_descriptor_t * const ed) { - u_int eptype; + u_int eptype = 0; switch (UE_GET_XFERTYPE(ed->bmAttributes)) { case UE_CONTROL: @@ -482,9 +492,9 @@ static inline void xhci_trb_put(struct xhci_trb * const trb, uint64_t parameter, uint32_t status, uint32_t control) { - trb->trb_0 = parameter; - trb->trb_2 = status; - trb->trb_3 = control; + trb->trb_0 = htole64(parameter); + trb->trb_2 = htole32(status); + trb->trb_3 = htole32(control); } /* --- */ @@ -508,7 +518,7 @@ xhci_detach(struct xhci_softc *sc, int flags) rv = config_detach(sc->sc_child, flags); if (rv != 0) - return (rv); + return rv; /* XXX unconfigure/free slots */ @@ -535,6 +545,7 @@ xhci_detach(struct xhci_softc *sc, int flags) mutex_destroy(&sc->sc_lock); mutex_destroy(&sc->sc_intr_lock); + cv_destroy(&sc->sc_softwake_cv); pool_cache_destroy(sc->sc_xferpool); @@ -601,12 +612,46 @@ hexdump(const char *msg, const void *base, size_t len) #endif } +#define XHCI_HCCPREV1_BITS \ + "\177\020" /* New bitmask */ \ + "f\020\020XECP\0" \ + "f\014\4MAXPSA\0" \ + "b\013CFC\0" \ + "b\012SEC\0" \ + "b\011SBD\0" \ + "b\010FSE\0" \ + "b\7NSS\0" \ + "b\6LTC\0" \ + "b\5LHRC\0" \ + "b\4PIND\0" \ + "b\3PPC\0" \ + "b\2CZC\0" \ + "b\1BNC\0" \ + "b\0AC64\0" \ + "\0" +#define XHCI_HCCV1_x_BITS \ + "\177\020" /* New bitmask */ \ + "f\020\020XECP\0" \ + "f\014\4MAXPSA\0" \ + "b\013CFC\0" \ + "b\012SEC\0" \ + "b\011SPC\0" \ + "b\010PAE\0" \ + "b\7NSS\0" \ + "b\6LTC\0" \ + "b\5LHRC\0" \ + "b\4PIND\0" \ + "b\3PPC\0" \ + "b\2CSZ\0" \ + "b\1BNC\0" \ + "b\0AC64\0" \ + "\0" int xhci_init(struct xhci_softc *sc) { bus_size_t bsz; - uint32_t cap, hcs1, hcs2, hcc, dboff, rtsoff; + uint32_t cap, hcs1, hcs2, hcs3, hcc, dboff, rtsoff; uint32_t ecp, ecr; uint32_t usbcmd, usbsts, pagesize, config; int i; @@ -615,14 +660,15 @@ xhci_init(struct xhci_softc *sc) XHCIHIST_FUNC(); XHCIHIST_CALLED(); - /* XXX Low/Full/High speeds for now */ - sc->sc_bus.usbrev = USBREV_2_0; + sc->sc_bus.ub_revision = USBREV_3_0; + sc->sc_bus.ub_usedma = true; cap = xhci_read_4(sc, XHCI_CAPLENGTH); caplength = XHCI_CAP_CAPLENGTH(cap); hciversion = XHCI_CAP_HCIVERSION(cap); - if ((hciversion < 0x0096) || (hciversion > 0x0100)) { + if (hciversion < XHCI_HCIVERSION_0_96 || + hciversion > XHCI_HCIVERSION_1_0) { aprint_normal_dev(sc->sc_dev, "xHCI version %x.%x not known to be supported\n", (hciversion >> 8) & 0xff, (hciversion >> 0) & 0xff); @@ -642,15 +688,22 @@ xhci_init(struct xhci_softc *sc) sc->sc_maxintrs = XHCI_HCS1_MAXINTRS(hcs1); sc->sc_maxports = XHCI_HCS1_MAXPORTS(hcs1); hcs2 = xhci_cap_read_4(sc, XHCI_HCSPARAMS2); - (void)xhci_cap_read_4(sc, XHCI_HCSPARAMS3); - hcc = xhci_cap_read_4(sc, XHCI_HCCPARAMS); + hcs3 = xhci_cap_read_4(sc, XHCI_HCSPARAMS3); + aprint_debug_dev(sc->sc_dev, + "hcs1=%"PRIx32" hcs2=%"PRIx32" hcs3=%"PRIx32"\n", hcs1, hcs2, hcs3); + hcc = xhci_cap_read_4(sc, XHCI_HCCPARAMS); sc->sc_ac64 = XHCI_HCC_AC64(hcc); sc->sc_ctxsz = XHCI_HCC_CSZ(hcc) ? 64 : 32; - aprint_debug_dev(sc->sc_dev, "ac64 %d ctxsz %d\n", sc->sc_ac64, - sc->sc_ctxsz); + char sbuf[128]; + if (hciversion < XHCI_HCIVERSION_1_0) + snprintb(sbuf, sizeof(sbuf), XHCI_HCCPREV1_BITS, hcc); + else + snprintb(sbuf, sizeof(sbuf), XHCI_HCCV1_x_BITS, hcc); + aprint_debug_dev(sc->sc_dev, "hcc=%s\n", sbuf); aprint_debug_dev(sc->sc_dev, "xECP %x\n", XHCI_HCC_XECP(hcc) * 4); + ecp = XHCI_HCC_XECP(hcc) * 4; while (ecp != 0) { ecr = xhci_read_4(sc, ecp); @@ -675,6 +728,28 @@ xhci_init(struct xhci_softc *sc) } break; } + case XHCI_ID_USB_LEGACY: { + uint8_t bios_sem; + + /* Take host controller from BIOS */ + bios_sem = xhci_read_1(sc, ecp + XHCI_XECP_BIOS_SEM); + if (bios_sem) { + /* sets xHCI to be owned by OS */ + xhci_write_1(sc, ecp + XHCI_XECP_OS_SEM, 1); + aprint_debug( + "waiting for BIOS to give up control\n"); + for (i = 0; i < 5000; i++) { + bios_sem = xhci_read_1(sc, ecp + + XHCI_XECP_BIOS_SEM); + if (bios_sem == 0) + break; + DELAY(1000); + } + if (bios_sem) + printf("timed out waiting for BIOS\n"); + } + break; + } default: break; } @@ -740,6 +815,9 @@ xhci_init(struct xhci_softc *sc) if (i >= 100) return EIO; + if (sc->sc_vendor_init) + sc->sc_vendor_init(sc); + pagesize = xhci_op_read_4(sc, XHCI_PAGESIZE); aprint_debug_dev(sc->sc_dev, "PAGESIZE 0x%08x\n", pagesize); pagesize = ffs(pagesize); @@ -749,6 +827,7 @@ xhci_init(struct xhci_softc *sc) aprint_debug_dev(sc->sc_dev, "sc_pgsz 0x%08x\n", (uint32_t)sc->sc_pgsz); aprint_debug_dev(sc->sc_dev, "sc_maxslots 0x%08x\n", (uint32_t)sc->sc_maxslots); + aprint_debug_dev(sc->sc_dev, "sc_maxports %d\n", sc->sc_maxports); usbd_status err; @@ -815,7 +894,7 @@ xhci_init(struct xhci_softc *sc) usbd_errstr(err), (uintmax_t)DMAADDR(&sc->sc_eventst_dma, 0), KERNADDR(&sc->sc_eventst_dma, 0), - sc->sc_eventst_dma.block->size); + sc->sc_eventst_dma.udma_block->size); dma = &sc->sc_dcbaa_dma; size = (1 + sc->sc_maxslots) * sizeof(uint64_t); @@ -836,12 +915,22 @@ xhci_init(struct xhci_softc *sc) usbd_errstr(err), (uintmax_t)DMAADDR(&sc->sc_dcbaa_dma, 0), KERNADDR(&sc->sc_dcbaa_dma, 0), - sc->sc_dcbaa_dma.block->size); + sc->sc_dcbaa_dma.udma_block->size); sc->sc_slots = kmem_zalloc(sizeof(*sc->sc_slots) * sc->sc_maxslots, KM_SLEEP); cv_init(&sc->sc_command_cv, "xhcicmd"); + mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); + mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB); + cv_init(&sc->sc_softwake_cv, "xhciab"); + + sc->sc_xferpool = pool_cache_init(sizeof(struct xhci_xfer), 0, 0, 0, + "xhcixfer", NULL, IPL_USB, NULL, NULL, NULL); + + /* Set up the bus struct. */ + sc->sc_bus.ub_methods = &xhci_bus_methods; + sc->sc_bus.ub_pipesize = sizeof(struct xhci_pipe); struct xhci_erste *erst; erst = KERNADDR(&sc->sc_eventst_dma, 0); @@ -865,23 +954,18 @@ xhci_init(struct xhci_softc *sc) #endif xhci_rt_write_4(sc, XHCI_IMAN(0), XHCI_IMAN_INTR_ENA); - xhci_rt_write_4(sc, XHCI_IMOD(0), 0); + if ((sc->sc_quirks & XHCI_QUIRK_INTEL) != 0) + /* Intel xhci needs interrupt rate moderated. */ + xhci_rt_write_4(sc, XHCI_IMOD(0), XHCI_IMOD_DEFAULT_LP); + else + xhci_rt_write_4(sc, XHCI_IMOD(0), 0); + aprint_debug_dev(sc->sc_dev, "setting IMOD %u\n", + xhci_rt_read_4(sc, XHCI_IMOD(0))); xhci_op_write_4(sc, XHCI_USBCMD, XHCI_CMD_INTE|XHCI_CMD_RS); /* Go! */ aprint_debug_dev(sc->sc_dev, "USBCMD %08"PRIx32"\n", xhci_op_read_4(sc, XHCI_USBCMD)); - mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); - mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB); - cv_init(&sc->sc_softwake_cv, "xhciab"); - - sc->sc_xferpool = pool_cache_init(sizeof(struct xhci_xfer), 0, 0, 0, - "xhcixfer", NULL, IPL_USB, NULL, NULL, NULL); - - /* Set up the bus struct. */ - sc->sc_bus.methods = &xhci_bus_methods; - sc->sc_bus.pipe_size = sizeof(struct xhci_pipe); - return USBD_NORMAL_COMPLETION; } @@ -902,7 +986,7 @@ xhci_intr(void *v) goto done; /* If we get an interrupt while polling, then just ignore it. */ - if (sc->sc_bus.use_polling) { + if (sc->sc_bus.ub_usepolling) { #ifdef DIAGNOSTIC DPRINTFN(16, "ignored interrupt while polling", 0, 0, 0, 0); #endif @@ -937,36 +1021,358 @@ xhci_intr1(struct xhci_softc * const sc) iman = xhci_rt_read_4(sc, XHCI_IMAN(0)); DPRINTFN(16, "IMAN0 %08x", iman, 0, 0, 0); - if ((iman & XHCI_IMAN_INTR_PEND) == 0) { - return 0; - } + iman |= XHCI_IMAN_INTR_PEND; xhci_rt_write_4(sc, XHCI_IMAN(0), iman); iman = xhci_rt_read_4(sc, XHCI_IMAN(0)); DPRINTFN(16, "IMAN0 %08x", iman, 0, 0, 0); usbsts = xhci_op_read_4(sc, XHCI_USBSTS); DPRINTFN(16, "USBSTS %08x", usbsts, 0, 0, 0); - sc->sc_bus.no_intrs++; usb_schedsoftintr(&sc->sc_bus); return 1; } -static usbd_status -xhci_configure_endpoint(usbd_pipe_handle pipe) +/* + * 3 port speed types used in USB stack + * + * usbdi speed + * definition: USB_SPEED_* in usb.h + * They are used in struct usbd_device in USB stack. + * ioctl interface uses these values too. + * port_status speed + * definition: UPS_*_SPEED in usb.h + * They are used in usb_port_status_t and valid only for USB 2.0. + * Speed value is always 0 for Super Speed or more, and dwExtPortStatus + * of usb_port_status_ext_t indicates port speed. + * Note that some 3.0 values overlap with 2.0 values. + * (e.g. 0x200 means UPS_POER_POWER_SS in SS and + * means UPS_LOW_SPEED in HS.) + * port status returned from hub also uses these values. + * On NetBSD UPS_OTHER_SPEED indicates port speed is super speed + * or more. + * xspeed: + * definition: Protocol Speed ID (PSI) (xHCI 1.1 7.2.1) + * They are used in only slot context and PORTSC reg of xhci. + * The difference between usbdi speed and xspeed is + * that FS and LS values are swapped. + */ + +/* convert usbdi speed to xspeed */ +static int +xhci_speed2xspeed(int speed) +{ + switch (speed) { + case USB_SPEED_LOW: return 2; + case USB_SPEED_FULL: return 1; + default: return speed; + } +} + +#if 0 +/* convert xspeed to usbdi speed */ +static int +xhci_xspeed2speed(int xspeed) +{ + switch (xspeed) { + case 1: return USB_SPEED_FULL; + case 2: return USB_SPEED_LOW; + default: return xspeed; + } +} +#endif + +/* convert xspeed to port status speed */ +static int +xhci_xspeed2psspeed(int xspeed) +{ + switch (xspeed) { + case 0: return 0; + case 1: return UPS_FULL_SPEED; + case 2: return UPS_LOW_SPEED; + case 3: return UPS_HIGH_SPEED; + default: return UPS_OTHER_SPEED; + } +} + +/* construct slot context */ +static void +xhci_setup_sctx(struct usbd_device *dev, uint32_t *cp) +{ + usb_device_descriptor_t * const dd = &dev->ud_ddesc; + int speed = dev->ud_speed; + int tthubslot, ttportnum; + bool ishub; + bool usemtt; + + XHCIHIST_FUNC(); XHCIHIST_CALLED(); + + /* + * 6.2.2, Table 57-60, 6.2.2.1, 6.2.2.2 + * tthubslot: + * This is the slot ID of parent HS hub + * if LS/FS device is connected && connected through HS hub. + * This is 0 if device is not LS/FS device || + * parent hub is not HS hub || + * attached to root hub. + * ttportnum: + * This is the downstream facing port of parent HS hub + * if LS/FS device is connected. + * This is 0 if device is not LS/FS device || + * parent hub is not HS hub || + * attached to root hub. + */ + if (dev->ud_myhsport != NULL && + dev->ud_myhub != NULL && dev->ud_myhub->ud_depth != 0 && + (dev->ud_myhub != NULL && + dev->ud_myhub->ud_speed == USB_SPEED_HIGH) && + (speed == USB_SPEED_LOW || speed == USB_SPEED_FULL)) { + ttportnum = dev->ud_myhsport->up_portno; + tthubslot = dev->ud_myhsport->up_parent->ud_addr; + } else { + ttportnum = 0; + tthubslot = 0; + } + DPRINTFN(4, "myhsport %p ttportnum=%d tthubslot=%d", + dev->ud_myhsport, ttportnum, tthubslot, 0); + + /* ishub is valid after reading UDESC_DEVICE */ + ishub = (dd->bDeviceClass == UDCLASS_HUB); + + /* dev->ud_hub is valid after reading UDESC_HUB */ + if (ishub && dev->ud_hub) { + usb_hub_descriptor_t *hd = &dev->ud_hub->uh_hubdesc; + + cp[1] |= htole32(XHCI_SCTX_1_NUM_PORTS_SET(hd->bNbrPorts)); + cp[2] |= htole32(XHCI_SCTX_2_TT_THINK_TIME_SET( + __SHIFTOUT(UGETW(hd->wHubCharacteristics), UHD_TT_THINK))); + DPRINTFN(4, "nports=%d ttt=%d", + hd->bNbrPorts, XHCI_SCTX_2_TT_THINK_TIME_GET(cp[2]), 0, 0); + } + +#define IS_TTHUB(dd) \ + ((dd)->bDeviceProtocol == UDPROTO_HSHUBSTT || \ + (dd)->bDeviceProtocol == UDPROTO_HSHUBMTT) + + /* + * MTT flag is set if + * 1. this is HS hub && MTT is enabled + * or + * 2. this is not hub && this is LS or FS device && + * MTT of parent HS hub (and its parent, too) is enabled + */ + if (ishub && speed == USB_SPEED_HIGH && IS_TTHUB(dd)) + usemtt = true; + else if (!ishub && + (speed == USB_SPEED_LOW || speed == USB_SPEED_FULL) && + dev->ud_myhub != NULL && dev->ud_myhub->ud_depth != 0 && + (dev->ud_myhub != NULL && + dev->ud_myhub->ud_speed == USB_SPEED_HIGH) && + dev->ud_myhsport != NULL && + IS_TTHUB(&dev->ud_myhsport->up_parent->ud_ddesc)) + usemtt = true; + else + usemtt = false; + DPRINTFN(4, "class %u proto %u ishub %d usemtt %d", + dd->bDeviceClass, dd->bDeviceProtocol, ishub, usemtt); + + cp[0] |= htole32( + XHCI_SCTX_0_SPEED_SET(xhci_speed2xspeed(speed)) | + XHCI_SCTX_0_HUB_SET(ishub ? 1 : 0) | + XHCI_SCTX_0_MTT_SET(usemtt ? 1 : 0) + ); + cp[1] |= htole32(0); + cp[2] |= htole32( + XHCI_SCTX_2_IRQ_TARGET_SET(0) | + XHCI_SCTX_2_TT_HUB_SID_SET(tthubslot) | + XHCI_SCTX_2_TT_PORT_NUM_SET(ttportnum) + ); + cp[3] |= htole32(0); +} + +static uint32_t +xhci_get_maxburst(struct usbd_pipe *pipe) +{ + usb_endpoint_descriptor_t * const ed = pipe->up_endpoint->ue_edesc; + usbd_desc_iter_t iter; + const usb_cdc_descriptor_t *cdcd; + const usb_endpoint_ss_comp_descriptor_t * esscd = NULL; + uint32_t maxb = 0; + uint8_t ep; + + cdcd = (const usb_cdc_descriptor_t *)usb_find_desc( + pipe->up_dev, UDESC_INTERFACE, USBD_CDCSUBTYPE_ANY); + usb_desc_iter_init(pipe->up_dev, &iter); + iter.cur = (const void *)cdcd; + + /* find endpoint_ss_comp desc for ep of this pipe */ + for (ep = 0;;) { + cdcd = (const usb_cdc_descriptor_t *)usb_desc_iter_next(&iter); + if (cdcd == NULL) + break; + if (ep == 0 && cdcd->bDescriptorType == UDESC_ENDPOINT) { + ep = ((const usb_endpoint_descriptor_t *)cdcd)-> + bEndpointAddress; + if (UE_GET_ADDR(ep) == + UE_GET_ADDR(ed->bEndpointAddress)) { + cdcd = (const usb_cdc_descriptor_t *) + usb_desc_iter_next(&iter); + break; + } + ep = 0; + } + } + if (cdcd != NULL && cdcd->bDescriptorType == UDESC_ENDPOINT_SS_COMP) { + esscd = (const usb_endpoint_ss_comp_descriptor_t *)cdcd; + maxb = esscd->bMaxBurst; + } + + return maxb; +} + +/* + * Convert endpoint bInterval value to endpoint context interval value + * for Interrupt pipe. + * xHCI 6.2.3.6 Table 65, USB 2.0 9.6.6 + */ +static uint32_t +xhci_bival2ival(uint32_t ival, int speed) { - struct xhci_softc * const sc = pipe->device->bus->hci_private; - struct xhci_slot * const xs = pipe->device->hci_private; - const u_int dci = xhci_ep_get_dci(pipe->endpoint->edesc); - usb_endpoint_descriptor_t * const ed = pipe->endpoint->edesc; + if (speed == USB_SPEED_LOW || speed == USB_SPEED_FULL) { + int i; + + /* + * round ival down to "the nearest base 2 multiple of + * bInterval * 8". + * bInterval is at most 255 as its type is uByte. + * 255(ms) = 2040(x 125us) < 2^11, so start with 10. + */ + for (i = 10; i > 0; i--) { + if ((ival * 8) >= (1 << i)) + break; + } + ival = i; + } else { + /* Interval = bInterval-1 for SS/HS */ + ival--; + } + + return ival; +} + +/* + * 4.8.2, 6.2.3.2 + * construct common endpoint parameters + */ +static void +xhci_setup_endp_ctx(struct usbd_pipe *pipe, uint32_t *cp) +{ + struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; + usb_endpoint_descriptor_t * const ed = pipe->up_endpoint->ue_edesc; + const u_int dci = xhci_ep_get_dci(ed); const uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes); + uint32_t mps = UGETW(ed->wMaxPacketSize); + uint32_t maxb = 0; + int speed = pipe->up_dev->ud_speed; + uint32_t ival = ed->bInterval; + + cp[0] = htole32( + XHCI_EPCTX_0_EPSTATE_SET(0) | + XHCI_EPCTX_0_MULT_SET(0) | /* always 0 except SS iscoh */ + XHCI_EPCTX_0_MAXP_STREAMS_SET(0) | + XHCI_EPCTX_0_LSA_SET(0) | + XHCI_EPCTX_0_MAX_ESIT_PAYLOAD_HI_SET(0) + ); + cp[1] = htole32( + XHCI_EPCTX_1_EPTYPE_SET(xhci_ep_get_type(ed)) | + XHCI_EPCTX_1_HID_SET(0) | + XHCI_EPCTX_1_MAXB_SET(0) + ); + if (xfertype != UE_ISOCHRONOUS) + cp[1] |= htole32(XHCI_EPCTX_1_CERR_SET(3)); + + /* 6.2.3.4, 4.8.2.4 */ + if (USB_IS_SS(speed)) { + /* UBS 3.1 9.6.6 */ + cp[1] |= htole32(XHCI_EPCTX_1_MAXP_SIZE_SET(mps)); + /* UBS 3.1 9.6.7 */ + maxb = xhci_get_maxburst(pipe); + cp[1] |= htole32(XHCI_EPCTX_1_MAXB_SET(maxb)); + } else { + /* UBS 2.0 9.6.6 */ + cp[1] |= htole32(XHCI_EPCTX_1_MAXP_SIZE_SET(UE_GET_SIZE(mps))); + + /* 6.2.3.4 */ + if (speed == USB_SPEED_HIGH && + (xfertype == UE_ISOCHRONOUS || xfertype == UE_INTERRUPT)) { + maxb = UE_GET_TRANS(mps); + } else { + /* LS/FS or HS CTRL or HS BULK */ + maxb = 0; + } + cp[1] |= htole32(XHCI_EPCTX_1_MAXB_SET(maxb)); + } + + if (xfertype == UE_CONTROL) + cp[4] = htole32(XHCI_EPCTX_4_AVG_TRB_LEN_SET(8)); /* 6.2.3 */ + else if (USB_IS_SS(speed)) + cp[4] = htole32(XHCI_EPCTX_4_AVG_TRB_LEN_SET(mps)); + else + cp[4] = htole32(XHCI_EPCTX_4_AVG_TRB_LEN_SET(UE_GET_SIZE(mps))); + + switch (xfertype) { + case UE_CONTROL: + break; + case UE_BULK: + /* XXX Set MaxPStreams, HID, and LSA if streams enabled */ + break; + case UE_INTERRUPT: + if (pipe->up_interval != USBD_DEFAULT_INTERVAL) + ival = pipe->up_interval; + + ival = xhci_bival2ival(ival, speed); + cp[0] |= htole32(XHCI_EPCTX_0_IVAL_SET(ival)); + break; + case UE_ISOCHRONOUS: + if (pipe->up_interval != USBD_DEFAULT_INTERVAL) + ival = pipe->up_interval; + + /* xHCI 6.2.3.6 Table 65, USB 2.0 9.6.6 */ + if (speed == USB_SPEED_FULL) + ival += 3; /* 1ms -> 125us */ + ival--; + cp[0] |= htole32(XHCI_EPCTX_0_IVAL_SET(ival)); + + if (USB_IS_SS(speed)) { + /* XXX if LEC = 1, set ESIT instead */ + cp[0] |= htole32(XHCI_EPCTX_0_MULT_SET(0)); + } + break; + default: + break; + } + *(uint64_t *)(&cp[2]) = htole64( + xhci_ring_trbp(&xs->xs_ep[dci].xe_tr, 0) | + XHCI_EPCTX_2_DCS_SET(1)); +} + +/* + * Construct input contexts and issue TRB + */ +static usbd_status +xhci_configure_endpoint(struct usbd_pipe *pipe) +{ + struct xhci_softc * const sc = XHCI_PIPE2SC(pipe); + struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; + const u_int dci = xhci_ep_get_dci(pipe->up_endpoint->ue_edesc); struct xhci_trb trb; usbd_status err; uint32_t *cp; XHCIHIST_FUNC(); XHCIHIST_CALLED(); - DPRINTFN(4, "dci %u epaddr 0x%02x attr 0x%02x", - dci, ed->bEndpointAddress, ed->bmAttributes, 0); + DPRINTFN(4, "slot %u dci %u epaddr 0x%02x attr 0x%02x", + xs->xs_idx, dci, pipe->up_endpoint->ue_edesc->bEndpointAddress, + pipe->up_endpoint->ue_edesc->bmAttributes); /* XXX ensure input context is available? */ @@ -978,38 +1384,12 @@ xhci_configure_endpoint(usbd_pipe_handle pipe) /* set up input slot context */ cp = xhci_slot_get_icv(sc, xs, xhci_dci_to_ici(XHCI_DCI_SLOT)); - cp[0] = htole32(XHCI_SCTX_0_CTX_NUM_SET(dci)); - cp[1] = htole32(0); - cp[2] = htole32(0); - cp[3] = htole32(0); + xhci_setup_sctx(pipe->up_dev, cp); + cp[0] |= htole32(XHCI_SCTX_0_CTX_NUM_SET(dci)); + /* set up input endpoint context */ cp = xhci_slot_get_icv(sc, xs, xhci_dci_to_ici(dci)); - uint8_t eptype = xhci_ep_get_type(pipe->endpoint->edesc); - if (xfertype == UE_INTERRUPT) { - cp[0] = htole32( - XHCI_EPCTX_0_IVAL_SET(3) /* XXX */ - ); - cp[1] = htole32( - XHCI_EPCTX_1_CERR_SET(3) | - XHCI_EPCTX_1_EPTYPE_SET(eptype) | - XHCI_EPCTX_1_MAXB_SET(0) | - XHCI_EPCTX_1_MAXP_SIZE_SET(8) /* XXX */ - ); - cp[4] = htole32( - XHCI_EPCTX_4_AVG_TRB_LEN_SET(8) - ); - } else { - cp[0] = htole32(0); - cp[1] = htole32( - XHCI_EPCTX_1_CERR_SET(3) | - XHCI_EPCTX_1_EPTYPE_SET(eptype) | - XHCI_EPCTX_1_MAXB_SET(0) | - XHCI_EPCTX_1_MAXP_SIZE_SET(512) /* XXX */ - ); - } - *(uint64_t *)(&cp[2]) = htole64( - xhci_ring_trbp(&xs->xs_ep[dci].xe_tr, 0) | - XHCI_EPCTX_2_DCS_SET(1)); + xhci_setup_endp_ctx(pipe, cp); /* sync input contexts before they are read from memory */ usb_syncmem(&xs->xs_ic_dma, 0, sc->sc_pgsz, BUS_DMASYNC_PREWRITE); @@ -1032,11 +1412,12 @@ xhci_configure_endpoint(usbd_pipe_handle pipe) return err; } +#if 0 static usbd_status -xhci_unconfigure_endpoint(usbd_pipe_handle pipe) +xhci_unconfigure_endpoint(struct usbd_pipe *pipe) { #ifdef USB_DEBUG - struct xhci_slot * const xs = pipe->device->hci_private; + struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; #endif XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -1044,18 +1425,22 @@ xhci_unconfigure_endpoint(usbd_pipe_handle pipe) return USBD_NORMAL_COMPLETION; } +#endif +/* 4.6.8, 6.4.3.7 */ static usbd_status -xhci_reset_endpoint(usbd_pipe_handle pipe) +xhci_reset_endpoint(struct usbd_pipe *pipe) { - struct xhci_softc * const sc = pipe->device->bus->hci_private; - struct xhci_slot * const xs = pipe->device->hci_private; - const u_int dci = xhci_ep_get_dci(pipe->endpoint->edesc); + struct xhci_softc * const sc = XHCI_PIPE2SC(pipe); + struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; + const u_int dci = xhci_ep_get_dci(pipe->up_endpoint->ue_edesc); struct xhci_trb trb; usbd_status err; XHCIHIST_FUNC(); XHCIHIST_CALLED(); - DPRINTFN(4, "dci %u", dci, 0, 0, 0); + DPRINTFN(4, "slot %u dci %u", xs->xs_idx, dci, 0, 0); + + KASSERT(!mutex_owned(&sc->sc_lock)); trb.trb_0 = 0; trb.trb_2 = 0; @@ -1068,18 +1453,24 @@ xhci_reset_endpoint(usbd_pipe_handle pipe) return err; } -#if 0 +/* + * 4.6.9, 6.4.3.8 + * Stop execution of TDs on xfer ring. + * Should be called with sc_lock held. + */ static usbd_status -xhci_stop_endpoint(usbd_pipe_handle pipe) +xhci_stop_endpoint(struct usbd_pipe *pipe) { - struct xhci_softc * const sc = pipe->device->bus->hci_private; - struct xhci_slot * const xs = pipe->device->hci_private; + struct xhci_softc * const sc = XHCI_PIPE2SC(pipe); + struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; struct xhci_trb trb; usbd_status err; - const u_int dci = xhci_ep_get_dci(pipe->endpoint->edesc); + const u_int dci = xhci_ep_get_dci(pipe->up_endpoint->ue_edesc); XHCIHIST_FUNC(); XHCIHIST_CALLED(); - DPRINTFN(4, "dci %u", dci, 0, 0, 0); + DPRINTFN(4, "slot %u dci %u", xs->xs_idx, dci, 0, 0); + + KASSERT(mutex_owned(&sc->sc_lock)); trb.trb_0 = 0; trb.trb_2 = 0; @@ -1087,18 +1478,23 @@ xhci_stop_endpoint(usbd_pipe_handle pipe) XHCI_TRB_3_EP_SET(dci) | XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_STOP_EP); - err = xhci_do_command(sc, &trb, USBD_DEFAULT_TIMEOUT); + err = xhci_do_command_locked(sc, &trb, USBD_DEFAULT_TIMEOUT); return err; } -#endif +/* + * Set TR Dequeue Pointer. + * xCHI 1.1 4.6.10 6.4.3.9 + * Purge all of the transfer requests on ring. + * EPSTATE of endpoint must be ERROR or STOPPED, or CONTEXT_STATE error. + */ static usbd_status -xhci_set_dequeue(usbd_pipe_handle pipe) +xhci_set_dequeue(struct usbd_pipe *pipe) { - struct xhci_softc * const sc = pipe->device->bus->hci_private; - struct xhci_slot * const xs = pipe->device->hci_private; - const u_int dci = xhci_ep_get_dci(pipe->endpoint->edesc); + struct xhci_softc * const sc = XHCI_PIPE2SC(pipe); + struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; + const u_int dci = xhci_ep_get_dci(pipe->up_endpoint->ue_edesc); struct xhci_ring * const xr = &xs->xs_ep[dci].xe_tr; struct xhci_trb trb; usbd_status err; @@ -1109,10 +1505,12 @@ xhci_set_dequeue(usbd_pipe_handle pipe) memset(xr->xr_trb, 0, xr->xr_ntrb * XHCI_TRB_SIZE); usb_syncmem(&xr->xr_dma, 0, xr->xr_ntrb * XHCI_TRB_SIZE, BUS_DMASYNC_PREWRITE); + memset(xr->xr_cookies, 0, xr->xr_ntrb * sizeof(*xr->xr_cookies)); xr->xr_ep = 0; xr->xr_cs = 1; + /* set DCS */ trb.trb_0 = xhci_ring_trbp(xr, 0) | 1; /* XXX */ trb.trb_2 = 0; trb.trb_3 = XHCI_TRB_3_SLOT_SET(xs->xs_idx) | @@ -1124,33 +1522,38 @@ xhci_set_dequeue(usbd_pipe_handle pipe) return err; } +/* + * Open new pipe: called from usbd_setup_pipe_flags. + * Fills methods of pipe. + * If pipe is not for ep0, calls configure_endpoint. + */ static usbd_status -xhci_open(usbd_pipe_handle pipe) +xhci_open(struct usbd_pipe *pipe) { - usbd_device_handle const dev = pipe->device; - struct xhci_softc * const sc = dev->bus->hci_private; - usb_endpoint_descriptor_t * const ed = pipe->endpoint->edesc; + struct usbd_device * const dev = pipe->up_dev; + struct xhci_softc * const sc = XHCI_BUS2SC(dev->ud_bus); + usb_endpoint_descriptor_t * const ed = pipe->up_endpoint->ue_edesc; const uint8_t xfertype = UE_GET_XFERTYPE(ed->bmAttributes); XHCIHIST_FUNC(); XHCIHIST_CALLED(); DPRINTFN(1, "addr %d depth %d port %d speed %d", - dev->address, dev->depth, dev->powersrc->portno, dev->speed); + dev->ud_addr, dev->ud_depth, dev->ud_powersrc->up_portno, + dev->ud_speed); if (sc->sc_dying) return USBD_IOERROR; /* Root Hub */ - if (dev->depth == 0 && dev->powersrc->portno == 0 && - dev->speed != USB_SPEED_SUPER) { + if (dev->ud_depth == 0 && dev->ud_powersrc->up_portno == 0) { switch (ed->bEndpointAddress) { case USB_CONTROL_ENDPOINT: - pipe->methods = &xhci_root_ctrl_methods; + pipe->up_methods = &roothub_ctrl_methods; break; - case UE_DIR_IN | XHCI_INTR_ENDPT: - pipe->methods = &xhci_root_intr_methods; + case UE_DIR_IN | USBROOTHUB_INTR_ENDPT: + pipe->up_methods = &xhci_root_intr_methods; break; default: - pipe->methods = NULL; + pipe->up_methods = NULL; DPRINTFN(0, "bad bEndpointAddress 0x%02x", ed->bEndpointAddress, 0, 0, 0); return USBD_INVAL; @@ -1160,17 +1563,17 @@ xhci_open(usbd_pipe_handle pipe) switch (xfertype) { case UE_CONTROL: - pipe->methods = &xhci_device_ctrl_methods; + pipe->up_methods = &xhci_device_ctrl_methods; break; case UE_ISOCHRONOUS: - pipe->methods = &xhci_device_isoc_methods; + pipe->up_methods = &xhci_device_isoc_methods; return USBD_INVAL; break; case UE_BULK: - pipe->methods = &xhci_device_bulk_methods; + pipe->up_methods = &xhci_device_bulk_methods; break; case UE_INTERRUPT: - pipe->methods = &xhci_device_intr_methods; + pipe->up_methods = &xhci_device_intr_methods; break; default: return USBD_IOERROR; @@ -1178,137 +1581,403 @@ xhci_open(usbd_pipe_handle pipe) } if (ed->bEndpointAddress != USB_CONTROL_ENDPOINT) - xhci_configure_endpoint(pipe); + return xhci_configure_endpoint(pipe); + + return USBD_NORMAL_COMPLETION; +} + +/* + * Closes pipe, called from usbd_kill_pipe via close methods. + * If the endpoint to be closed is ep0, disable_slot. + * Should be called with sc_lock held. + */ +static void +xhci_close_pipe(struct usbd_pipe *pipe) +{ + struct xhci_softc * const sc = XHCI_PIPE2SC(pipe); + struct xhci_slot * const xs = pipe->up_dev->ud_hcpriv; + usb_endpoint_descriptor_t * const ed = pipe->up_endpoint->ue_edesc; + const u_int dci = xhci_ep_get_dci(ed); + struct xhci_trb trb; + uint32_t *cp; + + XHCIHIST_FUNC(); XHCIHIST_CALLED(); + + if (sc->sc_dying) + return; + + if (xs == NULL || xs->xs_idx == 0) + /* xs is uninitialized before xhci_init_slot */ + return; + + DPRINTFN(4, "pipe %p slot %u dci %u", pipe, xs->xs_idx, dci, 0); + + KASSERTMSG(!cpu_intr_p() && !cpu_softintr_p(), "called from intr ctx"); + KASSERT(mutex_owned(&sc->sc_lock)); + + if (pipe->up_dev->ud_depth == 0) + return; + + if (dci == XHCI_DCI_EP_CONTROL) { + DPRINTFN(4, "closing ep0", 0, 0, 0, 0); + xhci_disable_slot(sc, xs->xs_idx); + return; + } + + /* + * This may fail in the case that xhci_close_pipe is called after + * xhci_abort_xfer e.g. usbd_kill_pipe. + */ + (void)xhci_stop_endpoint(pipe); + + /* + * set appropriate bit to be dropped. + * don't set DC bit to 1, otherwise all endpoints + * would be deconfigured. + */ + cp = xhci_slot_get_icv(sc, xs, XHCI_ICI_INPUT_CONTROL); + cp[0] = htole32(XHCI_INCTX_0_DROP_MASK(dci)); + cp[1] = htole32(0); + + /* XXX should be most significant one, not dci? */ + cp = xhci_slot_get_icv(sc, xs, xhci_dci_to_ici(XHCI_DCI_SLOT)); + cp[0] = htole32(XHCI_SCTX_0_CTX_NUM_SET(dci)); + + /* sync input contexts before they are read from memory */ + usb_syncmem(&xs->xs_ic_dma, 0, sc->sc_pgsz, BUS_DMASYNC_PREWRITE); + + trb.trb_0 = xhci_slot_get_icp(sc, xs, 0); + trb.trb_2 = 0; + trb.trb_3 = XHCI_TRB_3_SLOT_SET(xs->xs_idx) | + XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_CONFIGURE_EP); + + (void)xhci_do_command_locked(sc, &trb, USBD_DEFAULT_TIMEOUT); + usb_syncmem(&xs->xs_dc_dma, 0, sc->sc_pgsz, BUS_DMASYNC_POSTREAD); +} + +/* + * Abort transfer. + * Called with sc_lock held. + * May be called from softintr context. + */ +static void +xhci_abort_xfer(struct usbd_xfer *xfer, usbd_status status) +{ + struct xhci_softc * const sc = XHCI_XFER2SC(xfer); + + XHCIHIST_FUNC(); XHCIHIST_CALLED(); + DPRINTFN(4, "xfer %p pipe %p status %d", + xfer, xfer->ux_pipe, status, 0); + + KASSERT(mutex_owned(&sc->sc_lock)); + + if (sc->sc_dying) { + /* If we're dying, just do the software part. */ + DPRINTFN(4, "dying", 0, 0, 0, 0); + xfer->ux_status = status; /* make software ignore it */ + callout_stop(&xfer->ux_callout); + usb_transfer_complete(xfer); + return; + } + + /* XXX need more stuff */ + xfer->ux_status = status; + callout_stop(&xfer->ux_callout); + usb_transfer_complete(xfer); + DPRINTFN(14, "end", 0, 0, 0, 0); + + KASSERT(mutex_owned(&sc->sc_lock)); +} + +/* + * Recover STALLed endpoint. + * xHCI 1.1 sect 4.10.2.1 + * Issue RESET_EP to recover halt condition and SET_TR_DEQUEUE to remove + * all transfers on transfer ring. + * These are done in thread context asynchronously. + */ +static void +xhci_clear_endpoint_stall_async_task(void *cookie) +{ + struct usbd_xfer * const xfer = cookie; + struct xhci_softc * const sc = XHCI_XFER2SC(xfer); + struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv; + const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc); + struct xhci_ring * const tr = &xs->xs_ep[dci].xe_tr; + + XHCIHIST_FUNC(); XHCIHIST_CALLED(); + DPRINTFN(4, "xfer %p slot %u dci %u", xfer, xs->xs_idx, dci, 0); + + xhci_reset_endpoint(xfer->ux_pipe); + xhci_set_dequeue(xfer->ux_pipe); + + mutex_enter(&sc->sc_lock); + tr->is_halted = false; + usb_transfer_complete(xfer); + mutex_exit(&sc->sc_lock); + DPRINTFN(4, "ends", 0, 0, 0, 0); +} + +static usbd_status +xhci_clear_endpoint_stall_async(struct usbd_xfer *xfer) +{ + struct xhci_softc * const sc = XHCI_XFER2SC(xfer); + struct xhci_pipe * const xp = (struct xhci_pipe *)xfer->ux_pipe; + + XHCIHIST_FUNC(); XHCIHIST_CALLED(); + DPRINTFN(4, "xfer %p", xfer, 0, 0, 0); + + if (sc->sc_dying) { + return USBD_IOERROR; + } + + usb_init_task(&xp->xp_async_task, + xhci_clear_endpoint_stall_async_task, xfer, USB_TASKQ_MPSAFE); + usb_add_task(xfer->ux_pipe->up_dev, &xp->xp_async_task, USB_TASKQ_HC); + DPRINTFN(4, "ends", 0, 0, 0, 0); return USBD_NORMAL_COMPLETION; } +/* Process roothub port status/change events and notify to uhub_intr. */ static void xhci_rhpsc(struct xhci_softc * const sc, u_int port) { - usbd_xfer_handle const xfer = sc->sc_intrxfer; + struct usbd_xfer * const xfer = sc->sc_intrxfer; uint8_t *p; XHCIHIST_FUNC(); XHCIHIST_CALLED(); - DPRINTFN(4, "port %u status change", port, 0, 0, 0); + DPRINTFN(4, "xhci%d: port %u status change", device_unit(sc->sc_dev), + port, 0, 0); if (xfer == NULL) return; - if (!(port >= sc->sc_hs_port_start && - port < sc->sc_hs_port_start + sc->sc_hs_port_count)) + if (port > sc->sc_maxports) return; - port -= sc->sc_hs_port_start; - port += 1; - DPRINTFN(4, "hs port %u status change", port, 0, 0, 0); - - p = KERNADDR(&xfer->dmabuf, 0); - memset(p, 0, xfer->length); + p = xfer->ux_buf; + memset(p, 0, xfer->ux_length); p[port/NBBY] |= 1 << (port%NBBY); - xfer->actlen = xfer->length; - xfer->status = USBD_NORMAL_COMPLETION; + xfer->ux_actlen = xfer->ux_length; + xfer->ux_status = USBD_NORMAL_COMPLETION; usb_transfer_complete(xfer); } +/* Process Transfer Events */ static void -xhci_handle_event(struct xhci_softc * const sc, +xhci_event_transfer(struct xhci_softc * const sc, const struct xhci_trb * const trb) { uint64_t trb_0; uint32_t trb_2, trb_3; + uint8_t trbcode; + u_int slot, dci; + struct xhci_slot *xs; + struct xhci_ring *xr; + struct xhci_xfer *xx; + struct usbd_xfer *xfer; + usbd_status err; XHCIHIST_FUNC(); XHCIHIST_CALLED(); trb_0 = le64toh(trb->trb_0); trb_2 = le32toh(trb->trb_2); trb_3 = le32toh(trb->trb_3); + trbcode = XHCI_TRB_2_ERROR_GET(trb_2); + slot = XHCI_TRB_3_SLOT_GET(trb_3); + dci = XHCI_TRB_3_EP_GET(trb_3); + xs = &sc->sc_slots[slot]; + xr = &xs->xs_ep[dci].xe_tr; - DPRINTFN(14, "event: %p 0x%016"PRIx64" 0x%08"PRIx32" 0x%08"PRIx32, - trb, trb_0, trb_2, trb_3); + /* sanity check */ + KASSERTMSG(xs->xs_idx != 0 && xs->xs_idx <= sc->sc_maxslots, + "invalid xs_idx %u slot %u", xs->xs_idx, slot); - switch (XHCI_TRB_3_TYPE_GET(trb_3)){ - case XHCI_TRB_EVENT_TRANSFER: { - u_int slot, dci; - struct xhci_slot *xs; - struct xhci_ring *xr; - struct xhci_xfer *xx; - usbd_xfer_handle xfer; - usbd_status err; + if ((trb_3 & XHCI_TRB_3_ED_BIT) == 0) { + /* + * When ED == 0, trb_0 is physical address of the TRB + * that caused this event. (6.4.2.1) + */ + bus_addr_t trbp = xhci_ring_trbp(xr, 0); + + /* trb_0 range sanity check */ + if (trb_0 < trbp || + (trb_0 - trbp) % sizeof(struct xhci_trb) != 0 || + (trb_0 - trbp) / sizeof(struct xhci_trb) >= xr->xr_ntrb) { + DPRINTFN(1, "invalid trb_0 0x%"PRIx64" trbp 0x%"PRIx64, + trb_0, trbp, 0, 0); + return; + } + int idx = (trb_0 - trbp) / sizeof(struct xhci_trb); + xx = xr->xr_cookies[idx]; - slot = XHCI_TRB_3_SLOT_GET(trb_3); - dci = XHCI_TRB_3_EP_GET(trb_3); + /* + * If endpoint is stopped between TDs, TRB pointer points at + * next TRB, however, it is not put yet or is a garbage TRB. + * That's why xr_cookies may be NULL or look like broken. + * Note: this ev happens only when hciversion >= 1.0 or + * hciversion == 0.96 and FSE of hcc1 is set. + */ + if (xx == NULL || trbcode == XHCI_TRB_ERROR_LENGTH) { + DPRINTFN(1, "xx NULL: #%u: cookie %p: code %u trb_0 %" + PRIx64, idx, xx, trbcode, trb_0); + } + } else { + /* When ED != 0, trb_0 is kaddr of struct xhci_xfer. */ + xx = (void *)(uintptr_t)(trb_0 & ~0x3); + } + /* XXX this may not happen */ + if (xx == NULL) { + DPRINTFN(1, "xfer done: xx is NULL", 0, 0, 0, 0); + return; + } + xfer = &xx->xx_xfer; + /* XXX this may happen when detaching */ + if (xfer == NULL) { + DPRINTFN(1, "xx(%p)->xx_xfer is NULL trb_0 %#"PRIx64, + xx, trb_0, 0, 0); + return; + } + DPRINTFN(14, "xfer %p", xfer, 0, 0, 0); + /* XXX I dunno why this happens */ + KASSERTMSG(xfer->ux_pipe != NULL, "xfer(%p)->ux_pipe is NULL", xfer); - xs = &sc->sc_slots[slot]; - xr = &xs->xs_ep[dci].xe_tr; + if (!xfer->ux_pipe->up_repeat && + SIMPLEQ_EMPTY(&xfer->ux_pipe->up_queue)) { + DPRINTFN(1, "xfer(%p)->pipe not queued", xfer, 0, 0, 0); + return; + } - if ((trb_3 & XHCI_TRB_3_ED_BIT) == 0) { - xx = xr->xr_cookies[(trb_0 - xhci_ring_trbp(xr, 0))/ - sizeof(struct xhci_trb)]; - } else { - xx = (void *)(uintptr_t)(trb_0 & ~0x3); + /* 4.11.5.2 Event Data TRB */ + if ((trb_3 & XHCI_TRB_3_ED_BIT) != 0) { + DPRINTFN(14, "transfer Event Data: 0x%016"PRIx64" 0x%08"PRIx32 + " %02x", trb_0, XHCI_TRB_2_REM_GET(trb_2), trbcode, 0); + if ((trb_0 & 0x3) == 0x3) { + xfer->ux_actlen = XHCI_TRB_2_REM_GET(trb_2); } - xfer = &xx->xx_xfer; - DPRINTFN(14, "xfer %p", xfer, 0, 0, 0); - - if ((trb_3 & XHCI_TRB_3_ED_BIT) != 0) { - DPRINTFN(14, "transfer event data: " - "0x%016"PRIx64" 0x%08"PRIx32" %02x", - trb_0, XHCI_TRB_2_REM_GET(trb_2), - XHCI_TRB_2_ERROR_GET(trb_2), 0); - if ((trb_0 & 0x3) == 0x3) { - xfer->actlen = XHCI_TRB_2_REM_GET(trb_2); - } + } + + switch (trbcode) { + case XHCI_TRB_ERROR_SHORT_PKT: + case XHCI_TRB_ERROR_SUCCESS: + xfer->ux_actlen = + xfer->ux_length - XHCI_TRB_2_REM_GET(trb_2); + err = USBD_NORMAL_COMPLETION; + break; + case XHCI_TRB_ERROR_STALL: + case XHCI_TRB_ERROR_BABBLE: + DPRINTFN(1, "ERR %u slot %u dci %u", trbcode, slot, dci, 0); + xr->is_halted = true; + err = USBD_STALLED; + /* + * Stalled endpoints can be recoverd by issuing + * command TRB TYPE_RESET_EP on xHCI instead of + * issuing request CLEAR_FEATURE UF_ENDPOINT_HALT + * on the endpoint. However, this function may be + * called from softint context (e.g. from umass), + * in that case driver gets KASSERT in cv_timedwait + * in xhci_do_command. + * To avoid this, this runs reset_endpoint and + * usb_transfer_complete in usb task thread + * asynchronously (and then umass issues clear + * UF_ENDPOINT_HALT). + */ + xfer->ux_status = err; + xhci_clear_endpoint_stall_async(xfer); + return; + default: + DPRINTFN(1, "ERR %u slot %u dci %u", trbcode, slot, dci, 0); + err = USBD_IOERROR; + break; + } + xfer->ux_status = err; + + if ((trb_3 & XHCI_TRB_3_ED_BIT) != 0) { + if ((trb_0 & 0x3) == 0x0) { + callout_stop(&xfer->ux_callout); + usb_transfer_complete(xfer); } + } else { + callout_stop(&xfer->ux_callout); + usb_transfer_complete(xfer); + } +} + +/* Process Command complete events */ +static void +xhci_event_cmd(struct xhci_softc * const sc, + const struct xhci_trb * const trb) +{ + uint64_t trb_0; + uint32_t trb_2, trb_3; + + XHCIHIST_FUNC(); XHCIHIST_CALLED(); + + trb_0 = le64toh(trb->trb_0); + trb_2 = le32toh(trb->trb_2); + trb_3 = le32toh(trb->trb_3); - if (XHCI_TRB_2_ERROR_GET(trb_2) == + if (trb_0 == sc->sc_command_addr) { + sc->sc_result_trb.trb_0 = trb_0; + sc->sc_result_trb.trb_2 = trb_2; + sc->sc_result_trb.trb_3 = trb_3; + if (XHCI_TRB_2_ERROR_GET(trb_2) != XHCI_TRB_ERROR_SUCCESS) { - xfer->actlen = xfer->length - XHCI_TRB_2_REM_GET(trb_2); - err = USBD_NORMAL_COMPLETION; - } else if (XHCI_TRB_2_ERROR_GET(trb_2) == - XHCI_TRB_ERROR_SHORT_PKT) { - xfer->actlen = xfer->length - XHCI_TRB_2_REM_GET(trb_2); - err = USBD_NORMAL_COMPLETION; - } else if (XHCI_TRB_2_ERROR_GET(trb_2) == - XHCI_TRB_ERROR_STALL) { - err = USBD_STALLED; - xr->is_halted = true; - DPRINTFN(1, "ev: xfer done: err %u slot %u dci %u", - XHCI_TRB_2_ERROR_GET(trb_2), slot, dci, 0); - } else { - err = USBD_IOERROR; + DPRINTFN(1, "command completion " + "failure: 0x%016"PRIx64" 0x%08"PRIx32" " + "0x%08"PRIx32, trb_0, trb_2, trb_3, 0); } - xfer->status = err; + cv_signal(&sc->sc_command_cv); + } else { + DPRINTFN(1, "spurious event: %p 0x%016"PRIx64" " + "0x%08"PRIx32" 0x%08"PRIx32, trb, trb_0, + trb_2, trb_3); + } +} - //mutex_enter(&sc->sc_lock); /* XXX ??? */ - if ((trb_3 & XHCI_TRB_3_ED_BIT) != 0) { - if ((trb_0 & 0x3) == 0x0) { - usb_transfer_complete(xfer); - } - } else { - usb_transfer_complete(xfer); - } - //mutex_exit(&sc->sc_lock); /* XXX ??? */ +/* + * Process events. + * called from xhci_softintr + */ +static void +xhci_handle_event(struct xhci_softc * const sc, + const struct xhci_trb * const trb) +{ + uint64_t trb_0; + uint32_t trb_2, trb_3; + + XHCIHIST_FUNC(); XHCIHIST_CALLED(); + trb_0 = le64toh(trb->trb_0); + trb_2 = le32toh(trb->trb_2); + trb_3 = le32toh(trb->trb_3); + + DPRINTFN(14, "event: %p 0x%016"PRIx64" 0x%08"PRIx32" 0x%08"PRIx32, + trb, trb_0, trb_2, trb_3); + + /* + * 4.11.3.1, 6.4.2.1 + * TRB Pointer is invalid for these completion codes. + */ + switch (XHCI_TRB_2_ERROR_GET(trb_2)) { + case XHCI_TRB_ERROR_RING_UNDERRUN: + case XHCI_TRB_ERROR_RING_OVERRUN: + case XHCI_TRB_ERROR_VF_RING_FULL: + return; + default: + if (trb_0 == 0) { + return; } break; + } + + switch (XHCI_TRB_3_TYPE_GET(trb_3)) { + case XHCI_TRB_EVENT_TRANSFER: + xhci_event_transfer(sc, trb); + break; case XHCI_TRB_EVENT_CMD_COMPLETE: - if (trb_0 == sc->sc_command_addr) { - sc->sc_result_trb.trb_0 = trb_0; - sc->sc_result_trb.trb_2 = trb_2; - sc->sc_result_trb.trb_3 = trb_3; - if (XHCI_TRB_2_ERROR_GET(trb_2) != - XHCI_TRB_ERROR_SUCCESS) { - DPRINTFN(1, "command completion " - "failure: 0x%016"PRIx64" 0x%08"PRIx32" " - "0x%08"PRIx32, trb_0, trb_2, trb_3, 0); - } - cv_signal(&sc->sc_command_cv); - } else { - DPRINTFN(1, "event: %p 0x%016"PRIx64" " - "0x%08"PRIx32" 0x%08"PRIx32, trb, trb_0, - trb_2, trb_3); - } + xhci_event_cmd(sc, trb); break; case XHCI_TRB_EVENT_PORT_STS_CHANGE: xhci_rhpsc(sc, (uint32_t)((trb_0 >> 24) & 0xff)); @@ -1322,13 +1991,15 @@ static void xhci_softintr(void *v) { struct usbd_bus * const bus = v; - struct xhci_softc * const sc = bus->hci_private; + struct xhci_softc * const sc = XHCI_BUS2SC(bus); struct xhci_ring * const er = &sc->sc_er; struct xhci_trb *trb; int i, j, k; XHCIHIST_FUNC(); XHCIHIST_CALLED(); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); + i = er->xr_ep; j = er->xr_cs; @@ -1366,7 +2037,7 @@ xhci_softintr(void *v) static void xhci_poll(struct usbd_bus *bus) { - struct xhci_softc * const sc = bus->hci_private; + struct xhci_softc * const sc = XHCI_BUS2SC(bus); XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -1377,48 +2048,11 @@ xhci_poll(struct usbd_bus *bus) return; } -static usbd_status -xhci_allocm(struct usbd_bus *bus, usb_dma_t *dma, uint32_t size) -{ - struct xhci_softc * const sc = bus->hci_private; - usbd_status err; - - XHCIHIST_FUNC(); XHCIHIST_CALLED(); - - err = usb_allocmem(&sc->sc_bus, size, 0, dma); -#if 0 - if (err == USBD_NOMEM) - err = usb_reserve_allocm(&sc->sc_dma_reserve, dma, size); -#endif -#ifdef XHCI_DEBUG - if (err) - DPRINTFN(1, "usb_allocmem(%u)=%d", err, size, 0, 0); -#endif - - return err; -} - -static void -xhci_freem(struct usbd_bus *bus, usb_dma_t *dma) +static struct usbd_xfer * +xhci_allocx(struct usbd_bus *bus, unsigned int nframes) { - struct xhci_softc * const sc = bus->hci_private; - - XHCIHIST_FUNC(); XHCIHIST_CALLED(); - -#if 0 - if (dma->block->flags & USB_DMA_RESERVE) { - usb_reserve_freem(&sc->sc_dma_reserve, dma); - return; - } -#endif - usb_freemem(&sc->sc_bus, dma); -} - -static usbd_xfer_handle -xhci_allocx(struct usbd_bus *bus) -{ - struct xhci_softc * const sc = bus->hci_private; - usbd_xfer_handle xfer; + struct xhci_softc * const sc = XHCI_BUS2SC(bus); + struct usbd_xfer *xfer; XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -1426,7 +2060,7 @@ xhci_allocx(struct usbd_bus *bus) if (xfer != NULL) { memset(xfer, 0, sizeof(struct xhci_xfer)); #ifdef DIAGNOSTIC - xfer->busy_free = XFER_BUSY; + xfer->ux_state = XFER_BUSY; #endif } @@ -1434,18 +2068,18 @@ xhci_allocx(struct usbd_bus *bus) } static void -xhci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) +xhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) { - struct xhci_softc * const sc = bus->hci_private; + struct xhci_softc * const sc = XHCI_BUS2SC(bus); XHCIHIST_FUNC(); XHCIHIST_CALLED(); #ifdef DIAGNOSTIC - if (xfer->busy_free != XFER_BUSY) { + if (xfer->ux_state != XFER_BUSY) { DPRINTFN(0, "xfer=%p not busy, 0x%08x", - xfer, xfer->busy_free, 0, 0); + xfer, xfer->ux_state, 0, 0); } - xfer->busy_free = XFER_FREE; + xfer->ux_state = XFER_FREE; #endif pool_cache_put(sc->sc_xferpool, xfer); } @@ -1453,19 +2087,29 @@ xhci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer) static void xhci_get_lock(struct usbd_bus *bus, kmutex_t **lock) { - struct xhci_softc * const sc = bus->hci_private; + struct xhci_softc * const sc = XHCI_BUS2SC(bus); *lock = &sc->sc_lock; } -extern u_int32_t usb_cookie_no; +extern uint32_t usb_cookie_no; +/* + * Called if uhub_explore finds a new device (via usbd_new_device). + * Allocate and construct dev structure of default endpoint (ep0). + * Determine initial MaxPacketSize (mps) by speed. + * Determine route string and roothub port for slot of dev. + * Allocate pipe of ep0. + * Enable and initialize slot and Set Address. + * Read device descriptor. + * Register this device. + */ static usbd_status -xhci_new_device(device_t parent, usbd_bus_handle bus, int depth, +xhci_new_device(device_t parent, struct usbd_bus *bus, int depth, int speed, int port, struct usbd_port *up) { - struct xhci_softc * const sc = bus->hci_private; - usbd_device_handle dev; + struct xhci_softc * const sc = XHCI_BUS2SC(bus); + struct usbd_device *dev; usbd_status err; usb_device_descriptor_t *dd; struct usbd_device *hub; @@ -1473,104 +2117,148 @@ xhci_new_device(device_t parent, usbd_bus_handle bus, int depth, int rhport = 0; struct xhci_slot *xs; uint32_t *cp; - uint8_t slot; + uint32_t route = 0; + uint8_t slot = 0; uint8_t addr; XHCIHIST_FUNC(); XHCIHIST_CALLED(); DPRINTFN(4, "port=%d depth=%d speed=%d upport %d", - port, depth, speed, up->portno); + port, depth, speed, up->up_portno); - dev = malloc(sizeof *dev, M_USB, M_NOWAIT|M_ZERO); + dev = kmem_zalloc(sizeof(*dev), KM_SLEEP); if (dev == NULL) return USBD_NOMEM; - dev->bus = bus; + dev->ud_bus = bus; /* Set up default endpoint handle. */ - dev->def_ep.edesc = &dev->def_ep_desc; + dev->ud_ep0.ue_edesc = &dev->ud_ep0desc; /* Set up default endpoint descriptor. */ - dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE; - dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT; - dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT; - dev->def_ep_desc.bmAttributes = UE_CONTROL; - /* XXX */ - if (speed == USB_SPEED_LOW) - USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET); - else - USETW(dev->def_ep_desc.wMaxPacketSize, 64); - dev->def_ep_desc.bInterval = 0; + dev->ud_ep0desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE; + dev->ud_ep0desc.bDescriptorType = UDESC_ENDPOINT; + dev->ud_ep0desc.bEndpointAddress = USB_CONTROL_ENDPOINT; + dev->ud_ep0desc.bmAttributes = UE_CONTROL; + /* 4.3, 4.8.2.1 */ + switch (speed) { + case USB_SPEED_SUPER: + case USB_SPEED_SUPER_PLUS: + USETW(dev->ud_ep0desc.wMaxPacketSize, USB_3_MAX_CTRL_PACKET); + break; + case USB_SPEED_FULL: + /* XXX using 64 as initial mps of ep0 in FS */ + case USB_SPEED_HIGH: + USETW(dev->ud_ep0desc.wMaxPacketSize, USB_2_MAX_CTRL_PACKET); + break; + case USB_SPEED_LOW: + default: + USETW(dev->ud_ep0desc.wMaxPacketSize, USB_MAX_IPACKET); + break; + } + dev->ud_ep0desc.bInterval = 0; /* doesn't matter, just don't let it uninitialized */ - dev->def_ep.datatoggle = 0; + dev->ud_ep0.ue_toggle = 0; - DPRINTFN(4, "up %p portno %d", up, up->portno, 0, 0); + DPRINTFN(4, "up %p portno %d", up, up->up_portno, 0, 0); - dev->quirks = &usbd_no_quirk; - dev->address = 0; - dev->ddesc.bMaxPacketSize = 0; - dev->depth = depth; - dev->powersrc = up; - dev->myhub = up->parent; + dev->ud_quirks = &usbd_no_quirk; + dev->ud_addr = 0; + dev->ud_ddesc.bMaxPacketSize = 0; + dev->ud_depth = depth; + dev->ud_powersrc = up; + dev->ud_myhub = up->up_parent; - up->device = dev; + up->up_dev = dev; /* Locate root hub port */ - for (adev = dev, hub = dev; - hub != NULL; - adev = hub, hub = hub->myhub) { - DPRINTFN(4, "hub %p", hub, 0, 0, 0); - } - DPRINTFN(4, "hub %p", hub, 0, 0, 0); + for (hub = dev; hub != NULL; hub = hub->ud_myhub) { + uint32_t dep; - if (hub != NULL) { - for (int p = 0; p < hub->hub->hubdesc.bNbrPorts; p++) { - if (hub->hub->ports[p].device == adev) { - rhport = p; + DPRINTFN(4, "hub %p depth %d upport %p upportno %d", + hub, hub->ud_depth, hub->ud_powersrc, + hub->ud_powersrc ? hub->ud_powersrc->up_portno : -1); + + if (hub->ud_powersrc == NULL) + break; + dep = hub->ud_depth; + if (dep == 0) + break; + rhport = hub->ud_powersrc->up_portno; + if (dep > USB_HUB_MAX_DEPTH) + continue; + + route |= + (rhport > UHD_SS_NPORTS_MAX ? UHD_SS_NPORTS_MAX : rhport) + << ((dep - 1) * 4); + } + route = route >> 4; + DPRINTFN(4, "rhport %d Route %05x hub %p", rhport, route, hub, 0); + + /* Locate port on upstream high speed hub */ + for (adev = dev, hub = up->up_parent; + hub != NULL && hub->ud_speed != USB_SPEED_HIGH; + adev = hub, hub = hub->ud_myhub) + ; + if (hub) { + int p; + for (p = 0; p < hub->ud_hub->uh_hubdesc.bNbrPorts; p++) { + if (hub->ud_hub->uh_ports[p].up_dev == adev) { + dev->ud_myhsport = &hub->ud_hub->uh_ports[p]; + goto found; } } + panic("xhci_new_device: cannot find HS port"); + found: + DPRINTFN(4, "high speed port %d", p, 0, 0, 0); } else { - rhport = port; - } - if (speed == USB_SPEED_SUPER) { - rhport += sc->sc_ss_port_start - 1; - } else { - rhport += sc->sc_hs_port_start - 1; + dev->ud_myhsport = NULL; } - DPRINTFN(4, "rhport %d", rhport, 0, 0, 0); - dev->speed = speed; - dev->langid = USBD_NOLANG; - dev->cookie.cookie = ++usb_cookie_no; + dev->ud_speed = speed; + dev->ud_langid = USBD_NOLANG; + dev->ud_cookie.cookie = ++usb_cookie_no; /* Establish the default pipe. */ - err = usbd_setup_pipe(dev, 0, &dev->def_ep, USBD_DEFAULT_INTERVAL, - &dev->default_pipe); + err = usbd_setup_pipe(dev, 0, &dev->ud_ep0, USBD_DEFAULT_INTERVAL, + &dev->ud_pipe0); if (err) { - usbd_remove_device(dev, up); - return (err); + goto bad; } - dd = &dev->ddesc; + dd = &dev->ud_ddesc; if ((depth == 0) && (port == 0)) { - KASSERT(bus->devices[dev->address] == NULL); - bus->devices[dev->address] = dev; + KASSERT(bus->ub_devices[dev->ud_addr] == NULL); + bus->ub_devices[dev->ud_addr] = dev; err = usbd_get_initial_ddesc(dev, dd); if (err) - return err; + goto bad; err = usbd_reload_device_desc(dev); if (err) - return err; + goto bad; } else { err = xhci_enable_slot(sc, &slot); if (err) - return err; - err = xhci_init_slot(sc, slot, depth, speed, port, rhport); - if (err) - return err; + goto bad; xs = &sc->sc_slots[slot]; - dev->hci_private = xs; + dev->ud_hcpriv = xs; + err = xhci_init_slot(dev, slot, route, rhport); + if (err) { + dev->ud_hcpriv = NULL; + /* + * We have to disable_slot here because + * xs->xs_idx == 0 when xhci_init_slot fails, + * in that case usbd_remove_dev won't work. + */ + mutex_enter(&sc->sc_lock); + xhci_disable_slot(sc, slot); + mutex_exit(&sc->sc_lock); + goto bad; + } + + /* Allow device time to set new address */ + usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE); cp = xhci_slot_get_dcv(sc, xs, XHCI_DCI_SLOT); //hexdump("slot context", cp, sc->sc_ctxsz); addr = XHCI_SCTX_3_DEV_ADDR_GET(cp[3]); @@ -1578,41 +2266,52 @@ xhci_new_device(device_t parent, usbd_bus_handle bus, int depth, /* XXX ensure we know when the hardware does something we can't yet cope with */ KASSERT(addr >= 1 && addr <= 127); - dev->address = addr; - /* XXX dev->address not necessarily unique on bus */ - KASSERT(bus->devices[dev->address] == NULL); - bus->devices[dev->address] = dev; + dev->ud_addr = addr; + /* XXX dev->ud_addr not necessarily unique on bus */ + KASSERT(bus->ub_devices[dev->ud_addr] == NULL); + bus->ub_devices[dev->ud_addr] = dev; err = usbd_get_initial_ddesc(dev, dd); if (err) - return err; + goto bad; /* 4.8.2.1 */ - if (speed == USB_SPEED_SUPER) - USETW(dev->def_ep_desc.wMaxPacketSize, + if (USB_IS_SS(speed)) { + if (dd->bMaxPacketSize != 9) { + printf("%s: invalid mps 2^%u for SS ep0," + " using 512\n", + device_xname(sc->sc_dev), + dd->bMaxPacketSize); + dd->bMaxPacketSize = 9; + } + USETW(dev->ud_ep0desc.wMaxPacketSize, (1 << dd->bMaxPacketSize)); - else - USETW(dev->def_ep_desc.wMaxPacketSize, + } else + USETW(dev->ud_ep0desc.wMaxPacketSize, dd->bMaxPacketSize); DPRINTFN(4, "bMaxPacketSize %u", dd->bMaxPacketSize, 0, 0, 0); xhci_update_ep0_mps(sc, xs, - UGETW(dev->def_ep_desc.wMaxPacketSize)); + UGETW(dev->ud_ep0desc.wMaxPacketSize)); err = usbd_reload_device_desc(dev); if (err) - return err; + goto bad; - usbd_kill_pipe(dev->default_pipe); - err = usbd_setup_pipe(dev, 0, &dev->def_ep, - USBD_DEFAULT_INTERVAL, &dev->default_pipe); +#if 0 + /* Re-establish the default pipe with the new MPS. */ + /* In xhci this is done by xhci_update_ep0_mps. */ + usbd_kill_pipe(dev->ud_pipe0); + err = usbd_setup_pipe(dev, 0, &dev->ud_ep0, + USBD_DEFAULT_INTERVAL, &dev->ud_pipe0); +#endif } DPRINTFN(1, "adding unit addr=%d, rev=%02x,", - dev->address, UGETW(dd->bcdUSB), 0, 0); + dev->ud_addr, UGETW(dd->bcdUSB), 0, 0); DPRINTFN(1, " class=%d, subclass=%d, protocol=%d,", dd->bDeviceClass, dd->bDeviceSubClass, dd->bDeviceProtocol, 0); DPRINTFN(1, " mps=%d, len=%d, noconf=%d, speed=%d", dd->bMaxPacketSize, dd->bLength, dd->bNumConfigurations, - dev->speed); + dev->ud_speed); usbd_get_device_strings(dev); @@ -1620,18 +2319,18 @@ xhci_new_device(device_t parent, usbd_bus_handle bus, int depth, if ((depth == 0) && (port == 0)) { usbd_attach_roothub(parent, dev); - DPRINTFN(1, "root_hub %p", bus->root_hub, 0, 0, 0); + DPRINTFN(1, "root_hub %p", bus->ub_roothub, 0, 0, 0); return USBD_NORMAL_COMPLETION; } - err = usbd_probe_and_attach(parent, dev, port, dev->address); - if (err) { + err = usbd_probe_and_attach(parent, dev, port, dev->ud_addr); + bad: + if (err != USBD_NORMAL_COMPLETION) { usbd_remove_device(dev, up); - return (err); } - return USBD_NORMAL_COMPLETION; + return err; } static usbd_status @@ -1680,6 +2379,7 @@ xhci_ring_put(struct xhci_softc * const sc, struct xhci_ring * const xr, XHCIHIST_FUNC(); XHCIHIST_CALLED(); + KASSERT(ntrbs <= XHCI_XFER_NTRB); for (i = 0; i < ntrbs; i++) { DPRINTFN(12, "xr %p trbs %p num %zu", xr, trbs, i, 0); DPRINTFN(12, " %016"PRIx64" %08"PRIx32" %08"PRIx32, @@ -1712,8 +2412,7 @@ xhci_ring_put(struct xhci_softc * const sc, struct xhci_ring * const xr, status = 0; control = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_LINK) | XHCI_TRB_3_TC_BIT | (cs ? XHCI_TRB_3_CYCLE_BIT : 0); - xhci_trb_put(&xr->xr_trb[ri], htole64(parameter), - htole32(status), htole32(control)); + xhci_trb_put(&xr->xr_trb[ri], parameter, status, control); usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * ri, XHCI_TRB_SIZE * 1, BUS_DMASYNC_PREWRITE); xr->xr_cookies[ri] = NULL; @@ -1737,8 +2436,7 @@ xhci_ring_put(struct xhci_softc * const sc, struct xhci_ring * const xr, control &= ~XHCI_TRB_3_CYCLE_BIT; } - xhci_trb_put(&xr->xr_trb[ri], htole64(parameter), - htole32(status), htole32(control)); + xhci_trb_put(&xr->xr_trb[ri], parameter, status, control); usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * ri, XHCI_TRB_SIZE * 1, BUS_DMASYNC_PREWRITE); xr->xr_cookies[ri] = cookie; @@ -1747,32 +2445,36 @@ xhci_ring_put(struct xhci_softc * const sc, struct xhci_ring * const xr, /* Write the first TRB last */ i = 0; - { - parameter = trbs[i].trb_0; - status = trbs[i].trb_2; - control = trbs[i].trb_3; + parameter = trbs[i].trb_0; + status = trbs[i].trb_2; + control = trbs[i].trb_3; - if (xr->xr_cs) { - control |= XHCI_TRB_3_CYCLE_BIT; - } else { - control &= ~XHCI_TRB_3_CYCLE_BIT; - } - - xhci_trb_put(&xr->xr_trb[xr->xr_ep], htole64(parameter), - htole32(status), htole32(control)); - usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * ri, XHCI_TRB_SIZE * 1, - BUS_DMASYNC_PREWRITE); - xr->xr_cookies[xr->xr_ep] = cookie; + if (xr->xr_cs) { + control |= XHCI_TRB_3_CYCLE_BIT; + } else { + control &= ~XHCI_TRB_3_CYCLE_BIT; } + xhci_trb_put(&xr->xr_trb[xr->xr_ep], parameter, status, control); + usb_syncmem(&xr->xr_dma, XHCI_TRB_SIZE * ri, XHCI_TRB_SIZE * 1, + BUS_DMASYNC_PREWRITE); + xr->xr_cookies[xr->xr_ep] = cookie; + xr->xr_ep = ri; xr->xr_cs = cs; DPRINTFN(12, "%p xr_ep 0x%x xr_cs %u", xr, xr->xr_ep, xr->xr_cs, 0); } +/* + * Put a command on command ring, ring bell, set timer, and cv_timedwait. + * Command completion is notified by cv_signal from xhci_handle_event + * (called from interrupt from xHCI), or timed-out. + * Command validation is performed in xhci_handle_event by checking if + * trb_0 in CMD_COMPLETE TRB and sc->sc_command_addr are identical. + */ static usbd_status -xhci_do_command(struct xhci_softc * const sc, struct xhci_trb * const trb, +xhci_do_command_locked(struct xhci_softc * const sc, struct xhci_trb * const trb, int timeout) { struct xhci_ring * const cr = &sc->sc_cr; @@ -1782,8 +2484,10 @@ xhci_do_command(struct xhci_softc * const sc, struct xhci_trb * const trb, DPRINTFN(12, "input: 0x%016"PRIx64" 0x%08"PRIx32" 0x%08"PRIx32, trb->trb_0, trb->trb_2, trb->trb_3, 0); - mutex_enter(&sc->sc_lock); + KASSERTMSG(!cpu_intr_p() && !cpu_softintr_p(), "called from intr ctx"); + KASSERT(mutex_owned(&sc->sc_lock)); + /* XXX KASSERT may fire when cv_timedwait unlocks sc_lock */ KASSERT(sc->sc_command_addr == 0); sc->sc_command_addr = xhci_ring_trbp(cr, cr->xr_ep); @@ -1821,11 +2525,22 @@ xhci_do_command(struct xhci_softc * const sc, struct xhci_trb * const trb, timedout: sc->sc_command_addr = 0; - mutex_exit(&sc->sc_lock); return err; } static usbd_status +xhci_do_command(struct xhci_softc * const sc, struct xhci_trb * const trb, + int timeout) +{ + + mutex_enter(&sc->sc_lock); + int ret = xhci_do_command_locked(sc, trb, timeout); + mutex_exit(&sc->sc_lock); + + return ret; +} + +static usbd_status xhci_enable_slot(struct xhci_softc * const sc, uint8_t * const slotp) { struct xhci_trb trb; @@ -1847,6 +2562,53 @@ xhci_enable_slot(struct xhci_softc * const sc, uint8_t * const slotp) return err; } +/* + * Deallocate DMA buffer and ring buffer, and disable_slot. + * Should be called with sc_lock held. + */ +static usbd_status +xhci_disable_slot(struct xhci_softc * const sc, uint8_t slot) +{ + struct xhci_trb trb; + struct xhci_slot *xs; + usbd_status err; + + XHCIHIST_FUNC(); XHCIHIST_CALLED(); + + if (sc->sc_dying) + return USBD_IOERROR; + + trb.trb_0 = 0; + trb.trb_2 = 0; + trb.trb_3 = htole32( + XHCI_TRB_3_SLOT_SET(slot) | + XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_DISABLE_SLOT)); + + err = xhci_do_command_locked(sc, &trb, USBD_DEFAULT_TIMEOUT); + + if (!err) { + xs = &sc->sc_slots[slot]; + if (xs->xs_idx != 0) { + for (int i = XHCI_DCI_SLOT + 1; i < 32; i++) { + xhci_ring_free(sc, &xs->xs_ep[i].xe_tr); + memset(&xs->xs_ep[i], 0, sizeof(xs->xs_ep[i])); + } + usb_freemem(&sc->sc_bus, &xs->xs_ic_dma); + usb_freemem(&sc->sc_bus, &xs->xs_dc_dma); + xhci_set_dcba(sc, 0, slot); + memset(xs, 0, sizeof(*xs)); + } + } + + return err; +} + +/* + * Change slot state. + * bsr=0: ENABLED -> ADDRESSED + * bsr=1: ENABLED -> DEFAULT + * see xHCI 1.1 4.5.3, 3.3.4 + */ static usbd_status xhci_address_device(struct xhci_softc * const sc, uint64_t icp, uint8_t slot_id, bool bsr) @@ -1863,6 +2625,10 @@ xhci_address_device(struct xhci_softc * const sc, (bsr ? XHCI_TRB_3_BSR_BIT : 0); err = xhci_do_command(sc, &trb, USBD_DEFAULT_TIMEOUT); + + if (XHCI_TRB_2_ERROR_GET(trb.trb_2) == XHCI_TRB_ERROR_NO_SLOTS) + err = USBD_NO_ADDR; + return err; } @@ -1913,45 +2679,26 @@ xhci_set_dcba(struct xhci_softc * const sc, uint64_t dcba, int si) BUS_DMASYNC_PREWRITE); } +/* + * Allocate DMA buffer and ring buffer for specified slot + * and set Device Context Base Address + * and issue Set Address device command. + */ static usbd_status -xhci_init_slot(struct xhci_softc * const sc, uint32_t slot, int depth, - int speed, int port, int rhport) +xhci_init_slot(struct usbd_device *dev, uint32_t slot, uint32_t route, int rhport) { + struct xhci_softc * const sc = XHCI_BUS2SC(dev->ud_bus); struct xhci_slot *xs; usbd_status err; u_int dci; uint32_t *cp; - uint32_t mps; - uint32_t xspeed; + uint32_t mps = UGETW(dev->ud_ep0desc.wMaxPacketSize); XHCIHIST_FUNC(); XHCIHIST_CALLED(); - DPRINTFN(4, "slot %u depth %d speed %d", slot, depth, speed, 0); - DPRINTFN(4, " port %d rhport %d", port, rhport, 0, 0); - - switch (speed) { - case USB_SPEED_LOW: - xspeed = 2; - mps = USB_MAX_IPACKET; - break; - case USB_SPEED_FULL: - xspeed = 1; - mps = 64; - break; - case USB_SPEED_HIGH: - xspeed = 3; - mps = USB_2_MAX_CTRL_PACKET; - break; - case USB_SPEED_SUPER: - xspeed = 4; - mps = USB_3_MAX_CTRL_PACKET; - break; - default: - DPRINTFN(0, "impossible speed: %x", speed, 0, 0, 0); - return USBD_INVAL; - } + DPRINTFN(4, "slot %u speed %d route %05x rhport %d", + slot, dev->ud_speed, route, rhport); xs = &sc->sc_slots[slot]; - xs->xs_idx = slot; /* allocate contexts */ err = usb_allocmem(&sc->sc_bus, sc->sc_pgsz, sc->sc_pgsz, @@ -1963,7 +2710,7 @@ xhci_init_slot(struct xhci_softc * const sc, uint32_t slot, int depth, err = usb_allocmem(&sc->sc_bus, sc->sc_pgsz, sc->sc_pgsz, &xs->xs_ic_dma); if (err) - return err; + goto bad1; memset(KERNADDR(&xs->xs_ic_dma, 0), 0, sc->sc_pgsz); for (dci = 0; dci < 32; dci++) { @@ -1975,7 +2722,7 @@ xhci_init_slot(struct xhci_softc * const sc, uint32_t slot, int depth, XHCI_TRANSFER_RING_TRBS, XHCI_TRB_ALIGN); if (err) { DPRINTFN(0, "ring init failure", 0, 0, 0, 0); - return err; + goto bad2; } } @@ -1987,17 +2734,10 @@ xhci_init_slot(struct xhci_softc * const sc, uint32_t slot, int depth, /* set up input slot context */ cp = xhci_slot_get_icv(sc, xs, xhci_dci_to_ici(XHCI_DCI_SLOT)); - cp[0] = htole32( - XHCI_SCTX_0_CTX_NUM_SET(1) | - XHCI_SCTX_0_SPEED_SET(xspeed) - ); - cp[1] = htole32( - XHCI_SCTX_1_RH_PORT_SET(rhport) - ); - cp[2] = htole32( - XHCI_SCTX_2_IRQ_TARGET_SET(0) - ); - cp[3] = htole32(0); + xhci_setup_sctx(dev, cp); + cp[0] |= htole32(XHCI_SCTX_0_CTX_NUM_SET(1)); + cp[0] |= htole32(XHCI_SCTX_0_ROUTE_SET(route)); + cp[1] |= htole32(XHCI_SCTX_1_RH_PORT_SET(rhport)); /* set up input EP0 context */ cp = xhci_slot_get_icv(sc, xs, xhci_dci_to_ici(XHCI_DCI_EP_CONTROL)); @@ -2029,388 +2769,216 @@ xhci_init_slot(struct xhci_softc * const sc, uint32_t slot, int depth, hexdump("output context", xhci_slot_get_dcv(sc, xs, 0), sc->sc_ctxsz * 2); + bad2: + if (err == USBD_NORMAL_COMPLETION) { + xs->xs_idx = slot; + } else { + for (int i = 1; i < dci; i++) { + xhci_ring_free(sc, &xs->xs_ep[i].xe_tr); + memset(&xs->xs_ep[i], 0, sizeof(xs->xs_ep[i])); + } + usb_freemem(&sc->sc_bus, &xs->xs_ic_dma); + bad1: + usb_freemem(&sc->sc_bus, &xs->xs_dc_dma); + xs->xs_idx = 0; + } + return err; } /* ----- */ static void -xhci_noop(usbd_pipe_handle pipe) +xhci_noop(struct usbd_pipe *pipe) { XHCIHIST_FUNC(); XHCIHIST_CALLED(); } -/* root hub descriptors */ - -static const usb_device_descriptor_t xhci_devd = { - USB_DEVICE_DESCRIPTOR_SIZE, - UDESC_DEVICE, /* type */ - {0x00, 0x02}, /* USB version */ - UDCLASS_HUB, /* class */ - UDSUBCLASS_HUB, /* subclass */ - UDPROTO_HSHUBSTT, /* protocol */ - 64, /* max packet */ - {0},{0},{0x00,0x01}, /* device id */ - 1,2,0, /* string indexes */ - 1 /* # of configurations */ -}; - -static const usb_device_qualifier_t xhci_odevd = { - USB_DEVICE_DESCRIPTOR_SIZE, - UDESC_DEVICE_QUALIFIER, /* type */ - {0x00, 0x02}, /* USB version */ - UDCLASS_HUB, /* class */ - UDSUBCLASS_HUB, /* subclass */ - UDPROTO_FSHUB, /* protocol */ - 64, /* max packet */ - 1, /* # of configurations */ - 0 -}; - -static const usb_config_descriptor_t xhci_confd = { - USB_CONFIG_DESCRIPTOR_SIZE, - UDESC_CONFIG, - {USB_CONFIG_DESCRIPTOR_SIZE + - USB_INTERFACE_DESCRIPTOR_SIZE + - USB_ENDPOINT_DESCRIPTOR_SIZE}, - 1, - 1, - 0, - UC_ATTR_MBO | UC_SELF_POWERED, - 0 /* max power */ -}; - -static const usb_interface_descriptor_t xhci_ifcd = { - USB_INTERFACE_DESCRIPTOR_SIZE, - UDESC_INTERFACE, - 0, - 0, - 1, - UICLASS_HUB, - UISUBCLASS_HUB, - UIPROTO_HSHUBSTT, - 0 -}; - -static const usb_endpoint_descriptor_t xhci_endpd = { - USB_ENDPOINT_DESCRIPTOR_SIZE, - UDESC_ENDPOINT, - UE_DIR_IN | XHCI_INTR_ENDPT, - UE_INTERRUPT, - {8, 0}, /* max packet */ - 12 -}; - -static const usb_hub_descriptor_t xhci_hubd = { - USB_HUB_DESCRIPTOR_SIZE, - UDESC_HUB, - 0, - {0,0}, - 0, - 0, - {""}, - {""}, -}; - -/* root hub control */ - -static usbd_status -xhci_root_ctrl_transfer(usbd_xfer_handle xfer) -{ - struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; - usbd_status err; - - XHCIHIST_FUNC(); XHCIHIST_CALLED(); - - /* Insert last in queue. */ - mutex_enter(&sc->sc_lock); - err = usb_insert_transfer(xfer); - mutex_exit(&sc->sc_lock); - if (err) - return err; - - /* Pipe isn't running, start first */ - return (xhci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); -} - -static usbd_status -xhci_root_ctrl_start(usbd_xfer_handle xfer) +/* + * Process root hub request. + */ +static int +xhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, + void *buf, int buflen) { - struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; + struct xhci_softc * const sc = XHCI_BUS2SC(bus); usb_port_status_t ps; - usb_device_request_t *req; - void *buf = NULL; - usb_hub_descriptor_t hubd; - usbd_status err; - int len, value, index; int l, totlen = 0; + uint16_t len, value, index; int port, i; uint32_t v; XHCIHIST_FUNC(); XHCIHIST_CALLED(); if (sc->sc_dying) - return USBD_IOERROR; - - req = &xfer->request; + return -1; + len = UGETW(req->wLength); value = UGETW(req->wValue); index = UGETW(req->wIndex); - len = UGETW(req->wLength); - - if (len != 0) - buf = KERNADDR(&xfer->dmabuf, 0); DPRINTFN(12, "rhreq: %04x %04x %04x %04x", req->bmRequestType | (req->bRequest << 8), value, index, len); #define C(x,y) ((x) | ((y) << 8)) - switch(C(req->bRequest, req->bmRequestType)) { - case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE): - case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE): - case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT): - /* - * DEVICE_REMOTE_WAKEUP and ENDPOINT_HALT are no-ops - * for the integrated root hub. - */ - break; - case C(UR_GET_CONFIG, UT_READ_DEVICE): - if (len > 0) { - *(uint8_t *)buf = sc->sc_conf; - totlen = 1; - } - break; + switch (C(req->bRequest, req->bmRequestType)) { case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): DPRINTFN(8, "getdesc: wValue=0x%04x", value, 0, 0, 0); if (len == 0) break; - switch(value >> 8) { - case UDESC_DEVICE: - if ((value & 0xff) != 0) { - err = USBD_IOERROR; - goto ret; - } - totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE); - memcpy(buf, &xhci_devd, min(l, sizeof(xhci_devd))); + switch (value) { + case C(0, UDESC_DEVICE): { + usb_device_descriptor_t devd; + totlen = min(buflen, sizeof(devd)); + memcpy(&devd, buf, totlen); + USETW(devd.idVendor, sc->sc_id_vendor); + memcpy(buf, &devd, totlen); break; - case UDESC_DEVICE_QUALIFIER: - if ((value & 0xff) != 0) { - } - totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE); - memcpy(buf, &xhci_odevd, min(l, sizeof(xhci_odevd))); + } +#define sd ((usb_string_descriptor_t *)buf) + case C(1, UDESC_STRING): + /* Vendor */ + totlen = usb_makestrdesc(sd, len, sc->sc_vendor); break; - case UDESC_OTHER_SPEED_CONFIGURATION: - case UDESC_CONFIG: - if ((value & 0xff) != 0) { - err = USBD_IOERROR; - goto ret; - } - totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE); - memcpy(buf, &xhci_confd, min(l, sizeof(xhci_confd))); - ((usb_config_descriptor_t *)buf)->bDescriptorType = - value >> 8; - buf = (char *)buf + l; - len -= l; - l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE); - totlen += l; - memcpy(buf, &xhci_ifcd, min(l, sizeof(xhci_ifcd))); - buf = (char *)buf + l; - len -= l; - l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE); - totlen += l; - memcpy(buf, &xhci_endpd, min(l, sizeof(xhci_endpd))); + case C(2, UDESC_STRING): + /* Product */ + totlen = usb_makestrdesc(sd, len, "xHCI Root Hub"); break; - case UDESC_STRING: -#define sd ((usb_string_descriptor_t *)buf) - switch (value & 0xff) { - case 0: /* Language table */ - totlen = usb_makelangtbl(sd, len); - break; - case 1: /* Vendor */ - totlen = usb_makestrdesc(sd, len, "NetBSD"); - break; - case 2: /* Product */ - totlen = usb_makestrdesc(sd, len, - "xHCI Root Hub"); - break; - } #undef sd - break; default: - err = USBD_IOERROR; - goto ret; - } - break; - case C(UR_GET_INTERFACE, UT_READ_INTERFACE): - if (len > 0) { - *(uint8_t *)buf = 0; - totlen = 1; - } - break; - case C(UR_GET_STATUS, UT_READ_DEVICE): - if (len > 1) { - USETW(((usb_status_t *)buf)->wStatus,UDS_SELF_POWERED); - totlen = 2; - } - break; - case C(UR_GET_STATUS, UT_READ_INTERFACE): - case C(UR_GET_STATUS, UT_READ_ENDPOINT): - if (len > 1) { - USETW(((usb_status_t *)buf)->wStatus, 0); - totlen = 2; - } - break; - case C(UR_SET_ADDRESS, UT_WRITE_DEVICE): - if (value >= USB_MAX_DEVICES) { - err = USBD_IOERROR; - goto ret; - } - //sc->sc_addr = value; - break; - case C(UR_SET_CONFIG, UT_WRITE_DEVICE): - if (value != 0 && value != 1) { - err = USBD_IOERROR; - goto ret; + /* default from usbroothub */ + return buflen; } - sc->sc_conf = value; - break; - case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE): - break; - case C(UR_SET_FEATURE, UT_WRITE_DEVICE): - case C(UR_SET_FEATURE, UT_WRITE_INTERFACE): - case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT): - err = USBD_IOERROR; - goto ret; - case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE): - break; - case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT): break; + /* Hub requests */ case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE): break; + /* Clear Port Feature request */ case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): DPRINTFN(4, "UR_CLEAR_PORT_FEATURE port=%d feature=%d", index, value, 0, 0); - if (index < 1 || index > sc->sc_hs_port_count) { - err = USBD_IOERROR; - goto ret; + if (index < 1 || index > sc->sc_maxports) { + return -1; } - port = XHCI_PORTSC(sc->sc_hs_port_start - 1 + index); + port = XHCI_PORTSC(index); v = xhci_op_read_4(sc, port); DPRINTFN(4, "portsc=0x%08x", v, 0, 0, 0); v &= ~XHCI_PS_CLEAR; switch (value) { case UHF_PORT_ENABLE: - xhci_op_write_4(sc, port, v &~ XHCI_PS_PED); + xhci_op_write_4(sc, port, v & ~XHCI_PS_PED); break; case UHF_PORT_SUSPEND: - err = USBD_IOERROR; - goto ret; + return -1; case UHF_PORT_POWER: break; case UHF_PORT_TEST: case UHF_PORT_INDICATOR: - err = USBD_IOERROR; - goto ret; + return -1; case UHF_C_PORT_CONNECTION: xhci_op_write_4(sc, port, v | XHCI_PS_CSC); break; case UHF_C_PORT_ENABLE: case UHF_C_PORT_SUSPEND: case UHF_C_PORT_OVER_CURRENT: - err = USBD_IOERROR; - goto ret; + return -1; + case UHF_C_BH_PORT_RESET: + xhci_op_write_4(sc, port, v | XHCI_PS_WRC); + break; case UHF_C_PORT_RESET: xhci_op_write_4(sc, port, v | XHCI_PS_PRC); break; + case UHF_C_PORT_LINK_STATE: + xhci_op_write_4(sc, port, v | XHCI_PS_PLC); + break; + case UHF_C_PORT_CONFIG_ERROR: + xhci_op_write_4(sc, port, v | XHCI_PS_CEC); + break; default: - err = USBD_IOERROR; - goto ret; + return -1; } - break; case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE): if (len == 0) break; if ((value & 0xff) != 0) { - err = USBD_IOERROR; - goto ret; + return -1; } - hubd = xhci_hubd; - hubd.bNbrPorts = sc->sc_hs_port_count; + usb_hub_descriptor_t hubd; + + totlen = min(buflen, sizeof(hubd)); + memcpy(&hubd, buf, totlen); + hubd.bNbrPorts = sc->sc_maxports; USETW(hubd.wHubCharacteristics, UHD_PWR_NO_SWITCH); hubd.bPwrOn2PwrGood = 200; for (i = 0, l = sc->sc_maxports; l > 0; i++, l -= 8) hubd.DeviceRemovable[i++] = 0; /* XXX can't find out? */ hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + i; - l = min(len, hubd.bDescLength); - totlen = l; - memcpy(buf, &hubd, l); + totlen = min(totlen, hubd.bDescLength); + memcpy(buf, &hubd, totlen); break; case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): if (len != 4) { - err = USBD_IOERROR; - goto ret; + return -1; } memset(buf, 0, len); /* ? XXX */ totlen = len; break; + /* Get Port Status request */ case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): DPRINTFN(8, "get port status i=%d", index, 0, 0, 0); if (index < 1 || index > sc->sc_maxports) { - err = USBD_IOERROR; - goto ret; + return -1; } if (len != 4) { - err = USBD_IOERROR; - goto ret; - } - v = xhci_op_read_4(sc, XHCI_PORTSC(sc->sc_hs_port_start - 1 + - index)); - DPRINTFN(4, "READ_CLASS_OTHER GET_STATUS PORTSC %d (%d) %08x", - index, sc->sc_hs_port_start - 1 + index, v, 0); - switch (XHCI_PS_SPEED_GET(v)) { - case 1: - i = UPS_FULL_SPEED; - break; - case 2: - i = UPS_LOW_SPEED; - break; - case 3: - i = UPS_HIGH_SPEED; - break; - default: - i = 0; - break; + return -1; } + v = xhci_op_read_4(sc, XHCI_PORTSC(index)); + DPRINTFN(4, "getrhportsc %d %08x", index, v, 0, 0); + i = xhci_xspeed2psspeed(XHCI_PS_SPEED_GET(v)); if (v & XHCI_PS_CCS) i |= UPS_CURRENT_CONNECT_STATUS; if (v & XHCI_PS_PED) i |= UPS_PORT_ENABLED; if (v & XHCI_PS_OCA) i |= UPS_OVERCURRENT_INDICATOR; //if (v & XHCI_PS_SUSP) i |= UPS_SUSPEND; if (v & XHCI_PS_PR) i |= UPS_RESET; - if (v & XHCI_PS_PP) i |= UPS_PORT_POWER; + if (v & XHCI_PS_PP) { + if (i & UPS_OTHER_SPEED) + i |= UPS_PORT_POWER_SS; + else + i |= UPS_PORT_POWER; + } + if (i & UPS_OTHER_SPEED) + i |= UPS_PORT_LS_SET(XHCI_PS_PLS_GET(v)); + if (sc->sc_vendor_port_status) + i = sc->sc_vendor_port_status(sc, v, i); USETW(ps.wPortStatus, i); i = 0; if (v & XHCI_PS_CSC) i |= UPS_C_CONNECT_STATUS; if (v & XHCI_PS_PEC) i |= UPS_C_PORT_ENABLED; if (v & XHCI_PS_OCC) i |= UPS_C_OVERCURRENT_INDICATOR; if (v & XHCI_PS_PRC) i |= UPS_C_PORT_RESET; + if (v & XHCI_PS_WRC) i |= UPS_C_BH_PORT_RESET; + if (v & XHCI_PS_PLC) i |= UPS_C_PORT_LINK_STATE; + if (v & XHCI_PS_CEC) i |= UPS_C_PORT_CONFIG_ERROR; USETW(ps.wPortChange, i); - l = min(len, sizeof ps); - memcpy(buf, &ps, l); - totlen = l; + totlen = min(len, sizeof(ps)); + memcpy(buf, &ps, totlen); break; case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE): - err = USBD_IOERROR; - goto ret; + return -1; + case C(UR_SET_HUB_DEPTH, UT_WRITE_CLASS_DEVICE): + break; 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_hs_port_count) { - err = USBD_IOERROR; - goto ret; + /* Set Port Feature request */ + case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER): { + int optval = (index >> 8) & 0xff; + index &= 0xff; + if (index < 1 || index > sc->sc_maxports) { + return -1; } - port = XHCI_PORTSC(sc->sc_hs_port_start - 1 + index); + port = XHCI_PORTSC(index); v = xhci_op_read_4(sc, port); DPRINTFN(4, "portsc=0x%08x", v, 0, 0, 0); v &= ~XHCI_PS_CLEAR; @@ -2422,13 +2990,12 @@ xhci_root_ctrl_start(usbd_xfer_handle xfer) /* XXX suspend */ break; case UHF_PORT_RESET: - v &= ~ (XHCI_PS_PED | XHCI_PS_PR); + v &= ~(XHCI_PS_PED | XHCI_PS_PR); xhci_op_write_4(sc, port, v | XHCI_PS_PR); /* Wait for reset to complete. */ usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY); if (sc->sc_dying) { - err = USBD_IOERROR; - goto ret; + return -1; } v = xhci_op_read_4(sc, port); if (v & XHCI_PS_PR) { @@ -2444,10 +3011,30 @@ xhci_root_ctrl_start(usbd_xfer_handle xfer) case UHF_C_PORT_RESET: xhci_op_write_4(sc, port, v | XHCI_PS_PRC); break; + case UHF_PORT_U1_TIMEOUT: + if (XHCI_PS_SPEED_GET(v) < XHCI_PS_SPEED_SS) { + return -1; + } + port = XHCI_PORTPMSC(index); + v = xhci_op_read_4(sc, port); + v &= ~XHCI_PM3_U1TO_SET(0xff); + v |= XHCI_PM3_U1TO_SET(optval); + xhci_op_write_4(sc, port, v); + break; + case UHF_PORT_U2_TIMEOUT: + if (XHCI_PS_SPEED_GET(v) < XHCI_PS_SPEED_SS) { + return -1; + } + port = XHCI_PORTPMSC(index); + v = xhci_op_read_4(sc, port); + v &= ~XHCI_PM3_U2TO_SET(0xff); + v |= XHCI_PM3_U2TO_SET(optval); + xhci_op_write_4(sc, port, v); + break; default: - err = USBD_IOERROR; - goto ret; + return -1; } + } break; case C(UR_CLEAR_TT_BUFFER, UT_WRITE_CLASS_OTHER): case C(UR_RESET_TT, UT_WRITE_CLASS_OTHER): @@ -2455,49 +3042,19 @@ xhci_root_ctrl_start(usbd_xfer_handle xfer) case C(UR_STOP_TT, UT_WRITE_CLASS_OTHER): break; default: - err = USBD_IOERROR; - goto ret; + /* default from usbroothub */ + return buflen; } - xfer->actlen = totlen; - err = USBD_NORMAL_COMPLETION; -ret: - xfer->status = err; - mutex_enter(&sc->sc_lock); - usb_transfer_complete(xfer); - mutex_exit(&sc->sc_lock); - return USBD_IN_PROGRESS; -} - -static void -xhci_root_ctrl_abort(usbd_xfer_handle xfer) -{ - XHCIHIST_FUNC(); XHCIHIST_CALLED(); - /* Nothing to do, all transfers are synchronous. */ -} - - -static void -xhci_root_ctrl_close(usbd_pipe_handle pipe) -{ - XHCIHIST_FUNC(); XHCIHIST_CALLED(); - /* Nothing to do. */ -} - -static void -xhci_root_ctrl_done(usbd_xfer_handle xfer) -{ - XHCIHIST_FUNC(); XHCIHIST_CALLED(); - - xfer->hcpriv = NULL; + return totlen; } /* root hub interrupt */ static usbd_status -xhci_root_intr_transfer(usbd_xfer_handle xfer) +xhci_root_intr_transfer(struct usbd_xfer *xfer) { - struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; + struct xhci_softc * const sc = XHCI_XFER2SC(xfer); usbd_status err; XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -2510,13 +3067,14 @@ xhci_root_intr_transfer(usbd_xfer_handle xfer) return err; /* Pipe isn't running, start first */ - return (xhci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return xhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } +/* Wait for roothub port status/change */ static usbd_status -xhci_root_intr_start(usbd_xfer_handle xfer) +xhci_root_intr_start(struct usbd_xfer *xfer) { - struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; + struct xhci_softc * const sc = XHCI_XFER2SC(xfer); XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -2531,27 +3089,25 @@ xhci_root_intr_start(usbd_xfer_handle xfer) } static void -xhci_root_intr_abort(usbd_xfer_handle xfer) +xhci_root_intr_abort(struct usbd_xfer *xfer) { - struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; + struct xhci_softc * const sc = XHCI_XFER2SC(xfer); XHCIHIST_FUNC(); XHCIHIST_CALLED(); KASSERT(mutex_owned(&sc->sc_lock)); - KASSERT(xfer->pipe->intrxfer == xfer); - - DPRINTFN(1, "remove", 0, 0, 0, 0); + KASSERT(xfer->ux_pipe->up_intrxfer == xfer); sc->sc_intrxfer = NULL; - xfer->status = USBD_CANCELLED; + xfer->ux_status = USBD_CANCELLED; usb_transfer_complete(xfer); } static void -xhci_root_intr_close(usbd_pipe_handle pipe) +xhci_root_intr_close(struct usbd_pipe *pipe) { - struct xhci_softc * const sc = pipe->device->bus->hci_private; + struct xhci_softc * const sc = XHCI_PIPE2SC(pipe); XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -2561,20 +3117,19 @@ xhci_root_intr_close(usbd_pipe_handle pipe) } static void -xhci_root_intr_done(usbd_xfer_handle xfer) +xhci_root_intr_done(struct usbd_xfer *xfer) { XHCIHIST_FUNC(); XHCIHIST_CALLED(); - xfer->hcpriv = NULL; } /* -------------- */ /* device control */ static usbd_status -xhci_device_ctrl_transfer(usbd_xfer_handle xfer) +xhci_device_ctrl_transfer(struct usbd_xfer *xfer) { - struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; + struct xhci_softc * const sc = XHCI_XFER2SC(xfer); usbd_status err; XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -2584,24 +3139,24 @@ xhci_device_ctrl_transfer(usbd_xfer_handle xfer) err = usb_insert_transfer(xfer); mutex_exit(&sc->sc_lock); if (err) - return (err); + return err; /* Pipe isn't running, start first */ - return (xhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return xhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } static usbd_status -xhci_device_ctrl_start(usbd_xfer_handle xfer) +xhci_device_ctrl_start(struct usbd_xfer *xfer) { - struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; - struct xhci_slot * const xs = xfer->pipe->device->hci_private; - const u_int dci = xhci_ep_get_dci(xfer->pipe->endpoint->edesc); + struct xhci_softc * const sc = XHCI_XFER2SC(xfer); + struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv; + const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc); struct xhci_ring * const tr = &xs->xs_ep[dci].xe_tr; struct xhci_xfer * const xx = (void *)xfer; - usb_device_request_t * const req = &xfer->request; - const bool isread = UT_GET_DIR(req->bmRequestType) == UT_READ; + usb_device_request_t * const req = &xfer->ux_request; + const int isread = usbd_xfer_isread(xfer); const uint32_t len = UGETW(req->wLength); - usb_dma_t * const dma = &xfer->dmabuf; + usb_dma_t * const dma = &xfer->ux_dmabuf; uint64_t parameter; uint32_t status; uint32_t control; @@ -2612,23 +3167,26 @@ xhci_device_ctrl_start(usbd_xfer_handle xfer) req->bmRequestType | (req->bRequest << 8), UGETW(req->wValue), UGETW(req->wIndex), UGETW(req->wLength)); +#if 0 /* event handler does this */ /* XXX */ if (tr->is_halted) { - xhci_reset_endpoint(xfer->pipe); + DPRINTFN(1, "ctrl xfer %p halted: slot %u dci %u", + xfer, xs->xs_idx, dci, 0); + xhci_reset_endpoint(xfer->ux_pipe); tr->is_halted = false; - xhci_set_dequeue(xfer->pipe); + xhci_set_dequeue(xfer->ux_pipe); } +#endif /* we rely on the bottom bits for extra info */ KASSERT(((uintptr_t)xfer & 0x3) == 0x0); - KASSERT((xfer->rqflags & URQ_REQUEST) != 0); + KASSERT((xfer->ux_rqflags & URQ_REQUEST) != 0); i = 0; /* setup phase */ memcpy(¶meter, req, sizeof(*req)); - parameter = le64toh(parameter); status = XHCI_TRB_2_IRQ_SET(0) | XHCI_TRB_2_BYTES_SET(sizeof(*req)); control = ((len == 0) ? XHCI_TRB_3_TRT_NONE : (isread ? XHCI_TRB_3_TRT_IN : XHCI_TRB_3_TRT_OUT)) | @@ -2636,27 +3194,25 @@ xhci_device_ctrl_start(usbd_xfer_handle xfer) XHCI_TRB_3_IDT_BIT; xhci_trb_put(&xx->xx_trb[i++], parameter, status, control); - if (len == 0) - goto no_data; - - /* data phase */ - parameter = DMAADDR(dma, 0); - KASSERT(len <= 0x10000); - status = XHCI_TRB_2_IRQ_SET(0) | - XHCI_TRB_2_TDSZ_SET(1) | - XHCI_TRB_2_BYTES_SET(len); - control = (isread ? XHCI_TRB_3_DIR_IN : 0) | - XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_DATA_STAGE) | - XHCI_TRB_3_CHAIN_BIT | XHCI_TRB_3_ENT_BIT; - xhci_trb_put(&xx->xx_trb[i++], parameter, status, control); - - parameter = (uintptr_t)xfer | 0x3; - status = XHCI_TRB_2_IRQ_SET(0); - control = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_EVENT_DATA) | - XHCI_TRB_3_IOC_BIT; - xhci_trb_put(&xx->xx_trb[i++], parameter, status, control); + if (len != 0) { + /* data phase */ + parameter = DMAADDR(dma, 0); + KASSERT(len <= 0x10000); + status = XHCI_TRB_2_IRQ_SET(0) | + XHCI_TRB_2_TDSZ_SET(1) | + XHCI_TRB_2_BYTES_SET(len); + control = (isread ? XHCI_TRB_3_DIR_IN : 0) | + XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_DATA_STAGE) | + XHCI_TRB_3_CHAIN_BIT | XHCI_TRB_3_ENT_BIT; + xhci_trb_put(&xx->xx_trb[i++], parameter, status, control); + + parameter = (uintptr_t)xfer | 0x3; + status = XHCI_TRB_2_IRQ_SET(0); + control = XHCI_TRB_3_TYPE_SET(XHCI_TRB_TYPE_EVENT_DATA) | + XHCI_TRB_3_IOC_BIT; + xhci_trb_put(&xx->xx_trb[i++], parameter, status, control); + } -no_data: parameter = 0; status = XHCI_TRB_2_IRQ_SET(0); /* the status stage has inverted direction */ @@ -2677,12 +3233,12 @@ no_data: xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); - if (xfer->timeout && !sc->sc_bus.use_polling) { - callout_reset(&xfer->timeout_handle, mstohz(xfer->timeout), + if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { + callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), xhci_timeout, xfer); } - if (sc->sc_bus.use_polling) { + if (sc->sc_bus.ub_usepolling) { DPRINTFN(1, "polling", 0, 0, 0, 0); //xhci_waitintr(sc, xfer); } @@ -2691,36 +3247,44 @@ no_data: } static void -xhci_device_ctrl_done(usbd_xfer_handle xfer) +xhci_device_ctrl_done(struct usbd_xfer *xfer) { XHCIHIST_FUNC(); XHCIHIST_CALLED(); + usb_device_request_t *req = &xfer->ux_request; + int len = UGETW(req->wLength); + int rd = req->bmRequestType & UT_READ; - callout_stop(&xfer->timeout_handle); /* XXX wrong place */ - + if (len) + usb_syncmem(&xfer->ux_dmabuf, 0, len, + rd ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); } static void -xhci_device_ctrl_abort(usbd_xfer_handle xfer) +xhci_device_ctrl_abort(struct usbd_xfer *xfer) { XHCIHIST_FUNC(); XHCIHIST_CALLED(); + + xhci_abort_xfer(xfer, USBD_CANCELLED); } static void -xhci_device_ctrl_close(usbd_pipe_handle pipe) +xhci_device_ctrl_close(struct usbd_pipe *pipe) { XHCIHIST_FUNC(); XHCIHIST_CALLED(); + + xhci_close_pipe(pipe); } -/* ----------------- */ -/* device isochronus */ +/* ------------------ */ +/* device isochronous */ /* ----------- */ /* device bulk */ static usbd_status -xhci_device_bulk_transfer(usbd_xfer_handle xfer) +xhci_device_bulk_transfer(struct usbd_xfer *xfer) { - struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; + struct xhci_softc * const sc = XHCI_XFER2SC(xfer); usbd_status err; XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -2736,19 +3300,19 @@ xhci_device_bulk_transfer(usbd_xfer_handle xfer) * Pipe isn't running (otherwise err would be USBD_INPROG), * so start it first. */ - return (xhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return xhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } static usbd_status -xhci_device_bulk_start(usbd_xfer_handle xfer) +xhci_device_bulk_start(struct usbd_xfer *xfer) { - struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; - struct xhci_slot * const xs = xfer->pipe->device->hci_private; - const u_int dci = xhci_ep_get_dci(xfer->pipe->endpoint->edesc); + struct xhci_softc * const sc = XHCI_XFER2SC(xfer); + struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv; + const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc); struct xhci_ring * const tr = &xs->xs_ep[dci].xe_tr; struct xhci_xfer * const xx = (void *)xfer; - const uint32_t len = xfer->length; - usb_dma_t * const dma = &xfer->dmabuf; + const uint32_t len = xfer->ux_length; + usb_dma_t * const dma = &xfer->ux_dmabuf; uint64_t parameter; uint32_t status; uint32_t control; @@ -2761,7 +3325,7 @@ xhci_device_bulk_start(usbd_xfer_handle xfer) if (sc->sc_dying) return USBD_IOERROR; - KASSERT((xfer->rqflags & URQ_REQUEST) == 0); + KASSERT((xfer->ux_rqflags & URQ_REQUEST) == 0); parameter = DMAADDR(dma, 0); /* @@ -2789,7 +3353,12 @@ xhci_device_bulk_start(usbd_xfer_handle xfer) xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); - if (sc->sc_bus.use_polling) { + if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { + callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), + xhci_timeout, xfer); + } + + if (sc->sc_bus.ub_usepolling) { DPRINTFN(1, "polling", 0, 0, 0, 0); //xhci_waitintr(sc, xfer); } @@ -2798,46 +3367,45 @@ xhci_device_bulk_start(usbd_xfer_handle xfer) } static void -xhci_device_bulk_done(usbd_xfer_handle xfer) +xhci_device_bulk_done(struct usbd_xfer *xfer) { #ifdef USB_DEBUG - struct xhci_slot * const xs = xfer->pipe->device->hci_private; - const u_int dci = xhci_ep_get_dci(xfer->pipe->endpoint->edesc); + struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv; + const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc); #endif - const u_int endpt = xfer->pipe->endpoint->edesc->bEndpointAddress; - const bool isread = UE_GET_DIR(endpt) == UE_DIR_IN; + const int isread = usbd_xfer_isread(xfer); XHCIHIST_FUNC(); XHCIHIST_CALLED(); DPRINTFN(15, "%p slot %u dci %u", xfer, xs->xs_idx, dci, 0); - callout_stop(&xfer->timeout_handle); /* XXX wrong place */ - - usb_syncmem(&xfer->dmabuf, 0, xfer->length, + usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); - - } static void -xhci_device_bulk_abort(usbd_xfer_handle xfer) +xhci_device_bulk_abort(struct usbd_xfer *xfer) { XHCIHIST_FUNC(); XHCIHIST_CALLED(); + + xhci_abort_xfer(xfer, USBD_CANCELLED); } static void -xhci_device_bulk_close(usbd_pipe_handle pipe) +xhci_device_bulk_close(struct usbd_pipe *pipe) { XHCIHIST_FUNC(); XHCIHIST_CALLED(); + + xhci_close_pipe(pipe); } -/* --------------- */ -/* device intrrupt */ +/* ---------------- */ +/* device interrupt */ static usbd_status -xhci_device_intr_transfer(usbd_xfer_handle xfer) +xhci_device_intr_transfer(struct usbd_xfer *xfer) { - struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; + struct xhci_softc * const sc = XHCI_XFER2SC(xfer); usbd_status err; XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -2853,19 +3421,19 @@ xhci_device_intr_transfer(usbd_xfer_handle xfer) * Pipe isn't running (otherwise err would be USBD_INPROG), * so start it first. */ - return (xhci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue))); + return xhci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); } static usbd_status -xhci_device_intr_start(usbd_xfer_handle xfer) +xhci_device_intr_start(struct usbd_xfer *xfer) { - struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; - struct xhci_slot * const xs = xfer->pipe->device->hci_private; - const u_int dci = xhci_ep_get_dci(xfer->pipe->endpoint->edesc); + struct xhci_softc * const sc = XHCI_XFER2SC(xfer); + struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv; + const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc); struct xhci_ring * const tr = &xs->xs_ep[dci].xe_tr; struct xhci_xfer * const xx = (void *)xfer; - const uint32_t len = xfer->length; - usb_dma_t * const dma = &xfer->dmabuf; + const uint32_t len = xfer->ux_length; + usb_dma_t * const dma = &xfer->ux_dmabuf; uint64_t parameter; uint32_t status; uint32_t control; @@ -2878,7 +3446,7 @@ xhci_device_intr_start(usbd_xfer_handle xfer) if (sc->sc_dying) return USBD_IOERROR; - KASSERT((xfer->rqflags & URQ_REQUEST) == 0); + KASSERT((xfer->ux_rqflags & URQ_REQUEST) == 0); parameter = DMAADDR(dma, 0); KASSERT(len <= 0x10000); @@ -2895,7 +3463,12 @@ xhci_device_intr_start(usbd_xfer_handle xfer) xhci_db_write_4(sc, XHCI_DOORBELL(xs->xs_idx), dci); - if (sc->sc_bus.use_polling) { + if (xfer->ux_timeout && !sc->sc_bus.ub_usepolling) { + callout_reset(&xfer->ux_callout, mstohz(xfer->ux_timeout), + xhci_timeout, xfer); + } + + if (sc->sc_bus.ub_usepolling) { DPRINTFN(1, "polling", 0, 0, 0, 0); //xhci_waitintr(sc, xfer); } @@ -2904,66 +3477,56 @@ xhci_device_intr_start(usbd_xfer_handle xfer) } static void -xhci_device_intr_done(usbd_xfer_handle xfer) +xhci_device_intr_done(struct usbd_xfer *xfer) { - struct xhci_softc * const sc __diagused = - xfer->pipe->device->bus->hci_private; + struct xhci_softc * const sc __diagused = XHCI_XFER2SC(xfer); #ifdef USB_DEBUG - struct xhci_slot * const xs = xfer->pipe->device->hci_private; - const u_int dci = xhci_ep_get_dci(xfer->pipe->endpoint->edesc); + struct xhci_slot * const xs = xfer->ux_pipe->up_dev->ud_hcpriv; + const u_int dci = xhci_ep_get_dci(xfer->ux_pipe->up_endpoint->ue_edesc); #endif - const u_int endpt = xfer->pipe->endpoint->edesc->bEndpointAddress; - const bool isread = UE_GET_DIR(endpt) == UE_DIR_IN; + const int isread = usbd_xfer_isread(xfer); XHCIHIST_FUNC(); XHCIHIST_CALLED(); DPRINTFN(15, "%p slot %u dci %u", xfer, xs->xs_idx, dci, 0); - KASSERT(sc->sc_bus.use_polling || mutex_owned(&sc->sc_lock)); + KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); - usb_syncmem(&xfer->dmabuf, 0, xfer->length, + usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); #if 0 device_printf(sc->sc_dev, ""); - for (size_t i = 0; i < xfer->length; i++) { - printf(" %02x", ((uint8_t const *)xfer->buffer)[i]); + for (size_t i = 0; i < xfer->ux_length; i++) { + printf(" %02x", ((uint8_t const *)xfer->ux_buffer)[i]); } printf("\n"); #endif - if (xfer->pipe->repeat) { - xfer->status = xhci_device_intr_start(xfer); - } else { - callout_stop(&xfer->timeout_handle); /* XXX */ - } - } static void -xhci_device_intr_abort(usbd_xfer_handle xfer) +xhci_device_intr_abort(struct usbd_xfer *xfer) { - struct xhci_softc * const sc __diagused = - xfer->pipe->device->bus->hci_private; + struct xhci_softc * const sc __diagused = XHCI_XFER2SC(xfer); XHCIHIST_FUNC(); XHCIHIST_CALLED(); KASSERT(mutex_owned(&sc->sc_lock)); DPRINTFN(15, "%p", xfer, 0, 0, 0); - KASSERT(xfer->pipe->intrxfer == xfer); - xfer->status = USBD_CANCELLED; - usb_transfer_complete(xfer); + KASSERT(xfer->ux_pipe->up_intrxfer == xfer); + xhci_abort_xfer(xfer, USBD_CANCELLED); } static void -xhci_device_intr_close(usbd_pipe_handle pipe) +xhci_device_intr_close(struct usbd_pipe *pipe) { - //struct xhci_softc * const sc = pipe->device->bus->hci_private; + //struct xhci_softc * const sc = XHCI_PIPE2SC(pipe); XHCIHIST_FUNC(); XHCIHIST_CALLED(); DPRINTFN(15, "%p", pipe, 0, 0, 0); - xhci_unconfigure_endpoint(pipe); + xhci_close_pipe(pipe); } /* ------------ */ @@ -2972,8 +3535,8 @@ static void xhci_timeout(void *addr) { struct xhci_xfer * const xx = addr; - usbd_xfer_handle const xfer = &xx->xx_xfer; - struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; + struct usbd_xfer * const xfer = &xx->xx_xfer; + struct xhci_softc * const sc = XHCI_XFER2SC(xfer); XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -2983,15 +3546,15 @@ xhci_timeout(void *addr) usb_init_task(&xx->xx_abort_task, xhci_timeout_task, addr, USB_TASKQ_MPSAFE); - usb_add_task(xx->xx_xfer.pipe->device, &xx->xx_abort_task, + usb_add_task(xx->xx_xfer.ux_pipe->up_dev, &xx->xx_abort_task, USB_TASKQ_HC); } static void xhci_timeout_task(void *addr) { - usbd_xfer_handle const xfer = addr; - struct xhci_softc * const sc = xfer->pipe->device->bus->hci_private; + struct usbd_xfer * const xfer = addr; + struct xhci_softc * const sc = XHCI_XFER2SC(xfer); XHCIHIST_FUNC(); XHCIHIST_CALLED(); @@ -2999,7 +3562,7 @@ xhci_timeout_task(void *addr) #if 0 xhci_abort_xfer(xfer, USBD_TIMEOUT); #else - xfer->status = USBD_TIMEOUT; + xfer->ux_status = USBD_TIMEOUT; usb_transfer_complete(xfer); #endif mutex_exit(&sc->sc_lock); diff --git a/sys/dev/usb/xhcireg.h b/sys/dev/usb/xhcireg.h index 39872a3bb73..42e1ada3485 100644 --- a/sys/dev/usb/xhcireg.h +++ b/sys/dev/usb/xhcireg.h @@ -1,4 +1,4 @@ -/* $NetBSD: xhcireg.h,v 1.4 2015/12/10 15:51:11 skrll Exp $ */ +/* $NetBSD: xhcireg.h,v 1.5 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2010 Hans Petter Selasky. All rights reserved. @@ -25,8 +25,8 @@ * SUCH DAMAGE. */ -#ifndef _XHCIREG_H_ -#define _XHCIREG_H_ +#ifndef _DEV_USB_XHCIREG_H_ +#define _DEV_USB_XHCIREG_H_ /* XHCI PCI config registers */ #define PCI_CBMEM 0x10 /* configuration base MEM */ @@ -35,6 +35,7 @@ #define PCI_USBREV 0x60 /* RO USB protocol revision */ #define PCI_USBREV_MASK 0xFF #define PCI_USBREV_3_0 0x30 /* USB 3.0 */ + #define PCI_XHCI_FLADJ 0x61 /* RW frame length adjust */ #define PCI_XHCI_INTEL_XUSB2PR 0xD0 /* Intel USB2 Port Routing */ @@ -43,72 +44,87 @@ #define PCI_XHCI_INTEL_USB3PRM 0xDC /* Intel USB3 Port Routing Mask */ /* XHCI capability registers */ -#define XHCI_CAPLENGTH 0x00 /* RO capability */ -#define XHCI_CAP_CAPLENGTH(x) ((x) & 0xFF) -#define XHCI_CAP_HCIVERSION(x) (((x) >> 16) & 0xFFFF) /* RO Interface version number */ -#define XHCI_HCIVERSION_0_9 0x0090 /* xHCI version 0.9 */ -#define XHCI_HCIVERSION_1_0 0x0100 /* xHCI version 1.0 */ +#define XHCI_CAPLENGTH 0x00 /* RO capability */ +#define XHCI_CAP_CAPLENGTH(x) ((x) & 0xFF) +#define XHCI_CAP_HCIVERSION(x) (((x) >> 16) & 0xFFFF) /* RO Interface version number */ +#define XHCI_HCIVERSION_0_9 0x0090 /* xHCI version 0.9 */ +#define XHCI_HCIVERSION_0_96 0x0096 /* xHCI version 0.96 */ +#define XHCI_HCIVERSION_1_0 0x0100 /* xHCI version 1.0 */ + #define XHCI_HCSPARAMS1 0x04 /* RO structual parameters 1 */ -#define XHCI_HCS1_MAXSLOTS(x) ((x) & 0xFF) -#define XHCI_HCS1_MAXINTRS(x) (((x) >> 8) & 0x3FF) -#define XHCI_HCS1_MAXPORTS(x) (((x) >> 24) & 0xFF) +#define XHCI_HCS1_MAXSLOTS(x) ((x) & 0xFF) +#define XHCI_HCS1_MAXINTRS(x) (((x) >> 8) & 0x7FF) +#define XHCI_HCS1_MAXPORTS(x) (((x) >> 24) & 0xFF) + #define XHCI_HCSPARAMS2 0x08 /* RO structual parameters 2 */ -#define XHCI_HCS2_IST(x) ((x) & 0xF) -#define XHCI_HCS2_ERST_MAX(x) (((x) >> 4) & 0xF) -#define XHCI_HCS2_SPR(x) (((x) >> 24) & 0x1) -#define XHCI_HCS2_MAXSPBUF(x) (((x) >> 27) & 0x7F) +#define XHCI_HCS2_IST(x) ((x) & 0xF) +#define XHCI_HCS2_ERST_MAX(x) (((x) >> 4) & 0xF) +#define XHCI_HCS2_SPR(x) (((x) >> 24) & 0x1) +#define XHCI_HCS2_MAXSPBUF(x) (((x) >> 27) & 0x7F) + #define XHCI_HCSPARAMS3 0x0C /* RO structual parameters 3 */ -#define XHCI_HCS3_U1_DEL(x) ((x) & 0xFF) -#define XHCI_HCS3_U2_DEL(x) (((x) >> 16) & 0xFFFF) +#define XHCI_HCS3_U1_DEL(x) ((x) & 0xFF) +#define XHCI_HCS3_U2_DEL(x) (((x) >> 16) & 0xFFFF) + #define XHCI_HCCPARAMS 0x10 /* RO capability parameters */ -#define XHCI_HCC_AC64(x) ((x) & 0x1) /* 64-bit capable */ -#define XHCI_HCC_BNC(x) (((x) >> 1) & 0x1) /* BW negotiation */ -#define XHCI_HCC_CSZ(x) (((x) >> 2) & 0x1) /* context size */ -#define XHCI_HCC_PPC(x) (((x) >> 3) & 0x1) /* port power control */ -#define XHCI_HCC_PIND(x) (((x) >> 4) & 0x1) /* port indicators */ -#define XHCI_HCC_LHRC(x) (((x) >> 5) & 0x1) /* light HC reset */ -#define XHCI_HCC_LTC(x) (((x) >> 6) & 0x1) /* latency tolerance msg */ -#define XHCI_HCC_NSS(x) (((x) >> 7) & 0x1) /* no secondary sid */ -#define XHCI_HCC_MAXPSASIZE(x) (((x) >> 12) & 0xF) /* max pri. stream array size */ -#define XHCI_HCC_XECP(x) (((x) >> 16) & 0xFFFF) /* extended capabilities pointer */ -#define XHCI_DBOFF 0x14 /* RO doorbell offset */ -#define XHCI_RTSOFF 0x18 /* RO runtime register space offset */ +#define XHCI_HCC_AC64(x) (((x) >> 0) & 0x1) /* 64-bit capable */ +#define XHCI_HCC_BNC(x) (((x) >> 1) & 0x1) /* BW negotiation */ +#define XHCI_HCC_CSZ(x) (((x) >> 2) & 0x1) /* context size */ +#define XHCI_HCC_PPC(x) (((x) >> 3) & 0x1) /* port power control */ +#define XHCI_HCC_PIND(x) (((x) >> 4) & 0x1) /* port indicators */ +#define XHCI_HCC_LHRC(x) (((x) >> 5) & 0x1) /* light HC reset */ +#define XHCI_HCC_LTC(x) (((x) >> 6) & 0x1) /* latency tolerance msg */ +#define XHCI_HCC_NSS(x) (((x) >> 7) & 0x1) /* no secondary sid */ +#define XHCI_HCC_PAE(x) (((x) >> 8) & 0x1) /* Pase All Event Data */ +#define XHCI_HCC_SPC(x) (((x) >> 9) & 0x1) /* Short packet */ +#define XHCI_HCC_SEC(x) (((x) >> 10) & 0x1) /* Stopped EDTLA */ +#define XHCI_HCC_CFC(x) (((x) >> 11) & 0x1) /* Configuous Frame ID */ +#define XHCI_HCC_MAXPSASIZE(x) (((x) >> 12) & 0xF) /* max pri. stream array size */ +#define XHCI_HCC_XECP(x) (((x) >> 16) & 0xFFFF) /* extended capabilities pointer */ + +#define XHCI_DBOFF 0x14 /* RO doorbell offset */ +#define XHCI_RTSOFF 0x18 /* RO runtime register space offset */ /* XHCI operational registers. Offset given by XHCI_CAPLENGTH register */ #define XHCI_USBCMD 0x00 /* XHCI command */ -#define XHCI_CMD_RS 0x00000001 /* RW Run/Stop */ -#define XHCI_CMD_HCRST 0x00000002 /* RW Host Controller Reset */ -#define XHCI_CMD_INTE 0x00000004 /* RW Interrupter Enable */ -#define XHCI_CMD_HSEE 0x00000008 /* RW Host System Error Enable */ -#define XHCI_CMD_LHCRST 0x00000080 /* RO/RW Light Host Controller Reset */ -#define XHCI_CMD_CSS 0x00000100 /* RW Controller Save State */ -#define XHCI_CMD_CRS 0x00000200 /* RW Controller Restore State */ -#define XHCI_CMD_EWE 0x00000400 /* RW Enable Wrap Event */ -#define XHCI_CMD_EU3S 0x00000800 /* RW Enable U3 MFINDEX Stop */ +#define XHCI_CMD_RS 0x00000001 /* RW Run/Stop */ +#define XHCI_CMD_HCRST 0x00000002 /* RW Host Controller Reset */ +#define XHCI_CMD_INTE 0x00000004 /* RW Interrupter Enable */ +#define XHCI_CMD_HSEE 0x00000008 /* RW Host System Error Enable */ +#define XHCI_CMD_LHCRST 0x00000080 /* RO/RW Light Host Controller Reset */ +#define XHCI_CMD_CSS 0x00000100 /* RW Controller Save State */ +#define XHCI_CMD_CRS 0x00000200 /* RW Controller Restore State */ +#define XHCI_CMD_EWE 0x00000400 /* RW Enable Wrap Event */ +#define XHCI_CMD_EU3S 0x00000800 /* RW Enable U3 MFINDEX Stop */ + #define XHCI_USBSTS 0x04 /* XHCI status */ -#define XHCI_STS_HCH 0x00000001 /* RO - Host Controller Halted */ -#define XHCI_STS_HSE 0x00000004 /* RW - Host System Error */ -#define XHCI_STS_EINT 0x00000008 /* RW - Event Interrupt */ -#define XHCI_STS_PCD 0x00000010 /* RW - Port Change Detect */ -#define XHCI_STS_SSS 0x00000100 /* RO - Save State Status */ -#define XHCI_STS_RSS 0x00000200 /* RO - Restore State Status */ -#define XHCI_STS_SRE 0x00000400 /* RW - Save/Restore Error */ -#define XHCI_STS_CNR 0x00000800 /* RO - Controller Not Ready */ -#define XHCI_STS_HCE 0x00001000 /* RO - Host Controller Error */ +#define XHCI_STS_HCH 0x00000001 /* RO - Host Controller Halted */ +#define XHCI_STS_HSE 0x00000004 /* RW - Host System Error */ +#define XHCI_STS_EINT 0x00000008 /* RW - Event Interrupt */ +#define XHCI_STS_PCD 0x00000010 /* RW - Port Change Detect */ +#define XHCI_STS_SSS 0x00000100 /* RO - Save State Status */ +#define XHCI_STS_RSS 0x00000200 /* RO - Restore State Status */ +#define XHCI_STS_SRE 0x00000400 /* RW - Save/Restore Error */ +#define XHCI_STS_CNR 0x00000800 /* RO - Controller Not Ready */ +#define XHCI_STS_HCE 0x00001000 /* RO - Host Controller Error */ + #define XHCI_PAGESIZE 0x08 /* XHCI page size mask */ -#define XHCI_PAGESIZE_4K 0x00000001 /* 4K Page Size */ -#define XHCI_PAGESIZE_8K 0x00000002 /* 8K Page Size */ -#define XHCI_PAGESIZE_16K 0x00000004 /* 16K Page Size */ -#define XHCI_PAGESIZE_32K 0x00000008 /* 32K Page Size */ -#define XHCI_PAGESIZE_64K 0x00000010 /* 64K Page Size */ -#define XHCI_DNCTRL 0x14 /* XHCI device notification control */ +#define XHCI_PAGESIZE_4K 0x00000001 /* 4K Page Size */ +#define XHCI_PAGESIZE_8K 0x00000002 /* 8K Page Size */ +#define XHCI_PAGESIZE_16K 0x00000004 /* 16K Page Size */ +#define XHCI_PAGESIZE_32K 0x00000008 /* 32K Page Size */ +#define XHCI_PAGESIZE_64K 0x00000010 /* 64K Page Size */ + +#define XHCI_DNCTRL 0x14 /* XHCI device notification control */ #define XHCI_DNCTRL_MASK(n) (1U << (n)) + #define XHCI_CRCR 0x18 /* XHCI command ring control */ -#define XHCI_CRCR_LO_RCS 0x00000001 /* RW - consumer cycle state */ -#define XHCI_CRCR_LO_CS 0x00000002 /* RW - command stop */ -#define XHCI_CRCR_LO_CA 0x00000004 /* RW - command abort */ -#define XHCI_CRCR_LO_CRR 0x00000008 /* RW - command ring running */ -#define XHCI_CRCR_LO_MASK 0x0000000F +#define XHCI_CRCR_LO_RCS 0x00000001 /* RW - consumer cycle state */ +#define XHCI_CRCR_LO_CS 0x00000002 /* RW - command stop */ +#define XHCI_CRCR_LO_CA 0x00000004 /* RW - command abort */ +#define XHCI_CRCR_LO_CRR 0x00000008 /* RW - command ring running */ +#define XHCI_CRCR_LO_MASK 0x0000000F + #define XHCI_CRCR_HI 0x1C /* XHCI command ring control */ #define XHCI_DCBAAP 0x30 /* XHCI dev context BA pointer */ #define XHCI_DCBAAP_HI 0x34 /* XHCI dev context BA pointer */ @@ -117,78 +133,89 @@ /* XHCI port status registers */ #define XHCI_PORTSC(n) (0x3F0 + (0x10 * (n))) /* XHCI port status */ -#define XHCI_PS_CCS 0x00000001 /* RO - current connect status */ -#define XHCI_PS_PED 0x00000002 /* RW - port enabled / disabled */ -#define XHCI_PS_OCA 0x00000008 /* RO - over current active */ -#define XHCI_PS_PR 0x00000010 /* RW - port reset */ -#define XHCI_PS_PLS_GET(x) (((x) >> 5) & 0xF) /* RW - port link state */ -#define XHCI_PS_PLS_SET(x) (((x) & 0xF) << 5) /* RW - port link state */ -#define XHCI_PS_PP 0x00000200 /* RW - port power */ -#define XHCI_PS_SPEED_GET(x) (((x) >> 10) & 0xF) /* RO - port speed */ -#define XHCI_PS_PIC_GET(x) (((x) >> 14) & 0x3) /* RW - port indicator */ -#define XHCI_PS_PIC_SET(x) (((x) & 0x3) << 14) /* RW - port indicator */ -#define XHCI_PS_LWS 0x00010000 /* RW - port link state write strobe */ -#define XHCI_PS_CSC 0x00020000 /* RW - connect status change */ -#define XHCI_PS_PEC 0x00040000 /* RW - port enable/disable change */ -#define XHCI_PS_WRC 0x00080000 /* RW - warm port reset change */ -#define XHCI_PS_OCC 0x00100000 /* RW - over-current change */ -#define XHCI_PS_PRC 0x00200000 /* RW - port reset change */ -#define XHCI_PS_PLC 0x00400000 /* RW - port link state change */ -#define XHCI_PS_CEC 0x00800000 /* RW - config error change */ -#define XHCI_PS_CAS 0x01000000 /* RO - cold attach status */ -#define XHCI_PS_WCE 0x02000000 /* RW - wake on connect enable */ -#define XHCI_PS_WDE 0x04000000 /* RW - wake on disconnect enable */ -#define XHCI_PS_WOE 0x08000000 /* RW - wake on over-current enable */ -#define XHCI_PS_DR 0x40000000 /* RO - device removable */ -#define XHCI_PS_WPR 0x80000000U /* RW - warm port reset */ -#define XHCI_PS_CLEAR 0x80FF01FFU /* command bits */ +#define XHCI_PS_CCS 0x00000001 /* RO - current connect status */ +#define XHCI_PS_PED 0x00000002 /* RW - port enabled / disabled */ +#define XHCI_PS_OCA 0x00000008 /* RO - over current active */ +#define XHCI_PS_PR 0x00000010 /* RW - port reset */ +#define XHCI_PS_PLS_GET(x) (((x) >> 5) & 0xF) /* RW - port link state */ +#define XHCI_PS_PLS_SET(x) (((x) & 0xF) << 5) /* RW - port link state */ +#define XHCI_PS_PP 0x00000200 /* RW - port power */ +#define XHCI_PS_SPEED_GET(x) (((x) >> 10) & 0xF) /* RO - port speed */ +#define XHCI_PS_SPEED_FS 1 +#define XHCI_PS_SPEED_LS 2 +#define XHCI_PS_SPEED_HS 3 +#define XHCI_PS_SPEED_SS 4 +#define XHCI_PS_PIC_GET(x) (((x) >> 14) & 0x3) /* RW - port indicator */ +#define XHCI_PS_PIC_SET(x) (((x) & 0x3) << 14) /* RW - port indicator */ +#define XHCI_PS_LWS 0x00010000 /* RW - port link state write strobe */ +#define XHCI_PS_CSC 0x00020000 /* RW - connect status change */ +#define XHCI_PS_PEC 0x00040000 /* RW - port enable/disable change */ +#define XHCI_PS_WRC 0x00080000 /* RW - warm port reset change */ +#define XHCI_PS_OCC 0x00100000 /* RW - over-current change */ +#define XHCI_PS_PRC 0x00200000 /* RW - port reset change */ +#define XHCI_PS_PLC 0x00400000 /* RW - port link state change */ +#define XHCI_PS_CEC 0x00800000 /* RW - config error change */ +#define XHCI_PS_CAS 0x01000000 /* RO - cold attach status */ +#define XHCI_PS_WCE 0x02000000 /* RW - wake on connect enable */ +#define XHCI_PS_WDE 0x04000000 /* RW - wake on disconnect enable */ +#define XHCI_PS_WOE 0x08000000 /* RW - wake on over-current enable */ +#define XHCI_PS_DR 0x40000000 /* RO - device removable */ +#define XHCI_PS_WPR 0x80000000U /* RW - warm port reset */ +#define XHCI_PS_CLEAR 0x80FF01FFU /* command bits */ #define XHCI_PORTPMSC(n) (0x3F4 + (0x10 * (n))) /* XHCI status and control */ -#define XHCI_PM3_U1TO_GET(x) (((x) >> 0) & 0xFF) /* RW - U1 timeout */ -#define XHCI_PM3_U1TO_SET(x) (((x) & 0xFF) << 0) /* RW - U1 timeout */ -#define XHCI_PM3_U2TO_GET(x) (((x) >> 8) & 0xFF) /* RW - U2 timeout */ -#define XHCI_PM3_U2TO_SET(x) (((x) & 0xFF) << 8) /* RW - U2 timeout */ -#define XHCI_PM3_FLA 0x00010000 /* RW - Force Link PM Accept */ -#define XHCI_PM2_L1S_GET(x) (((x) >> 0) & 0x7) /* RO - L1 status */ -#define XHCI_PM2_RWE 0x00000008 /* RW - remote wakup enable */ -#define XHCI_PM2_HIRD_GET(x) (((x) >> 4) & 0xF) /* RW - host initiated resume duration */ -#define XHCI_PM2_HIRD_SET(x) (((x) & 0xF) << 4) /* RW - host initiated resume duration */ -#define XHCI_PM2_L1SLOT_GET(x) (((x) >> 8) & 0xFF) /* RW - L1 device slot */ -#define XHCI_PM2_L1SLOT_SET(x) (((x) & 0xFF) << 8) /* RW - L1 device slot */ -#define XHCI_PM2_HLE 0x00010000 /* RW - hardware LPM enable */ +#define XHCI_PM3_U1TO_GET(x) (((x) >> 0) & 0xFF) /* RW - U1 timeout */ +#define XHCI_PM3_U1TO_SET(x) (((x) & 0xFF) << 0) /* RW - U1 timeout */ +#define XHCI_PM3_U2TO_GET(x) (((x) >> 8) & 0xFF) /* RW - U2 timeout */ +#define XHCI_PM3_U2TO_SET(x) (((x) & 0xFF) << 8) /* RW - U2 timeout */ +#define XHCI_PM3_FLA 0x00010000 /* RW - Force Link PM Accept */ +#define XHCI_PM2_L1S_GET(x) (((x) >> 0) & 0x7) /* RO - L1 status */ +#define XHCI_PM2_RWE 0x00000008 /* RW - remote wakup enable */ +#define XHCI_PM2_HIRD_GET(x) (((x) >> 4) & 0xF) /* RW - host initiated resume duration */ +#define XHCI_PM2_HIRD_SET(x) (((x) & 0xF) << 4) /* RW - host initiated resume duration */ +#define XHCI_PM2_L1SLOT_GET(x) (((x) >> 8) & 0xFF) /* RW - L1 device slot */ +#define XHCI_PM2_L1SLOT_SET(x) (((x) & 0xFF) << 8) /* RW - L1 device slot */ +#define XHCI_PM2_HLE 0x00010000 /* RW - hardware LPM enable */ + #define XHCI_PORTLI(n) (0x3F8 + (0x10 * (n))) /* XHCI port link info */ -#define XHCI_PLI3_ERR_GET(x) (((x) >> 0) & 0xFFFF) /* RO - port link errors */ +#define XHCI_PLI3_ERR_GET(x) (((x) >> 0) & 0xFFFF) /* RO - port link errors */ + #define XHCI_PORTRSV(n) (0x3FC + (0x10 * (n))) /* XHCI port reserved */ /* XHCI runtime registers. Offset given by XHCI_CAPLENGTH + XHCI_RTSOFF registers */ #define XHCI_MFINDEX 0x0000 /* RO - microframe index */ #define XHCI_MFINDEX_GET(x) ((x) & 0x3FFF) + #define XHCI_IMAN(n) (0x0020 + (0x20 * (n))) /* XHCI interrupt management */ -#define XHCI_IMAN_INTR_PEND 0x00000001 /* RW - interrupt pending */ -#define XHCI_IMAN_INTR_ENA 0x00000002 /* RW - interrupt enable */ +#define XHCI_IMAN_INTR_PEND 0x00000001 /* RW - interrupt pending */ +#define XHCI_IMAN_INTR_ENA 0x00000002 /* RW - interrupt enable */ + #define XHCI_IMOD(n) (0x0024 + (0x20 * (n))) /* XHCI interrupt moderation */ -#define XHCI_IMOD_IVAL_GET(x) (((x) >> 0) & 0xFFFF) /* 250ns unit */ -#define XHCI_IMOD_IVAL_SET(x) (((x) & 0xFFFF) << 0) /* 250ns unit */ -#define XHCI_IMOD_ICNT_GET(x) (((x) >> 16) & 0xFFFF) /* 250ns unit */ -#define XHCI_IMOD_ICNT_SET(x) (((x) & 0xFFFF) << 16) /* 250ns unit */ -#define XHCI_IMOD_DEFAULT 0x000001F4U /* 8000 IRQ/second */ -#define XHCI_IMOD_DEFAULT_LP 0x000003E8U /* 4000 IRQ/sec for LynxPoint */ +#define XHCI_IMOD_IVAL_GET(x) (((x) >> 0) & 0xFFFF) /* 250ns unit */ +#define XHCI_IMOD_IVAL_SET(x) (((x) & 0xFFFF) << 0) /* 250ns unit */ +#define XHCI_IMOD_ICNT_GET(x) (((x) >> 16) & 0xFFFF) /* 250ns unit */ +#define XHCI_IMOD_ICNT_SET(x) (((x) & 0xFFFF) << 16) /* 250ns unit */ +#define XHCI_IMOD_DEFAULT 0x000001F4U /* 8000 IRQ/second */ +#define XHCI_IMOD_DEFAULT_LP 0x000003E8U /* 4000 IRQ/sec for LynxPoint */ + #define XHCI_ERSTSZ(n) (0x0028 + (0x20 * (n))) /* XHCI event ring segment table size */ -#define XHCI_ERSTS_GET(x) ((x) & 0xFFFF) -#define XHCI_ERSTS_SET(x) ((x) & 0xFFFF) -#define XHCI_ERSTBA(n) (0x0030 + (0x20 * (n))) /* XHCI event ring segment table BA */ +#define XHCI_ERSTS_GET(x) ((x) & 0xFFFF) +#define XHCI_ERSTS_SET(x) ((x) & 0xFFFF) + +#define XHCI_ERSTBA(n) (0x0030 + (0x20 * (n))) /* XHCI event ring segment table BA */ #define XHCI_ERSTBA_HI(n) (0x0034 + (0x20 * (n))) /* XHCI event ring segment table BA */ -#define XHCI_ERDP(n) (0x0038 + (0x20 * (n))) /* XHCI event ring dequeue pointer */ -#define XHCI_ERDP_LO_SINDEX(x) ((x) & 0x7) /* RO - dequeue segment index */ -#define XHCI_ERDP_LO_BUSY 0x00000008 /* RW - event handler busy */ -#define XHCI_ERDP_HI(n) (0x003C + (0x20 * (n))) /* XHCI event ring dequeue pointer */ + +#define XHCI_ERDP(n) (0x0038 + (0x20 * (n))) /* XHCI event ring dequeue pointer */ +#define XHCI_ERDP_HI(n) (0x003C + (0x20 * (n))) /* XHCI event ring dequeue pointer */ +#define XHCI_ERDP_LO_SINDEX(x) ((x) & 0x7) /* RO - dequeue segment index */ +#define XHCI_ERDP_LO_BUSY 0x00000008 /* RW - event handler busy */ /* XHCI doorbell registers. Offset given by XHCI_CAPLENGTH + XHCI_DBOFF registers */ #define XHCI_DOORBELL(n) (0x0000 + (4 * (n))) -#define XHCI_DB_TARGET_GET(x) ((x) & 0xFF) /* RW - doorbell target */ -#define XHCI_DB_TARGET_SET(x) ((x) & 0xFF) /* RW - doorbell target */ -#define XHCI_DB_SID_GET(x) (((x) >> 16) & 0xFFFF) /* RW - doorbell stream ID */ -#define XHCI_DB_SID_SET(x) (((x) & 0xFFFF) << 16) /* RW - doorbell stream ID */ +#define XHCI_DB_TARGET_GET(x) ((x) & 0xFF) /* RW - doorbell target */ +#define XHCI_DB_TARGET_SET(x) ((x) & 0xFF) /* RW - doorbell target */ +#define XHCI_DB_SID_GET(x) (((x) >> 16) & 0xFFFF) /* RW - doorbell stream ID */ +#define XHCI_DB_SID_SET(x) (((x) & 0xFFFF) << 16) /* RW - doorbell stream ID */ /* XHCI legacy support */ #define XHCI_XECP_ID(x) ((x) & 0xFF) @@ -343,6 +370,7 @@ struct xhci_trb { #define XHCI_TRB_ERROR_CMD_ABORTED 0x19 #define XHCI_TRB_ERROR_STOPPED 0x1A #define XHCI_TRB_ERROR_LENGTH 0x1B +#define XHCI_TRB_ERROR_STOPPED_SHORT 0x1C #define XHCI_TRB_ERROR_BAD_MELAT 0x1D #define XHCI_TRB_ERROR_ISOC_OVERRUN 0x1F #define XHCI_TRB_ERROR_EVENT_LOST 0x20 @@ -406,6 +434,9 @@ struct xhci_trb { #define XHCI_EPCTX_0_LSA_GET(x) (((x) >> 15) & 0x1) #define XHCI_EPCTX_0_IVAL_SET(x) (((x) & 0xFF) << 16) #define XHCI_EPCTX_0_IVAL_GET(x) (((x) >> 16) & 0xFF) +#define XHCI_EPCTX_0_MAX_ESIT_PAYLOAD_HI_MASK __BITS(31,24) +#define XHCI_EPCTX_0_MAX_ESIT_PAYLOAD_HI_SET(x) __SHIFTIN((x), XHCI_EPCTX_0_MAX_ESIT_PAYLOAD_HI_MASK) +#define XHCI_EPCTX_0_MAX_ESIT_PAYLOAD_HI_GET(x) __SHIFTOUT((x), XHCI_EPCTX_0_MAX_ESIT_PAYLOAD_HI_MASK) #define XHCI_EPCTX_1_CERR_SET(x) (((x) & 0x3) << 1) #define XHCI_EPCTX_1_CERR_GET(x) (((x) >> 1) & 0x3) @@ -442,4 +473,4 @@ struct xhci_erste { } __packed __aligned(XHCI_ERSTE_ALIGN); #define XHCI_ERSTE_SIZE sizeof(struct xhci_erste) -#endif /* _XHCIREG_H_ */ +#endif /* _DEV_USB_XHCIREG_H_ */ diff --git a/sys/dev/usb/xhcivar.h b/sys/dev/usb/xhcivar.h index 7ddbaa2662b..6159629aad1 100644 --- a/sys/dev/usb/xhcivar.h +++ b/sys/dev/usb/xhcivar.h @@ -1,4 +1,4 @@ -/* $NetBSD: xhcivar.h,v 1.4 2014/03/10 13:12:02 skrll Exp $ */ +/* $NetBSD: xhcivar.h,v 1.5 2016/04/23 10:15:32 skrll Exp $ */ /* * Copyright (c) 2013 Jonathan A. Kollasch @@ -31,12 +31,21 @@ #include <sys/pool.h> +#define XHCI_XFER_NTRB 20 + struct xhci_xfer { struct usbd_xfer xx_xfer; struct usb_task xx_abort_task; - struct xhci_trb xx_trb[20]; + struct xhci_trb xx_trb[XHCI_XFER_NTRB]; }; +#define XHCI_BUS2SC(bus) ((bus)->ub_hcpriv) +#define XHCI_PIPE2SC(pipe) XHCI_BUS2SC((pipe)->up_dev->ud_bus) +#define XHCI_XFER2SC(xfer) XHCI_BUS2SC((xfer)->ux_bus) +#define XHCI_XPIPE2SC(d) XHCI_BUS2SC((d)->xp_pipe.up_dev->ud_bus) + +#define XHCI_XFER2XXFER(xfer) ((struct xhci_xfer *)(xfer)) + struct xhci_ring { usb_dma_t xr_dma; kmutex_t xr_lock; @@ -62,7 +71,6 @@ struct xhci_slot { struct xhci_softc { device_t sc_dev; device_t sc_child; - void *sc_ih; bus_size_t sc_ios; bus_space_tag_t sc_iot; bus_space_handle_t sc_ioh; /* Base */ @@ -76,7 +84,10 @@ struct xhci_softc { kmutex_t sc_intr_lock; kcondvar_t sc_softwake_cv; - usbd_xfer_handle sc_intrxfer; + char sc_vendor[32]; /* vendor string for root hub */ + int sc_id_vendor; /* vendor ID for root hub */ + + struct usbd_xfer *sc_intrxfer; pool_cache_t sc_xferpool; @@ -103,8 +114,6 @@ struct xhci_softc { usb_dma_t sc_spbufarray_dma; usb_dma_t *sc_spbuf_dma; - //struct usb_dma_reserve sc_dma_reserve; - kcondvar_t sc_command_cv; bus_addr_t sc_command_addr; struct xhci_trb sc_result_trb; @@ -112,8 +121,12 @@ struct xhci_softc { bool sc_ac64; bool sc_dying; - uint8_t sc_addr; - uint8_t sc_conf; + void (*sc_vendor_init)(struct xhci_softc *); + int (*sc_vendor_port_status)(struct xhci_softc *, uint32_t, int); + + int sc_quirks; +#define XHCI_QUIRK_FORCE_INTR __BIT(0) /* force interrupt reading */ +#define XHCI_QUIRK_INTEL __BIT(1) /* Intel xhci chip */ }; int xhci_init(struct xhci_softc *); diff --git a/sys/dev/usb/xinput_rdesc.h b/sys/dev/usb/xinput_rdesc.h index 269e5f07d8b..9a6933db7db 100644 --- a/sys/dev/usb/xinput_rdesc.h +++ b/sys/dev/usb/xinput_rdesc.h @@ -1,4 +1,4 @@ -/* $NetBSD: xinput_rdesc.h,v 1.1 2011/07/30 12:15:44 jmcneill Exp $ */ +/* $NetBSD: xinput_rdesc.h,v 1.2 2016/04/23 10:15:32 skrll Exp $ */ /*- * Copyright (c) 2011 Jared D. McNeill <jmcneill@invisible.ca> @@ -30,10 +30,10 @@ * Descriptor from http://euc.jp/periphs/xbox-pad-report-desc.txt */ -#define USBIF_IS_XINPUT(uaa) \ - ((uaa)->class == UICLASS_VENDOR && \ - (uaa)->subclass == 0x5d && \ - (uaa)->proto == 0x01) +#define USBIF_IS_XINPUT(uiaa) \ + ((uiaa)->uiaa_class == UICLASS_VENDOR && \ + (uiaa)->uiaa_subclass == 0x5d && \ + (uiaa)->uiaa_proto == 0x01) static const uByte uhid_xinput_report_descr[] = { 0x05, 0x01, /* Usage Page (Generic Desktop) */ |
