Home | History | Annotate | Line # | Download | only in usb
vhci.c revision 1.4.2.1
      1  1.4.2.1    ad /*	$NetBSD: vhci.c,v 1.4.2.1 2020/02/29 20:19:17 ad Exp $ */
      2      1.1  maxv 
      3      1.1  maxv /*
      4      1.1  maxv  * Copyright (c) 2019 The NetBSD Foundation, Inc.
      5      1.1  maxv  * All rights reserved.
      6      1.1  maxv  *
      7      1.1  maxv  * This code is derived from software contributed to The NetBSD Foundation
      8      1.1  maxv  * by Maxime Villard.
      9      1.1  maxv  *
     10      1.1  maxv  * Redistribution and use in source and binary forms, with or without
     11      1.1  maxv  * modification, are permitted provided that the following conditions
     12      1.1  maxv  * are met:
     13      1.1  maxv  * 1. Redistributions of source code must retain the above copyright
     14      1.1  maxv  *    notice, this list of conditions and the following disclaimer.
     15      1.1  maxv  * 2. Redistributions in binary form must reproduce the above copyright
     16      1.1  maxv  *    notice, this list of conditions and the following disclaimer in the
     17      1.1  maxv  *    documentation and/or other materials provided with the distribution.
     18      1.1  maxv  *
     19      1.1  maxv  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20      1.1  maxv  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21      1.1  maxv  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22      1.1  maxv  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23      1.1  maxv  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24      1.1  maxv  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25      1.1  maxv  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26      1.1  maxv  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27      1.1  maxv  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28      1.1  maxv  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29      1.1  maxv  * POSSIBILITY OF SUCH DAMAGE.
     30      1.1  maxv  */
     31      1.1  maxv 
     32      1.1  maxv #include <sys/cdefs.h>
     33  1.4.2.1    ad __KERNEL_RCSID(0, "$NetBSD: vhci.c,v 1.4.2.1 2020/02/29 20:19:17 ad Exp $");
     34      1.1  maxv 
     35      1.1  maxv #ifdef _KERNEL_OPT
     36      1.1  maxv #include "opt_usb.h"
     37      1.1  maxv #endif
     38      1.1  maxv 
     39      1.1  maxv #include <sys/param.h>
     40      1.1  maxv 
     41      1.1  maxv #include <sys/bus.h>
     42      1.1  maxv #include <sys/cpu.h>
     43      1.1  maxv #include <sys/conf.h>
     44      1.1  maxv #include <sys/device.h>
     45      1.1  maxv #include <sys/kernel.h>
     46      1.1  maxv #include <sys/kmem.h>
     47      1.1  maxv #include <sys/mutex.h>
     48      1.1  maxv #include <sys/proc.h>
     49      1.1  maxv #include <sys/queue.h>
     50      1.1  maxv #include <sys/systm.h>
     51      1.1  maxv #include <sys/mman.h>
     52      1.1  maxv #include <sys/file.h>
     53      1.1  maxv #include <sys/filedesc.h>
     54      1.1  maxv 
     55      1.1  maxv #include <machine/endian.h>
     56      1.1  maxv 
     57      1.1  maxv #include "ioconf.h"
     58      1.1  maxv 
     59      1.1  maxv #include <dev/usb/usb.h>
     60      1.1  maxv #include <dev/usb/usbdi.h>
     61      1.1  maxv #include <dev/usb/usbdivar.h>
     62      1.1  maxv 
     63      1.1  maxv #include <dev/usb/usbroothub.h>
     64      1.1  maxv 
     65      1.1  maxv #ifdef VHCI_DEBUG
     66      1.1  maxv #define DPRINTF(fmt, ...)	printf(fmt, __VA_ARGS__)
     67      1.1  maxv #else
     68      1.1  maxv #define DPRINTF(fmt, ...)	__nothing
     69      1.1  maxv #endif
     70      1.1  maxv 
     71      1.1  maxv static usbd_status vhci_open(struct usbd_pipe *);
     72      1.1  maxv static void vhci_softintr(void *);
     73      1.1  maxv 
     74      1.1  maxv static struct usbd_xfer *vhci_allocx(struct usbd_bus *, unsigned int);
     75      1.1  maxv static void vhci_freex(struct usbd_bus *, struct usbd_xfer *);
     76      1.1  maxv static void vhci_get_lock(struct usbd_bus *, kmutex_t **);
     77      1.1  maxv static int vhci_roothub_ctrl(struct usbd_bus *, usb_device_request_t *,
     78      1.1  maxv     void *, int);
     79      1.1  maxv 
     80      1.1  maxv static const struct usbd_bus_methods vhci_bus_methods = {
     81      1.1  maxv 	.ubm_open =	vhci_open,
     82      1.1  maxv 	.ubm_softint =	vhci_softintr,
     83      1.1  maxv 	.ubm_dopoll =	NULL,
     84      1.1  maxv 	.ubm_allocx =	vhci_allocx,
     85      1.1  maxv 	.ubm_freex =	vhci_freex,
     86      1.1  maxv 	.ubm_getlock =	vhci_get_lock,
     87      1.1  maxv 	.ubm_rhctrl =	vhci_roothub_ctrl,
     88      1.1  maxv };
     89      1.1  maxv 
     90      1.1  maxv static usbd_status vhci_device_ctrl_transfer(struct usbd_xfer *);
     91      1.1  maxv static usbd_status vhci_device_ctrl_start(struct usbd_xfer *);
     92      1.1  maxv static void vhci_device_ctrl_abort(struct usbd_xfer *);
     93      1.1  maxv static void vhci_device_ctrl_close(struct usbd_pipe *);
     94      1.1  maxv static void vhci_device_ctrl_cleartoggle(struct usbd_pipe *);
     95      1.1  maxv static void vhci_device_ctrl_done(struct usbd_xfer *);
     96      1.1  maxv 
     97      1.1  maxv static const struct usbd_pipe_methods vhci_device_ctrl_methods = {
     98      1.1  maxv 	.upm_init =		NULL,
     99      1.1  maxv 	.upm_fini =		NULL,
    100      1.1  maxv 	.upm_transfer =		vhci_device_ctrl_transfer,
    101      1.1  maxv 	.upm_start =		vhci_device_ctrl_start,
    102      1.1  maxv 	.upm_abort =		vhci_device_ctrl_abort,
    103      1.1  maxv 	.upm_close =		vhci_device_ctrl_close,
    104      1.1  maxv 	.upm_cleartoggle =	vhci_device_ctrl_cleartoggle,
    105      1.1  maxv 	.upm_done =		vhci_device_ctrl_done,
    106      1.1  maxv };
    107      1.1  maxv 
    108      1.1  maxv static usbd_status vhci_root_intr_transfer(struct usbd_xfer *);
    109      1.1  maxv static usbd_status vhci_root_intr_start(struct usbd_xfer *);
    110      1.1  maxv static void vhci_root_intr_abort(struct usbd_xfer *);
    111      1.1  maxv static void vhci_root_intr_close(struct usbd_pipe *);
    112      1.1  maxv static void vhci_root_intr_cleartoggle(struct usbd_pipe *);
    113      1.1  maxv static void vhci_root_intr_done(struct usbd_xfer *);
    114      1.1  maxv 
    115      1.1  maxv static const struct usbd_pipe_methods vhci_root_intr_methods = {
    116      1.1  maxv 	.upm_init =		NULL,
    117      1.1  maxv 	.upm_fini =		NULL,
    118      1.1  maxv 	.upm_transfer =		vhci_root_intr_transfer,
    119      1.1  maxv 	.upm_start =		vhci_root_intr_start,
    120      1.1  maxv 	.upm_abort =		vhci_root_intr_abort,
    121      1.1  maxv 	.upm_close =		vhci_root_intr_close,
    122      1.1  maxv 	.upm_cleartoggle =	vhci_root_intr_cleartoggle,
    123      1.1  maxv 	.upm_done =		vhci_root_intr_done,
    124      1.1  maxv };
    125      1.1  maxv 
    126      1.1  maxv typedef struct vhci_packet {
    127      1.2  maxv 	TAILQ_ENTRY(vhci_packet) portlist;
    128      1.2  maxv 	TAILQ_ENTRY(vhci_packet) xferlist;
    129      1.1  maxv 	struct usbd_xfer *xfer; /* also vxfer */
    130      1.2  maxv 	bool utoh;
    131      1.1  maxv 	uint8_t *buf;
    132      1.1  maxv 	size_t size;
    133      1.1  maxv 	size_t cursor;
    134      1.1  maxv } vhci_packet_t;
    135      1.1  maxv 
    136      1.2  maxv typedef TAILQ_HEAD(, vhci_packet) vhci_packet_list_t;
    137      1.1  maxv 
    138      1.1  maxv typedef struct {
    139      1.1  maxv 	kmutex_t lock;
    140      1.1  maxv 	int status;
    141      1.1  maxv 	int change;
    142      1.1  maxv 	struct {
    143      1.1  maxv 		vhci_packet_list_t usb_to_host;
    144      1.1  maxv 		vhci_packet_list_t host_to_usb;
    145      1.1  maxv 	} pkts_device_ctrl;
    146      1.1  maxv } vhci_port_t;
    147      1.1  maxv 
    148      1.1  maxv typedef struct {
    149      1.1  maxv 	struct usbd_pipe pipe;
    150      1.1  maxv } vhci_pipe_t;
    151      1.1  maxv 
    152      1.1  maxv typedef struct vhci_xfer {
    153      1.1  maxv 	/* General. */
    154      1.1  maxv 	struct usbd_xfer xfer;
    155      1.1  maxv 
    156      1.1  maxv 	/* vHCI-specific. */
    157      1.1  maxv 	size_t refcnt;
    158      1.1  maxv 	vhci_port_t *port;
    159      1.1  maxv 	vhci_packet_list_t pkts;
    160      1.2  maxv 	TAILQ_ENTRY(vhci_xfer) freelist;
    161      1.1  maxv } vhci_xfer_t;
    162      1.1  maxv 
    163      1.2  maxv typedef TAILQ_HEAD(, vhci_xfer) vhci_xfer_list_t;
    164      1.1  maxv 
    165      1.1  maxv #define VHCI_INDEX2PORT(idx)	(idx)
    166      1.1  maxv #define VHCI_NPORTS		4
    167      1.1  maxv 
    168      1.1  maxv typedef struct {
    169      1.1  maxv 	device_t sc_dev;
    170      1.1  maxv 
    171      1.1  maxv 	struct usbd_bus sc_bus;
    172      1.1  maxv 	bool sc_dying;
    173      1.1  maxv 	kmutex_t sc_lock;
    174      1.1  maxv 
    175      1.1  maxv 	/*
    176      1.1  maxv 	 * Intr Root. Used to attach the devices.
    177      1.1  maxv 	 */
    178      1.1  maxv 	struct usbd_xfer *sc_intrxfer;
    179      1.1  maxv 
    180      1.1  maxv 	/*
    181      1.1  maxv 	 * The ports. Zero is for the roothub, one and beyond for the USB
    182      1.1  maxv 	 * devices.
    183      1.1  maxv 	 */
    184      1.1  maxv 	size_t sc_nports;
    185      1.1  maxv 	vhci_port_t sc_port[VHCI_NPORTS];
    186      1.1  maxv 
    187      1.1  maxv 	device_t sc_child; /* /dev/usb# device */
    188      1.1  maxv } vhci_softc_t;
    189      1.1  maxv 
    190      1.1  maxv typedef struct {
    191      1.1  maxv 	u_int port;
    192      1.1  maxv 	vhci_softc_t *softc;
    193      1.1  maxv } vhci_fd_t;
    194      1.1  maxv 
    195      1.1  maxv extern struct cfdriver vhci_cd;
    196      1.1  maxv 
    197      1.1  maxv /* -------------------------------------------------------------------------- */
    198      1.1  maxv 
    199      1.1  maxv static void
    200      1.1  maxv vhci_pkt_create(vhci_port_t *port, struct usbd_xfer *xfer, bool usb_to_host)
    201      1.1  maxv {
    202      1.1  maxv 	vhci_xfer_t *vxfer = (vhci_xfer_t *)xfer;
    203      1.1  maxv 	vhci_packet_list_t *reqlist, *pktlist;
    204      1.2  maxv 	vhci_packet_t *req, *pkt = NULL;
    205      1.2  maxv 	size_t refcnt = 0;
    206      1.1  maxv 
    207      1.1  maxv 	/* Setup packet. */
    208      1.1  maxv 	reqlist = &port->pkts_device_ctrl.host_to_usb;
    209      1.1  maxv 	req = kmem_zalloc(sizeof(*req), KM_SLEEP);
    210      1.1  maxv 	req->xfer = xfer;
    211      1.2  maxv 	req->utoh = false;
    212      1.1  maxv 	req->buf = (uint8_t *)&xfer->ux_request;
    213      1.1  maxv 	req->size = sizeof(xfer->ux_request);
    214      1.1  maxv 	req->cursor = 0;
    215      1.2  maxv 	refcnt++;
    216      1.1  maxv 
    217      1.1  maxv 	/* Data packet. */
    218      1.2  maxv 	if (xfer->ux_length > 0) {
    219      1.2  maxv 		if (usb_to_host) {
    220      1.2  maxv 			pktlist = &port->pkts_device_ctrl.usb_to_host;
    221      1.2  maxv 		} else {
    222      1.2  maxv 			pktlist = &port->pkts_device_ctrl.host_to_usb;
    223      1.2  maxv 		}
    224      1.2  maxv 		pkt = kmem_zalloc(sizeof(*pkt), KM_SLEEP);
    225      1.2  maxv 		pkt->xfer = xfer;
    226      1.2  maxv 		pkt->utoh = usb_to_host;
    227      1.2  maxv 		pkt->buf = xfer->ux_buf;
    228      1.2  maxv 		pkt->size = xfer->ux_length;
    229      1.2  maxv 		pkt->cursor = 0;
    230      1.2  maxv 		refcnt++;
    231      1.1  maxv 	}
    232      1.1  maxv 
    233      1.1  maxv 	/* Insert in the xfer. */
    234      1.2  maxv 	vxfer->refcnt = refcnt;
    235      1.1  maxv 	vxfer->port = port;
    236      1.2  maxv 	TAILQ_INIT(&vxfer->pkts);
    237      1.2  maxv 	TAILQ_INSERT_TAIL(&vxfer->pkts, req, xferlist);
    238      1.2  maxv 	if (pkt != NULL)
    239      1.2  maxv 		TAILQ_INSERT_TAIL(&vxfer->pkts, pkt, xferlist);
    240      1.1  maxv 
    241      1.1  maxv 	/* Insert in the port. */
    242      1.3  maxv 	KASSERT(mutex_owned(&port->lock));
    243      1.2  maxv 	TAILQ_INSERT_TAIL(reqlist, req, portlist);
    244      1.2  maxv 	if (pkt != NULL)
    245      1.2  maxv 		TAILQ_INSERT_TAIL(pktlist, pkt, portlist);
    246      1.1  maxv }
    247      1.1  maxv 
    248      1.1  maxv static void
    249      1.1  maxv vhci_pkt_destroy(vhci_softc_t *sc, vhci_packet_t *pkt)
    250      1.1  maxv {
    251      1.1  maxv 	struct usbd_xfer *xfer = pkt->xfer;
    252      1.1  maxv 	vhci_xfer_t *vxfer = (vhci_xfer_t *)xfer;
    253      1.1  maxv 	vhci_port_t *port = vxfer->port;
    254      1.2  maxv 	vhci_packet_list_t *pktlist;
    255      1.1  maxv 
    256      1.1  maxv 	KASSERT(mutex_owned(&port->lock));
    257      1.1  maxv 
    258      1.2  maxv 	if (pkt->utoh) {
    259      1.2  maxv 		pktlist = &port->pkts_device_ctrl.usb_to_host;
    260      1.2  maxv 	} else {
    261      1.2  maxv 		pktlist = &port->pkts_device_ctrl.host_to_usb;
    262      1.2  maxv 	}
    263      1.2  maxv 	TAILQ_REMOVE(pktlist, pkt, portlist);
    264      1.2  maxv 
    265      1.2  maxv 	TAILQ_REMOVE(&vxfer->pkts, pkt, xferlist);
    266      1.1  maxv 	kmem_free(pkt, sizeof(*pkt));
    267      1.1  maxv 
    268      1.1  maxv 	KASSERT(vxfer->refcnt > 0);
    269      1.1  maxv 	vxfer->refcnt--;
    270      1.1  maxv 	if (vxfer->refcnt > 0)
    271      1.1  maxv 		return;
    272      1.1  maxv 
    273      1.2  maxv 	KASSERT(TAILQ_FIRST(&vxfer->pkts) == NULL);
    274      1.1  maxv }
    275      1.1  maxv 
    276      1.1  maxv /* -------------------------------------------------------------------------- */
    277      1.1  maxv 
    278      1.1  maxv static usbd_status
    279      1.1  maxv vhci_open(struct usbd_pipe *pipe)
    280      1.1  maxv {
    281      1.1  maxv 	struct usbd_device *dev = pipe->up_dev;
    282      1.1  maxv 	struct usbd_bus *bus = dev->ud_bus;
    283      1.1  maxv 	usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc;
    284      1.1  maxv 	vhci_softc_t *sc = bus->ub_hcpriv;
    285      1.1  maxv 	uint8_t addr = dev->ud_addr;
    286      1.1  maxv 
    287      1.1  maxv 	if (sc->sc_dying)
    288      1.1  maxv 		return USBD_IOERROR;
    289      1.1  maxv 
    290      1.1  maxv 	DPRINTF("%s: called, type=%d\n", __func__,
    291      1.1  maxv 	    UE_GET_XFERTYPE(ed->bmAttributes));
    292      1.1  maxv 
    293      1.1  maxv 	if (addr == bus->ub_rhaddr) {
    294      1.1  maxv 		switch (ed->bEndpointAddress) {
    295      1.1  maxv 		case USB_CONTROL_ENDPOINT:
    296      1.1  maxv 			DPRINTF("%s: roothub_ctrl\n", __func__);
    297      1.1  maxv 			pipe->up_methods = &roothub_ctrl_methods;
    298      1.1  maxv 			break;
    299      1.1  maxv 		case UE_DIR_IN | USBROOTHUB_INTR_ENDPT:
    300      1.1  maxv 			DPRINTF("%s: root_intr\n", __func__);
    301      1.1  maxv 			pipe->up_methods = &vhci_root_intr_methods;
    302      1.1  maxv 			break;
    303      1.1  maxv 		default:
    304      1.1  maxv 			DPRINTF("%s: inval\n", __func__);
    305      1.1  maxv 			return USBD_INVAL;
    306      1.1  maxv 		}
    307      1.1  maxv 	} else {
    308      1.1  maxv 		switch (UE_GET_XFERTYPE(ed->bmAttributes)) {
    309      1.1  maxv 		case UE_CONTROL:
    310      1.1  maxv 			pipe->up_methods = &vhci_device_ctrl_methods;
    311      1.1  maxv 			break;
    312      1.1  maxv 		case UE_BULK:
    313      1.1  maxv 		case UE_INTERRUPT:
    314      1.1  maxv 		default:
    315      1.1  maxv 			goto bad;
    316      1.1  maxv 		}
    317      1.1  maxv 	}
    318      1.1  maxv 
    319      1.1  maxv 	return USBD_NORMAL_COMPLETION;
    320      1.1  maxv 
    321      1.1  maxv bad:
    322      1.1  maxv 	return USBD_NOMEM;
    323      1.1  maxv }
    324      1.1  maxv 
    325      1.1  maxv static void
    326      1.1  maxv vhci_softintr(void *v)
    327      1.1  maxv {
    328      1.1  maxv 	DPRINTF("%s: called\n", __func__);
    329      1.1  maxv }
    330      1.1  maxv 
    331      1.1  maxv static struct usbd_xfer *
    332      1.1  maxv vhci_allocx(struct usbd_bus *bus, unsigned int nframes)
    333      1.1  maxv {
    334      1.1  maxv 	vhci_xfer_t *vxfer;
    335      1.1  maxv 
    336      1.1  maxv 	vxfer = kmem_zalloc(sizeof(*vxfer), KM_SLEEP);
    337      1.1  maxv #ifdef DIAGNOSTIC
    338      1.1  maxv 	vxfer->xfer.ux_state = XFER_BUSY;
    339      1.1  maxv #endif
    340      1.1  maxv 	return (struct usbd_xfer *)vxfer;
    341      1.1  maxv }
    342      1.1  maxv 
    343      1.1  maxv static void
    344      1.1  maxv vhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
    345      1.1  maxv {
    346      1.1  maxv 	vhci_xfer_t *vxfer = (vhci_xfer_t *)xfer;
    347      1.1  maxv 
    348      1.1  maxv 	KASSERT(vxfer->refcnt == 0);
    349      1.2  maxv 	KASSERT(TAILQ_FIRST(&vxfer->pkts) == NULL);
    350      1.1  maxv 
    351      1.1  maxv #ifdef DIAGNOSTIC
    352      1.1  maxv 	vxfer->xfer.ux_state = XFER_FREE;
    353      1.1  maxv #endif
    354      1.1  maxv 	kmem_free(vxfer, sizeof(*vxfer));
    355      1.1  maxv }
    356      1.1  maxv 
    357      1.1  maxv static void
    358      1.1  maxv vhci_get_lock(struct usbd_bus *bus, kmutex_t **lock)
    359      1.1  maxv {
    360      1.1  maxv 	vhci_softc_t *sc = bus->ub_hcpriv;
    361      1.1  maxv 
    362      1.1  maxv 	*lock = &sc->sc_lock;
    363      1.1  maxv }
    364      1.1  maxv 
    365      1.1  maxv static int
    366      1.1  maxv vhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
    367      1.1  maxv     void *buf, int buflen)
    368      1.1  maxv {
    369      1.1  maxv 	vhci_softc_t *sc = bus->ub_hcpriv;
    370      1.1  maxv 	vhci_port_t *port;
    371      1.1  maxv 	usb_hub_descriptor_t hubd;
    372      1.1  maxv 	uint16_t len, value, index;
    373      1.1  maxv 	int totlen = 0;
    374      1.1  maxv 
    375      1.1  maxv 	len = UGETW(req->wLength);
    376      1.1  maxv 	value = UGETW(req->wValue);
    377      1.1  maxv 	index = UGETW(req->wIndex);
    378      1.1  maxv 
    379      1.1  maxv #define C(x,y) ((x) | ((y) << 8))
    380      1.1  maxv 	switch (C(req->bRequest, req->bmRequestType)) {
    381      1.1  maxv 	case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
    382      1.1  maxv 		switch (value) {
    383      1.1  maxv 		case C(0, UDESC_DEVICE): {
    384      1.1  maxv 			usb_device_descriptor_t devd;
    385      1.1  maxv 
    386      1.1  maxv 			totlen = uimin(buflen, sizeof(devd));
    387      1.1  maxv 			memcpy(&devd, buf, totlen);
    388      1.1  maxv 			USETW(devd.idVendor, 0);
    389      1.1  maxv 			USETW(devd.idProduct, 0);
    390      1.1  maxv 			memcpy(buf, &devd, totlen);
    391      1.1  maxv 			break;
    392      1.1  maxv 		}
    393      1.1  maxv #define sd ((usb_string_descriptor_t *)buf)
    394      1.1  maxv 		case C(1, UDESC_STRING):
    395      1.1  maxv 			/* Vendor */
    396      1.1  maxv 			totlen = usb_makestrdesc(sd, len, "NetBSD");
    397      1.1  maxv 			break;
    398      1.1  maxv 		case C(2, UDESC_STRING):
    399      1.1  maxv 			/* Product */
    400      1.1  maxv 			totlen = usb_makestrdesc(sd, len, "VHCI root hub");
    401      1.1  maxv 			break;
    402      1.1  maxv #undef sd
    403      1.1  maxv 		default:
    404      1.1  maxv 			/* default from usbroothub */
    405      1.1  maxv 			return buflen;
    406      1.1  maxv 		}
    407      1.1  maxv 		break;
    408      1.1  maxv 
    409      1.1  maxv 	case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
    410      1.1  maxv 		switch (value) {
    411      1.1  maxv 		case UHF_PORT_RESET:
    412      1.1  maxv 			if (index < 1 || index >= sc->sc_nports) {
    413      1.1  maxv 				return -1;
    414      1.1  maxv 			}
    415      1.4  maxv 			port = &sc->sc_port[VHCI_INDEX2PORT(index)];
    416      1.1  maxv 			port->status |= UPS_C_PORT_RESET;
    417      1.1  maxv 			break;
    418      1.1  maxv 		case UHF_PORT_POWER:
    419      1.1  maxv 			break;
    420      1.1  maxv 		default:
    421      1.1  maxv 			return -1;
    422      1.1  maxv 		}
    423      1.1  maxv 		break;
    424      1.1  maxv 
    425      1.1  maxv 	/* Hub requests. */
    426      1.1  maxv 	case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
    427      1.1  maxv 		break;
    428      1.1  maxv 	case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
    429      1.1  maxv 		if (index < 1 || index >= sc->sc_nports) {
    430      1.1  maxv 			return -1;
    431      1.1  maxv 		}
    432      1.4  maxv 		port = &sc->sc_port[VHCI_INDEX2PORT(index)];
    433      1.1  maxv 		switch (value) {
    434      1.1  maxv 		case UHF_PORT_ENABLE:
    435      1.1  maxv 			port->status &= ~UPS_PORT_ENABLED;
    436      1.1  maxv 			break;
    437      1.1  maxv 		case UHF_C_PORT_ENABLE:
    438      1.1  maxv 			port->change |= UPS_C_PORT_ENABLED;
    439      1.1  maxv 			break;
    440      1.1  maxv 		default:
    441      1.1  maxv 			return -1;
    442      1.1  maxv 		}
    443      1.1  maxv 		break;
    444      1.1  maxv 
    445      1.1  maxv 	case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
    446      1.1  maxv 		totlen = uimin(buflen, sizeof(hubd));
    447      1.1  maxv 		memcpy(&hubd, buf, totlen);
    448      1.1  maxv 		hubd.bNbrPorts = sc->sc_nports - 1;
    449      1.1  maxv 		hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE;
    450      1.1  maxv 		totlen = uimin(totlen, hubd.bDescLength);
    451      1.1  maxv 		memcpy(buf, &hubd, totlen);
    452      1.1  maxv 		break;
    453      1.1  maxv 
    454      1.1  maxv 	case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
    455      1.1  maxv 		/* XXX The other HCs do this */
    456      1.1  maxv 		memset(buf, 0, len);
    457      1.1  maxv 		totlen = len;
    458      1.1  maxv 		break;
    459      1.1  maxv 
    460      1.1  maxv 	case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): {
    461      1.1  maxv 		usb_port_status_t ps;
    462      1.1  maxv 
    463      1.1  maxv 		if (index < 1 || index >= sc->sc_nports) {
    464      1.1  maxv 			return -1;
    465      1.1  maxv 		}
    466      1.4  maxv 		port = &sc->sc_port[VHCI_INDEX2PORT(index)];
    467      1.1  maxv 		USETW(ps.wPortStatus, port->status);
    468      1.1  maxv 		USETW(ps.wPortChange, port->change);
    469      1.1  maxv 		totlen = uimin(len, sizeof(ps));
    470      1.1  maxv 		memcpy(buf, &ps, totlen);
    471      1.1  maxv 		break;
    472      1.1  maxv 	}
    473      1.1  maxv 	default:
    474      1.1  maxv 		/* default from usbroothub */
    475      1.1  maxv 		return buflen;
    476      1.1  maxv 	}
    477      1.1  maxv 
    478      1.1  maxv 	return totlen;
    479      1.1  maxv }
    480      1.1  maxv 
    481      1.1  maxv /* -------------------------------------------------------------------------- */
    482      1.1  maxv 
    483      1.1  maxv static usbd_status
    484      1.1  maxv vhci_device_ctrl_transfer(struct usbd_xfer *xfer)
    485      1.1  maxv {
    486      1.1  maxv 	vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
    487      1.1  maxv 	usbd_status err;
    488      1.1  maxv 
    489      1.1  maxv 	DPRINTF("%s: called\n", __func__);
    490      1.1  maxv 
    491      1.1  maxv 	/* Insert last in queue. */
    492      1.1  maxv 	mutex_enter(&sc->sc_lock);
    493      1.1  maxv 	err = usb_insert_transfer(xfer);
    494      1.1  maxv 	mutex_exit(&sc->sc_lock);
    495      1.1  maxv 	if (err)
    496      1.1  maxv 		return err;
    497      1.1  maxv 
    498      1.1  maxv 	/* Pipe isn't running, start first */
    499      1.1  maxv 	return vhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
    500      1.1  maxv }
    501      1.1  maxv 
    502      1.1  maxv static usbd_status
    503      1.1  maxv vhci_device_ctrl_start(struct usbd_xfer *xfer)
    504      1.1  maxv {
    505      1.1  maxv 	usb_device_request_t *req = &xfer->ux_request;
    506      1.1  maxv 	struct usbd_device *dev = xfer->ux_pipe->up_dev;
    507      1.1  maxv 	vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
    508      1.1  maxv 	vhci_port_t *port;
    509      1.1  maxv 	bool polling = sc->sc_bus.ub_usepolling;
    510      1.1  maxv 	bool isread = (req->bmRequestType & UT_READ) != 0;
    511      1.3  maxv 	int portno, ret;
    512      1.1  maxv 
    513      1.1  maxv 	KASSERT(xfer->ux_rqflags & URQ_REQUEST);
    514      1.1  maxv 	KASSERT(dev->ud_myhsport != NULL);
    515      1.1  maxv 	portno = dev->ud_myhsport->up_portno;
    516      1.1  maxv 
    517      1.1  maxv 	DPRINTF("%s: type=0x%02x, len=%d, isread=%d, portno=%d\n",
    518      1.1  maxv 	    __func__, req->bmRequestType, UGETW(req->wLength), isread, portno);
    519      1.1  maxv 
    520      1.1  maxv 	if (sc->sc_dying)
    521      1.1  maxv 		return USBD_IOERROR;
    522      1.1  maxv 
    523      1.1  maxv 	port = &sc->sc_port[portno];
    524      1.1  maxv 
    525      1.1  maxv 	if (!polling)
    526      1.1  maxv 		mutex_enter(&sc->sc_lock);
    527      1.3  maxv 
    528      1.3  maxv 	mutex_enter(&port->lock);
    529      1.3  maxv 	if (port->status & UPS_PORT_ENABLED) {
    530      1.3  maxv 		xfer->ux_status = USBD_IN_PROGRESS;
    531      1.3  maxv 		vhci_pkt_create(port, xfer, isread);
    532      1.3  maxv 		ret = USBD_IN_PROGRESS;
    533      1.3  maxv 	} else {
    534      1.3  maxv 		ret = USBD_IOERROR;
    535      1.3  maxv 	}
    536      1.3  maxv 	mutex_exit(&port->lock);
    537      1.3  maxv 
    538      1.1  maxv 	if (!polling)
    539      1.1  maxv 		mutex_exit(&sc->sc_lock);
    540      1.1  maxv 
    541      1.3  maxv 	return ret;
    542      1.1  maxv }
    543      1.1  maxv 
    544      1.1  maxv static void
    545      1.1  maxv vhci_device_ctrl_abort(struct usbd_xfer *xfer)
    546      1.1  maxv {
    547      1.1  maxv 	vhci_xfer_t *vxfer = (vhci_xfer_t *)xfer;
    548      1.1  maxv 	vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
    549      1.1  maxv 	vhci_port_t *port = vxfer->port;
    550      1.1  maxv 	vhci_packet_t *pkt;
    551      1.1  maxv 
    552      1.1  maxv 	DPRINTF("%s: called\n", __func__);
    553      1.1  maxv 
    554      1.1  maxv 	KASSERT(mutex_owned(&sc->sc_lock));
    555      1.1  maxv 
    556      1.1  maxv 	callout_halt(&xfer->ux_callout, &sc->sc_lock);
    557      1.1  maxv 
    558      1.1  maxv 	KASSERT(xfer->ux_status != USBD_CANCELLED);
    559      1.1  maxv 
    560      1.1  maxv 	/* If anyone else beat us, we're done.  */
    561      1.1  maxv 	if (xfer->ux_status != USBD_IN_PROGRESS)
    562      1.1  maxv 		return;
    563      1.1  maxv 
    564      1.1  maxv 	mutex_enter(&port->lock);
    565      1.3  maxv 	while (vxfer->refcnt > 0) {
    566      1.2  maxv 		pkt = TAILQ_FIRST(&vxfer->pkts);
    567      1.1  maxv 		KASSERT(pkt != NULL);
    568      1.1  maxv 		vhci_pkt_destroy(sc, pkt);
    569      1.1  maxv 	}
    570      1.2  maxv 	KASSERT(TAILQ_FIRST(&vxfer->pkts) == NULL);
    571      1.1  maxv 	mutex_exit(&port->lock);
    572      1.1  maxv 
    573      1.1  maxv 	xfer->ux_status = USBD_CANCELLED;
    574      1.1  maxv 	usb_transfer_complete(xfer);
    575      1.1  maxv 	KASSERT(mutex_owned(&sc->sc_lock));
    576      1.1  maxv }
    577      1.1  maxv 
    578      1.1  maxv static void
    579      1.1  maxv vhci_device_ctrl_close(struct usbd_pipe *pipe)
    580      1.1  maxv {
    581      1.1  maxv 	DPRINTF("%s: called\n", __func__);
    582      1.1  maxv }
    583      1.1  maxv 
    584      1.1  maxv static void
    585      1.1  maxv vhci_device_ctrl_cleartoggle(struct usbd_pipe *pipe)
    586      1.1  maxv {
    587      1.1  maxv 	DPRINTF("%s: called\n", __func__);
    588      1.1  maxv }
    589      1.1  maxv 
    590      1.1  maxv static void
    591      1.1  maxv vhci_device_ctrl_done(struct usbd_xfer *xfer)
    592      1.1  maxv {
    593      1.1  maxv 	DPRINTF("%s: called\n", __func__);
    594      1.1  maxv }
    595      1.1  maxv 
    596      1.1  maxv /* -------------------------------------------------------------------------- */
    597      1.1  maxv 
    598      1.1  maxv static usbd_status
    599      1.1  maxv vhci_root_intr_transfer(struct usbd_xfer *xfer)
    600      1.1  maxv {
    601      1.1  maxv 	vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
    602      1.1  maxv 	usbd_status err;
    603      1.1  maxv 
    604      1.1  maxv 	DPRINTF("%s: called\n", __func__);
    605      1.1  maxv 
    606      1.1  maxv 	/* Insert last in queue. */
    607      1.1  maxv 	mutex_enter(&sc->sc_lock);
    608      1.1  maxv 	err = usb_insert_transfer(xfer);
    609      1.1  maxv 	mutex_exit(&sc->sc_lock);
    610      1.1  maxv 	if (err)
    611      1.1  maxv 		return err;
    612      1.1  maxv 
    613      1.1  maxv 	/* Pipe isn't running, start first */
    614      1.1  maxv 	return vhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
    615      1.1  maxv }
    616      1.1  maxv 
    617      1.1  maxv static usbd_status
    618      1.1  maxv vhci_root_intr_start(struct usbd_xfer *xfer)
    619      1.1  maxv {
    620      1.1  maxv 	vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
    621      1.1  maxv 	const bool polling = sc->sc_bus.ub_usepolling;
    622      1.1  maxv 
    623      1.1  maxv 	DPRINTF("%s: called, len=%zu\n", __func__, (size_t)xfer->ux_length);
    624      1.1  maxv 
    625      1.1  maxv 	if (sc->sc_dying)
    626      1.1  maxv 		return USBD_IOERROR;
    627      1.1  maxv 
    628      1.1  maxv 	if (!polling)
    629      1.1  maxv 		mutex_enter(&sc->sc_lock);
    630  1.4.2.1    ad 	KASSERT(sc->sc_intrxfer == NULL);
    631      1.1  maxv 	sc->sc_intrxfer = xfer;
    632  1.4.2.1    ad 	xfer->ux_status = USBD_IN_PROGRESS;
    633      1.1  maxv 	if (!polling)
    634      1.1  maxv 		mutex_exit(&sc->sc_lock);
    635      1.1  maxv 
    636      1.1  maxv 	return USBD_IN_PROGRESS;
    637      1.1  maxv }
    638      1.1  maxv 
    639      1.1  maxv static void
    640      1.1  maxv vhci_root_intr_abort(struct usbd_xfer *xfer)
    641      1.1  maxv {
    642      1.1  maxv 	vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
    643      1.1  maxv 
    644      1.1  maxv 	DPRINTF("%s: called\n", __func__);
    645      1.1  maxv 
    646      1.1  maxv 	KASSERT(mutex_owned(&sc->sc_lock));
    647      1.1  maxv 	KASSERT(xfer->ux_pipe->up_intrxfer == xfer);
    648      1.1  maxv 
    649  1.4.2.1    ad 	/* If xfer has already completed, nothing to do here.  */
    650  1.4.2.1    ad 	if (sc->sc_intrxfer == NULL)
    651  1.4.2.1    ad 		return;
    652      1.1  maxv 
    653  1.4.2.1    ad 	/*
    654  1.4.2.1    ad 	 * Otherwise, sc->sc_intrxfer had better be this transfer.
    655  1.4.2.1    ad 	 * Cancel it.
    656  1.4.2.1    ad 	 */
    657  1.4.2.1    ad 	KASSERT(sc->sc_intrxfer == xfer);
    658  1.4.2.1    ad 	KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
    659      1.1  maxv 	xfer->ux_status = USBD_CANCELLED;
    660      1.1  maxv 	usb_transfer_complete(xfer);
    661      1.1  maxv }
    662      1.1  maxv 
    663      1.1  maxv static void
    664      1.1  maxv vhci_root_intr_close(struct usbd_pipe *pipe)
    665      1.1  maxv {
    666  1.4.2.1    ad 	vhci_softc_t *sc __diagused = pipe->up_dev->ud_bus->ub_hcpriv;
    667      1.1  maxv 
    668      1.1  maxv 	DPRINTF("%s: called\n", __func__);
    669      1.1  maxv 
    670      1.1  maxv 	KASSERT(mutex_owned(&sc->sc_lock));
    671      1.1  maxv 
    672  1.4.2.1    ad 	/*
    673  1.4.2.1    ad 	 * Caller must guarantee the xfer has completed first, by
    674  1.4.2.1    ad 	 * closing the pipe only after normal completion or an abort.
    675  1.4.2.1    ad 	 */
    676  1.4.2.1    ad 	KASSERT(sc->sc_intrxfer == NULL);
    677      1.1  maxv }
    678      1.1  maxv 
    679      1.1  maxv static void
    680      1.1  maxv vhci_root_intr_cleartoggle(struct usbd_pipe *pipe)
    681      1.1  maxv {
    682      1.1  maxv 	DPRINTF("%s: called\n", __func__);
    683      1.1  maxv }
    684      1.1  maxv 
    685      1.1  maxv static void
    686      1.1  maxv vhci_root_intr_done(struct usbd_xfer *xfer)
    687      1.1  maxv {
    688  1.4.2.1    ad 	vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
    689  1.4.2.1    ad 
    690  1.4.2.1    ad 	KASSERT(mutex_owned(&sc->sc_lock));
    691  1.4.2.1    ad 
    692  1.4.2.1    ad 	/* Claim the xfer so it doesn't get completed again.  */
    693  1.4.2.1    ad 	KASSERT(sc->sc_intrxfer == xfer);
    694  1.4.2.1    ad 	KASSERT(xfer->ux_status != USBD_IN_PROGRESS);
    695  1.4.2.1    ad 	sc->sc_intrxfer = NULL;
    696      1.1  maxv }
    697      1.1  maxv 
    698      1.1  maxv /* -------------------------------------------------------------------------- */
    699      1.1  maxv 
    700      1.1  maxv struct vhci_ioc_get_info {
    701      1.1  maxv 	/* General. */
    702      1.1  maxv 	size_t nports;
    703      1.1  maxv 
    704      1.1  maxv 	/* Current port. */
    705      1.1  maxv 	u_int port;
    706      1.1  maxv 	int status;
    707      1.1  maxv };
    708      1.1  maxv 
    709      1.1  maxv struct vhci_ioc_set_port {
    710      1.1  maxv 	u_int port;
    711      1.1  maxv };
    712      1.1  maxv 
    713      1.1  maxv struct vhci_ioc_usb_attach {
    714      1.1  maxv 	u_int port;
    715      1.1  maxv };
    716      1.1  maxv 
    717      1.1  maxv struct vhci_ioc_usb_detach {
    718      1.1  maxv 	u_int port;
    719      1.1  maxv };
    720      1.1  maxv 
    721      1.1  maxv #define VHCI_IOC_GET_INFO	_IOR('V', 0, struct vhci_ioc_get_info)
    722      1.1  maxv #define VHCI_IOC_SET_PORT	_IOW('V', 1, struct vhci_ioc_set_port)
    723      1.1  maxv #define VHCI_IOC_USB_ATTACH	_IOW('V', 10, struct vhci_ioc_usb_attach)
    724      1.1  maxv #define VHCI_IOC_USB_DETACH	_IOW('V', 11, struct vhci_ioc_usb_detach)
    725      1.1  maxv 
    726      1.1  maxv static int
    727      1.1  maxv vhci_usb_attach(vhci_fd_t *vfd, struct vhci_ioc_usb_attach *args)
    728      1.1  maxv {
    729      1.1  maxv 	vhci_softc_t *sc = vfd->softc;
    730      1.1  maxv 	vhci_port_t *port;
    731      1.1  maxv 	struct usbd_xfer *xfer;
    732      1.1  maxv 	u_char *p;
    733      1.1  maxv 	int ret = 0;
    734      1.1  maxv 
    735      1.1  maxv 	if (args->port == 0 || args->port >= sc->sc_nports)
    736      1.1  maxv 		return EINVAL;
    737      1.1  maxv 	port = &sc->sc_port[args->port];
    738      1.1  maxv 
    739      1.1  maxv 	mutex_enter(&sc->sc_lock);
    740      1.1  maxv 
    741      1.3  maxv 	mutex_enter(&port->lock);
    742      1.1  maxv 	port->status = UPS_CURRENT_CONNECT_STATUS | UPS_PORT_ENABLED |
    743      1.1  maxv 	    UPS_PORT_POWER;
    744      1.1  maxv 	port->change = UPS_C_CONNECT_STATUS | UPS_C_PORT_RESET;
    745      1.3  maxv 	mutex_exit(&port->lock);
    746      1.1  maxv 
    747      1.1  maxv 	xfer = sc->sc_intrxfer;
    748      1.1  maxv 
    749      1.1  maxv 	if (xfer == NULL) {
    750      1.1  maxv 		ret = ENOBUFS;
    751      1.1  maxv 		goto done;
    752      1.1  maxv 	}
    753  1.4.2.1    ad 	KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
    754      1.1  maxv 
    755      1.1  maxv 	p = xfer->ux_buf;
    756      1.1  maxv 	memset(p, 0, xfer->ux_length);
    757      1.1  maxv 	p[0] = __BIT(args->port);
    758      1.1  maxv 	xfer->ux_actlen = xfer->ux_length;
    759      1.1  maxv 	xfer->ux_status = USBD_NORMAL_COMPLETION;
    760      1.1  maxv 
    761      1.1  maxv 	usb_transfer_complete(xfer);
    762      1.1  maxv 
    763      1.1  maxv done:
    764      1.1  maxv 	mutex_exit(&sc->sc_lock);
    765      1.1  maxv 	return ret;
    766      1.1  maxv }
    767      1.1  maxv 
    768      1.1  maxv static void
    769      1.1  maxv vhci_port_flush(vhci_softc_t *sc, vhci_port_t *port)
    770      1.1  maxv {
    771      1.1  maxv 	vhci_packet_list_t *pktlist;
    772      1.1  maxv 	vhci_packet_t *pkt, *nxt;
    773      1.1  maxv 	vhci_xfer_list_t vxferlist;
    774      1.1  maxv 	vhci_xfer_t *vxfer;
    775      1.1  maxv 
    776      1.1  maxv 	KASSERT(mutex_owned(&sc->sc_lock));
    777      1.3  maxv 	KASSERT(mutex_owned(&port->lock));
    778      1.1  maxv 
    779      1.2  maxv 	TAILQ_INIT(&vxferlist);
    780      1.1  maxv 
    781      1.1  maxv 	pktlist = &port->pkts_device_ctrl.host_to_usb;
    782      1.2  maxv 	TAILQ_FOREACH_SAFE(pkt, pktlist, portlist, nxt) {
    783      1.1  maxv 		vxfer = (vhci_xfer_t *)pkt->xfer;
    784      1.1  maxv 		KASSERT(vxfer->xfer.ux_status == USBD_IN_PROGRESS);
    785      1.1  maxv 		vhci_pkt_destroy(sc, pkt);
    786      1.1  maxv 		if (vxfer->refcnt == 0)
    787      1.2  maxv 			TAILQ_INSERT_TAIL(&vxferlist, vxfer, freelist);
    788      1.1  maxv 	}
    789      1.2  maxv 	KASSERT(TAILQ_FIRST(pktlist) == NULL);
    790      1.1  maxv 
    791      1.1  maxv 	pktlist = &port->pkts_device_ctrl.usb_to_host;
    792      1.2  maxv 	TAILQ_FOREACH_SAFE(pkt, pktlist, portlist, nxt) {
    793      1.1  maxv 		vxfer = (vhci_xfer_t *)pkt->xfer;
    794      1.1  maxv 		KASSERT(vxfer->xfer.ux_status == USBD_IN_PROGRESS);
    795      1.1  maxv 		vhci_pkt_destroy(sc, pkt);
    796      1.1  maxv 		if (vxfer->refcnt == 0)
    797      1.2  maxv 			TAILQ_INSERT_TAIL(&vxferlist, vxfer, freelist);
    798      1.1  maxv 	}
    799      1.2  maxv 	KASSERT(TAILQ_FIRST(pktlist) == NULL);
    800      1.1  maxv 
    801      1.2  maxv 	while ((vxfer = TAILQ_FIRST(&vxferlist)) != NULL) {
    802      1.1  maxv 		struct usbd_xfer *xfer = &vxfer->xfer;
    803      1.2  maxv 		TAILQ_REMOVE(&vxferlist, vxfer, freelist);
    804      1.1  maxv 
    805      1.3  maxv 		xfer->ux_status = USBD_TIMEOUT;
    806      1.1  maxv 		usb_transfer_complete(xfer);
    807      1.1  maxv 	}
    808      1.1  maxv }
    809      1.1  maxv 
    810      1.1  maxv static int
    811      1.1  maxv vhci_usb_detach(vhci_fd_t *vfd, struct vhci_ioc_usb_detach *args)
    812      1.1  maxv {
    813      1.1  maxv 	vhci_softc_t *sc = vfd->softc;
    814      1.1  maxv 	vhci_port_t *port;
    815      1.1  maxv 	struct usbd_xfer *xfer;
    816      1.1  maxv 	u_char *p;
    817      1.1  maxv 
    818      1.1  maxv 	if (args->port == 0 || args->port >= sc->sc_nports)
    819      1.1  maxv 		return EINVAL;
    820      1.1  maxv 	port = &sc->sc_port[args->port];
    821      1.1  maxv 
    822      1.1  maxv 	mutex_enter(&sc->sc_lock);
    823      1.1  maxv 
    824      1.1  maxv 	xfer = sc->sc_intrxfer;
    825      1.1  maxv 	if (xfer == NULL) {
    826      1.1  maxv 		mutex_exit(&sc->sc_lock);
    827      1.1  maxv 		return ENOBUFS;
    828      1.1  maxv 	}
    829  1.4.2.1    ad 	KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
    830      1.1  maxv 
    831      1.3  maxv 	mutex_enter(&port->lock);
    832      1.3  maxv 
    833      1.1  maxv 	port->status = 0;
    834      1.1  maxv 	port->change = UPS_C_CONNECT_STATUS | UPS_C_PORT_RESET;
    835      1.1  maxv 
    836      1.1  maxv 	p = xfer->ux_buf;
    837      1.1  maxv 	memset(p, 0, xfer->ux_length);
    838      1.1  maxv 	p[0] = __BIT(args->port);
    839      1.1  maxv 	xfer->ux_actlen = xfer->ux_length;
    840      1.1  maxv 	xfer->ux_status = USBD_NORMAL_COMPLETION;
    841      1.1  maxv 
    842      1.1  maxv 	usb_transfer_complete(xfer);
    843      1.1  maxv 	vhci_port_flush(sc, port);
    844      1.3  maxv 
    845      1.3  maxv 	mutex_exit(&port->lock);
    846      1.1  maxv 	mutex_exit(&sc->sc_lock);
    847      1.1  maxv 	return 0;
    848      1.1  maxv }
    849      1.1  maxv 
    850      1.1  maxv static int
    851      1.1  maxv vhci_get_info(vhci_fd_t *vfd, struct vhci_ioc_get_info *args)
    852      1.1  maxv {
    853      1.1  maxv 	vhci_softc_t *sc = vfd->softc;
    854      1.1  maxv 	vhci_port_t *port;
    855      1.1  maxv 
    856      1.1  maxv 	port = &sc->sc_port[vfd->port];
    857      1.1  maxv 
    858      1.1  maxv 	args->nports = VHCI_NPORTS;
    859      1.1  maxv 	args->port = vfd->port;
    860      1.1  maxv 	mutex_enter(&port->lock);
    861      1.1  maxv 	args->status = port->status;
    862      1.1  maxv 	mutex_exit(&port->lock);
    863      1.1  maxv 
    864      1.1  maxv 	return 0;
    865      1.1  maxv }
    866      1.1  maxv 
    867      1.1  maxv static int
    868      1.1  maxv vhci_set_port(vhci_fd_t *vfd, struct vhci_ioc_set_port *args)
    869      1.1  maxv {
    870      1.1  maxv 	vhci_softc_t *sc = vfd->softc;
    871      1.1  maxv 
    872      1.1  maxv 	if (args->port == 0 || args->port >= sc->sc_nports)
    873      1.1  maxv 		return EINVAL;
    874      1.1  maxv 
    875      1.1  maxv 	vfd->port = args->port;
    876      1.1  maxv 
    877      1.1  maxv 	return 0;
    878      1.1  maxv }
    879      1.1  maxv 
    880      1.1  maxv /* -------------------------------------------------------------------------- */
    881      1.1  maxv 
    882      1.1  maxv static dev_type_open(vhci_fd_open);
    883      1.1  maxv 
    884      1.1  maxv const struct cdevsw vhci_cdevsw = {
    885      1.1  maxv 	.d_open = vhci_fd_open,
    886      1.1  maxv 	.d_close = noclose,
    887      1.1  maxv 	.d_read = noread,
    888      1.1  maxv 	.d_write = nowrite,
    889      1.1  maxv 	.d_ioctl = noioctl,
    890      1.1  maxv 	.d_stop = nostop,
    891      1.1  maxv 	.d_tty = notty,
    892      1.1  maxv 	.d_poll = nopoll,
    893      1.1  maxv 	.d_mmap = nommap,
    894      1.1  maxv 	.d_kqfilter = nokqfilter,
    895      1.1  maxv 	.d_discard = nodiscard,
    896      1.1  maxv 	.d_flag = D_OTHER | D_MPSAFE
    897      1.1  maxv };
    898      1.1  maxv 
    899      1.1  maxv static int vhci_fd_ioctl(file_t *, u_long, void *);
    900      1.1  maxv static int vhci_fd_close(file_t *);
    901      1.1  maxv static int vhci_fd_read(struct file *, off_t *, struct uio *, kauth_cred_t, int);
    902      1.1  maxv static int vhci_fd_write(struct file *, off_t *, struct uio *, kauth_cred_t, int);
    903      1.1  maxv 
    904      1.1  maxv const struct fileops vhci_fileops = {
    905      1.1  maxv 	.fo_read = vhci_fd_read,
    906      1.1  maxv 	.fo_write = vhci_fd_write,
    907      1.1  maxv 	.fo_ioctl = vhci_fd_ioctl,
    908      1.1  maxv 	.fo_fcntl = fnullop_fcntl,
    909      1.1  maxv 	.fo_poll = fnullop_poll,
    910      1.1  maxv 	.fo_stat = fbadop_stat,
    911      1.1  maxv 	.fo_close = vhci_fd_close,
    912      1.1  maxv 	.fo_kqfilter = fnullop_kqfilter,
    913      1.1  maxv 	.fo_restart = fnullop_restart,
    914      1.1  maxv 	.fo_mmap = NULL,
    915      1.1  maxv };
    916      1.1  maxv 
    917      1.1  maxv static int
    918      1.1  maxv vhci_fd_open(dev_t dev, int flags, int type, struct lwp *l)
    919      1.1  maxv {
    920      1.1  maxv 	vhci_fd_t *vfd;
    921      1.1  maxv 	struct file *fp;
    922      1.1  maxv 	int error, fd;
    923      1.1  maxv 
    924      1.1  maxv 	if (minor(dev) != 0)
    925      1.1  maxv 		return EXDEV;
    926      1.1  maxv 	error = fd_allocfile(&fp, &fd);
    927      1.1  maxv 	if (error)
    928      1.1  maxv 		return error;
    929      1.1  maxv 
    930      1.1  maxv 	vfd = kmem_alloc(sizeof(*vfd), KM_SLEEP);
    931      1.1  maxv 	vfd->port = 1;
    932      1.1  maxv 	vfd->softc = device_lookup_private(&vhci_cd, minor(dev));
    933      1.1  maxv 
    934      1.1  maxv 	return fd_clone(fp, fd, flags, &vhci_fileops, vfd);
    935      1.1  maxv }
    936      1.1  maxv 
    937      1.1  maxv static int
    938      1.1  maxv vhci_fd_close(file_t *fp)
    939      1.1  maxv {
    940      1.1  maxv 	struct vhci_ioc_usb_detach args;
    941      1.1  maxv 	vhci_fd_t *vfd = fp->f_data;
    942      1.3  maxv 	int ret __diagused;
    943      1.1  maxv 
    944      1.1  maxv 	KASSERT(vfd != NULL);
    945      1.1  maxv 
    946      1.1  maxv 	args.port = vfd->port;
    947      1.3  maxv 	ret = vhci_usb_detach(vfd, &args);
    948      1.3  maxv 	KASSERT(ret == 0);
    949      1.1  maxv 
    950      1.1  maxv 	kmem_free(vfd, sizeof(*vfd));
    951      1.1  maxv 	fp->f_data = NULL;
    952      1.1  maxv 
    953      1.1  maxv 	return 0;
    954      1.1  maxv }
    955      1.1  maxv 
    956      1.1  maxv static int
    957      1.1  maxv vhci_fd_read(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred,
    958      1.1  maxv     int flags)
    959      1.1  maxv {
    960      1.1  maxv 	vhci_fd_t *vfd = fp->f_data;
    961      1.1  maxv 	vhci_softc_t *sc = vfd->softc;
    962      1.1  maxv 	vhci_packet_list_t *pktlist;
    963      1.1  maxv 	vhci_packet_t *pkt, *nxt;
    964      1.1  maxv 	vhci_xfer_list_t vxferlist;
    965      1.1  maxv 	vhci_xfer_t *vxfer;
    966      1.1  maxv 	vhci_port_t *port;
    967      1.1  maxv 	int error = 0;
    968      1.1  maxv 	uint8_t *buf;
    969      1.1  maxv 	size_t size;
    970      1.1  maxv 
    971      1.1  maxv 	if (uio->uio_resid == 0)
    972      1.1  maxv 		return 0;
    973      1.1  maxv 	port = &sc->sc_port[vfd->port];
    974      1.1  maxv 	pktlist = &port->pkts_device_ctrl.host_to_usb;
    975      1.1  maxv 
    976      1.2  maxv 	TAILQ_INIT(&vxferlist);
    977      1.1  maxv 
    978      1.1  maxv 	mutex_enter(&port->lock);
    979      1.1  maxv 
    980      1.1  maxv 	if (!(port->status & UPS_PORT_ENABLED)) {
    981      1.1  maxv 		error = ENOBUFS;
    982      1.1  maxv 		goto out;
    983      1.1  maxv 	}
    984      1.1  maxv 
    985      1.2  maxv 	TAILQ_FOREACH_SAFE(pkt, pktlist, portlist, nxt) {
    986      1.1  maxv 		vxfer = (vhci_xfer_t *)pkt->xfer;
    987      1.1  maxv 		buf = pkt->buf + pkt->cursor;
    988      1.2  maxv 		KASSERT(pkt->size >= pkt->cursor);
    989      1.1  maxv 		size = uimin(uio->uio_resid, pkt->size - pkt->cursor);
    990      1.1  maxv 
    991      1.1  maxv 		KASSERT(vxfer->xfer.ux_status == USBD_IN_PROGRESS);
    992      1.1  maxv 
    993      1.1  maxv 		error = uiomove(buf, size, uio);
    994      1.1  maxv 		if (error) {
    995      1.1  maxv 			DPRINTF("%s: error = %d\n", __func__, error);
    996      1.1  maxv 			goto out;
    997      1.1  maxv 		}
    998      1.1  maxv 
    999      1.1  maxv 		pkt->cursor += size;
   1000      1.1  maxv 
   1001      1.1  maxv 		if (pkt->cursor == pkt->size) {
   1002      1.1  maxv 			vhci_pkt_destroy(sc, pkt);
   1003      1.1  maxv 			if (vxfer->refcnt == 0) {
   1004      1.2  maxv 				TAILQ_INSERT_TAIL(&vxferlist, vxfer, freelist);
   1005      1.1  maxv 			}
   1006      1.1  maxv 		}
   1007      1.1  maxv 		if (uio->uio_resid == 0) {
   1008      1.1  maxv 			break;
   1009      1.1  maxv 		}
   1010      1.1  maxv 	}
   1011      1.1  maxv 
   1012      1.1  maxv out:
   1013      1.1  maxv 	mutex_exit(&port->lock);
   1014      1.1  maxv 
   1015      1.2  maxv 	while ((vxfer = TAILQ_FIRST(&vxferlist)) != NULL) {
   1016      1.1  maxv 		struct usbd_xfer *xfer = &vxfer->xfer;
   1017      1.2  maxv 		TAILQ_REMOVE(&vxferlist, vxfer, freelist);
   1018      1.1  maxv 
   1019      1.1  maxv 		mutex_enter(&sc->sc_lock);
   1020      1.1  maxv 		xfer->ux_actlen = xfer->ux_length;
   1021      1.1  maxv 		xfer->ux_status = USBD_NORMAL_COMPLETION;
   1022      1.1  maxv 		usb_transfer_complete(xfer);
   1023      1.1  maxv 		mutex_exit(&sc->sc_lock);
   1024      1.1  maxv 	}
   1025      1.1  maxv 
   1026      1.1  maxv 	return error;
   1027      1.1  maxv }
   1028      1.1  maxv 
   1029      1.1  maxv static int
   1030      1.1  maxv vhci_fd_write(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred,
   1031      1.1  maxv     int flags)
   1032      1.1  maxv {
   1033      1.1  maxv 	vhci_fd_t *vfd = fp->f_data;
   1034      1.1  maxv 	vhci_softc_t *sc = vfd->softc;
   1035      1.1  maxv 	vhci_packet_list_t *pktlist;
   1036      1.1  maxv 	vhci_packet_t *pkt, *nxt;
   1037      1.1  maxv 	vhci_xfer_list_t vxferlist;
   1038      1.1  maxv 	vhci_xfer_t *vxfer;
   1039      1.1  maxv 	vhci_port_t *port;
   1040      1.1  maxv 	int error = 0;
   1041      1.1  maxv 	uint8_t *buf;
   1042      1.1  maxv 	size_t size;
   1043      1.1  maxv 
   1044      1.1  maxv 	if (uio->uio_resid == 0)
   1045      1.1  maxv 		return 0;
   1046      1.1  maxv 	port = &sc->sc_port[vfd->port];
   1047      1.1  maxv 	pktlist = &port->pkts_device_ctrl.usb_to_host;
   1048      1.1  maxv 
   1049      1.2  maxv 	TAILQ_INIT(&vxferlist);
   1050      1.1  maxv 
   1051      1.1  maxv 	mutex_enter(&port->lock);
   1052      1.1  maxv 
   1053      1.1  maxv 	if (!(port->status & UPS_PORT_ENABLED)) {
   1054      1.1  maxv 		error = ENOBUFS;
   1055      1.1  maxv 		goto out;
   1056      1.1  maxv 	}
   1057      1.1  maxv 
   1058      1.2  maxv 	TAILQ_FOREACH_SAFE(pkt, pktlist, portlist, nxt) {
   1059      1.1  maxv 		vxfer = (vhci_xfer_t *)pkt->xfer;
   1060      1.1  maxv 		buf = pkt->buf + pkt->cursor;
   1061      1.3  maxv 		KASSERT(pkt->size >= pkt->cursor);
   1062      1.1  maxv 		size = uimin(uio->uio_resid, pkt->size - pkt->cursor);
   1063      1.1  maxv 
   1064      1.1  maxv 		KASSERT(vxfer->xfer.ux_status == USBD_IN_PROGRESS);
   1065      1.1  maxv 
   1066      1.1  maxv 		error = uiomove(buf, size, uio);
   1067      1.1  maxv 		if (error) {
   1068      1.1  maxv 			DPRINTF("%s: error = %d\n", __func__, error);
   1069      1.1  maxv 			goto out;
   1070      1.1  maxv 		}
   1071      1.1  maxv 
   1072      1.1  maxv 		pkt->cursor += size;
   1073      1.1  maxv 
   1074      1.1  maxv 		if (pkt->cursor == pkt->size) {
   1075      1.1  maxv 			vhci_pkt_destroy(sc, pkt);
   1076      1.1  maxv 			if (vxfer->refcnt == 0) {
   1077      1.2  maxv 				TAILQ_INSERT_TAIL(&vxferlist, vxfer, freelist);
   1078      1.1  maxv 			}
   1079      1.1  maxv 		}
   1080      1.1  maxv 		if (uio->uio_resid == 0) {
   1081      1.1  maxv 			break;
   1082      1.1  maxv 		}
   1083      1.1  maxv 	}
   1084      1.1  maxv 
   1085      1.1  maxv out:
   1086      1.1  maxv 	mutex_exit(&port->lock);
   1087      1.1  maxv 
   1088      1.2  maxv 	while ((vxfer = TAILQ_FIRST(&vxferlist)) != NULL) {
   1089      1.1  maxv 		struct usbd_xfer *xfer = &vxfer->xfer;
   1090      1.2  maxv 		TAILQ_REMOVE(&vxferlist, vxfer, freelist);
   1091      1.1  maxv 
   1092      1.1  maxv 		mutex_enter(&sc->sc_lock);
   1093      1.1  maxv 		xfer->ux_actlen = xfer->ux_length;
   1094      1.1  maxv 		xfer->ux_status = USBD_NORMAL_COMPLETION;
   1095      1.1  maxv 		usb_transfer_complete(xfer);
   1096      1.1  maxv 		mutex_exit(&sc->sc_lock);
   1097      1.1  maxv 	}
   1098      1.1  maxv 
   1099      1.1  maxv 	return error;
   1100      1.1  maxv }
   1101      1.1  maxv 
   1102      1.1  maxv static int
   1103      1.1  maxv vhci_fd_ioctl(file_t *fp, u_long cmd, void *data)
   1104      1.1  maxv {
   1105      1.1  maxv 	vhci_fd_t *vfd = fp->f_data;
   1106      1.1  maxv 
   1107      1.1  maxv 	KASSERT(vfd != NULL);
   1108      1.1  maxv 
   1109      1.1  maxv 	switch (cmd) {
   1110      1.1  maxv 	case VHCI_IOC_GET_INFO:
   1111      1.1  maxv 		return vhci_get_info(vfd, data);
   1112      1.1  maxv 	case VHCI_IOC_SET_PORT:
   1113      1.1  maxv 		return vhci_set_port(vfd, data);
   1114      1.1  maxv 	case VHCI_IOC_USB_ATTACH:
   1115      1.1  maxv 		return vhci_usb_attach(vfd, data);
   1116      1.1  maxv 	case VHCI_IOC_USB_DETACH:
   1117      1.1  maxv 		return vhci_usb_detach(vfd, data);
   1118      1.1  maxv 	default:
   1119      1.1  maxv 		return EINVAL;
   1120      1.1  maxv 	}
   1121      1.1  maxv }
   1122      1.1  maxv 
   1123      1.1  maxv /* -------------------------------------------------------------------------- */
   1124      1.1  maxv 
   1125      1.1  maxv static int vhci_match(device_t, cfdata_t, void *);
   1126      1.1  maxv static void vhci_attach(device_t, device_t, void *);
   1127      1.3  maxv static int vhci_activate(device_t, enum devact);
   1128      1.1  maxv 
   1129      1.1  maxv CFATTACH_DECL_NEW(vhci, sizeof(vhci_softc_t), vhci_match, vhci_attach,
   1130      1.3  maxv     NULL, vhci_activate);
   1131      1.1  maxv 
   1132      1.1  maxv void
   1133      1.1  maxv vhciattach(int nunits)
   1134      1.1  maxv {
   1135      1.1  maxv 	static struct cfdata vhci_cfdata = {
   1136      1.1  maxv 		.cf_name = "vhci",
   1137      1.1  maxv 		.cf_atname = "vhci",
   1138      1.1  maxv 		.cf_unit = 0,
   1139      1.1  maxv 		.cf_fstate = FSTATE_STAR,
   1140      1.1  maxv 	};
   1141      1.1  maxv 	int error;
   1142      1.1  maxv 
   1143      1.1  maxv 	error = config_cfattach_attach(vhci_cd.cd_name, &vhci_ca);
   1144      1.1  maxv 	if (error) {
   1145      1.1  maxv 		aprint_error("%s: unable to register cfattach\n",
   1146      1.1  maxv 		    vhci_cd.cd_name);
   1147      1.1  maxv 		(void)config_cfdriver_detach(&vhci_cd);
   1148      1.1  maxv 		return;
   1149      1.1  maxv 	}
   1150      1.1  maxv 
   1151      1.1  maxv 	config_attach_pseudo(&vhci_cfdata);
   1152      1.1  maxv }
   1153      1.1  maxv 
   1154      1.1  maxv static int
   1155      1.3  maxv vhci_activate(device_t self, enum devact act)
   1156      1.3  maxv {
   1157      1.3  maxv 	vhci_softc_t *sc = device_private(self);
   1158      1.3  maxv 
   1159      1.3  maxv 	switch (act) {
   1160      1.3  maxv 	case DVACT_DEACTIVATE:
   1161      1.3  maxv 		sc->sc_dying = 1;
   1162      1.3  maxv 		return 0;
   1163      1.3  maxv 	default:
   1164      1.3  maxv 		return EOPNOTSUPP;
   1165      1.3  maxv 	}
   1166      1.3  maxv }
   1167      1.3  maxv 
   1168      1.3  maxv static int
   1169      1.1  maxv vhci_match(device_t parent, cfdata_t match, void *aux)
   1170      1.1  maxv {
   1171      1.1  maxv 	return 1;
   1172      1.1  maxv }
   1173      1.1  maxv 
   1174      1.1  maxv static void
   1175      1.1  maxv vhci_attach(device_t parent, device_t self, void *aux)
   1176      1.1  maxv {
   1177      1.1  maxv 	vhci_softc_t *sc = device_private(self);
   1178      1.1  maxv 	vhci_port_t *port;
   1179      1.1  maxv 	size_t i;
   1180      1.1  maxv 
   1181      1.1  maxv 	sc->sc_dev = self;
   1182      1.1  maxv 	sc->sc_bus.ub_revision = USBREV_2_0;
   1183      1.1  maxv 	sc->sc_bus.ub_usedma = false;
   1184      1.1  maxv 	sc->sc_bus.ub_methods = &vhci_bus_methods;
   1185      1.1  maxv 	sc->sc_bus.ub_pipesize = sizeof(vhci_pipe_t);
   1186      1.1  maxv 	sc->sc_bus.ub_hcpriv = sc;
   1187      1.1  maxv 	sc->sc_dying = false;
   1188      1.1  maxv 	mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
   1189      1.1  maxv 
   1190      1.1  maxv 	sc->sc_nports = VHCI_NPORTS;
   1191      1.1  maxv 	for (i = 0; i < sc->sc_nports; i++) {
   1192      1.1  maxv 		port = &sc->sc_port[i];
   1193      1.1  maxv 		mutex_init(&port->lock, MUTEX_DEFAULT, IPL_SOFTUSB);
   1194      1.2  maxv 		TAILQ_INIT(&port->pkts_device_ctrl.usb_to_host);
   1195      1.2  maxv 		TAILQ_INIT(&port->pkts_device_ctrl.host_to_usb);
   1196      1.1  maxv 	}
   1197      1.1  maxv 
   1198      1.1  maxv 	sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
   1199      1.1  maxv }
   1200