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