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