vhci.c revision 1.16 1 /* $NetBSD: vhci.c,v 1.16 2020/03/31 16:34:25 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.16 2020/03/31 16:34:25 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 struct vhci_xfer;
178
179 typedef struct vhci_packet {
180 /* General. */
181 TAILQ_ENTRY(vhci_packet) portlist;
182 TAILQ_ENTRY(vhci_packet) xferlist;
183 struct vhci_xfer *vxfer;
184 bool utoh;
185 uint8_t addr;
186
187 /* Type. */
188 struct {
189 bool req:1;
190 bool res:1;
191 bool dat:1;
192 } type;
193
194 /* Exposed for FD operations. */
195 uint8_t *buf;
196 size_t size;
197 size_t cursor;
198 } vhci_packet_t;
199
200 typedef TAILQ_HEAD(, vhci_packet) vhci_packet_list_t;
201
202 #define VHCI_NADDRS 16 /* maximum supported by USB */
203
204 typedef struct {
205 kmutex_t lock;
206 int status;
207 int change;
208 struct {
209 vhci_packet_list_t usb_to_host;
210 vhci_packet_list_t host_to_usb;
211 } endpoints[VHCI_NADDRS];
212 } vhci_port_t;
213
214 typedef struct {
215 struct usbd_pipe pipe;
216 } vhci_pipe_t;
217
218 typedef struct vhci_xfer {
219 /* General. */
220 struct usbd_xfer xfer;
221
222 /* Port where the xfer occurs. */
223 vhci_port_t *port;
224
225 /* Packets in the xfer. */
226 size_t npkts;
227 vhci_packet_list_t pkts;
228
229 /* Header storage. */
230 vhci_request_t reqbuf;
231 vhci_response_t resbuf;
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, *reslist, *datlist = NULL;
280 vhci_packet_t *req, *res = NULL, *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->type.req = true;
290 req->buf = (uint8_t *)&vxfer->reqbuf;
291 req->size = sizeof(vxfer->reqbuf);
292 req->cursor = 0;
293 npkts++;
294
295 /* Init the request buffer. */
296 memset(&vxfer->reqbuf, 0, sizeof(vxfer->reqbuf));
297 vxfer->reqbuf.type = VHCI_REQ_CTRL;
298 memcpy(&vxfer->reqbuf.u.ctrl, &xfer->ux_request,
299 sizeof(xfer->ux_request));
300
301 /* Response packet. */
302 if (utoh && (xfer->ux_length > 0)) {
303 reslist = &port->endpoints[addr].usb_to_host;
304 res = kmem_zalloc(sizeof(*res), KM_SLEEP);
305 res->vxfer = vxfer;
306 res->utoh = true;
307 res->addr = addr;
308 res->type.res = true;
309 res->buf = (uint8_t *)&vxfer->resbuf;
310 res->size = sizeof(vxfer->resbuf);
311 res->cursor = 0;
312 npkts++;
313 }
314
315 /* Data packet. */
316 if (xfer->ux_length > 0) {
317 if (utoh) {
318 datlist = &port->endpoints[addr].usb_to_host;
319 } else {
320 datlist = &port->endpoints[addr].host_to_usb;
321 }
322 dat = kmem_zalloc(sizeof(*dat), KM_SLEEP);
323 dat->vxfer = vxfer;
324 dat->utoh = utoh;
325 dat->addr = addr;
326 dat->type.dat = true;
327 dat->buf = xfer->ux_buf;
328 dat->size = xfer->ux_length;
329 dat->cursor = 0;
330 npkts++;
331 }
332
333 /* Insert in the xfer. */
334 vxfer->port = port;
335 vxfer->npkts = npkts;
336 TAILQ_INIT(&vxfer->pkts);
337 TAILQ_INSERT_TAIL(&vxfer->pkts, req, xferlist);
338 if (res != NULL)
339 TAILQ_INSERT_TAIL(&vxfer->pkts, res, xferlist);
340 if (dat != NULL)
341 TAILQ_INSERT_TAIL(&vxfer->pkts, dat, xferlist);
342
343 /* Insert in the port. */
344 KASSERT(mutex_owned(&port->lock));
345 TAILQ_INSERT_TAIL(reqlist, req, portlist);
346 if (res != NULL)
347 TAILQ_INSERT_TAIL(reslist, res, portlist);
348 if (dat != NULL)
349 TAILQ_INSERT_TAIL(datlist, dat, portlist);
350 }
351
352 static void
353 vhci_pkt_destroy(vhci_softc_t *sc, vhci_packet_t *pkt)
354 {
355 vhci_xfer_t *vxfer = pkt->vxfer;
356 vhci_port_t *port = vxfer->port;
357 vhci_packet_list_t *pktlist;
358
359 KASSERT(mutex_owned(&port->lock));
360
361 /* Remove from the port. */
362 if (pkt->utoh) {
363 pktlist = &port->endpoints[pkt->addr].usb_to_host;
364 } else {
365 pktlist = &port->endpoints[pkt->addr].host_to_usb;
366 }
367 TAILQ_REMOVE(pktlist, pkt, portlist);
368
369 /* Remove from the xfer. */
370 TAILQ_REMOVE(&vxfer->pkts, pkt, xferlist);
371 kmem_free(pkt, sizeof(*pkt));
372
373 /* Unref. */
374 KASSERT(vxfer->npkts > 0);
375 vxfer->npkts--;
376 if (vxfer->npkts > 0)
377 return;
378 KASSERT(TAILQ_FIRST(&vxfer->pkts) == NULL);
379 }
380
381 /* -------------------------------------------------------------------------- */
382
383 static usbd_status
384 vhci_open(struct usbd_pipe *pipe)
385 {
386 struct usbd_device *dev = pipe->up_dev;
387 struct usbd_bus *bus = dev->ud_bus;
388 usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc;
389 vhci_softc_t *sc = bus->ub_hcpriv;
390 uint8_t addr = dev->ud_addr;
391
392 if (sc->sc_dying)
393 return USBD_IOERROR;
394
395 DPRINTF("%s: called, type=%d\n", __func__,
396 UE_GET_XFERTYPE(ed->bmAttributes));
397
398 if (addr == bus->ub_rhaddr) {
399 switch (ed->bEndpointAddress) {
400 case USB_CONTROL_ENDPOINT:
401 DPRINTF("%s: roothub_ctrl\n", __func__);
402 pipe->up_methods = &roothub_ctrl_methods;
403 break;
404 case UE_DIR_IN | USBROOTHUB_INTR_ENDPT:
405 DPRINTF("%s: root_intr\n", __func__);
406 pipe->up_methods = &vhci_root_intr_methods;
407 break;
408 default:
409 DPRINTF("%s: inval\n", __func__);
410 return USBD_INVAL;
411 }
412 } else {
413 switch (UE_GET_XFERTYPE(ed->bmAttributes)) {
414 case UE_CONTROL:
415 pipe->up_methods = &vhci_device_ctrl_methods;
416 break;
417 case UE_INTERRUPT:
418 case UE_BULK:
419 default:
420 goto bad;
421 }
422 }
423
424 return USBD_NORMAL_COMPLETION;
425
426 bad:
427 return USBD_NOMEM;
428 }
429
430 static void
431 vhci_softintr(void *v)
432 {
433 DPRINTF("%s: called\n", __func__);
434 }
435
436 static struct usbd_xfer *
437 vhci_allocx(struct usbd_bus *bus, unsigned int nframes)
438 {
439 vhci_xfer_t *vxfer;
440
441 vxfer = kmem_zalloc(sizeof(*vxfer), KM_SLEEP);
442 #ifdef DIAGNOSTIC
443 vxfer->xfer.ux_state = XFER_BUSY;
444 #endif
445 return (struct usbd_xfer *)vxfer;
446 }
447
448 static void
449 vhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
450 {
451 vhci_xfer_t *vxfer = (vhci_xfer_t *)xfer;
452
453 KASSERT(vxfer->npkts == 0);
454 KASSERT(TAILQ_FIRST(&vxfer->pkts) == NULL);
455
456 #ifdef DIAGNOSTIC
457 vxfer->xfer.ux_state = XFER_FREE;
458 #endif
459 kmem_free(vxfer, sizeof(*vxfer));
460 }
461
462 static void
463 vhci_get_lock(struct usbd_bus *bus, kmutex_t **lock)
464 {
465 vhci_softc_t *sc = bus->ub_hcpriv;
466
467 *lock = &sc->sc_lock;
468 }
469
470 static int
471 vhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
472 void *buf, int buflen)
473 {
474 vhci_softc_t *sc = bus->ub_hcpriv;
475 vhci_port_t *port;
476 usb_hub_descriptor_t hubd;
477 uint16_t len, value, index;
478 int totlen = 0;
479
480 len = UGETW(req->wLength);
481 value = UGETW(req->wValue);
482 index = UGETW(req->wIndex);
483
484 #define C(x,y) ((x) | ((y) << 8))
485 switch (C(req->bRequest, req->bmRequestType)) {
486 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
487 switch (value) {
488 case C(0, UDESC_DEVICE): {
489 usb_device_descriptor_t devd;
490
491 totlen = uimin(buflen, sizeof(devd));
492 memcpy(&devd, buf, totlen);
493 USETW(devd.idVendor, 0);
494 USETW(devd.idProduct, 0);
495 memcpy(buf, &devd, totlen);
496 break;
497 }
498 #define sd ((usb_string_descriptor_t *)buf)
499 case C(1, UDESC_STRING):
500 /* Vendor */
501 totlen = usb_makestrdesc(sd, len, "NetBSD");
502 break;
503 case C(2, UDESC_STRING):
504 /* Product */
505 totlen = usb_makestrdesc(sd, len, "VHCI root hub");
506 break;
507 #undef sd
508 default:
509 /* default from usbroothub */
510 return buflen;
511 }
512 break;
513
514 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
515 switch (value) {
516 case UHF_PORT_RESET:
517 if (index < 1 || index >= sc->sc_nports) {
518 return -1;
519 }
520 port = &sc->sc_port[VHCI_INDEX2PORT(index)];
521 port->status |= UPS_C_PORT_RESET;
522 break;
523 case UHF_PORT_POWER:
524 break;
525 default:
526 return -1;
527 }
528 break;
529
530 /* Hub requests. */
531 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
532 break;
533 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
534 if (index < 1 || index >= sc->sc_nports) {
535 return -1;
536 }
537 port = &sc->sc_port[VHCI_INDEX2PORT(index)];
538 switch (value) {
539 case UHF_PORT_ENABLE:
540 port->status &= ~UPS_PORT_ENABLED;
541 break;
542 case UHF_C_PORT_ENABLE:
543 port->change |= UPS_C_PORT_ENABLED;
544 break;
545 default:
546 return -1;
547 }
548 break;
549
550 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
551 totlen = uimin(buflen, sizeof(hubd));
552 memcpy(&hubd, buf, totlen);
553 hubd.bNbrPorts = sc->sc_nports - 1;
554 hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE;
555 totlen = uimin(totlen, hubd.bDescLength);
556 memcpy(buf, &hubd, totlen);
557 break;
558
559 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
560 /* XXX The other HCs do this */
561 memset(buf, 0, len);
562 totlen = len;
563 break;
564
565 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): {
566 usb_port_status_t ps;
567
568 if (index < 1 || index >= sc->sc_nports) {
569 return -1;
570 }
571 port = &sc->sc_port[VHCI_INDEX2PORT(index)];
572 USETW(ps.wPortStatus, port->status);
573 USETW(ps.wPortChange, port->change);
574 totlen = uimin(len, sizeof(ps));
575 memcpy(buf, &ps, totlen);
576 break;
577 }
578 default:
579 /* default from usbroothub */
580 return buflen;
581 }
582
583 return totlen;
584 }
585
586 /* -------------------------------------------------------------------------- */
587
588 static usbd_status
589 vhci_device_ctrl_transfer(struct usbd_xfer *xfer)
590 {
591 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
592 usbd_status err;
593
594 DPRINTF("%s: called\n", __func__);
595
596 /* Insert last in queue. */
597 mutex_enter(&sc->sc_lock);
598 err = usb_insert_transfer(xfer);
599 mutex_exit(&sc->sc_lock);
600 if (err)
601 return err;
602
603 /* Pipe isn't running, start first */
604 return vhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
605 }
606
607 static usbd_status
608 vhci_device_ctrl_start(struct usbd_xfer *xfer)
609 {
610 usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc;
611 usb_device_request_t *req = &xfer->ux_request;
612 struct usbd_device *dev = xfer->ux_pipe->up_dev;
613 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
614 vhci_port_t *port;
615 bool polling = sc->sc_bus.ub_usepolling;
616 bool isread = (req->bmRequestType & UT_READ) != 0;
617 uint8_t addr = UE_GET_ADDR(ed->bEndpointAddress);
618 int portno, ret;
619
620 KASSERT(addr == 0);
621 KASSERT(xfer->ux_rqflags & URQ_REQUEST);
622 KASSERT(dev->ud_myhsport != NULL);
623 portno = dev->ud_myhsport->up_portno;
624
625 DPRINTF("%s: type=0x%02x, len=%d, isread=%d, portno=%d\n",
626 __func__, req->bmRequestType, UGETW(req->wLength), isread, portno);
627
628 if (sc->sc_dying)
629 return USBD_IOERROR;
630
631 port = &sc->sc_port[portno];
632
633 if (!polling)
634 mutex_enter(&sc->sc_lock);
635
636 mutex_enter(&port->lock);
637 if (port->status & UPS_PORT_ENABLED) {
638 xfer->ux_status = USBD_IN_PROGRESS;
639 vhci_pkt_ctrl_create(port, xfer, isread, addr);
640 ret = USBD_IN_PROGRESS;
641 } else {
642 ret = USBD_IOERROR;
643 }
644 mutex_exit(&port->lock);
645
646 if (!polling)
647 mutex_exit(&sc->sc_lock);
648
649 return ret;
650 }
651
652 static void
653 vhci_device_ctrl_abort(struct usbd_xfer *xfer)
654 {
655 vhci_xfer_t *vxfer = (vhci_xfer_t *)xfer;
656 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
657 vhci_port_t *port = vxfer->port;
658 vhci_packet_t *pkt;
659
660 DPRINTF("%s: called\n", __func__);
661
662 KASSERT(mutex_owned(&sc->sc_lock));
663
664 callout_halt(&xfer->ux_callout, &sc->sc_lock);
665
666 /* If anyone else beat us, we're done. */
667 KASSERT(xfer->ux_status != USBD_CANCELLED);
668 if (xfer->ux_status != USBD_IN_PROGRESS)
669 return;
670
671 mutex_enter(&port->lock);
672 while (vxfer->npkts > 0) {
673 pkt = TAILQ_FIRST(&vxfer->pkts);
674 KASSERT(pkt != NULL);
675 vhci_pkt_destroy(sc, pkt);
676 }
677 KASSERT(TAILQ_FIRST(&vxfer->pkts) == NULL);
678 mutex_exit(&port->lock);
679
680 xfer->ux_status = USBD_CANCELLED;
681 usb_transfer_complete(xfer);
682 KASSERT(mutex_owned(&sc->sc_lock));
683 }
684
685 static void
686 vhci_device_ctrl_close(struct usbd_pipe *pipe)
687 {
688 DPRINTF("%s: called\n", __func__);
689 }
690
691 static void
692 vhci_device_ctrl_cleartoggle(struct usbd_pipe *pipe)
693 {
694 DPRINTF("%s: called\n", __func__);
695 }
696
697 static void
698 vhci_device_ctrl_done(struct usbd_xfer *xfer)
699 {
700 DPRINTF("%s: called\n", __func__);
701 }
702
703 /* -------------------------------------------------------------------------- */
704
705 static usbd_status
706 vhci_root_intr_transfer(struct usbd_xfer *xfer)
707 {
708 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
709 usbd_status err;
710
711 DPRINTF("%s: called\n", __func__);
712
713 /* Insert last in queue. */
714 mutex_enter(&sc->sc_lock);
715 err = usb_insert_transfer(xfer);
716 mutex_exit(&sc->sc_lock);
717 if (err)
718 return err;
719
720 /* Pipe isn't running, start first */
721 return vhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
722 }
723
724 static usbd_status
725 vhci_root_intr_start(struct usbd_xfer *xfer)
726 {
727 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
728 const bool polling = sc->sc_bus.ub_usepolling;
729
730 DPRINTF("%s: called, len=%zu\n", __func__, (size_t)xfer->ux_length);
731
732 if (sc->sc_dying)
733 return USBD_IOERROR;
734
735 if (!polling)
736 mutex_enter(&sc->sc_lock);
737 KASSERT(sc->sc_intrxfer == NULL);
738 sc->sc_intrxfer = xfer;
739 xfer->ux_status = USBD_IN_PROGRESS;
740 if (!polling)
741 mutex_exit(&sc->sc_lock);
742
743 return USBD_IN_PROGRESS;
744 }
745
746 static void
747 vhci_root_intr_abort(struct usbd_xfer *xfer)
748 {
749 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
750
751 DPRINTF("%s: called\n", __func__);
752
753 KASSERT(mutex_owned(&sc->sc_lock));
754 KASSERT(xfer->ux_pipe->up_intrxfer == xfer);
755
756 /* If xfer has already completed, nothing to do here. */
757 if (sc->sc_intrxfer == NULL)
758 return;
759
760 /*
761 * Otherwise, sc->sc_intrxfer had better be this transfer.
762 * Cancel it.
763 */
764 KASSERT(sc->sc_intrxfer == xfer);
765 KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
766 xfer->ux_status = USBD_CANCELLED;
767 usb_transfer_complete(xfer);
768 }
769
770 static void
771 vhci_root_intr_close(struct usbd_pipe *pipe)
772 {
773 vhci_softc_t *sc __diagused = pipe->up_dev->ud_bus->ub_hcpriv;
774
775 DPRINTF("%s: called\n", __func__);
776
777 KASSERT(mutex_owned(&sc->sc_lock));
778
779 /*
780 * Caller must guarantee the xfer has completed first, by
781 * closing the pipe only after normal completion or an abort.
782 */
783 KASSERT(sc->sc_intrxfer == NULL);
784 }
785
786 static void
787 vhci_root_intr_cleartoggle(struct usbd_pipe *pipe)
788 {
789 DPRINTF("%s: called\n", __func__);
790 }
791
792 static void
793 vhci_root_intr_done(struct usbd_xfer *xfer)
794 {
795 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv;
796
797 KASSERT(mutex_owned(&sc->sc_lock));
798
799 /* Claim the xfer so it doesn't get completed again. */
800 KASSERT(sc->sc_intrxfer == xfer);
801 KASSERT(xfer->ux_status != USBD_IN_PROGRESS);
802 sc->sc_intrxfer = NULL;
803 }
804
805 /* -------------------------------------------------------------------------- */
806
807 static int
808 vhci_usb_attach(vhci_fd_t *vfd)
809 {
810 vhci_softc_t *sc = vfd->softc;
811 vhci_port_t *port;
812 struct usbd_xfer *xfer;
813 u_char *p;
814 int ret = 0;
815
816 port = &sc->sc_port[vfd->port];
817
818 mutex_enter(&sc->sc_lock);
819
820 mutex_enter(&port->lock);
821 port->status = UPS_CURRENT_CONNECT_STATUS | UPS_PORT_ENABLED |
822 UPS_PORT_POWER;
823 port->change = UPS_C_CONNECT_STATUS | UPS_C_PORT_RESET;
824 mutex_exit(&port->lock);
825
826 xfer = sc->sc_intrxfer;
827
828 if (xfer == NULL) {
829 ret = ENOBUFS;
830 goto done;
831 }
832 KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
833
834 p = xfer->ux_buf;
835 memset(p, 0, xfer->ux_length);
836 p[0] = __BIT(vfd->port);
837 xfer->ux_actlen = xfer->ux_length;
838 xfer->ux_status = USBD_NORMAL_COMPLETION;
839
840 usb_transfer_complete(xfer);
841
842 done:
843 mutex_exit(&sc->sc_lock);
844 return ret;
845 }
846
847 static void
848 vhci_port_flush(vhci_softc_t *sc, vhci_port_t *port)
849 {
850 vhci_packet_list_t *pktlist;
851 vhci_packet_t *pkt, *nxt;
852 vhci_xfer_list_t vxferlist;
853 vhci_xfer_t *vxfer;
854 uint8_t addr;
855
856 KASSERT(mutex_owned(&sc->sc_lock));
857 KASSERT(mutex_owned(&port->lock));
858
859 TAILQ_INIT(&vxferlist);
860
861 for (addr = 0; addr < VHCI_NADDRS; addr++) {
862 /* Drop all the packets in the H->U direction. */
863 pktlist = &port->endpoints[addr].host_to_usb;
864 TAILQ_FOREACH_SAFE(pkt, pktlist, portlist, nxt) {
865 vxfer = pkt->vxfer;
866 KASSERT(vxfer->xfer.ux_status == USBD_IN_PROGRESS);
867 vhci_pkt_destroy(sc, pkt);
868 if (vxfer->npkts == 0)
869 TAILQ_INSERT_TAIL(&vxferlist, vxfer, freelist);
870 }
871 KASSERT(TAILQ_FIRST(pktlist) == NULL);
872
873 /* Drop all the packets in the U->H direction. */
874 pktlist = &port->endpoints[addr].usb_to_host;
875 TAILQ_FOREACH_SAFE(pkt, pktlist, portlist, nxt) {
876 vxfer = pkt->vxfer;
877 KASSERT(vxfer->xfer.ux_status == USBD_IN_PROGRESS);
878 vhci_pkt_destroy(sc, pkt);
879 if (vxfer->npkts == 0)
880 TAILQ_INSERT_TAIL(&vxferlist, vxfer, freelist);
881 }
882 KASSERT(TAILQ_FIRST(pktlist) == NULL);
883
884 /* Terminate all the xfers collected. */
885 while ((vxfer = TAILQ_FIRST(&vxferlist)) != NULL) {
886 struct usbd_xfer *xfer = &vxfer->xfer;
887 TAILQ_REMOVE(&vxferlist, vxfer, freelist);
888
889 xfer->ux_status = USBD_TIMEOUT;
890 usb_transfer_complete(xfer);
891 }
892 }
893 }
894
895 static int
896 vhci_usb_detach(vhci_fd_t *vfd)
897 {
898 vhci_softc_t *sc = vfd->softc;
899 vhci_port_t *port;
900 struct usbd_xfer *xfer;
901 u_char *p;
902
903 port = &sc->sc_port[vfd->port];
904
905 mutex_enter(&sc->sc_lock);
906
907 xfer = sc->sc_intrxfer;
908 if (xfer == NULL) {
909 mutex_exit(&sc->sc_lock);
910 return ENOBUFS;
911 }
912 KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
913
914 mutex_enter(&port->lock);
915
916 port->status = 0;
917 port->change = UPS_C_CONNECT_STATUS | UPS_C_PORT_RESET;
918
919 p = xfer->ux_buf;
920 memset(p, 0, xfer->ux_length);
921 p[0] = __BIT(vfd->port);
922 xfer->ux_actlen = xfer->ux_length;
923 xfer->ux_status = USBD_NORMAL_COMPLETION;
924
925 usb_transfer_complete(xfer);
926 vhci_port_flush(sc, port);
927
928 mutex_exit(&port->lock);
929 mutex_exit(&sc->sc_lock);
930 return 0;
931 }
932
933 static int
934 vhci_get_info(vhci_fd_t *vfd, struct vhci_ioc_get_info *args)
935 {
936 vhci_softc_t *sc = vfd->softc;
937 vhci_port_t *port;
938
939 port = &sc->sc_port[vfd->port];
940
941 args->nports = VHCI_NPORTS;
942 args->port = vfd->port;
943 mutex_enter(&port->lock);
944 args->status = port->status;
945 mutex_exit(&port->lock);
946 args->addr = vfd->addr;
947
948 return 0;
949 }
950
951 static int
952 vhci_set_port(vhci_fd_t *vfd, struct vhci_ioc_set_port *args)
953 {
954 vhci_softc_t *sc = vfd->softc;
955
956 if (args->port == 0 || args->port >= sc->sc_nports)
957 return EINVAL;
958
959 vfd->port = args->port;
960
961 return 0;
962 }
963
964 static int
965 vhci_set_addr(vhci_fd_t *vfd, struct vhci_ioc_set_addr *args)
966 {
967 if (args->addr >= VHCI_NADDRS)
968 return EINVAL;
969
970 vfd->addr = args->addr;
971
972 return 0;
973 }
974
975 /* -------------------------------------------------------------------------- */
976
977 static dev_type_open(vhci_fd_open);
978
979 const struct cdevsw vhci_cdevsw = {
980 .d_open = vhci_fd_open,
981 .d_close = noclose,
982 .d_read = noread,
983 .d_write = nowrite,
984 .d_ioctl = noioctl,
985 .d_stop = nostop,
986 .d_tty = notty,
987 .d_poll = nopoll,
988 .d_mmap = nommap,
989 .d_kqfilter = nokqfilter,
990 .d_discard = nodiscard,
991 .d_flag = D_OTHER | D_MPSAFE
992 };
993
994 static int vhci_fd_ioctl(file_t *, u_long, void *);
995 static int vhci_fd_close(file_t *);
996 static int vhci_fd_read(struct file *, off_t *, struct uio *, kauth_cred_t, int);
997 static int vhci_fd_write(struct file *, off_t *, struct uio *, kauth_cred_t, int);
998
999 const struct fileops vhci_fileops = {
1000 .fo_read = vhci_fd_read,
1001 .fo_write = vhci_fd_write,
1002 .fo_ioctl = vhci_fd_ioctl,
1003 .fo_fcntl = fnullop_fcntl,
1004 .fo_poll = fnullop_poll,
1005 .fo_stat = fbadop_stat,
1006 .fo_close = vhci_fd_close,
1007 .fo_kqfilter = fnullop_kqfilter,
1008 .fo_restart = fnullop_restart,
1009 .fo_mmap = NULL,
1010 };
1011
1012 static int
1013 vhci_fd_open(dev_t dev, int flags, int type, struct lwp *l)
1014 {
1015 vhci_fd_t *vfd;
1016 struct file *fp;
1017 int error, fd;
1018
1019 if (minor(dev) != 0)
1020 return EXDEV;
1021 error = fd_allocfile(&fp, &fd);
1022 if (error)
1023 return error;
1024
1025 vfd = kmem_alloc(sizeof(*vfd), KM_SLEEP);
1026 vfd->port = 1;
1027 vfd->addr = 0;
1028 vfd->softc = device_lookup_private(&vhci_cd, minor(dev));
1029
1030 return fd_clone(fp, fd, flags, &vhci_fileops, vfd);
1031 }
1032
1033 static int
1034 vhci_fd_close(file_t *fp)
1035 {
1036 vhci_fd_t *vfd = fp->f_data;
1037 int ret __diagused;
1038
1039 KASSERT(vfd != NULL);
1040 ret = vhci_usb_detach(vfd);
1041 KASSERT(ret == 0);
1042
1043 kmem_free(vfd, sizeof(*vfd));
1044 fp->f_data = NULL;
1045
1046 return 0;
1047 }
1048
1049 static int
1050 vhci_fd_read(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred,
1051 int flags)
1052 {
1053 vhci_fd_t *vfd = fp->f_data;
1054 vhci_softc_t *sc = vfd->softc;
1055 vhci_packet_list_t *pktlist;
1056 vhci_packet_t *pkt, *nxt;
1057 vhci_xfer_list_t vxferlist;
1058 vhci_xfer_t *vxfer;
1059 vhci_port_t *port;
1060 int error = 0;
1061 uint8_t *buf;
1062 size_t size;
1063
1064 if (uio->uio_resid == 0)
1065 return 0;
1066 port = &sc->sc_port[vfd->port];
1067 pktlist = &port->endpoints[vfd->addr].host_to_usb;
1068
1069 TAILQ_INIT(&vxferlist);
1070
1071 mutex_enter(&port->lock);
1072
1073 if (!(port->status & UPS_PORT_ENABLED)) {
1074 error = ENOBUFS;
1075 goto out;
1076 }
1077
1078 TAILQ_FOREACH_SAFE(pkt, pktlist, portlist, nxt) {
1079 vxfer = pkt->vxfer;
1080 buf = pkt->buf + pkt->cursor;
1081
1082 KASSERT(pkt->size >= pkt->cursor);
1083 size = uimin(uio->uio_resid, pkt->size - pkt->cursor);
1084
1085 KASSERT(vxfer->xfer.ux_status == USBD_IN_PROGRESS);
1086
1087 error = uiomove(buf, size, uio);
1088 if (error) {
1089 DPRINTF("%s: error = %d\n", __func__, error);
1090 goto out;
1091 }
1092
1093 pkt->cursor += size;
1094
1095 if (pkt->cursor == pkt->size) {
1096 vhci_pkt_destroy(sc, pkt);
1097 if (vxfer->npkts == 0) {
1098 TAILQ_INSERT_TAIL(&vxferlist, vxfer, freelist);
1099 }
1100 }
1101 if (uio->uio_resid == 0) {
1102 break;
1103 }
1104 }
1105
1106 out:
1107 mutex_exit(&port->lock);
1108
1109 while ((vxfer = TAILQ_FIRST(&vxferlist)) != NULL) {
1110 struct usbd_xfer *xfer = &vxfer->xfer;
1111 TAILQ_REMOVE(&vxferlist, vxfer, freelist);
1112
1113 mutex_enter(&sc->sc_lock);
1114 xfer->ux_actlen = xfer->ux_length;
1115 xfer->ux_status = USBD_NORMAL_COMPLETION;
1116 usb_transfer_complete(xfer);
1117 mutex_exit(&sc->sc_lock);
1118 }
1119
1120 return error;
1121 }
1122
1123 static int
1124 vhci_fd_write(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred,
1125 int flags)
1126 {
1127 vhci_fd_t *vfd = fp->f_data;
1128 vhci_softc_t *sc = vfd->softc;
1129 vhci_packet_list_t *pktlist;
1130 vhci_packet_t *pkt, *nxt;
1131 vhci_xfer_list_t vxferlist;
1132 vhci_xfer_t *vxfer;
1133 vhci_port_t *port;
1134 int error = 0;
1135 uint8_t *buf;
1136 size_t pktsize, size;
1137
1138 if (uio->uio_resid == 0)
1139 return 0;
1140 port = &sc->sc_port[vfd->port];
1141 pktlist = &port->endpoints[vfd->addr].usb_to_host;
1142
1143 TAILQ_INIT(&vxferlist);
1144
1145 mutex_enter(&port->lock);
1146
1147 if (!(port->status & UPS_PORT_ENABLED)) {
1148 error = ENOBUFS;
1149 goto out;
1150 }
1151
1152 TAILQ_FOREACH_SAFE(pkt, pktlist, portlist, nxt) {
1153 vxfer = pkt->vxfer;
1154 buf = pkt->buf + pkt->cursor;
1155
1156 pktsize = pkt->size;
1157 if (pkt->type.dat)
1158 pktsize = ulmin(vxfer->resbuf.size, pktsize);
1159
1160 KASSERT(pktsize >= pkt->cursor);
1161 size = uimin(uio->uio_resid, pktsize - 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 == pktsize) {
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 = ulmin(vxfer->resbuf.size, 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