1 /* $NetBSD: vhci.c,v 1.20 2020/06/05 17:20:56 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.20 2020/06/05 17:20:56 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 8 /* above 8, update TODO-bitmap */ 242 #define VHCI_NBUSES 8 243 244 typedef struct { 245 device_t sc_dev; 246 247 struct usbd_bus sc_bus; 248 bool sc_dying; 249 kmutex_t sc_lock; 250 251 /* 252 * Intr Root. Used to attach the devices. 253 */ 254 struct usbd_xfer *sc_intrxfer; 255 256 /* 257 * The ports. Zero is for the roothub, one and beyond for the USB 258 * devices. 259 */ 260 size_t sc_nports; 261 vhci_port_t sc_port[VHCI_NPORTS]; 262 263 device_t sc_child; /* /dev/usb# device */ 264 } vhci_softc_t; 265 266 typedef struct { 267 u_int port; 268 uint8_t addr; 269 vhci_softc_t *softc; 270 } vhci_fd_t; 271 272 extern struct cfdriver vhci_cd; 273 274 /* -------------------------------------------------------------------------- */ 275 276 static void 277 vhci_pkt_ctrl_create(vhci_port_t *port, struct usbd_xfer *xfer, bool utoh, 278 uint8_t addr) 279 { 280 vhci_xfer_t *vxfer = (vhci_xfer_t *)xfer; 281 vhci_packet_list_t *reqlist, *reslist, *datlist = NULL; 282 vhci_packet_t *req, *res = NULL, *dat = NULL; 283 size_t npkts = 0; 284 285 /* Request packet. */ 286 reqlist = &port->endpoints[addr].host_to_usb; 287 req = kmem_zalloc(sizeof(*req), KM_SLEEP); 288 req->vxfer = vxfer; 289 req->utoh = false; 290 req->addr = addr; 291 req->type.req = true; 292 req->buf = (uint8_t *)&vxfer->reqbuf; 293 req->size = sizeof(vxfer->reqbuf); 294 req->cursor = 0; 295 npkts++; 296 297 /* Init the request buffer. */ 298 memset(&vxfer->reqbuf, 0, sizeof(vxfer->reqbuf)); 299 vxfer->reqbuf.type = VHCI_REQ_CTRL; 300 memcpy(&vxfer->reqbuf.u.ctrl, &xfer->ux_request, 301 sizeof(xfer->ux_request)); 302 303 /* Response packet. */ 304 if (utoh && (xfer->ux_length > 0)) { 305 reslist = &port->endpoints[addr].usb_to_host; 306 res = kmem_zalloc(sizeof(*res), KM_SLEEP); 307 res->vxfer = vxfer; 308 res->utoh = true; 309 res->addr = addr; 310 res->type.res = true; 311 res->buf = (uint8_t *)&vxfer->resbuf; 312 res->size = sizeof(vxfer->resbuf); 313 res->cursor = 0; 314 npkts++; 315 } 316 317 /* Data packet. */ 318 if (xfer->ux_length > 0) { 319 if (utoh) { 320 datlist = &port->endpoints[addr].usb_to_host; 321 } else { 322 datlist = &port->endpoints[addr].host_to_usb; 323 } 324 dat = kmem_zalloc(sizeof(*dat), KM_SLEEP); 325 dat->vxfer = vxfer; 326 dat->utoh = utoh; 327 dat->addr = addr; 328 dat->type.dat = true; 329 dat->buf = xfer->ux_buf; 330 dat->size = xfer->ux_length; 331 dat->cursor = 0; 332 npkts++; 333 } 334 335 /* Insert in the xfer. */ 336 vxfer->port = port; 337 vxfer->npkts = npkts; 338 TAILQ_INIT(&vxfer->pkts); 339 TAILQ_INSERT_TAIL(&vxfer->pkts, req, xferlist); 340 if (res != NULL) 341 TAILQ_INSERT_TAIL(&vxfer->pkts, res, xferlist); 342 if (dat != NULL) 343 TAILQ_INSERT_TAIL(&vxfer->pkts, dat, xferlist); 344 345 /* Insert in the port. */ 346 KASSERT(mutex_owned(&port->lock)); 347 TAILQ_INSERT_TAIL(reqlist, req, portlist); 348 if (res != NULL) 349 TAILQ_INSERT_TAIL(reslist, res, portlist); 350 if (dat != NULL) 351 TAILQ_INSERT_TAIL(datlist, dat, portlist); 352 } 353 354 static void 355 vhci_pkt_destroy(vhci_softc_t *sc, vhci_packet_t *pkt) 356 { 357 vhci_xfer_t *vxfer = pkt->vxfer; 358 vhci_port_t *port = vxfer->port; 359 vhci_packet_list_t *pktlist; 360 361 KASSERT(mutex_owned(&port->lock)); 362 363 /* Remove from the port. */ 364 if (pkt->utoh) { 365 pktlist = &port->endpoints[pkt->addr].usb_to_host; 366 } else { 367 pktlist = &port->endpoints[pkt->addr].host_to_usb; 368 } 369 TAILQ_REMOVE(pktlist, pkt, portlist); 370 371 /* Remove from the xfer. */ 372 TAILQ_REMOVE(&vxfer->pkts, pkt, xferlist); 373 kmem_free(pkt, sizeof(*pkt)); 374 375 /* Unref. */ 376 KASSERT(vxfer->npkts > 0); 377 vxfer->npkts--; 378 if (vxfer->npkts > 0) 379 return; 380 KASSERT(TAILQ_FIRST(&vxfer->pkts) == NULL); 381 } 382 383 /* -------------------------------------------------------------------------- */ 384 385 static usbd_status 386 vhci_open(struct usbd_pipe *pipe) 387 { 388 struct usbd_device *dev = pipe->up_dev; 389 struct usbd_bus *bus = dev->ud_bus; 390 usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc; 391 vhci_softc_t *sc = bus->ub_hcpriv; 392 uint8_t addr = dev->ud_addr; 393 394 if (sc->sc_dying) 395 return USBD_IOERROR; 396 397 DPRINTF("%s: called, type=%d\n", __func__, 398 UE_GET_XFERTYPE(ed->bmAttributes)); 399 400 if (addr == bus->ub_rhaddr) { 401 switch (ed->bEndpointAddress) { 402 case USB_CONTROL_ENDPOINT: 403 DPRINTF("%s: roothub_ctrl\n", __func__); 404 pipe->up_methods = &roothub_ctrl_methods; 405 break; 406 case UE_DIR_IN | USBROOTHUB_INTR_ENDPT: 407 DPRINTF("%s: root_intr\n", __func__); 408 pipe->up_methods = &vhci_root_intr_methods; 409 break; 410 default: 411 DPRINTF("%s: inval\n", __func__); 412 return USBD_INVAL; 413 } 414 } else { 415 switch (UE_GET_XFERTYPE(ed->bmAttributes)) { 416 case UE_CONTROL: 417 pipe->up_methods = &vhci_device_ctrl_methods; 418 break; 419 case UE_INTERRUPT: 420 case UE_BULK: 421 default: 422 goto bad; 423 } 424 } 425 426 return USBD_NORMAL_COMPLETION; 427 428 bad: 429 return USBD_NOMEM; 430 } 431 432 static void 433 vhci_softintr(void *v) 434 { 435 DPRINTF("%s: called\n", __func__); 436 } 437 438 static struct usbd_xfer * 439 vhci_allocx(struct usbd_bus *bus, unsigned int nframes) 440 { 441 vhci_xfer_t *vxfer; 442 443 vxfer = kmem_zalloc(sizeof(*vxfer), KM_SLEEP); 444 #ifdef DIAGNOSTIC 445 vxfer->xfer.ux_state = XFER_BUSY; 446 #endif 447 return (struct usbd_xfer *)vxfer; 448 } 449 450 static void 451 vhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) 452 { 453 vhci_xfer_t *vxfer = (vhci_xfer_t *)xfer; 454 455 KASSERT(vxfer->npkts == 0); 456 KASSERT(TAILQ_FIRST(&vxfer->pkts) == NULL); 457 458 #ifdef DIAGNOSTIC 459 vxfer->xfer.ux_state = XFER_FREE; 460 #endif 461 kmem_free(vxfer, sizeof(*vxfer)); 462 } 463 464 static void 465 vhci_get_lock(struct usbd_bus *bus, kmutex_t **lock) 466 { 467 vhci_softc_t *sc = bus->ub_hcpriv; 468 469 *lock = &sc->sc_lock; 470 } 471 472 static int 473 vhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, 474 void *buf, int buflen) 475 { 476 vhci_softc_t *sc = bus->ub_hcpriv; 477 vhci_port_t *port; 478 usb_hub_descriptor_t hubd; 479 uint16_t len, value, index; 480 int totlen = 0; 481 482 len = UGETW(req->wLength); 483 value = UGETW(req->wValue); 484 index = UGETW(req->wIndex); 485 486 #define C(x,y) ((x) | ((y) << 8)) 487 switch (C(req->bRequest, req->bmRequestType)) { 488 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): 489 switch (value) { 490 case C(0, UDESC_DEVICE): { 491 usb_device_descriptor_t devd; 492 493 totlen = uimin(buflen, sizeof(devd)); 494 memcpy(&devd, buf, totlen); 495 USETW(devd.idVendor, 0); 496 USETW(devd.idProduct, 0); 497 memcpy(buf, &devd, totlen); 498 break; 499 } 500 #define sd ((usb_string_descriptor_t *)buf) 501 case C(1, UDESC_STRING): 502 /* Vendor */ 503 totlen = usb_makestrdesc(sd, len, "NetBSD"); 504 break; 505 case C(2, UDESC_STRING): 506 /* Product */ 507 totlen = usb_makestrdesc(sd, len, "VHCI root hub"); 508 break; 509 #undef sd 510 default: 511 /* default from usbroothub */ 512 return buflen; 513 } 514 break; 515 516 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER): 517 switch (value) { 518 case UHF_PORT_RESET: 519 if (index < 1 || index >= sc->sc_nports) { 520 return -1; 521 } 522 port = &sc->sc_port[VHCI_INDEX2PORT(index)]; 523 port->status |= UPS_C_PORT_RESET; 524 break; 525 case UHF_PORT_POWER: 526 break; 527 default: 528 return -1; 529 } 530 break; 531 532 /* Hub requests. */ 533 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE): 534 break; 535 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): 536 if (index < 1 || index >= sc->sc_nports) { 537 return -1; 538 } 539 port = &sc->sc_port[VHCI_INDEX2PORT(index)]; 540 switch (value) { 541 case UHF_PORT_ENABLE: 542 port->status &= ~UPS_PORT_ENABLED; 543 break; 544 case UHF_C_PORT_ENABLE: 545 port->change |= UPS_C_PORT_ENABLED; 546 break; 547 default: 548 return -1; 549 } 550 break; 551 552 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE): 553 totlen = uimin(buflen, sizeof(hubd)); 554 memcpy(&hubd, buf, totlen); 555 hubd.bNbrPorts = sc->sc_nports - 1; 556 hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE; 557 totlen = uimin(totlen, hubd.bDescLength); 558 memcpy(buf, &hubd, totlen); 559 break; 560 561 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): 562 /* XXX The other HCs do this */ 563 memset(buf, 0, len); 564 totlen = len; 565 break; 566 567 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): { 568 usb_port_status_t ps; 569 570 if (index < 1 || index >= sc->sc_nports) { 571 return -1; 572 } 573 port = &sc->sc_port[VHCI_INDEX2PORT(index)]; 574 USETW(ps.wPortStatus, port->status); 575 USETW(ps.wPortChange, port->change); 576 totlen = uimin(len, sizeof(ps)); 577 memcpy(buf, &ps, totlen); 578 break; 579 } 580 default: 581 /* default from usbroothub */ 582 return buflen; 583 } 584 585 return totlen; 586 } 587 588 /* -------------------------------------------------------------------------- */ 589 590 static usbd_status 591 vhci_device_ctrl_transfer(struct usbd_xfer *xfer) 592 { 593 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; 594 usbd_status err; 595 596 DPRINTF("%s: called\n", __func__); 597 598 /* Insert last in queue. */ 599 mutex_enter(&sc->sc_lock); 600 err = usb_insert_transfer(xfer); 601 mutex_exit(&sc->sc_lock); 602 if (err) 603 return err; 604 605 /* Pipe isn't running, start first */ 606 return vhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 607 } 608 609 static usbd_status 610 vhci_device_ctrl_start(struct usbd_xfer *xfer) 611 { 612 usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc; 613 usb_device_request_t *req = &xfer->ux_request; 614 struct usbd_device *dev = xfer->ux_pipe->up_dev; 615 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; 616 vhci_port_t *port; 617 bool polling = sc->sc_bus.ub_usepolling; 618 bool isread = (req->bmRequestType & UT_READ) != 0; 619 uint8_t addr = UE_GET_ADDR(ed->bEndpointAddress); 620 int portno, ret; 621 622 KASSERT(addr == 0); 623 KASSERT(xfer->ux_rqflags & URQ_REQUEST); 624 KASSERT(dev->ud_myhsport != NULL); 625 portno = dev->ud_myhsport->up_portno; 626 627 DPRINTF("%s: type=0x%02x, len=%d, isread=%d, portno=%d\n", 628 __func__, req->bmRequestType, UGETW(req->wLength), isread, portno); 629 630 if (sc->sc_dying) 631 return USBD_IOERROR; 632 633 port = &sc->sc_port[portno]; 634 635 if (!polling) 636 mutex_enter(&sc->sc_lock); 637 638 mutex_enter(&port->lock); 639 if (port->status & UPS_PORT_ENABLED) { 640 xfer->ux_status = USBD_IN_PROGRESS; 641 vhci_pkt_ctrl_create(port, xfer, isread, addr); 642 ret = USBD_IN_PROGRESS; 643 } else { 644 ret = USBD_IOERROR; 645 } 646 mutex_exit(&port->lock); 647 648 if (!polling) 649 mutex_exit(&sc->sc_lock); 650 651 return ret; 652 } 653 654 static void 655 vhci_device_ctrl_abort(struct usbd_xfer *xfer) 656 { 657 vhci_xfer_t *vxfer = (vhci_xfer_t *)xfer; 658 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; 659 vhci_port_t *port = vxfer->port; 660 vhci_packet_t *pkt; 661 662 DPRINTF("%s: called\n", __func__); 663 664 KASSERT(mutex_owned(&sc->sc_lock)); 665 666 callout_halt(&xfer->ux_callout, &sc->sc_lock); 667 668 /* If anyone else beat us, we're done. */ 669 KASSERT(xfer->ux_status != USBD_CANCELLED); 670 if (xfer->ux_status != USBD_IN_PROGRESS) 671 return; 672 673 mutex_enter(&port->lock); 674 while (vxfer->npkts > 0) { 675 pkt = TAILQ_FIRST(&vxfer->pkts); 676 KASSERT(pkt != NULL); 677 vhci_pkt_destroy(sc, pkt); 678 } 679 KASSERT(TAILQ_FIRST(&vxfer->pkts) == NULL); 680 mutex_exit(&port->lock); 681 682 xfer->ux_status = USBD_CANCELLED; 683 usb_transfer_complete(xfer); 684 KASSERT(mutex_owned(&sc->sc_lock)); 685 } 686 687 static void 688 vhci_device_ctrl_close(struct usbd_pipe *pipe) 689 { 690 DPRINTF("%s: called\n", __func__); 691 } 692 693 static void 694 vhci_device_ctrl_cleartoggle(struct usbd_pipe *pipe) 695 { 696 DPRINTF("%s: called\n", __func__); 697 } 698 699 static void 700 vhci_device_ctrl_done(struct usbd_xfer *xfer) 701 { 702 DPRINTF("%s: called\n", __func__); 703 } 704 705 /* -------------------------------------------------------------------------- */ 706 707 static usbd_status 708 vhci_root_intr_transfer(struct usbd_xfer *xfer) 709 { 710 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; 711 usbd_status err; 712 713 DPRINTF("%s: called\n", __func__); 714 715 /* Insert last in queue. */ 716 mutex_enter(&sc->sc_lock); 717 err = usb_insert_transfer(xfer); 718 mutex_exit(&sc->sc_lock); 719 if (err) 720 return err; 721 722 /* Pipe isn't running, start first */ 723 return vhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 724 } 725 726 static usbd_status 727 vhci_root_intr_start(struct usbd_xfer *xfer) 728 { 729 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; 730 const bool polling = sc->sc_bus.ub_usepolling; 731 732 DPRINTF("%s: called, len=%zu\n", __func__, (size_t)xfer->ux_length); 733 734 if (sc->sc_dying) 735 return USBD_IOERROR; 736 737 if (!polling) 738 mutex_enter(&sc->sc_lock); 739 KASSERT(sc->sc_intrxfer == NULL); 740 sc->sc_intrxfer = xfer; 741 xfer->ux_status = USBD_IN_PROGRESS; 742 if (!polling) 743 mutex_exit(&sc->sc_lock); 744 745 return USBD_IN_PROGRESS; 746 } 747 748 static void 749 vhci_root_intr_abort(struct usbd_xfer *xfer) 750 { 751 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; 752 753 DPRINTF("%s: called\n", __func__); 754 755 KASSERT(mutex_owned(&sc->sc_lock)); 756 KASSERT(xfer->ux_pipe->up_intrxfer == xfer); 757 758 /* If xfer has already completed, nothing to do here. */ 759 if (sc->sc_intrxfer == NULL) 760 return; 761 762 /* 763 * Otherwise, sc->sc_intrxfer had better be this transfer. 764 * Cancel it. 765 */ 766 KASSERT(sc->sc_intrxfer == xfer); 767 KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 768 xfer->ux_status = USBD_CANCELLED; 769 usb_transfer_complete(xfer); 770 } 771 772 static void 773 vhci_root_intr_close(struct usbd_pipe *pipe) 774 { 775 vhci_softc_t *sc __diagused = pipe->up_dev->ud_bus->ub_hcpriv; 776 777 DPRINTF("%s: called\n", __func__); 778 779 KASSERT(mutex_owned(&sc->sc_lock)); 780 781 /* 782 * Caller must guarantee the xfer has completed first, by 783 * closing the pipe only after normal completion or an abort. 784 */ 785 KASSERT(sc->sc_intrxfer == NULL); 786 } 787 788 static void 789 vhci_root_intr_cleartoggle(struct usbd_pipe *pipe) 790 { 791 DPRINTF("%s: called\n", __func__); 792 } 793 794 static void 795 vhci_root_intr_done(struct usbd_xfer *xfer) 796 { 797 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; 798 799 KASSERT(mutex_owned(&sc->sc_lock)); 800 801 /* Claim the xfer so it doesn't get completed again. */ 802 KASSERT(sc->sc_intrxfer == xfer); 803 KASSERT(xfer->ux_status != USBD_IN_PROGRESS); 804 sc->sc_intrxfer = NULL; 805 } 806 807 /* -------------------------------------------------------------------------- */ 808 809 static int 810 vhci_usb_attach(vhci_fd_t *vfd) 811 { 812 vhci_softc_t *sc = vfd->softc; 813 vhci_port_t *port; 814 struct usbd_xfer *xfer; 815 u_char *p; 816 int ret = 0; 817 818 port = &sc->sc_port[vfd->port]; 819 820 mutex_enter(&sc->sc_lock); 821 822 mutex_enter(&port->lock); 823 port->status = UPS_CURRENT_CONNECT_STATUS | UPS_PORT_ENABLED | 824 UPS_PORT_POWER; 825 port->change = UPS_C_CONNECT_STATUS | UPS_C_PORT_RESET; 826 mutex_exit(&port->lock); 827 828 xfer = sc->sc_intrxfer; 829 830 if (xfer == NULL) { 831 ret = ENOBUFS; 832 goto done; 833 } 834 KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 835 836 /* 837 * Mark our port has having changed state. Uhub will then fetch 838 * status/change and see it needs to perform an attach. 839 */ 840 p = xfer->ux_buf; 841 memset(p, 0, xfer->ux_length); 842 p[0] = __BIT(vfd->port); /* TODO-bitmap */ 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 /* 926 * Mark our port has having changed state. Uhub will then fetch 927 * status/change and see it needs to perform a detach. 928 */ 929 p = xfer->ux_buf; 930 memset(p, 0, xfer->ux_length); 931 p[0] = __BIT(vfd->port); /* TODO-bitmap */ 932 xfer->ux_actlen = xfer->ux_length; 933 xfer->ux_status = USBD_NORMAL_COMPLETION; 934 935 usb_transfer_complete(xfer); 936 vhci_port_flush(sc, port); 937 938 mutex_exit(&port->lock); 939 mutex_exit(&sc->sc_lock); 940 return 0; 941 } 942 943 static int 944 vhci_get_info(vhci_fd_t *vfd, struct vhci_ioc_get_info *args) 945 { 946 vhci_softc_t *sc = vfd->softc; 947 vhci_port_t *port; 948 949 port = &sc->sc_port[vfd->port]; 950 951 args->nports = VHCI_NPORTS; 952 args->port = vfd->port; 953 mutex_enter(&port->lock); 954 args->status = port->status; 955 mutex_exit(&port->lock); 956 args->addr = vfd->addr; 957 958 return 0; 959 } 960 961 static int 962 vhci_set_port(vhci_fd_t *vfd, struct vhci_ioc_set_port *args) 963 { 964 vhci_softc_t *sc = vfd->softc; 965 966 if (args->port == 0 || args->port >= sc->sc_nports) 967 return EINVAL; 968 969 vfd->port = args->port; 970 971 return 0; 972 } 973 974 static int 975 vhci_set_addr(vhci_fd_t *vfd, struct vhci_ioc_set_addr *args) 976 { 977 if (args->addr >= VHCI_NADDRS) 978 return EINVAL; 979 980 vfd->addr = args->addr; 981 982 return 0; 983 } 984 985 /* -------------------------------------------------------------------------- */ 986 987 static dev_type_open(vhci_fd_open); 988 989 const struct cdevsw vhci_cdevsw = { 990 .d_open = vhci_fd_open, 991 .d_close = noclose, 992 .d_read = noread, 993 .d_write = nowrite, 994 .d_ioctl = noioctl, 995 .d_stop = nostop, 996 .d_tty = notty, 997 .d_poll = nopoll, 998 .d_mmap = nommap, 999 .d_kqfilter = nokqfilter, 1000 .d_discard = nodiscard, 1001 .d_flag = D_OTHER | D_MPSAFE 1002 }; 1003 1004 static int vhci_fd_ioctl(file_t *, u_long, void *); 1005 static int vhci_fd_close(file_t *); 1006 static int vhci_fd_read(struct file *, off_t *, struct uio *, kauth_cred_t, int); 1007 static int vhci_fd_write(struct file *, off_t *, struct uio *, kauth_cred_t, int); 1008 1009 const struct fileops vhci_fileops = { 1010 .fo_read = vhci_fd_read, 1011 .fo_write = vhci_fd_write, 1012 .fo_ioctl = vhci_fd_ioctl, 1013 .fo_fcntl = fnullop_fcntl, 1014 .fo_poll = fnullop_poll, 1015 .fo_stat = fbadop_stat, 1016 .fo_close = vhci_fd_close, 1017 .fo_kqfilter = fnullop_kqfilter, 1018 .fo_restart = fnullop_restart, 1019 .fo_mmap = NULL, 1020 }; 1021 1022 static int 1023 vhci_fd_open(dev_t dev, int flags, int type, struct lwp *l) 1024 { 1025 vhci_softc_t *sc; 1026 vhci_fd_t *vfd; 1027 struct file *fp; 1028 int error, fd; 1029 1030 sc = device_lookup_private(&vhci_cd, minor(dev)); 1031 if (sc == NULL) 1032 return EXDEV; 1033 1034 error = fd_allocfile(&fp, &fd); 1035 if (error) 1036 return error; 1037 1038 vfd = kmem_alloc(sizeof(*vfd), KM_SLEEP); 1039 vfd->port = 1; 1040 vfd->addr = 0; 1041 vfd->softc = sc; 1042 1043 return fd_clone(fp, fd, flags, &vhci_fileops, vfd); 1044 } 1045 1046 static int 1047 vhci_fd_close(file_t *fp) 1048 { 1049 vhci_fd_t *vfd = fp->f_data; 1050 int ret __diagused; 1051 1052 KASSERT(vfd != NULL); 1053 ret = vhci_usb_detach(vfd); 1054 KASSERT(ret == 0); 1055 1056 kmem_free(vfd, sizeof(*vfd)); 1057 fp->f_data = NULL; 1058 1059 return 0; 1060 } 1061 1062 static int 1063 vhci_fd_read(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred, 1064 int flags) 1065 { 1066 vhci_fd_t *vfd = fp->f_data; 1067 vhci_softc_t *sc = vfd->softc; 1068 vhci_packet_list_t *pktlist; 1069 vhci_packet_t *pkt, *nxt; 1070 vhci_xfer_list_t vxferlist; 1071 vhci_xfer_t *vxfer; 1072 vhci_port_t *port; 1073 int error = 0; 1074 uint8_t *buf; 1075 size_t size; 1076 1077 if (uio->uio_resid == 0) 1078 return 0; 1079 port = &sc->sc_port[vfd->port]; 1080 pktlist = &port->endpoints[vfd->addr].host_to_usb; 1081 1082 TAILQ_INIT(&vxferlist); 1083 1084 mutex_enter(&port->lock); 1085 1086 if (!(port->status & UPS_PORT_ENABLED)) { 1087 error = ENOBUFS; 1088 goto out; 1089 } 1090 1091 TAILQ_FOREACH_SAFE(pkt, pktlist, portlist, nxt) { 1092 vxfer = pkt->vxfer; 1093 buf = pkt->buf + pkt->cursor; 1094 1095 KASSERT(pkt->size >= pkt->cursor); 1096 size = uimin(uio->uio_resid, pkt->size - pkt->cursor); 1097 1098 KASSERT(vxfer->xfer.ux_status == USBD_IN_PROGRESS); 1099 1100 error = uiomove(buf, size, uio); 1101 if (error) { 1102 DPRINTF("%s: error = %d\n", __func__, error); 1103 goto out; 1104 } 1105 1106 pkt->cursor += size; 1107 1108 if (pkt->cursor == pkt->size) { 1109 vhci_pkt_destroy(sc, pkt); 1110 if (vxfer->npkts == 0) { 1111 TAILQ_INSERT_TAIL(&vxferlist, vxfer, freelist); 1112 } 1113 } 1114 if (uio->uio_resid == 0) { 1115 break; 1116 } 1117 } 1118 1119 out: 1120 mutex_exit(&port->lock); 1121 1122 while ((vxfer = TAILQ_FIRST(&vxferlist)) != NULL) { 1123 struct usbd_xfer *xfer = &vxfer->xfer; 1124 TAILQ_REMOVE(&vxferlist, vxfer, freelist); 1125 1126 mutex_enter(&sc->sc_lock); 1127 xfer->ux_actlen = xfer->ux_length; 1128 xfer->ux_status = USBD_NORMAL_COMPLETION; 1129 usb_transfer_complete(xfer); 1130 mutex_exit(&sc->sc_lock); 1131 } 1132 1133 return error; 1134 } 1135 1136 static int 1137 vhci_fd_write(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred, 1138 int flags) 1139 { 1140 vhci_fd_t *vfd = fp->f_data; 1141 vhci_softc_t *sc = vfd->softc; 1142 vhci_packet_list_t *pktlist; 1143 vhci_packet_t *pkt, *nxt; 1144 vhci_xfer_list_t vxferlist; 1145 vhci_xfer_t *vxfer; 1146 vhci_port_t *port; 1147 int error = 0; 1148 uint8_t *buf; 1149 size_t pktsize, size; 1150 1151 if (uio->uio_resid == 0) 1152 return 0; 1153 port = &sc->sc_port[vfd->port]; 1154 pktlist = &port->endpoints[vfd->addr].usb_to_host; 1155 1156 TAILQ_INIT(&vxferlist); 1157 1158 mutex_enter(&port->lock); 1159 1160 if (!(port->status & UPS_PORT_ENABLED)) { 1161 error = ENOBUFS; 1162 goto out; 1163 } 1164 1165 TAILQ_FOREACH_SAFE(pkt, pktlist, portlist, nxt) { 1166 vxfer = pkt->vxfer; 1167 buf = pkt->buf + pkt->cursor; 1168 1169 pktsize = pkt->size; 1170 if (pkt->type.dat) 1171 pktsize = ulmin(vxfer->resbuf.size, pktsize); 1172 1173 KASSERT(pktsize >= pkt->cursor); 1174 size = uimin(uio->uio_resid, pktsize - pkt->cursor); 1175 1176 KASSERT(vxfer->xfer.ux_status == USBD_IN_PROGRESS); 1177 1178 error = uiomove(buf, size, uio); 1179 if (error) { 1180 DPRINTF("%s: error = %d\n", __func__, error); 1181 goto out; 1182 } 1183 1184 pkt->cursor += size; 1185 1186 if (pkt->cursor == pktsize) { 1187 vhci_pkt_destroy(sc, pkt); 1188 if (vxfer->npkts == 0) { 1189 TAILQ_INSERT_TAIL(&vxferlist, vxfer, freelist); 1190 } 1191 } 1192 if (uio->uio_resid == 0) { 1193 break; 1194 } 1195 } 1196 1197 out: 1198 mutex_exit(&port->lock); 1199 1200 while ((vxfer = TAILQ_FIRST(&vxferlist)) != NULL) { 1201 struct usbd_xfer *xfer = &vxfer->xfer; 1202 TAILQ_REMOVE(&vxferlist, vxfer, freelist); 1203 1204 mutex_enter(&sc->sc_lock); 1205 xfer->ux_actlen = ulmin(vxfer->resbuf.size, xfer->ux_length); 1206 xfer->ux_status = USBD_NORMAL_COMPLETION; 1207 usb_transfer_complete(xfer); 1208 mutex_exit(&sc->sc_lock); 1209 } 1210 1211 return error; 1212 } 1213 1214 static int 1215 vhci_fd_ioctl(file_t *fp, u_long cmd, void *data) 1216 { 1217 vhci_fd_t *vfd = fp->f_data; 1218 1219 KASSERT(vfd != NULL); 1220 1221 switch (cmd) { 1222 case VHCI_IOC_GET_INFO: 1223 return vhci_get_info(vfd, data); 1224 case VHCI_IOC_SET_PORT: 1225 return vhci_set_port(vfd, data); 1226 case VHCI_IOC_SET_ADDR: 1227 return vhci_set_addr(vfd, data); 1228 case VHCI_IOC_USB_ATTACH: 1229 return vhci_usb_attach(vfd); 1230 case VHCI_IOC_USB_DETACH: 1231 return vhci_usb_detach(vfd); 1232 default: 1233 return EINVAL; 1234 } 1235 } 1236 1237 /* -------------------------------------------------------------------------- */ 1238 1239 static int vhci_match(device_t, cfdata_t, void *); 1240 static void vhci_attach(device_t, device_t, void *); 1241 static int vhci_activate(device_t, enum devact); 1242 1243 CFATTACH_DECL_NEW(vhci, sizeof(vhci_softc_t), vhci_match, vhci_attach, 1244 NULL, vhci_activate); 1245 1246 void 1247 vhciattach(int nunits) 1248 { 1249 struct cfdata *cf; 1250 int error; 1251 size_t i; 1252 1253 error = config_cfattach_attach(vhci_cd.cd_name, &vhci_ca); 1254 if (error) { 1255 aprint_error("%s: unable to register cfattach\n", 1256 vhci_cd.cd_name); 1257 (void)config_cfdriver_detach(&vhci_cd); 1258 return; 1259 } 1260 1261 for (i = 0; i < VHCI_NBUSES; i++) { 1262 cf = kmem_alloc(sizeof(*cf), KM_SLEEP); 1263 cf->cf_name = vhci_cd.cd_name; 1264 cf->cf_atname = vhci_cd.cd_name; 1265 cf->cf_unit = i; 1266 cf->cf_fstate = FSTATE_STAR; 1267 config_attach_pseudo(cf); 1268 } 1269 } 1270 1271 static int 1272 vhci_activate(device_t self, enum devact act) 1273 { 1274 vhci_softc_t *sc = device_private(self); 1275 1276 switch (act) { 1277 case DVACT_DEACTIVATE: 1278 sc->sc_dying = 1; 1279 return 0; 1280 default: 1281 return EOPNOTSUPP; 1282 } 1283 } 1284 1285 static int 1286 vhci_match(device_t parent, cfdata_t match, void *aux) 1287 { 1288 return 1; 1289 } 1290 1291 static void 1292 vhci_attach(device_t parent, device_t self, void *aux) 1293 { 1294 vhci_softc_t *sc = device_private(self); 1295 vhci_port_t *port; 1296 uint8_t addr; 1297 size_t i; 1298 1299 sc->sc_dev = self; 1300 sc->sc_bus.ub_revision = USBREV_2_0; 1301 sc->sc_bus.ub_hctype = USBHCTYPE_VHCI; 1302 sc->sc_bus.ub_busnum = self->dv_unit; 1303 sc->sc_bus.ub_usedma = false; 1304 sc->sc_bus.ub_methods = &vhci_bus_methods; 1305 sc->sc_bus.ub_pipesize = sizeof(vhci_pipe_t); 1306 sc->sc_bus.ub_hcpriv = sc; 1307 sc->sc_dying = false; 1308 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); 1309 1310 sc->sc_nports = VHCI_NPORTS; 1311 for (i = 0; i < sc->sc_nports; i++) { 1312 port = &sc->sc_port[i]; 1313 mutex_init(&port->lock, MUTEX_DEFAULT, IPL_SOFTUSB); 1314 for (addr = 0; addr < VHCI_NADDRS; addr++) { 1315 TAILQ_INIT(&port->endpoints[addr].usb_to_host); 1316 TAILQ_INIT(&port->endpoints[addr].host_to_usb); 1317 } 1318 kcov_remote_register(KCOV_REMOTE_VHCI, 1319 KCOV_REMOTE_VHCI_ID(sc->sc_bus.ub_busnum, i)); 1320 } 1321 1322 sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint); 1323 } 1324