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