1 /* $NetBSD: usbdi.c,v 1.175 2017/10/28 00:37:12 pgoyette Exp $ */ 2 3 /* 4 * Copyright (c) 1998, 2012, 2015 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Lennart Augustsson (lennart@augustsson.net) at 9 * Carlstedt Research & Technology, Matthew R. Green (mrg@eterna.com.au), 10 * and Nick Hudson. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <sys/cdefs.h> 35 __KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.175 2017/10/28 00:37:12 pgoyette Exp $"); 36 37 #ifdef _KERNEL_OPT 38 #include "opt_usb.h" 39 #include "opt_compat_netbsd.h" 40 #include "usb_dma.h" 41 #endif 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/kernel.h> 46 #include <sys/device.h> 47 #include <sys/kmem.h> 48 #include <sys/proc.h> 49 #include <sys/bus.h> 50 #include <sys/cpu.h> 51 52 #include <dev/usb/usb.h> 53 #include <dev/usb/usbdi.h> 54 #include <dev/usb/usbdi_util.h> 55 #include <dev/usb/usbdivar.h> 56 #include <dev/usb/usb_mem.h> 57 #include <dev/usb/usb_quirks.h> 58 #include <dev/usb/usbhist.h> 59 60 /* UTF-8 encoding stuff */ 61 #include <fs/unicode.h> 62 63 extern int usbdebug; 64 65 Static usbd_status usbd_ar_pipe(struct usbd_pipe *); 66 Static void usbd_start_next(struct usbd_pipe *); 67 Static usbd_status usbd_open_pipe_ival 68 (struct usbd_interface *, uint8_t, uint8_t, struct usbd_pipe **, int); 69 static void *usbd_alloc_buffer(struct usbd_xfer *, uint32_t); 70 static void usbd_free_buffer(struct usbd_xfer *); 71 static struct usbd_xfer *usbd_alloc_xfer(struct usbd_device *, unsigned int); 72 static usbd_status usbd_free_xfer(struct usbd_xfer *); 73 74 #if defined(USB_DEBUG) 75 void 76 usbd_dump_iface(struct usbd_interface *iface) 77 { 78 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 79 80 USBHIST_LOG(usbdebug, "iface %#jx", (uintptr_t)iface, 0, 0, 0); 81 if (iface == NULL) 82 return; 83 USBHIST_LOG(usbdebug, " device = %#jx idesc = %#jx index = %d", 84 (uintptr_t)iface->ui_dev, (uintptr_t)iface->ui_idesc, 85 iface->ui_index, 0); 86 USBHIST_LOG(usbdebug, " altindex=%d priv=%#jx", 87 iface->ui_altindex, (uintptr_t)iface->ui_priv, 0, 0); 88 } 89 90 void 91 usbd_dump_device(struct usbd_device *dev) 92 { 93 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 94 95 USBHIST_LOG(usbdebug, "dev = %#jx", (uintptr_t)dev, 0, 0, 0); 96 if (dev == NULL) 97 return; 98 USBHIST_LOG(usbdebug, " bus = %#jx default_pipe = %#jx", 99 (uintptr_t)dev->ud_bus, (uintptr_t)dev->ud_pipe0, 0, 0); 100 USBHIST_LOG(usbdebug, " address = %jd config = %jd depth = %jd ", 101 dev->ud_addr, dev->ud_config, dev->ud_depth, 0); 102 USBHIST_LOG(usbdebug, " speed = %jd self_powered = %jd " 103 "power = %jd langid = %jd", 104 dev->ud_speed, dev->ud_selfpowered, dev->ud_power, dev->ud_langid); 105 } 106 107 void 108 usbd_dump_endpoint(struct usbd_endpoint *endp) 109 { 110 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 111 112 USBHIST_LOG(usbdebug, "endp = %#jx", (uintptr_t)endp, 0, 0, 0); 113 if (endp == NULL) 114 return; 115 USBHIST_LOG(usbdebug, " edesc = %#jx refcnt = %jd", 116 (uintptr_t)endp->ue_edesc, endp->ue_refcnt, 0, 0); 117 if (endp->ue_edesc) 118 USBHIST_LOG(usbdebug, " bEndpointAddress=0x%02x", 119 endp->ue_edesc->bEndpointAddress, 0, 0, 0); 120 } 121 122 void 123 usbd_dump_queue(struct usbd_pipe *pipe) 124 { 125 struct usbd_xfer *xfer; 126 127 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 128 129 USBHIST_LOG(usbdebug, "pipe = %#jx", (uintptr_t)pipe, 0, 0, 0); 130 SIMPLEQ_FOREACH(xfer, &pipe->up_queue, ux_next) { 131 USBHIST_LOG(usbdebug, " xfer = %#jx", (uintptr_t)xfer, 132 0, 0, 0); 133 } 134 } 135 136 void 137 usbd_dump_pipe(struct usbd_pipe *pipe) 138 { 139 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 140 141 USBHIST_LOG(usbdebug, "pipe = %#jx", (uintptr_t)pipe, 0, 0, 0); 142 if (pipe == NULL) 143 return; 144 usbd_dump_iface(pipe->up_iface); 145 usbd_dump_device(pipe->up_dev); 146 usbd_dump_endpoint(pipe->up_endpoint); 147 USBHIST_LOG(usbdebug, "(usbd_dump_pipe)", 0, 0, 0, 0); 148 USBHIST_LOG(usbdebug, " running = %jd aborting = %jd", 149 pipe->up_running, pipe->up_aborting, 0, 0); 150 USBHIST_LOG(usbdebug, " intrxfer = %#jx, repeat = %jd, " 151 "interval = %jd", (uintptr_t)pipe->up_intrxfer, pipe->up_repeat, 152 pipe->up_interval, 0); 153 } 154 #endif 155 156 usbd_status 157 usbd_open_pipe(struct usbd_interface *iface, uint8_t address, 158 uint8_t flags, struct usbd_pipe **pipe) 159 { 160 return (usbd_open_pipe_ival(iface, address, flags, pipe, 161 USBD_DEFAULT_INTERVAL)); 162 } 163 164 usbd_status 165 usbd_open_pipe_ival(struct usbd_interface *iface, uint8_t address, 166 uint8_t flags, struct usbd_pipe **pipe, int ival) 167 { 168 struct usbd_pipe *p; 169 struct usbd_endpoint *ep; 170 usbd_status err; 171 int i; 172 173 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 174 175 USBHIST_LOG(usbdebug, "iface = %#jx address = 0x%jx flags = 0x%jx", 176 (uintptr_t)iface, address, flags, 0); 177 178 for (i = 0; i < iface->ui_idesc->bNumEndpoints; i++) { 179 ep = &iface->ui_endpoints[i]; 180 if (ep->ue_edesc == NULL) 181 return USBD_IOERROR; 182 if (ep->ue_edesc->bEndpointAddress == address) 183 goto found; 184 } 185 return USBD_BAD_ADDRESS; 186 found: 187 if ((flags & USBD_EXCLUSIVE_USE) && ep->ue_refcnt != 0) 188 return USBD_IN_USE; 189 err = usbd_setup_pipe_flags(iface->ui_dev, iface, ep, ival, &p, flags); 190 if (err) 191 return err; 192 LIST_INSERT_HEAD(&iface->ui_pipes, p, up_next); 193 *pipe = p; 194 return USBD_NORMAL_COMPLETION; 195 } 196 197 usbd_status 198 usbd_open_pipe_intr(struct usbd_interface *iface, uint8_t address, 199 uint8_t flags, struct usbd_pipe **pipe, 200 void *priv, void *buffer, uint32_t len, 201 usbd_callback cb, int ival) 202 { 203 usbd_status err; 204 struct usbd_xfer *xfer; 205 struct usbd_pipe *ipipe; 206 207 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 208 209 USBHIST_LOG(usbdebug, "address = 0x%jx flags = 0x%jx len = %jd", 210 address, flags, len, 0); 211 212 err = usbd_open_pipe_ival(iface, address, 213 USBD_EXCLUSIVE_USE | (flags & USBD_MPSAFE), 214 &ipipe, ival); 215 if (err) 216 return err; 217 err = usbd_create_xfer(ipipe, len, flags, 0, &xfer); 218 if (err) 219 goto bad1; 220 221 usbd_setup_xfer(xfer, priv, buffer, len, flags, USBD_NO_TIMEOUT, cb); 222 ipipe->up_intrxfer = xfer; 223 ipipe->up_repeat = 1; 224 err = usbd_transfer(xfer); 225 *pipe = ipipe; 226 if (err != USBD_IN_PROGRESS) 227 goto bad3; 228 return USBD_NORMAL_COMPLETION; 229 230 bad3: 231 ipipe->up_intrxfer = NULL; 232 ipipe->up_repeat = 0; 233 234 usbd_destroy_xfer(xfer); 235 bad1: 236 usbd_close_pipe(ipipe); 237 return err; 238 } 239 240 usbd_status 241 usbd_close_pipe(struct usbd_pipe *pipe) 242 { 243 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 244 245 KASSERT(pipe != NULL); 246 247 usbd_lock_pipe(pipe); 248 249 if (!SIMPLEQ_EMPTY(&pipe->up_queue)) { 250 printf("WARNING: pipe closed with active xfers on addr %d\n", 251 pipe->up_dev->ud_addr); 252 usbd_ar_pipe(pipe); 253 } 254 255 KASSERT(SIMPLEQ_EMPTY(&pipe->up_queue)); 256 257 LIST_REMOVE(pipe, up_next); 258 pipe->up_endpoint->ue_refcnt--; 259 260 if (pipe->up_intrxfer != NULL) { 261 usbd_unlock_pipe(pipe); 262 usbd_destroy_xfer(pipe->up_intrxfer); 263 usbd_lock_pipe(pipe); 264 } 265 266 pipe->up_methods->upm_close(pipe); 267 usbd_unlock_pipe(pipe); 268 kmem_free(pipe, pipe->up_dev->ud_bus->ub_pipesize); 269 270 return USBD_NORMAL_COMPLETION; 271 } 272 273 usbd_status 274 usbd_transfer(struct usbd_xfer *xfer) 275 { 276 struct usbd_pipe *pipe = xfer->ux_pipe; 277 usbd_status err; 278 unsigned int size, flags; 279 280 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 281 282 USBHIST_LOG(usbdebug, 283 "xfer = %#jx, flags = %#jx, pipe = %#jx, running = %jd", 284 (uintptr_t)xfer, xfer->ux_flags, (uintptr_t)pipe, pipe->up_running); 285 286 #ifdef USB_DEBUG 287 if (usbdebug > 5) 288 usbd_dump_queue(pipe); 289 #endif 290 xfer->ux_done = 0; 291 292 if (pipe->up_aborting) { 293 USBHIST_LOG(usbdebug, "<- done xfer %#jx, aborting", 294 (uintptr_t)xfer, 0, 0, 0); 295 return USBD_CANCELLED; 296 } 297 298 KASSERT(xfer->ux_length == 0 || xfer->ux_buf != NULL); 299 300 size = xfer->ux_length; 301 flags = xfer->ux_flags; 302 303 if (size != 0) { 304 /* 305 * Use the xfer buffer if none specified in transfer setup. 306 * isoc transfers always use the xfer buffer, i.e. 307 * ux_buffer is always NULL for isoc. 308 */ 309 if (xfer->ux_buffer == NULL) { 310 xfer->ux_buffer = xfer->ux_buf; 311 } 312 313 /* 314 * If not using the xfer buffer copy data to the 315 * xfer buffer for OUT transfers of >0 length 316 */ 317 if (xfer->ux_buffer != xfer->ux_buf) { 318 KASSERT(xfer->ux_buf); 319 if (!usbd_xfer_isread(xfer)) { 320 memcpy(xfer->ux_buf, xfer->ux_buffer, size); 321 } 322 } 323 } 324 325 /* xfer is not valid after the transfer method unless synchronous */ 326 err = pipe->up_methods->upm_transfer(xfer); 327 USBHIST_LOG(usbdebug, "<- done transfer %#jx, err = %jd", 328 (uintptr_t)xfer, err, 0, 0); 329 330 if (err != USBD_IN_PROGRESS && err) { 331 /* 332 * The transfer made it onto the pipe queue, but didn't get 333 * accepted by the HCD for some reason. It needs removing 334 * from the pipe queue. 335 */ 336 usbd_lock_pipe(pipe); 337 SIMPLEQ_REMOVE_HEAD(&pipe->up_queue, ux_next); 338 if (pipe->up_serialise) 339 usbd_start_next(pipe); 340 usbd_unlock_pipe(pipe); 341 } 342 343 if (!(flags & USBD_SYNCHRONOUS)) { 344 USBHIST_LOG(usbdebug, "<- done xfer %#jx, not sync (err %jd)", 345 (uintptr_t)xfer, err, 0, 0); 346 return err; 347 } 348 349 if (err != USBD_IN_PROGRESS) { 350 USBHIST_LOG(usbdebug, "<- done xfer %#jx, err %jd " 351 "(complete/error)", (uintptr_t)xfer, err, 0, 0); 352 return err; 353 } 354 355 /* Sync transfer, wait for completion. */ 356 usbd_lock_pipe(pipe); 357 while (!xfer->ux_done) { 358 if (pipe->up_dev->ud_bus->ub_usepolling) 359 panic("usbd_transfer: not done"); 360 USBHIST_LOG(usbdebug, "<- sleeping on xfer %#jx", 361 (uintptr_t)xfer, 0, 0, 0); 362 363 err = 0; 364 if ((flags & USBD_SYNCHRONOUS_SIG) != 0) { 365 err = cv_wait_sig(&xfer->ux_cv, pipe->up_dev->ud_bus->ub_lock); 366 } else { 367 cv_wait(&xfer->ux_cv, pipe->up_dev->ud_bus->ub_lock); 368 } 369 if (err) { 370 if (!xfer->ux_done) 371 pipe->up_methods->upm_abort(xfer); 372 break; 373 } 374 } 375 usbd_unlock_pipe(pipe); 376 return xfer->ux_status; 377 } 378 379 /* Like usbd_transfer(), but waits for completion. */ 380 usbd_status 381 usbd_sync_transfer(struct usbd_xfer *xfer) 382 { 383 xfer->ux_flags |= USBD_SYNCHRONOUS; 384 return usbd_transfer(xfer); 385 } 386 387 /* Like usbd_transfer(), but waits for completion and listens for signals. */ 388 usbd_status 389 usbd_sync_transfer_sig(struct usbd_xfer *xfer) 390 { 391 xfer->ux_flags |= USBD_SYNCHRONOUS | USBD_SYNCHRONOUS_SIG; 392 return usbd_transfer(xfer); 393 } 394 395 static void * 396 usbd_alloc_buffer(struct usbd_xfer *xfer, uint32_t size) 397 { 398 KASSERT(xfer->ux_buf == NULL); 399 KASSERT(size != 0); 400 401 xfer->ux_bufsize = 0; 402 #if NUSB_DMA > 0 403 struct usbd_bus *bus = xfer->ux_bus; 404 405 if (bus->ub_usedma) { 406 usb_dma_t *dmap = &xfer->ux_dmabuf; 407 408 int err = usb_allocmem_flags(bus, size, 0, dmap, bus->ub_dmaflags); 409 if (err) { 410 return NULL; 411 } 412 xfer->ux_buf = KERNADDR(&xfer->ux_dmabuf, 0); 413 xfer->ux_bufsize = size; 414 415 return xfer->ux_buf; 416 } 417 #endif 418 KASSERT(xfer->ux_bus->ub_usedma == false); 419 xfer->ux_buf = kmem_alloc(size, KM_SLEEP); 420 xfer->ux_bufsize = size; 421 return xfer->ux_buf; 422 } 423 424 static void 425 usbd_free_buffer(struct usbd_xfer *xfer) 426 { 427 KASSERT(xfer->ux_buf != NULL); 428 KASSERT(xfer->ux_bufsize != 0); 429 430 void *buf = xfer->ux_buf; 431 uint32_t size = xfer->ux_bufsize; 432 433 xfer->ux_buf = NULL; 434 xfer->ux_bufsize = 0; 435 436 #if NUSB_DMA > 0 437 struct usbd_bus *bus = xfer->ux_bus; 438 439 if (bus->ub_usedma) { 440 usb_dma_t *dmap = &xfer->ux_dmabuf; 441 442 usb_freemem(bus, dmap); 443 return; 444 } 445 #endif 446 KASSERT(xfer->ux_bus->ub_usedma == false); 447 448 kmem_free(buf, size); 449 } 450 451 void * 452 usbd_get_buffer(struct usbd_xfer *xfer) 453 { 454 return xfer->ux_buf; 455 } 456 457 struct usbd_pipe * 458 usbd_get_pipe0(struct usbd_device *dev) 459 { 460 461 return dev->ud_pipe0; 462 } 463 464 static struct usbd_xfer * 465 usbd_alloc_xfer(struct usbd_device *dev, unsigned int nframes) 466 { 467 struct usbd_xfer *xfer; 468 469 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 470 471 ASSERT_SLEEPABLE(); 472 473 xfer = dev->ud_bus->ub_methods->ubm_allocx(dev->ud_bus, nframes); 474 if (xfer == NULL) 475 return NULL; 476 xfer->ux_bus = dev->ud_bus; 477 callout_init(&xfer->ux_callout, CALLOUT_MPSAFE); 478 cv_init(&xfer->ux_cv, "usbxfer"); 479 cv_init(&xfer->ux_hccv, "usbhcxfer"); 480 481 USBHIST_LOG(usbdebug, "returns %#jx", (uintptr_t)xfer, 0, 0, 0); 482 483 return xfer; 484 } 485 486 static usbd_status 487 usbd_free_xfer(struct usbd_xfer *xfer) 488 { 489 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 490 491 USBHIST_LOG(usbdebug, "%#jx", (uintptr_t)xfer, 0, 0, 0); 492 if (xfer->ux_buf) { 493 usbd_free_buffer(xfer); 494 } 495 #if defined(DIAGNOSTIC) 496 if (callout_pending(&xfer->ux_callout)) { 497 callout_stop(&xfer->ux_callout); 498 printf("usbd_free_xfer: timeout_handle pending\n"); 499 } 500 #endif 501 cv_destroy(&xfer->ux_cv); 502 cv_destroy(&xfer->ux_hccv); 503 xfer->ux_bus->ub_methods->ubm_freex(xfer->ux_bus, xfer); 504 return USBD_NORMAL_COMPLETION; 505 } 506 507 int 508 usbd_create_xfer(struct usbd_pipe *pipe, size_t len, unsigned int flags, 509 unsigned int nframes, struct usbd_xfer **xp) 510 { 511 KASSERT(xp != NULL); 512 void *buf = NULL; 513 514 struct usbd_xfer *xfer = usbd_alloc_xfer(pipe->up_dev, nframes); 515 if (xfer == NULL) 516 return ENOMEM; 517 518 if (len) { 519 buf = usbd_alloc_buffer(xfer, len); 520 if (!buf) { 521 usbd_free_xfer(xfer); 522 return ENOMEM; 523 } 524 } 525 xfer->ux_pipe = pipe; 526 xfer->ux_flags = flags; 527 xfer->ux_nframes = nframes; 528 xfer->ux_methods = pipe->up_methods; 529 530 if (xfer->ux_methods->upm_init) { 531 int err = xfer->ux_methods->upm_init(xfer); 532 if (err) { 533 if (buf) 534 usbd_free_buffer(xfer); 535 usbd_free_xfer(xfer); 536 return err; 537 } 538 } 539 540 *xp = xfer; 541 return 0; 542 } 543 544 void 545 usbd_destroy_xfer(struct usbd_xfer *xfer) 546 { 547 548 if (xfer->ux_methods->upm_fini) { 549 xfer->ux_methods->upm_fini(xfer); 550 } 551 552 usbd_free_xfer(xfer); 553 } 554 555 void 556 usbd_setup_xfer(struct usbd_xfer *xfer, void *priv, void *buffer, 557 uint32_t length, uint16_t flags, uint32_t timeout, usbd_callback callback) 558 { 559 KASSERT(xfer->ux_pipe); 560 561 xfer->ux_priv = priv; 562 xfer->ux_buffer = buffer; 563 xfer->ux_length = length; 564 xfer->ux_actlen = 0; 565 xfer->ux_flags = flags; 566 xfer->ux_timeout = timeout; 567 xfer->ux_status = USBD_NOT_STARTED; 568 xfer->ux_callback = callback; 569 xfer->ux_rqflags &= ~URQ_REQUEST; 570 xfer->ux_nframes = 0; 571 } 572 573 void 574 usbd_setup_default_xfer(struct usbd_xfer *xfer, struct usbd_device *dev, 575 void *priv, uint32_t timeout, usb_device_request_t *req, void *buffer, 576 uint32_t length, uint16_t flags, usbd_callback callback) 577 { 578 KASSERT(xfer->ux_pipe == dev->ud_pipe0); 579 580 xfer->ux_priv = priv; 581 xfer->ux_buffer = buffer; 582 xfer->ux_length = length; 583 xfer->ux_actlen = 0; 584 xfer->ux_flags = flags; 585 xfer->ux_timeout = timeout; 586 xfer->ux_status = USBD_NOT_STARTED; 587 xfer->ux_callback = callback; 588 xfer->ux_request = *req; 589 xfer->ux_rqflags |= URQ_REQUEST; 590 xfer->ux_nframes = 0; 591 } 592 593 void 594 usbd_setup_isoc_xfer(struct usbd_xfer *xfer, void *priv, uint16_t *frlengths, 595 uint32_t nframes, uint16_t flags, usbd_callback callback) 596 { 597 xfer->ux_priv = priv; 598 xfer->ux_buffer = NULL; 599 xfer->ux_length = 0; 600 xfer->ux_actlen = 0; 601 xfer->ux_flags = flags; 602 xfer->ux_timeout = USBD_NO_TIMEOUT; 603 xfer->ux_status = USBD_NOT_STARTED; 604 xfer->ux_callback = callback; 605 xfer->ux_rqflags &= ~URQ_REQUEST; 606 xfer->ux_frlengths = frlengths; 607 xfer->ux_nframes = nframes; 608 } 609 610 void 611 usbd_get_xfer_status(struct usbd_xfer *xfer, void **priv, 612 void **buffer, uint32_t *count, usbd_status *status) 613 { 614 if (priv != NULL) 615 *priv = xfer->ux_priv; 616 if (buffer != NULL) 617 *buffer = xfer->ux_buffer; 618 if (count != NULL) 619 *count = xfer->ux_actlen; 620 if (status != NULL) 621 *status = xfer->ux_status; 622 } 623 624 usb_config_descriptor_t * 625 usbd_get_config_descriptor(struct usbd_device *dev) 626 { 627 KASSERT(dev != NULL); 628 629 return dev->ud_cdesc; 630 } 631 632 usb_interface_descriptor_t * 633 usbd_get_interface_descriptor(struct usbd_interface *iface) 634 { 635 KASSERT(iface != NULL); 636 637 return iface->ui_idesc; 638 } 639 640 usb_device_descriptor_t * 641 usbd_get_device_descriptor(struct usbd_device *dev) 642 { 643 KASSERT(dev != NULL); 644 645 return &dev->ud_ddesc; 646 } 647 648 usb_endpoint_descriptor_t * 649 usbd_interface2endpoint_descriptor(struct usbd_interface *iface, uint8_t index) 650 { 651 652 if (index >= iface->ui_idesc->bNumEndpoints) 653 return NULL; 654 return iface->ui_endpoints[index].ue_edesc; 655 } 656 657 /* Some drivers may wish to abort requests on the default pipe, * 658 * but there is no mechanism for getting a handle on it. */ 659 usbd_status 660 usbd_abort_default_pipe(struct usbd_device *device) 661 { 662 return usbd_abort_pipe(device->ud_pipe0); 663 } 664 665 usbd_status 666 usbd_abort_pipe(struct usbd_pipe *pipe) 667 { 668 usbd_status err; 669 670 KASSERT(pipe != NULL); 671 672 usbd_lock_pipe(pipe); 673 err = usbd_ar_pipe(pipe); 674 usbd_unlock_pipe(pipe); 675 return err; 676 } 677 678 usbd_status 679 usbd_clear_endpoint_stall(struct usbd_pipe *pipe) 680 { 681 struct usbd_device *dev = pipe->up_dev; 682 usb_device_request_t req; 683 usbd_status err; 684 685 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 686 687 /* 688 * Clearing en endpoint stall resets the endpoint toggle, so 689 * do the same to the HC toggle. 690 */ 691 pipe->up_methods->upm_cleartoggle(pipe); 692 693 req.bmRequestType = UT_WRITE_ENDPOINT; 694 req.bRequest = UR_CLEAR_FEATURE; 695 USETW(req.wValue, UF_ENDPOINT_HALT); 696 USETW(req.wIndex, pipe->up_endpoint->ue_edesc->bEndpointAddress); 697 USETW(req.wLength, 0); 698 err = usbd_do_request(dev, &req, 0); 699 #if 0 700 XXX should we do this? 701 if (!err) { 702 pipe->state = USBD_PIPE_ACTIVE; 703 /* XXX activate pipe */ 704 } 705 #endif 706 return err; 707 } 708 709 void 710 usbd_clear_endpoint_stall_task(void *arg) 711 { 712 struct usbd_pipe *pipe = arg; 713 struct usbd_device *dev = pipe->up_dev; 714 usb_device_request_t req; 715 716 pipe->up_methods->upm_cleartoggle(pipe); 717 718 req.bmRequestType = UT_WRITE_ENDPOINT; 719 req.bRequest = UR_CLEAR_FEATURE; 720 USETW(req.wValue, UF_ENDPOINT_HALT); 721 USETW(req.wIndex, pipe->up_endpoint->ue_edesc->bEndpointAddress); 722 USETW(req.wLength, 0); 723 (void)usbd_do_request(dev, &req, 0); 724 } 725 726 void 727 usbd_clear_endpoint_stall_async(struct usbd_pipe *pipe) 728 { 729 usb_add_task(pipe->up_dev, &pipe->up_async_task, USB_TASKQ_DRIVER); 730 } 731 732 void 733 usbd_clear_endpoint_toggle(struct usbd_pipe *pipe) 734 { 735 736 pipe->up_methods->upm_cleartoggle(pipe); 737 } 738 739 usbd_status 740 usbd_endpoint_count(struct usbd_interface *iface, uint8_t *count) 741 { 742 KASSERT(iface != NULL); 743 KASSERT(iface->ui_idesc != NULL); 744 745 *count = iface->ui_idesc->bNumEndpoints; 746 return USBD_NORMAL_COMPLETION; 747 } 748 749 usbd_status 750 usbd_interface_count(struct usbd_device *dev, uint8_t *count) 751 { 752 753 if (dev->ud_cdesc == NULL) 754 return USBD_NOT_CONFIGURED; 755 *count = dev->ud_cdesc->bNumInterface; 756 return USBD_NORMAL_COMPLETION; 757 } 758 759 void 760 usbd_interface2device_handle(struct usbd_interface *iface, 761 struct usbd_device **dev) 762 { 763 764 *dev = iface->ui_dev; 765 } 766 767 usbd_status 768 usbd_device2interface_handle(struct usbd_device *dev, 769 uint8_t ifaceno, struct usbd_interface **iface) 770 { 771 772 if (dev->ud_cdesc == NULL) 773 return USBD_NOT_CONFIGURED; 774 if (ifaceno >= dev->ud_cdesc->bNumInterface) 775 return USBD_INVAL; 776 *iface = &dev->ud_ifaces[ifaceno]; 777 return USBD_NORMAL_COMPLETION; 778 } 779 780 struct usbd_device * 781 usbd_pipe2device_handle(struct usbd_pipe *pipe) 782 { 783 KASSERT(pipe != NULL); 784 785 return pipe->up_dev; 786 } 787 788 /* XXXX use altno */ 789 usbd_status 790 usbd_set_interface(struct usbd_interface *iface, int altidx) 791 { 792 usb_device_request_t req; 793 usbd_status err; 794 void *endpoints; 795 796 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 797 798 if (LIST_FIRST(&iface->ui_pipes) != NULL) 799 return USBD_IN_USE; 800 801 endpoints = iface->ui_endpoints; 802 int nendpt = iface->ui_idesc->bNumEndpoints; 803 USBHIST_LOG(usbdebug, "iface %#jx endpoints = %#jx nendpt %jd", 804 (uintptr_t)iface, (uintptr_t)endpoints, 805 iface->ui_idesc->bNumEndpoints, 0); 806 err = usbd_fill_iface_data(iface->ui_dev, iface->ui_index, altidx); 807 if (err) 808 return err; 809 810 /* new setting works, we can free old endpoints */ 811 if (endpoints != NULL) { 812 USBHIST_LOG(usbdebug, "iface %#jx endpoints = %#jx nendpt %jd", 813 (uintptr_t)iface, (uintptr_t)endpoints, nendpt, 0); 814 kmem_free(endpoints, nendpt * sizeof(struct usbd_endpoint)); 815 } 816 KASSERT(iface->ui_idesc != NULL); 817 818 req.bmRequestType = UT_WRITE_INTERFACE; 819 req.bRequest = UR_SET_INTERFACE; 820 USETW(req.wValue, iface->ui_idesc->bAlternateSetting); 821 USETW(req.wIndex, iface->ui_idesc->bInterfaceNumber); 822 USETW(req.wLength, 0); 823 return usbd_do_request(iface->ui_dev, &req, 0); 824 } 825 826 int 827 usbd_get_no_alts(usb_config_descriptor_t *cdesc, int ifaceno) 828 { 829 char *p = (char *)cdesc; 830 char *end = p + UGETW(cdesc->wTotalLength); 831 usb_interface_descriptor_t *d; 832 int n; 833 834 for (n = 0; p < end; p += d->bLength) { 835 d = (usb_interface_descriptor_t *)p; 836 if (p + d->bLength <= end && 837 d->bDescriptorType == UDESC_INTERFACE && 838 d->bInterfaceNumber == ifaceno) 839 n++; 840 } 841 return n; 842 } 843 844 int 845 usbd_get_interface_altindex(struct usbd_interface *iface) 846 { 847 return iface->ui_altindex; 848 } 849 850 usbd_status 851 usbd_get_interface(struct usbd_interface *iface, uint8_t *aiface) 852 { 853 usb_device_request_t req; 854 855 req.bmRequestType = UT_READ_INTERFACE; 856 req.bRequest = UR_GET_INTERFACE; 857 USETW(req.wValue, 0); 858 USETW(req.wIndex, iface->ui_idesc->bInterfaceNumber); 859 USETW(req.wLength, 1); 860 return usbd_do_request(iface->ui_dev, &req, aiface); 861 } 862 863 /*** Internal routines ***/ 864 865 /* Dequeue all pipe operations, called with bus lock held. */ 866 Static usbd_status 867 usbd_ar_pipe(struct usbd_pipe *pipe) 868 { 869 struct usbd_xfer *xfer; 870 871 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 872 873 KASSERT(mutex_owned(pipe->up_dev->ud_bus->ub_lock)); 874 875 USBHIST_LOG(usbdebug, "pipe = %#jx", (uintptr_t)pipe, 0, 0, 0); 876 #ifdef USB_DEBUG 877 if (usbdebug > 5) 878 usbd_dump_queue(pipe); 879 #endif 880 pipe->up_repeat = 0; 881 pipe->up_aborting = 1; 882 while ((xfer = SIMPLEQ_FIRST(&pipe->up_queue)) != NULL) { 883 USBHIST_LOG(usbdebug, "pipe = %#jx xfer = %#jx " 884 "(methods = %#jx)", (uintptr_t)pipe, (uintptr_t)xfer, 885 (uintptr_t)pipe->up_methods, 0); 886 /* Make the HC abort it (and invoke the callback). */ 887 pipe->up_methods->upm_abort(xfer); 888 /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */ 889 } 890 pipe->up_aborting = 0; 891 return USBD_NORMAL_COMPLETION; 892 } 893 894 /* Called with USB lock held. */ 895 void 896 usb_transfer_complete(struct usbd_xfer *xfer) 897 { 898 struct usbd_pipe *pipe = xfer->ux_pipe; 899 struct usbd_bus *bus = pipe->up_dev->ud_bus; 900 int sync = xfer->ux_flags & USBD_SYNCHRONOUS; 901 int erred = 902 xfer->ux_status == USBD_CANCELLED || 903 xfer->ux_status == USBD_TIMEOUT; 904 int polling = bus->ub_usepolling; 905 int repeat = pipe->up_repeat; 906 907 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 908 909 USBHIST_LOG(usbdebug, "pipe = %#jx xfer = %#jx status = %jd " 910 "actlen = %jd", (uintptr_t)pipe, (uintptr_t)xfer, xfer->ux_status, 911 xfer->ux_actlen); 912 913 KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock)); 914 KASSERT(xfer->ux_state == XFER_ONQU); 915 KASSERT(pipe != NULL); 916 917 if (!repeat) { 918 /* Remove request from queue. */ 919 920 KASSERTMSG(!SIMPLEQ_EMPTY(&pipe->up_queue), 921 "pipe %p is empty, but xfer %p wants to complete", pipe, 922 xfer); 923 KASSERTMSG(xfer == SIMPLEQ_FIRST(&pipe->up_queue), 924 "xfer %p is not start of queue (%p is at start)", xfer, 925 SIMPLEQ_FIRST(&pipe->up_queue)); 926 927 #ifdef DIAGNOSTIC 928 xfer->ux_state = XFER_BUSY; 929 #endif 930 SIMPLEQ_REMOVE_HEAD(&pipe->up_queue, ux_next); 931 } 932 USBHIST_LOG(usbdebug, "xfer %#jx: repeat %jd new head = %#jx", 933 (uintptr_t)xfer, repeat, (uintptr_t)SIMPLEQ_FIRST(&pipe->up_queue), 934 0); 935 936 /* Count completed transfers. */ 937 ++pipe->up_dev->ud_bus->ub_stats.uds_requests 938 [pipe->up_endpoint->ue_edesc->bmAttributes & UE_XFERTYPE]; 939 940 xfer->ux_done = 1; 941 if (!xfer->ux_status && xfer->ux_actlen < xfer->ux_length && 942 !(xfer->ux_flags & USBD_SHORT_XFER_OK)) { 943 USBHIST_LOG(usbdebug, "short transfer %jd < %jd", 944 xfer->ux_actlen, xfer->ux_length, 0, 0); 945 xfer->ux_status = USBD_SHORT_XFER; 946 } 947 948 USBHIST_LOG(usbdebug, "xfer %#jx doing done %#jx", (uintptr_t)xfer, 949 (uintptr_t)pipe->up_methods->upm_done, 0, 0); 950 pipe->up_methods->upm_done(xfer); 951 952 if (xfer->ux_length != 0 && xfer->ux_buffer != xfer->ux_buf) { 953 KDASSERTMSG(xfer->ux_actlen <= xfer->ux_length, 954 "actlen %d length %d",xfer->ux_actlen, xfer->ux_length); 955 956 /* Only if IN transfer */ 957 if (usbd_xfer_isread(xfer)) { 958 memcpy(xfer->ux_buffer, xfer->ux_buf, xfer->ux_actlen); 959 } 960 } 961 962 USBHIST_LOG(usbdebug, "xfer %#jx doing callback %#jx status %jd", 963 (uintptr_t)xfer, (uintptr_t)xfer->ux_callback, xfer->ux_status, 0); 964 965 if (xfer->ux_callback) { 966 if (!polling) 967 mutex_exit(pipe->up_dev->ud_bus->ub_lock); 968 969 if (!(pipe->up_flags & USBD_MPSAFE)) 970 KERNEL_LOCK(1, curlwp); 971 972 xfer->ux_callback(xfer, xfer->ux_priv, xfer->ux_status); 973 974 if (!(pipe->up_flags & USBD_MPSAFE)) 975 KERNEL_UNLOCK_ONE(curlwp); 976 977 if (!polling) 978 mutex_enter(pipe->up_dev->ud_bus->ub_lock); 979 } 980 981 if (sync && !polling) { 982 USBHIST_LOG(usbdebug, "<- done xfer %#jx, wakeup", 983 (uintptr_t)xfer, 0, 0, 0); 984 cv_broadcast(&xfer->ux_cv); 985 } 986 987 if (repeat) { 988 xfer->ux_actlen = 0; 989 xfer->ux_status = USBD_NOT_STARTED; 990 } else { 991 /* XXX should we stop the queue on all errors? */ 992 if (erred && pipe->up_iface != NULL) /* not control pipe */ 993 pipe->up_running = 0; 994 } 995 if (pipe->up_running && pipe->up_serialise) 996 usbd_start_next(pipe); 997 } 998 999 /* Called with USB lock held. */ 1000 usbd_status 1001 usb_insert_transfer(struct usbd_xfer *xfer) 1002 { 1003 struct usbd_pipe *pipe = xfer->ux_pipe; 1004 usbd_status err; 1005 1006 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 1007 1008 USBHIST_LOG(usbdebug, "xfer = %#jx pipe = %#jx running = %jd " 1009 "timeout = %jd", (uintptr_t)xfer, (uintptr_t)pipe, 1010 pipe->up_running, xfer->ux_timeout); 1011 1012 KASSERT(mutex_owned(pipe->up_dev->ud_bus->ub_lock)); 1013 KASSERTMSG(xfer->ux_state == XFER_BUSY, "xfer %p state is %x", xfer, 1014 xfer->ux_state); 1015 1016 #ifdef DIAGNOSTIC 1017 xfer->ux_state = XFER_ONQU; 1018 #endif 1019 SIMPLEQ_INSERT_TAIL(&pipe->up_queue, xfer, ux_next); 1020 if (pipe->up_running && pipe->up_serialise) 1021 err = USBD_IN_PROGRESS; 1022 else { 1023 pipe->up_running = 1; 1024 err = USBD_NORMAL_COMPLETION; 1025 } 1026 USBHIST_LOG(usbdebug, "<- done xfer %#jx, err %jd", (uintptr_t)xfer, 1027 err, 0, 0); 1028 return err; 1029 } 1030 1031 /* Called with USB lock held. */ 1032 void 1033 usbd_start_next(struct usbd_pipe *pipe) 1034 { 1035 struct usbd_xfer *xfer; 1036 usbd_status err; 1037 1038 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 1039 1040 KASSERT(pipe != NULL); 1041 KASSERT(pipe->up_methods != NULL); 1042 KASSERT(pipe->up_methods->upm_start != NULL); 1043 KASSERT(pipe->up_serialise == true); 1044 1045 int polling = pipe->up_dev->ud_bus->ub_usepolling; 1046 KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock)); 1047 1048 /* Get next request in queue. */ 1049 xfer = SIMPLEQ_FIRST(&pipe->up_queue); 1050 USBHIST_LOG(usbdebug, "pipe = %#jx, xfer = %#jx", (uintptr_t)pipe, 1051 (uintptr_t)xfer, 0, 0); 1052 if (xfer == NULL) { 1053 pipe->up_running = 0; 1054 } else { 1055 if (!polling) 1056 mutex_exit(pipe->up_dev->ud_bus->ub_lock); 1057 err = pipe->up_methods->upm_start(xfer); 1058 if (!polling) 1059 mutex_enter(pipe->up_dev->ud_bus->ub_lock); 1060 1061 if (err != USBD_IN_PROGRESS) { 1062 USBHIST_LOG(usbdebug, "error = %jd", err, 0, 0, 0); 1063 pipe->up_running = 0; 1064 /* XXX do what? */ 1065 } 1066 } 1067 1068 KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock)); 1069 } 1070 1071 usbd_status 1072 usbd_do_request(struct usbd_device *dev, usb_device_request_t *req, void *data) 1073 { 1074 1075 return usbd_do_request_flags(dev, req, data, 0, 0, 1076 USBD_DEFAULT_TIMEOUT); 1077 } 1078 1079 usbd_status 1080 usbd_do_request_flags(struct usbd_device *dev, usb_device_request_t *req, 1081 void *data, uint16_t flags, int *actlen, uint32_t timeout) 1082 { 1083 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 1084 struct usbd_xfer *xfer; 1085 usbd_status err; 1086 1087 ASSERT_SLEEPABLE(); 1088 1089 size_t len = UGETW(req->wLength); 1090 int error = usbd_create_xfer(dev->ud_pipe0, len, 0, 0, &xfer); 1091 if (error) 1092 return error; 1093 1094 usbd_setup_default_xfer(xfer, dev, 0, timeout, req, data, 1095 UGETW(req->wLength), flags, NULL); 1096 KASSERT(xfer->ux_pipe == dev->ud_pipe0); 1097 err = usbd_sync_transfer(xfer); 1098 #if defined(USB_DEBUG) || defined(DIAGNOSTIC) 1099 if (xfer->ux_actlen > xfer->ux_length) { 1100 USBHIST_LOG(usbdebug, "overrun addr = %jd type = 0x%02jx", 1101 dev->ud_addr, xfer->ux_request.bmRequestType, 0, 0); 1102 USBHIST_LOG(usbdebug, " req = 0x%02jx val = %jd " 1103 "index = %jd", 1104 xfer->ux_request.bRequest, UGETW(xfer->ux_request.wValue), 1105 UGETW(xfer->ux_request.wIndex), 0); 1106 USBHIST_LOG(usbdebug, " rlen = %jd length = %jd " 1107 "actlen = %jd", 1108 UGETW(xfer->ux_request.wLength), 1109 xfer->ux_length, xfer->ux_actlen, 0); 1110 } 1111 #endif 1112 if (actlen != NULL) 1113 *actlen = xfer->ux_actlen; 1114 1115 usbd_destroy_xfer(xfer); 1116 1117 if (err) { 1118 USBHIST_LOG(usbdebug, "returning err = %jd", err, 0, 0, 0); 1119 } 1120 return err; 1121 } 1122 1123 const struct usbd_quirks * 1124 usbd_get_quirks(struct usbd_device *dev) 1125 { 1126 #ifdef DIAGNOSTIC 1127 if (dev == NULL) { 1128 printf("usbd_get_quirks: dev == NULL\n"); 1129 return 0; 1130 } 1131 #endif 1132 return dev->ud_quirks; 1133 } 1134 1135 /* XXX do periodic free() of free list */ 1136 1137 /* 1138 * Called from keyboard driver when in polling mode. 1139 */ 1140 void 1141 usbd_dopoll(struct usbd_interface *iface) 1142 { 1143 iface->ui_dev->ud_bus->ub_methods->ubm_dopoll(iface->ui_dev->ud_bus); 1144 } 1145 1146 /* 1147 * XXX use this more??? ub_usepolling it touched manually all over 1148 */ 1149 void 1150 usbd_set_polling(struct usbd_device *dev, int on) 1151 { 1152 if (on) 1153 dev->ud_bus->ub_usepolling++; 1154 else 1155 dev->ud_bus->ub_usepolling--; 1156 1157 /* Kick the host controller when switching modes */ 1158 mutex_enter(dev->ud_bus->ub_lock); 1159 dev->ud_bus->ub_methods->ubm_softint(dev->ud_bus); 1160 mutex_exit(dev->ud_bus->ub_lock); 1161 } 1162 1163 1164 usb_endpoint_descriptor_t * 1165 usbd_get_endpoint_descriptor(struct usbd_interface *iface, uint8_t address) 1166 { 1167 struct usbd_endpoint *ep; 1168 int i; 1169 1170 for (i = 0; i < iface->ui_idesc->bNumEndpoints; i++) { 1171 ep = &iface->ui_endpoints[i]; 1172 if (ep->ue_edesc->bEndpointAddress == address) 1173 return iface->ui_endpoints[i].ue_edesc; 1174 } 1175 return NULL; 1176 } 1177 1178 /* 1179 * usbd_ratecheck() can limit the number of error messages that occurs. 1180 * When a device is unplugged it may take up to 0.25s for the hub driver 1181 * to notice it. If the driver continuously tries to do I/O operations 1182 * this can generate a large number of messages. 1183 */ 1184 int 1185 usbd_ratecheck(struct timeval *last) 1186 { 1187 static struct timeval errinterval = { 0, 250000 }; /* 0.25 s*/ 1188 1189 return ratecheck(last, &errinterval); 1190 } 1191 1192 /* 1193 * Search for a vendor/product pair in an array. The item size is 1194 * given as an argument. 1195 */ 1196 const struct usb_devno * 1197 usb_match_device(const struct usb_devno *tbl, u_int nentries, u_int sz, 1198 uint16_t vendor, uint16_t product) 1199 { 1200 while (nentries-- > 0) { 1201 uint16_t tproduct = tbl->ud_product; 1202 if (tbl->ud_vendor == vendor && 1203 (tproduct == product || tproduct == USB_PRODUCT_ANY)) 1204 return tbl; 1205 tbl = (const struct usb_devno *)((const char *)tbl + sz); 1206 } 1207 return NULL; 1208 } 1209 1210 1211 void 1212 usb_desc_iter_init(struct usbd_device *dev, usbd_desc_iter_t *iter) 1213 { 1214 const usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev); 1215 1216 iter->cur = (const uByte *)cd; 1217 iter->end = (const uByte *)cd + UGETW(cd->wTotalLength); 1218 } 1219 1220 const usb_descriptor_t * 1221 usb_desc_iter_next(usbd_desc_iter_t *iter) 1222 { 1223 const usb_descriptor_t *desc; 1224 1225 if (iter->cur + sizeof(usb_descriptor_t) >= iter->end) { 1226 if (iter->cur != iter->end) 1227 printf("usb_desc_iter_next: bad descriptor\n"); 1228 return NULL; 1229 } 1230 desc = (const usb_descriptor_t *)iter->cur; 1231 if (desc->bLength == 0) { 1232 printf("usb_desc_iter_next: descriptor length = 0\n"); 1233 return NULL; 1234 } 1235 iter->cur += desc->bLength; 1236 if (iter->cur > iter->end) { 1237 printf("usb_desc_iter_next: descriptor length too large\n"); 1238 return NULL; 1239 } 1240 return desc; 1241 } 1242 1243 usbd_status 1244 usbd_get_string(struct usbd_device *dev, int si, char *buf) 1245 { 1246 return usbd_get_string0(dev, si, buf, 1); 1247 } 1248 1249 usbd_status 1250 usbd_get_string0(struct usbd_device *dev, int si, char *buf, int unicode) 1251 { 1252 int swap = dev->ud_quirks->uq_flags & UQ_SWAP_UNICODE; 1253 usb_string_descriptor_t us; 1254 char *s; 1255 int i, n; 1256 uint16_t c; 1257 usbd_status err; 1258 int size; 1259 1260 USBHIST_FUNC(); USBHIST_CALLED(usbdebug); 1261 1262 buf[0] = '\0'; 1263 if (si == 0) 1264 return USBD_INVAL; 1265 if (dev->ud_quirks->uq_flags & UQ_NO_STRINGS) 1266 return USBD_STALLED; 1267 if (dev->ud_langid == USBD_NOLANG) { 1268 /* Set up default language */ 1269 err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us, 1270 &size); 1271 if (err || size < 4) { 1272 USBHIST_LOG(usbdebug, "getting lang failed, using 0", 1273 0, 0, 0, 0); 1274 dev->ud_langid = 0; /* Well, just pick something then */ 1275 } else { 1276 /* Pick the first language as the default. */ 1277 dev->ud_langid = UGETW(us.bString[0]); 1278 } 1279 } 1280 err = usbd_get_string_desc(dev, si, dev->ud_langid, &us, &size); 1281 if (err) 1282 return err; 1283 s = buf; 1284 n = size / 2 - 1; 1285 if (unicode) { 1286 for (i = 0; i < n; i++) { 1287 c = UGETW(us.bString[i]); 1288 if (swap) 1289 c = (c >> 8) | (c << 8); 1290 s += wput_utf8(s, 3, c); 1291 } 1292 *s++ = 0; 1293 } 1294 #ifdef COMPAT_30 1295 else { 1296 for (i = 0; i < n; i++) { 1297 c = UGETW(us.bString[i]); 1298 if (swap) 1299 c = (c >> 8) | (c << 8); 1300 *s++ = (c < 0x80) ? c : '?'; 1301 } 1302 *s++ = 0; 1303 } 1304 #endif 1305 return USBD_NORMAL_COMPLETION; 1306 } 1307