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