1 /* $NetBSD: vhci.c,v 1.27 2022/03/12 15:30:51 riastradh 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.27 2022/03/12 15:30:51 riastradh 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 594 DPRINTF("%s: called\n", __func__); 595 596 /* Pipe isn't running, start first */ 597 return vhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 598 } 599 600 static usbd_status 601 vhci_device_ctrl_start(struct usbd_xfer *xfer) 602 { 603 usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc; 604 usb_device_request_t *req = &xfer->ux_request; 605 struct usbd_device *dev = xfer->ux_pipe->up_dev; 606 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; 607 vhci_port_t *port; 608 bool isread = (req->bmRequestType & UT_READ) != 0; 609 uint8_t addr = UE_GET_ADDR(ed->bEndpointAddress); 610 int portno, ret; 611 612 KASSERT(addr == 0); 613 KASSERT(xfer->ux_rqflags & URQ_REQUEST); 614 KASSERT(dev->ud_myhsport != NULL); 615 portno = dev->ud_myhsport->up_portno; 616 617 DPRINTF("%s: type=0x%02x, len=%d, isread=%d, portno=%d\n", 618 __func__, req->bmRequestType, UGETW(req->wLength), isread, portno); 619 620 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 621 622 if (sc->sc_dying) 623 return USBD_IOERROR; 624 625 port = &sc->sc_port[portno]; 626 627 mutex_enter(&port->lock); 628 if (port->status & UPS_PORT_ENABLED) { 629 xfer->ux_status = USBD_IN_PROGRESS; 630 vhci_pkt_ctrl_create(port, xfer, isread, addr); 631 ret = USBD_IN_PROGRESS; 632 } else { 633 ret = USBD_IOERROR; 634 } 635 mutex_exit(&port->lock); 636 637 return ret; 638 } 639 640 static void 641 vhci_device_ctrl_abort(struct usbd_xfer *xfer) 642 { 643 vhci_xfer_t *vxfer = (vhci_xfer_t *)xfer; 644 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; 645 vhci_port_t *port = vxfer->port; 646 vhci_packet_t *pkt; 647 648 DPRINTF("%s: called\n", __func__); 649 650 KASSERT(mutex_owned(&sc->sc_lock)); 651 652 callout_halt(&xfer->ux_callout, &sc->sc_lock); 653 654 /* If anyone else beat us, we're done. */ 655 KASSERT(xfer->ux_status != USBD_CANCELLED); 656 if (xfer->ux_status != USBD_IN_PROGRESS) 657 return; 658 659 mutex_enter(&port->lock); 660 while (vxfer->npkts > 0) { 661 pkt = TAILQ_FIRST(&vxfer->pkts); 662 KASSERT(pkt != NULL); 663 vhci_pkt_destroy(sc, pkt); 664 } 665 KASSERT(TAILQ_FIRST(&vxfer->pkts) == NULL); 666 mutex_exit(&port->lock); 667 668 xfer->ux_status = USBD_CANCELLED; 669 usb_transfer_complete(xfer); 670 KASSERT(mutex_owned(&sc->sc_lock)); 671 } 672 673 static void 674 vhci_device_ctrl_close(struct usbd_pipe *pipe) 675 { 676 DPRINTF("%s: called\n", __func__); 677 } 678 679 static void 680 vhci_device_ctrl_cleartoggle(struct usbd_pipe *pipe) 681 { 682 DPRINTF("%s: called\n", __func__); 683 } 684 685 static void 686 vhci_device_ctrl_done(struct usbd_xfer *xfer) 687 { 688 DPRINTF("%s: called\n", __func__); 689 } 690 691 /* -------------------------------------------------------------------------- */ 692 693 static usbd_status 694 vhci_root_intr_transfer(struct usbd_xfer *xfer) 695 { 696 697 DPRINTF("%s: called\n", __func__); 698 699 /* Pipe isn't running, start first */ 700 return vhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 701 } 702 703 static usbd_status 704 vhci_root_intr_start(struct usbd_xfer *xfer) 705 { 706 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; 707 708 DPRINTF("%s: called, len=%zu\n", __func__, (size_t)xfer->ux_length); 709 710 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 711 712 if (sc->sc_dying) 713 return USBD_IOERROR; 714 715 KASSERT(sc->sc_intrxfer == NULL); 716 sc->sc_intrxfer = xfer; 717 xfer->ux_status = USBD_IN_PROGRESS; 718 719 return USBD_IN_PROGRESS; 720 } 721 722 static void 723 vhci_root_intr_abort(struct usbd_xfer *xfer) 724 { 725 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; 726 727 DPRINTF("%s: called\n", __func__); 728 729 KASSERT(mutex_owned(&sc->sc_lock)); 730 KASSERT(xfer->ux_pipe->up_intrxfer == xfer); 731 732 /* If xfer has already completed, nothing to do here. */ 733 if (sc->sc_intrxfer == NULL) 734 return; 735 736 /* 737 * Otherwise, sc->sc_intrxfer had better be this transfer. 738 * Cancel it. 739 */ 740 KASSERT(sc->sc_intrxfer == xfer); 741 KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 742 xfer->ux_status = USBD_CANCELLED; 743 usb_transfer_complete(xfer); 744 } 745 746 static void 747 vhci_root_intr_close(struct usbd_pipe *pipe) 748 { 749 vhci_softc_t *sc __diagused = pipe->up_dev->ud_bus->ub_hcpriv; 750 751 DPRINTF("%s: called\n", __func__); 752 753 KASSERT(mutex_owned(&sc->sc_lock)); 754 755 /* 756 * Caller must guarantee the xfer has completed first, by 757 * closing the pipe only after normal completion or an abort. 758 */ 759 KASSERT(sc->sc_intrxfer == NULL); 760 } 761 762 static void 763 vhci_root_intr_cleartoggle(struct usbd_pipe *pipe) 764 { 765 DPRINTF("%s: called\n", __func__); 766 } 767 768 static void 769 vhci_root_intr_done(struct usbd_xfer *xfer) 770 { 771 vhci_softc_t *sc = xfer->ux_bus->ub_hcpriv; 772 773 KASSERT(mutex_owned(&sc->sc_lock)); 774 775 /* Claim the xfer so it doesn't get completed again. */ 776 KASSERT(sc->sc_intrxfer == xfer); 777 KASSERT(xfer->ux_status != USBD_IN_PROGRESS); 778 sc->sc_intrxfer = NULL; 779 } 780 781 /* -------------------------------------------------------------------------- */ 782 783 static void 784 vhci_usb_attach(vhci_fd_t *vfd) 785 { 786 vhci_softc_t *sc = vfd->softc; 787 vhci_port_t *port; 788 struct usbd_xfer *xfer; 789 u_char *p; 790 791 port = &sc->sc_port[vfd->port]; 792 793 mutex_enter(&sc->sc_lock); 794 795 mutex_enter(&port->lock); 796 port->status = UPS_CURRENT_CONNECT_STATUS | UPS_PORT_ENABLED | 797 UPS_PORT_POWER; 798 port->change = UPS_C_CONNECT_STATUS | UPS_C_PORT_RESET; 799 mutex_exit(&port->lock); 800 801 xfer = sc->sc_intrxfer; 802 803 if (xfer == NULL) { 804 goto done; 805 } 806 KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 807 808 /* 809 * Mark our port has having changed state. Uhub will then fetch 810 * status/change and see it needs to perform an attach. 811 */ 812 p = xfer->ux_buf; 813 memset(p, 0, xfer->ux_length); 814 p[0] = __BIT(vfd->port); /* TODO-bitmap */ 815 xfer->ux_actlen = xfer->ux_length; 816 xfer->ux_status = USBD_NORMAL_COMPLETION; 817 818 usb_transfer_complete(xfer); 819 820 done: 821 mutex_exit(&sc->sc_lock); 822 } 823 824 static void 825 vhci_port_flush(vhci_softc_t *sc, vhci_port_t *port) 826 { 827 vhci_packet_list_t *pktlist; 828 vhci_packet_t *pkt, *nxt; 829 vhci_xfer_list_t vxferlist; 830 vhci_xfer_t *vxfer; 831 uint8_t addr; 832 833 KASSERT(mutex_owned(&sc->sc_lock)); 834 KASSERT(mutex_owned(&port->lock)); 835 836 TAILQ_INIT(&vxferlist); 837 838 for (addr = 0; addr < VHCI_NADDRS; addr++) { 839 /* Drop all the packets in the H->U direction. */ 840 pktlist = &port->endpoints[addr].host_to_usb; 841 TAILQ_FOREACH_SAFE(pkt, pktlist, portlist, nxt) { 842 vxfer = pkt->vxfer; 843 KASSERT(vxfer->xfer.ux_status == USBD_IN_PROGRESS); 844 vhci_pkt_destroy(sc, pkt); 845 if (vxfer->npkts == 0) 846 TAILQ_INSERT_TAIL(&vxferlist, vxfer, freelist); 847 } 848 KASSERT(TAILQ_FIRST(pktlist) == NULL); 849 850 /* Drop all the packets in the U->H direction. */ 851 pktlist = &port->endpoints[addr].usb_to_host; 852 TAILQ_FOREACH_SAFE(pkt, pktlist, portlist, nxt) { 853 vxfer = pkt->vxfer; 854 KASSERT(vxfer->xfer.ux_status == USBD_IN_PROGRESS); 855 vhci_pkt_destroy(sc, pkt); 856 if (vxfer->npkts == 0) 857 TAILQ_INSERT_TAIL(&vxferlist, vxfer, freelist); 858 } 859 KASSERT(TAILQ_FIRST(pktlist) == NULL); 860 861 /* Terminate all the xfers collected. */ 862 while ((vxfer = TAILQ_FIRST(&vxferlist)) != NULL) { 863 struct usbd_xfer *xfer = &vxfer->xfer; 864 TAILQ_REMOVE(&vxferlist, vxfer, freelist); 865 866 xfer->ux_status = USBD_TIMEOUT; 867 usb_transfer_complete(xfer); 868 } 869 } 870 } 871 872 static void 873 vhci_usb_detach(vhci_fd_t *vfd) 874 { 875 vhci_softc_t *sc = vfd->softc; 876 vhci_port_t *port; 877 struct usbd_xfer *xfer; 878 u_char *p; 879 880 port = &sc->sc_port[vfd->port]; 881 882 mutex_enter(&sc->sc_lock); 883 884 xfer = sc->sc_intrxfer; 885 if (xfer == NULL) { 886 goto done; 887 } 888 KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 889 890 mutex_enter(&port->lock); 891 892 port->status = 0; 893 port->change = UPS_C_CONNECT_STATUS | UPS_C_PORT_RESET; 894 895 /* 896 * Mark our port has having changed state. Uhub will then fetch 897 * status/change and see it needs to perform a detach. 898 */ 899 p = xfer->ux_buf; 900 memset(p, 0, xfer->ux_length); 901 p[0] = __BIT(vfd->port); /* TODO-bitmap */ 902 xfer->ux_actlen = xfer->ux_length; 903 xfer->ux_status = USBD_NORMAL_COMPLETION; 904 905 usb_transfer_complete(xfer); 906 vhci_port_flush(sc, port); 907 908 mutex_exit(&port->lock); 909 done: 910 mutex_exit(&sc->sc_lock); 911 } 912 913 static int 914 vhci_get_info(vhci_fd_t *vfd, struct vhci_ioc_get_info *args) 915 { 916 vhci_softc_t *sc = vfd->softc; 917 vhci_port_t *port; 918 919 port = &sc->sc_port[vfd->port]; 920 921 args->nports = VHCI_NPORTS; 922 args->port = vfd->port; 923 mutex_enter(&port->lock); 924 args->status = port->status; 925 mutex_exit(&port->lock); 926 args->addr = vfd->addr; 927 928 return 0; 929 } 930 931 static int 932 vhci_set_port(vhci_fd_t *vfd, struct vhci_ioc_set_port *args) 933 { 934 vhci_softc_t *sc = vfd->softc; 935 936 if (args->port == 0 || args->port >= sc->sc_nports) 937 return EINVAL; 938 939 vfd->port = args->port; 940 941 return 0; 942 } 943 944 static int 945 vhci_set_addr(vhci_fd_t *vfd, struct vhci_ioc_set_addr *args) 946 { 947 if (args->addr >= VHCI_NADDRS) 948 return EINVAL; 949 950 vfd->addr = args->addr; 951 952 return 0; 953 } 954 955 /* -------------------------------------------------------------------------- */ 956 957 static dev_type_open(vhci_fd_open); 958 959 const struct cdevsw vhci_cdevsw = { 960 .d_open = vhci_fd_open, 961 .d_close = noclose, 962 .d_read = noread, 963 .d_write = nowrite, 964 .d_ioctl = noioctl, 965 .d_stop = nostop, 966 .d_tty = notty, 967 .d_poll = nopoll, 968 .d_mmap = nommap, 969 .d_kqfilter = nokqfilter, 970 .d_discard = nodiscard, 971 .d_flag = D_OTHER | D_MPSAFE 972 }; 973 974 static int vhci_fd_ioctl(file_t *, u_long, void *); 975 static int vhci_fd_close(file_t *); 976 static int vhci_fd_read(struct file *, off_t *, struct uio *, kauth_cred_t, int); 977 static int vhci_fd_write(struct file *, off_t *, struct uio *, kauth_cred_t, int); 978 979 const struct fileops vhci_fileops = { 980 .fo_read = vhci_fd_read, 981 .fo_write = vhci_fd_write, 982 .fo_ioctl = vhci_fd_ioctl, 983 .fo_fcntl = fnullop_fcntl, 984 .fo_poll = fnullop_poll, 985 .fo_stat = fbadop_stat, 986 .fo_close = vhci_fd_close, 987 .fo_kqfilter = fnullop_kqfilter, 988 .fo_restart = fnullop_restart, 989 .fo_mmap = NULL, 990 }; 991 992 static int 993 vhci_fd_open(dev_t dev, int flags, int type, struct lwp *l) 994 { 995 vhci_softc_t *sc; 996 vhci_fd_t *vfd; 997 struct file *fp; 998 int error, fd; 999 1000 sc = device_lookup_private(&vhci_cd, minor(dev)); 1001 if (sc == NULL) 1002 return EXDEV; 1003 1004 error = fd_allocfile(&fp, &fd); 1005 if (error) 1006 return error; 1007 1008 vfd = kmem_alloc(sizeof(*vfd), KM_SLEEP); 1009 vfd->port = 1; 1010 vfd->addr = 0; 1011 vfd->softc = sc; 1012 1013 return fd_clone(fp, fd, flags, &vhci_fileops, vfd); 1014 } 1015 1016 static int 1017 vhci_fd_close(file_t *fp) 1018 { 1019 vhci_fd_t *vfd = fp->f_data; 1020 1021 KASSERT(vfd != NULL); 1022 vhci_usb_detach(vfd); 1023 1024 kmem_free(vfd, sizeof(*vfd)); 1025 fp->f_data = NULL; 1026 1027 return 0; 1028 } 1029 1030 static int 1031 vhci_fd_read(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred, 1032 int flags) 1033 { 1034 vhci_fd_t *vfd = fp->f_data; 1035 vhci_softc_t *sc = vfd->softc; 1036 vhci_packet_list_t *pktlist; 1037 vhci_packet_t *pkt, *nxt; 1038 vhci_xfer_list_t vxferlist; 1039 vhci_xfer_t *vxfer; 1040 vhci_port_t *port; 1041 int error = 0; 1042 uint8_t *buf; 1043 size_t size; 1044 1045 if (uio->uio_resid == 0) 1046 return 0; 1047 port = &sc->sc_port[vfd->port]; 1048 pktlist = &port->endpoints[vfd->addr].host_to_usb; 1049 1050 TAILQ_INIT(&vxferlist); 1051 1052 mutex_enter(&port->lock); 1053 1054 if (!(port->status & UPS_PORT_ENABLED)) { 1055 error = ENOBUFS; 1056 goto out; 1057 } 1058 1059 TAILQ_FOREACH_SAFE(pkt, pktlist, portlist, nxt) { 1060 vxfer = pkt->vxfer; 1061 buf = pkt->buf + pkt->cursor; 1062 1063 KASSERT(pkt->size >= pkt->cursor); 1064 size = uimin(uio->uio_resid, pkt->size - pkt->cursor); 1065 1066 KASSERT(vxfer->xfer.ux_status == USBD_IN_PROGRESS); 1067 1068 error = uiomove(buf, size, uio); 1069 if (error) { 1070 DPRINTF("%s: error = %d\n", __func__, error); 1071 goto out; 1072 } 1073 1074 pkt->cursor += size; 1075 1076 if (pkt->cursor == pkt->size) { 1077 vhci_pkt_destroy(sc, pkt); 1078 if (vxfer->npkts == 0) { 1079 TAILQ_INSERT_TAIL(&vxferlist, vxfer, freelist); 1080 } 1081 } 1082 if (uio->uio_resid == 0) { 1083 break; 1084 } 1085 } 1086 1087 out: 1088 mutex_exit(&port->lock); 1089 1090 while ((vxfer = TAILQ_FIRST(&vxferlist)) != NULL) { 1091 struct usbd_xfer *xfer = &vxfer->xfer; 1092 TAILQ_REMOVE(&vxferlist, vxfer, freelist); 1093 1094 mutex_enter(&sc->sc_lock); 1095 xfer->ux_actlen = xfer->ux_length; 1096 xfer->ux_status = USBD_NORMAL_COMPLETION; 1097 usb_transfer_complete(xfer); 1098 mutex_exit(&sc->sc_lock); 1099 } 1100 1101 return error; 1102 } 1103 1104 static int 1105 vhci_fd_write(struct file *fp, off_t *offp, struct uio *uio, kauth_cred_t cred, 1106 int flags) 1107 { 1108 vhci_fd_t *vfd = fp->f_data; 1109 vhci_softc_t *sc = vfd->softc; 1110 vhci_packet_list_t *pktlist; 1111 vhci_packet_t *pkt, *nxt; 1112 vhci_xfer_list_t vxferlist; 1113 vhci_xfer_t *vxfer; 1114 vhci_port_t *port; 1115 int error = 0; 1116 uint8_t *buf; 1117 size_t pktsize, size; 1118 1119 if (uio->uio_resid == 0) 1120 return 0; 1121 port = &sc->sc_port[vfd->port]; 1122 pktlist = &port->endpoints[vfd->addr].usb_to_host; 1123 1124 TAILQ_INIT(&vxferlist); 1125 1126 mutex_enter(&port->lock); 1127 1128 if (!(port->status & UPS_PORT_ENABLED)) { 1129 error = ENOBUFS; 1130 goto out; 1131 } 1132 1133 TAILQ_FOREACH_SAFE(pkt, pktlist, portlist, nxt) { 1134 vxfer = pkt->vxfer; 1135 buf = pkt->buf + pkt->cursor; 1136 1137 pktsize = pkt->size; 1138 if (pkt->type.dat) 1139 pktsize = ulmin(vxfer->resbuf.size, pktsize); 1140 1141 KASSERT(pktsize >= pkt->cursor); 1142 size = uimin(uio->uio_resid, pktsize - pkt->cursor); 1143 1144 KASSERT(vxfer->xfer.ux_status == USBD_IN_PROGRESS); 1145 1146 error = uiomove(buf, size, uio); 1147 if (error) { 1148 DPRINTF("%s: error = %d\n", __func__, error); 1149 goto out; 1150 } 1151 1152 pkt->cursor += size; 1153 1154 if (pkt->cursor == pktsize) { 1155 vhci_pkt_destroy(sc, pkt); 1156 if (vxfer->npkts == 0) { 1157 TAILQ_INSERT_TAIL(&vxferlist, vxfer, freelist); 1158 } 1159 } 1160 if (uio->uio_resid == 0) { 1161 break; 1162 } 1163 } 1164 1165 out: 1166 mutex_exit(&port->lock); 1167 1168 while ((vxfer = TAILQ_FIRST(&vxferlist)) != NULL) { 1169 struct usbd_xfer *xfer = &vxfer->xfer; 1170 TAILQ_REMOVE(&vxferlist, vxfer, freelist); 1171 1172 mutex_enter(&sc->sc_lock); 1173 xfer->ux_actlen = ulmin(vxfer->resbuf.size, xfer->ux_length); 1174 xfer->ux_status = USBD_NORMAL_COMPLETION; 1175 usb_transfer_complete(xfer); 1176 mutex_exit(&sc->sc_lock); 1177 } 1178 1179 return error; 1180 } 1181 1182 static int 1183 vhci_fd_ioctl(file_t *fp, u_long cmd, void *data) 1184 { 1185 vhci_fd_t *vfd = fp->f_data; 1186 1187 KASSERT(vfd != NULL); 1188 1189 switch (cmd) { 1190 case VHCI_IOC_GET_INFO: 1191 return vhci_get_info(vfd, data); 1192 case VHCI_IOC_SET_PORT: 1193 return vhci_set_port(vfd, data); 1194 case VHCI_IOC_SET_ADDR: 1195 return vhci_set_addr(vfd, data); 1196 case VHCI_IOC_USB_ATTACH: 1197 vhci_usb_attach(vfd); 1198 return 0; 1199 case VHCI_IOC_USB_DETACH: 1200 vhci_usb_detach(vfd); 1201 return 0; 1202 default: 1203 return EINVAL; 1204 } 1205 } 1206 1207 /* -------------------------------------------------------------------------- */ 1208 1209 static int vhci_match(device_t, cfdata_t, void *); 1210 static void vhci_attach(device_t, device_t, void *); 1211 static int vhci_activate(device_t, enum devact); 1212 1213 CFATTACH_DECL_NEW(vhci, sizeof(vhci_softc_t), vhci_match, vhci_attach, 1214 NULL, vhci_activate); 1215 1216 void 1217 vhciattach(int nunits) 1218 { 1219 struct cfdata *cf; 1220 int error; 1221 size_t i; 1222 1223 error = config_cfattach_attach(vhci_cd.cd_name, &vhci_ca); 1224 if (error) { 1225 aprint_error("%s: unable to register cfattach\n", 1226 vhci_cd.cd_name); 1227 (void)config_cfdriver_detach(&vhci_cd); 1228 return; 1229 } 1230 1231 for (i = 0; i < VHCI_NBUSES; i++) { 1232 cf = kmem_alloc(sizeof(*cf), KM_SLEEP); 1233 cf->cf_name = vhci_cd.cd_name; 1234 cf->cf_atname = vhci_cd.cd_name; 1235 cf->cf_unit = i; 1236 cf->cf_fstate = FSTATE_STAR; 1237 config_attach_pseudo(cf); 1238 } 1239 } 1240 1241 static int 1242 vhci_activate(device_t self, enum devact act) 1243 { 1244 vhci_softc_t *sc = device_private(self); 1245 1246 switch (act) { 1247 case DVACT_DEACTIVATE: 1248 sc->sc_dying = 1; 1249 return 0; 1250 default: 1251 return EOPNOTSUPP; 1252 } 1253 } 1254 1255 static int 1256 vhci_match(device_t parent, cfdata_t match, void *aux) 1257 { 1258 return 1; 1259 } 1260 1261 static void 1262 vhci_attach(device_t parent, device_t self, void *aux) 1263 { 1264 vhci_softc_t *sc = device_private(self); 1265 vhci_port_t *port; 1266 uint8_t addr; 1267 size_t i; 1268 1269 sc->sc_dev = self; 1270 sc->sc_bus.ub_revision = USBREV_2_0; 1271 sc->sc_bus.ub_hctype = USBHCTYPE_VHCI; 1272 sc->sc_bus.ub_busnum = device_unit(self); 1273 sc->sc_bus.ub_usedma = false; 1274 sc->sc_bus.ub_methods = &vhci_bus_methods; 1275 sc->sc_bus.ub_pipesize = sizeof(vhci_pipe_t); 1276 sc->sc_bus.ub_hcpriv = sc; 1277 sc->sc_dying = false; 1278 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); 1279 1280 sc->sc_nports = VHCI_NPORTS; 1281 for (i = 0; i < sc->sc_nports; i++) { 1282 port = &sc->sc_port[i]; 1283 mutex_init(&port->lock, MUTEX_DEFAULT, IPL_SOFTUSB); 1284 for (addr = 0; addr < VHCI_NADDRS; addr++) { 1285 TAILQ_INIT(&port->endpoints[addr].usb_to_host); 1286 TAILQ_INIT(&port->endpoints[addr].host_to_usb); 1287 } 1288 kcov_remote_register(KCOV_REMOTE_VHCI, 1289 KCOV_REMOTE_VHCI_ID(sc->sc_bus.ub_busnum, i)); 1290 } 1291 1292 sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint, CFARGS_NONE); 1293 } 1294