usb_request.c revision 208008
1/* $FreeBSD: head/sys/dev/usb/usb_request.c 208008 2010-05-12 22:42:35Z thompsa $ */ 2/*- 3 * Copyright (c) 1998 The NetBSD Foundation, Inc. All rights reserved. 4 * Copyright (c) 1998 Lennart Augustsson. All rights reserved. 5 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/stdint.h> 30#include <sys/stddef.h> 31#include <sys/param.h> 32#include <sys/queue.h> 33#include <sys/types.h> 34#include <sys/systm.h> 35#include <sys/kernel.h> 36#include <sys/bus.h> 37#include <sys/linker_set.h> 38#include <sys/module.h> 39#include <sys/lock.h> 40#include <sys/mutex.h> 41#include <sys/condvar.h> 42#include <sys/sysctl.h> 43#include <sys/sx.h> 44#include <sys/unistd.h> 45#include <sys/callout.h> 46#include <sys/malloc.h> 47#include <sys/priv.h> 48 49#include <dev/usb/usb.h> 50#include <dev/usb/usbdi.h> 51#include <dev/usb/usbdi_util.h> 52#include <dev/usb/usb_ioctl.h> 53#include <dev/usb/usbhid.h> 54 55#define USB_DEBUG_VAR usb_debug 56 57#include <dev/usb/usb_core.h> 58#include <dev/usb/usb_busdma.h> 59#include <dev/usb/usb_request.h> 60#include <dev/usb/usb_process.h> 61#include <dev/usb/usb_transfer.h> 62#include <dev/usb/usb_debug.h> 63#include <dev/usb/usb_device.h> 64#include <dev/usb/usb_util.h> 65#include <dev/usb/usb_dynamic.h> 66 67#include <dev/usb/usb_controller.h> 68#include <dev/usb/usb_bus.h> 69#include <sys/ctype.h> 70 71#ifdef USB_DEBUG 72static int usb_pr_poll_delay = USB_PORT_RESET_DELAY; 73static int usb_pr_recovery_delay = USB_PORT_RESET_RECOVERY; 74static int usb_ss_delay = 0; 75 76SYSCTL_INT(_hw_usb, OID_AUTO, pr_poll_delay, CTLFLAG_RW, 77 &usb_pr_poll_delay, 0, "USB port reset poll delay in ms"); 78SYSCTL_INT(_hw_usb, OID_AUTO, pr_recovery_delay, CTLFLAG_RW, 79 &usb_pr_recovery_delay, 0, "USB port reset recovery delay in ms"); 80SYSCTL_INT(_hw_usb, OID_AUTO, ss_delay, CTLFLAG_RW, 81 &usb_ss_delay, 0, "USB status stage delay in ms"); 82#endif 83 84/*------------------------------------------------------------------------* 85 * usbd_do_request_callback 86 * 87 * This function is the USB callback for generic USB Host control 88 * transfers. 89 *------------------------------------------------------------------------*/ 90void 91usbd_do_request_callback(struct usb_xfer *xfer, usb_error_t error) 92{ 93 ; /* workaround for a bug in "indent" */ 94 95 DPRINTF("st=%u\n", USB_GET_STATE(xfer)); 96 97 switch (USB_GET_STATE(xfer)) { 98 case USB_ST_SETUP: 99 usbd_transfer_submit(xfer); 100 break; 101 default: 102 cv_signal(&xfer->xroot->udev->ctrlreq_cv); 103 break; 104 } 105} 106 107/*------------------------------------------------------------------------* 108 * usb_do_clear_stall_callback 109 * 110 * This function is the USB callback for generic clear stall requests. 111 *------------------------------------------------------------------------*/ 112void 113usb_do_clear_stall_callback(struct usb_xfer *xfer, usb_error_t error) 114{ 115 struct usb_device_request req; 116 struct usb_device *udev; 117 struct usb_endpoint *ep; 118 struct usb_endpoint *ep_end; 119 struct usb_endpoint *ep_first; 120 uint8_t to; 121 122 udev = xfer->xroot->udev; 123 124 USB_BUS_LOCK(udev->bus); 125 126 /* round robin endpoint clear stall */ 127 128 ep = udev->ep_curr; 129 ep_end = udev->endpoints + udev->endpoints_max; 130 ep_first = udev->endpoints; 131 to = udev->endpoints_max; 132 133 switch (USB_GET_STATE(xfer)) { 134 case USB_ST_TRANSFERRED: 135 if (ep == NULL) 136 goto tr_setup; /* device was unconfigured */ 137 if (ep->edesc && 138 ep->is_stalled) { 139 ep->toggle_next = 0; 140 ep->is_stalled = 0; 141 /* start up the current or next transfer, if any */ 142 usb_command_wrapper(&ep->endpoint_q, 143 ep->endpoint_q.curr); 144 } 145 ep++; 146 147 case USB_ST_SETUP: 148tr_setup: 149 if (to == 0) 150 break; /* no endpoints - nothing to do */ 151 if ((ep < ep_first) || (ep >= ep_end)) 152 ep = ep_first; /* endpoint wrapped around */ 153 if (ep->edesc && 154 ep->is_stalled) { 155 156 /* setup a clear-stall packet */ 157 158 req.bmRequestType = UT_WRITE_ENDPOINT; 159 req.bRequest = UR_CLEAR_FEATURE; 160 USETW(req.wValue, UF_ENDPOINT_HALT); 161 req.wIndex[0] = ep->edesc->bEndpointAddress; 162 req.wIndex[1] = 0; 163 USETW(req.wLength, 0); 164 165 /* copy in the transfer */ 166 167 usbd_copy_in(xfer->frbuffers, 0, &req, sizeof(req)); 168 169 /* set length */ 170 usbd_xfer_set_frame_len(xfer, 0, sizeof(req)); 171 xfer->nframes = 1; 172 USB_BUS_UNLOCK(udev->bus); 173 174 usbd_transfer_submit(xfer); 175 176 USB_BUS_LOCK(udev->bus); 177 break; 178 } 179 ep++; 180 to--; 181 goto tr_setup; 182 183 default: 184 if (xfer->error == USB_ERR_CANCELLED) { 185 break; 186 } 187 goto tr_setup; 188 } 189 190 /* store current endpoint */ 191 udev->ep_curr = ep; 192 USB_BUS_UNLOCK(udev->bus); 193} 194 195static usb_handle_req_t * 196usbd_get_hr_func(struct usb_device *udev) 197{ 198 /* figure out if there is a Handle Request function */ 199 if (udev->flags.usb_mode == USB_MODE_DEVICE) 200 return (usb_temp_get_desc_p); 201 else if (udev->parent_hub == NULL) 202 return (udev->bus->methods->roothub_exec); 203 else 204 return (NULL); 205} 206 207/*------------------------------------------------------------------------* 208 * usbd_do_request_flags and usbd_do_request 209 * 210 * Description of arguments passed to these functions: 211 * 212 * "udev" - this is the "usb_device" structure pointer on which the 213 * request should be performed. It is possible to call this function 214 * in both Host Side mode and Device Side mode. 215 * 216 * "mtx" - if this argument is non-NULL the mutex pointed to by it 217 * will get dropped and picked up during the execution of this 218 * function, hence this function sometimes needs to sleep. If this 219 * argument is NULL it has no effect. 220 * 221 * "req" - this argument must always be non-NULL and points to an 222 * 8-byte structure holding the USB request to be done. The USB 223 * request structure has a bit telling the direction of the USB 224 * request, if it is a read or a write. 225 * 226 * "data" - if the "wLength" part of the structure pointed to by "req" 227 * is non-zero this argument must point to a valid kernel buffer which 228 * can hold at least "wLength" bytes. If "wLength" is zero "data" can 229 * be NULL. 230 * 231 * "flags" - here is a list of valid flags: 232 * 233 * o USB_SHORT_XFER_OK: allows the data transfer to be shorter than 234 * specified 235 * 236 * o USB_DELAY_STATUS_STAGE: allows the status stage to be performed 237 * at a later point in time. This is tunable by the "hw.usb.ss_delay" 238 * sysctl. This flag is mostly useful for debugging. 239 * 240 * o USB_USER_DATA_PTR: treat the "data" pointer like a userland 241 * pointer. 242 * 243 * "actlen" - if non-NULL the actual transfer length will be stored in 244 * the 16-bit unsigned integer pointed to by "actlen". This 245 * information is mostly useful when the "USB_SHORT_XFER_OK" flag is 246 * used. 247 * 248 * "timeout" - gives the timeout for the control transfer in 249 * milliseconds. A "timeout" value less than 50 milliseconds is 250 * treated like a 50 millisecond timeout. A "timeout" value greater 251 * than 30 seconds is treated like a 30 second timeout. This USB stack 252 * does not allow control requests without a timeout. 253 * 254 * NOTE: This function is thread safe. All calls to 255 * "usbd_do_request_flags" will be serialised by the use of an 256 * internal "sx_lock". 257 * 258 * Returns: 259 * 0: Success 260 * Else: Failure 261 *------------------------------------------------------------------------*/ 262usb_error_t 263usbd_do_request_flags(struct usb_device *udev, struct mtx *mtx, 264 struct usb_device_request *req, void *data, uint16_t flags, 265 uint16_t *actlen, usb_timeout_t timeout) 266{ 267 usb_handle_req_t *hr_func; 268 struct usb_xfer *xfer; 269 const void *desc; 270 int err = 0; 271 usb_ticks_t start_ticks; 272 usb_ticks_t delta_ticks; 273 usb_ticks_t max_ticks; 274 uint16_t length; 275 uint16_t temp; 276 uint8_t enum_locked; 277 278 if (timeout < 50) { 279 /* timeout is too small */ 280 timeout = 50; 281 } 282 if (timeout > 30000) { 283 /* timeout is too big */ 284 timeout = 30000; 285 } 286 length = UGETW(req->wLength); 287 288 enum_locked = usbd_enum_is_locked(udev); 289 290 DPRINTFN(5, "udev=%p bmRequestType=0x%02x bRequest=0x%02x " 291 "wValue=0x%02x%02x wIndex=0x%02x%02x wLength=0x%02x%02x\n", 292 udev, req->bmRequestType, req->bRequest, 293 req->wValue[1], req->wValue[0], 294 req->wIndex[1], req->wIndex[0], 295 req->wLength[1], req->wLength[0]); 296 297 /* Check if the device is still alive */ 298 if (udev->state < USB_STATE_POWERED) { 299 DPRINTF("usb device has gone\n"); 300 return (USB_ERR_NOT_CONFIGURED); 301 } 302 303 /* 304 * Set "actlen" to a known value in case the caller does not 305 * check the return value: 306 */ 307 if (actlen) 308 *actlen = 0; 309 310#if (USB_HAVE_USER_IO == 0) 311 if (flags & USB_USER_DATA_PTR) 312 return (USB_ERR_INVAL); 313#endif 314 if ((mtx != NULL) && (mtx != &Giant)) { 315 mtx_unlock(mtx); 316 mtx_assert(mtx, MA_NOTOWNED); 317 } 318 319 /* 320 * We need to allow suspend and resume at this point, else the 321 * control transfer will timeout if the device is suspended! 322 */ 323 if (enum_locked) 324 usbd_sr_unlock(udev); 325 326 /* 327 * Grab the default sx-lock so that serialisation 328 * is achieved when multiple threads are involved: 329 */ 330 331 sx_xlock(&udev->ctrl_sx); 332 333 hr_func = usbd_get_hr_func(udev); 334 335 if (hr_func != NULL) { 336 DPRINTF("Handle Request function is set\n"); 337 338 desc = NULL; 339 temp = 0; 340 341 if (!(req->bmRequestType & UT_READ)) { 342 if (length != 0) { 343 DPRINTFN(1, "The handle request function " 344 "does not support writing data!\n"); 345 err = USB_ERR_INVAL; 346 goto done; 347 } 348 } 349 350 /* The root HUB code needs the BUS lock locked */ 351 352 USB_BUS_LOCK(udev->bus); 353 err = (hr_func) (udev, req, &desc, &temp); 354 USB_BUS_UNLOCK(udev->bus); 355 356 if (err) 357 goto done; 358 359 if (length > temp) { 360 if (!(flags & USB_SHORT_XFER_OK)) { 361 err = USB_ERR_SHORT_XFER; 362 goto done; 363 } 364 length = temp; 365 } 366 if (actlen) 367 *actlen = length; 368 369 if (length > 0) { 370#if USB_HAVE_USER_IO 371 if (flags & USB_USER_DATA_PTR) { 372 if (copyout(desc, data, length)) { 373 err = USB_ERR_INVAL; 374 goto done; 375 } 376 } else 377#endif 378 bcopy(desc, data, length); 379 } 380 goto done; /* success */ 381 } 382 383 /* 384 * Setup a new USB transfer or use the existing one, if any: 385 */ 386 usbd_ctrl_transfer_setup(udev); 387 388 xfer = udev->ctrl_xfer[0]; 389 if (xfer == NULL) { 390 /* most likely out of memory */ 391 err = USB_ERR_NOMEM; 392 goto done; 393 } 394 USB_XFER_LOCK(xfer); 395 396 if (flags & USB_DELAY_STATUS_STAGE) 397 xfer->flags.manual_status = 1; 398 else 399 xfer->flags.manual_status = 0; 400 401 if (flags & USB_SHORT_XFER_OK) 402 xfer->flags.short_xfer_ok = 1; 403 else 404 xfer->flags.short_xfer_ok = 0; 405 406 xfer->timeout = timeout; 407 408 start_ticks = ticks; 409 410 max_ticks = USB_MS_TO_TICKS(timeout); 411 412 usbd_copy_in(xfer->frbuffers, 0, req, sizeof(*req)); 413 414 usbd_xfer_set_frame_len(xfer, 0, sizeof(*req)); 415 xfer->nframes = 2; 416 417 while (1) { 418 temp = length; 419 if (temp > xfer->max_data_length) { 420 temp = usbd_xfer_max_len(xfer); 421 } 422 usbd_xfer_set_frame_len(xfer, 1, temp); 423 424 if (temp > 0) { 425 if (!(req->bmRequestType & UT_READ)) { 426#if USB_HAVE_USER_IO 427 if (flags & USB_USER_DATA_PTR) { 428 USB_XFER_UNLOCK(xfer); 429 err = usbd_copy_in_user(xfer->frbuffers + 1, 430 0, data, temp); 431 USB_XFER_LOCK(xfer); 432 if (err) { 433 err = USB_ERR_INVAL; 434 break; 435 } 436 } else 437#endif 438 usbd_copy_in(xfer->frbuffers + 1, 439 0, data, temp); 440 } 441 xfer->nframes = 2; 442 } else { 443 if (xfer->frlengths[0] == 0) { 444 if (xfer->flags.manual_status) { 445#ifdef USB_DEBUG 446 int temp; 447 448 temp = usb_ss_delay; 449 if (temp > 5000) { 450 temp = 5000; 451 } 452 if (temp > 0) { 453 usb_pause_mtx( 454 xfer->xroot->xfer_mtx, 455 USB_MS_TO_TICKS(temp)); 456 } 457#endif 458 xfer->flags.manual_status = 0; 459 } else { 460 break; 461 } 462 } 463 xfer->nframes = 1; 464 } 465 466 usbd_transfer_start(xfer); 467 468 while (usbd_transfer_pending(xfer)) { 469 cv_wait(&udev->ctrlreq_cv, 470 xfer->xroot->xfer_mtx); 471 } 472 473 err = xfer->error; 474 475 if (err) { 476 break; 477 } 478 /* subtract length of SETUP packet, if any */ 479 480 if (xfer->aframes > 0) { 481 xfer->actlen -= xfer->frlengths[0]; 482 } else { 483 xfer->actlen = 0; 484 } 485 486 /* check for short packet */ 487 488 if (temp > xfer->actlen) { 489 temp = xfer->actlen; 490 length = temp; 491 } 492 if (temp > 0) { 493 if (req->bmRequestType & UT_READ) { 494#if USB_HAVE_USER_IO 495 if (flags & USB_USER_DATA_PTR) { 496 USB_XFER_UNLOCK(xfer); 497 err = usbd_copy_out_user(xfer->frbuffers + 1, 498 0, data, temp); 499 USB_XFER_LOCK(xfer); 500 if (err) { 501 err = USB_ERR_INVAL; 502 break; 503 } 504 } else 505#endif 506 usbd_copy_out(xfer->frbuffers + 1, 507 0, data, temp); 508 } 509 } 510 /* 511 * Clear "frlengths[0]" so that we don't send the setup 512 * packet again: 513 */ 514 usbd_xfer_set_frame_len(xfer, 0, 0); 515 516 /* update length and data pointer */ 517 length -= temp; 518 data = USB_ADD_BYTES(data, temp); 519 520 if (actlen) { 521 (*actlen) += temp; 522 } 523 /* check for timeout */ 524 525 delta_ticks = ticks - start_ticks; 526 if (delta_ticks > max_ticks) { 527 if (!err) { 528 err = USB_ERR_TIMEOUT; 529 } 530 } 531 if (err) { 532 break; 533 } 534 } 535 536 if (err) { 537 /* 538 * Make sure that the control endpoint is no longer 539 * blocked in case of a non-transfer related error: 540 */ 541 usbd_transfer_stop(xfer); 542 } 543 USB_XFER_UNLOCK(xfer); 544 545done: 546 sx_xunlock(&udev->ctrl_sx); 547 548 if (enum_locked) 549 usbd_sr_lock(udev); 550 551 if ((mtx != NULL) && (mtx != &Giant)) 552 mtx_lock(mtx); 553 554 return ((usb_error_t)err); 555} 556 557/*------------------------------------------------------------------------* 558 * usbd_do_request_proc - factored out code 559 * 560 * This function is factored out code. It does basically the same like 561 * usbd_do_request_flags, except it will check the status of the 562 * passed process argument before doing the USB request. If the 563 * process is draining the USB_ERR_IOERROR code will be returned. It 564 * is assumed that the mutex associated with the process is locked 565 * when calling this function. 566 *------------------------------------------------------------------------*/ 567usb_error_t 568usbd_do_request_proc(struct usb_device *udev, struct usb_process *pproc, 569 struct usb_device_request *req, void *data, uint16_t flags, 570 uint16_t *actlen, usb_timeout_t timeout) 571{ 572 usb_error_t err; 573 uint16_t len; 574 575 /* get request data length */ 576 len = UGETW(req->wLength); 577 578 /* check if the device is being detached */ 579 if (usb_proc_is_gone(pproc)) { 580 err = USB_ERR_IOERROR; 581 goto done; 582 } 583 584 /* forward the USB request */ 585 err = usbd_do_request_flags(udev, pproc->up_mtx, 586 req, data, flags, actlen, timeout); 587 588done: 589 /* on failure we zero the data */ 590 /* on short packet we zero the unused data */ 591 if ((len != 0) && (req->bmRequestType & UE_DIR_IN)) { 592 if (err) 593 memset(data, 0, len); 594 else if (actlen && *actlen != len) 595 memset(((uint8_t *)data) + *actlen, 0, len - *actlen); 596 } 597 return (err); 598} 599 600/*------------------------------------------------------------------------* 601 * usbd_req_reset_port 602 * 603 * This function will instruct an USB HUB to perform a reset sequence 604 * on the specified port number. 605 * 606 * Returns: 607 * 0: Success. The USB device should now be at address zero. 608 * Else: Failure. No USB device is present and the USB port should be 609 * disabled. 610 *------------------------------------------------------------------------*/ 611usb_error_t 612usbd_req_reset_port(struct usb_device *udev, struct mtx *mtx, uint8_t port) 613{ 614 struct usb_port_status ps; 615 usb_error_t err; 616 uint16_t n; 617 618#ifdef USB_DEBUG 619 uint16_t pr_poll_delay; 620 uint16_t pr_recovery_delay; 621 622#endif 623 err = usbd_req_set_port_feature(udev, mtx, port, UHF_PORT_RESET); 624 if (err) { 625 goto done; 626 } 627#ifdef USB_DEBUG 628 /* range check input parameters */ 629 pr_poll_delay = usb_pr_poll_delay; 630 if (pr_poll_delay < 1) { 631 pr_poll_delay = 1; 632 } else if (pr_poll_delay > 1000) { 633 pr_poll_delay = 1000; 634 } 635 pr_recovery_delay = usb_pr_recovery_delay; 636 if (pr_recovery_delay > 1000) { 637 pr_recovery_delay = 1000; 638 } 639#endif 640 n = 0; 641 while (1) { 642#ifdef USB_DEBUG 643 /* wait for the device to recover from reset */ 644 usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_poll_delay)); 645 n += pr_poll_delay; 646#else 647 /* wait for the device to recover from reset */ 648 usb_pause_mtx(mtx, USB_MS_TO_TICKS(USB_PORT_RESET_DELAY)); 649 n += USB_PORT_RESET_DELAY; 650#endif 651 err = usbd_req_get_port_status(udev, mtx, &ps, port); 652 if (err) { 653 goto done; 654 } 655 /* if the device disappeared, just give up */ 656 if (!(UGETW(ps.wPortStatus) & UPS_CURRENT_CONNECT_STATUS)) { 657 goto done; 658 } 659 /* check if reset is complete */ 660 if (UGETW(ps.wPortChange) & UPS_C_PORT_RESET) { 661 break; 662 } 663 /* check for timeout */ 664 if (n > 1000) { 665 n = 0; 666 break; 667 } 668 } 669 670 /* clear port reset first */ 671 err = usbd_req_clear_port_feature( 672 udev, mtx, port, UHF_C_PORT_RESET); 673 if (err) { 674 goto done; 675 } 676 /* check for timeout */ 677 if (n == 0) { 678 err = USB_ERR_TIMEOUT; 679 goto done; 680 } 681#ifdef USB_DEBUG 682 /* wait for the device to recover from reset */ 683 usb_pause_mtx(mtx, USB_MS_TO_TICKS(pr_recovery_delay)); 684#else 685 /* wait for the device to recover from reset */ 686 usb_pause_mtx(mtx, USB_MS_TO_TICKS(USB_PORT_RESET_RECOVERY)); 687#endif 688 689done: 690 DPRINTFN(2, "port %d reset returning error=%s\n", 691 port, usbd_errstr(err)); 692 return (err); 693} 694 695/*------------------------------------------------------------------------* 696 * usbd_req_get_desc 697 * 698 * This function can be used to retrieve USB descriptors. It contains 699 * some additional logic like zeroing of missing descriptor bytes and 700 * retrying an USB descriptor in case of failure. The "min_len" 701 * argument specifies the minimum descriptor length. The "max_len" 702 * argument specifies the maximum descriptor length. If the real 703 * descriptor length is less than the minimum length the missing 704 * byte(s) will be zeroed. The type field, the second byte of the USB 705 * descriptor, will get forced to the correct type. If the "actlen" 706 * pointer is non-NULL, the actual length of the transfer will get 707 * stored in the 16-bit unsigned integer which it is pointing to. The 708 * first byte of the descriptor will not get updated. If the "actlen" 709 * pointer is NULL the first byte of the descriptor will get updated 710 * to reflect the actual length instead. If "min_len" is not equal to 711 * "max_len" then this function will try to retrive the beginning of 712 * the descriptor and base the maximum length on the first byte of the 713 * descriptor. 714 * 715 * Returns: 716 * 0: Success 717 * Else: Failure 718 *------------------------------------------------------------------------*/ 719usb_error_t 720usbd_req_get_desc(struct usb_device *udev, 721 struct mtx *mtx, uint16_t *actlen, void *desc, 722 uint16_t min_len, uint16_t max_len, 723 uint16_t id, uint8_t type, uint8_t index, 724 uint8_t retries) 725{ 726 struct usb_device_request req; 727 uint8_t *buf; 728 usb_error_t err; 729 730 DPRINTFN(4, "id=%d, type=%d, index=%d, max_len=%d\n", 731 id, type, index, max_len); 732 733 req.bmRequestType = UT_READ_DEVICE; 734 req.bRequest = UR_GET_DESCRIPTOR; 735 USETW2(req.wValue, type, index); 736 USETW(req.wIndex, id); 737 738 while (1) { 739 740 if ((min_len < 2) || (max_len < 2)) { 741 err = USB_ERR_INVAL; 742 goto done; 743 } 744 USETW(req.wLength, min_len); 745 746 err = usbd_do_request_flags(udev, mtx, &req, 747 desc, 0, NULL, 1000); 748 749 if (err) { 750 if (!retries) { 751 goto done; 752 } 753 retries--; 754 755 usb_pause_mtx(mtx, hz / 5); 756 757 continue; 758 } 759 buf = desc; 760 761 if (min_len == max_len) { 762 763 /* enforce correct length */ 764 if ((buf[0] > min_len) && (actlen == NULL)) 765 buf[0] = min_len; 766 767 /* enforce correct type */ 768 buf[1] = type; 769 770 goto done; 771 } 772 /* range check */ 773 774 if (max_len > buf[0]) { 775 max_len = buf[0]; 776 } 777 /* zero minimum data */ 778 779 while (min_len > max_len) { 780 min_len--; 781 buf[min_len] = 0; 782 } 783 784 /* set new minimum length */ 785 786 min_len = max_len; 787 } 788done: 789 if (actlen != NULL) { 790 if (err) 791 *actlen = 0; 792 else 793 *actlen = min_len; 794 } 795 return (err); 796} 797 798/*------------------------------------------------------------------------* 799 * usbd_req_get_string_any 800 * 801 * This function will return the string given by "string_index" 802 * using the first language ID. The maximum length "len" includes 803 * the terminating zero. The "len" argument should be twice as 804 * big pluss 2 bytes, compared with the actual maximum string length ! 805 * 806 * Returns: 807 * 0: Success 808 * Else: Failure 809 *------------------------------------------------------------------------*/ 810usb_error_t 811usbd_req_get_string_any(struct usb_device *udev, struct mtx *mtx, char *buf, 812 uint16_t len, uint8_t string_index) 813{ 814 char *s; 815 uint8_t *temp; 816 uint16_t i; 817 uint16_t n; 818 uint16_t c; 819 uint8_t swap; 820 usb_error_t err; 821 822 if (len == 0) { 823 /* should not happen */ 824 return (USB_ERR_NORMAL_COMPLETION); 825 } 826 if (string_index == 0) { 827 /* this is the language table */ 828 buf[0] = 0; 829 return (USB_ERR_INVAL); 830 } 831 if (udev->flags.no_strings) { 832 buf[0] = 0; 833 return (USB_ERR_STALLED); 834 } 835 err = usbd_req_get_string_desc 836 (udev, mtx, buf, len, udev->langid, string_index); 837 if (err) { 838 buf[0] = 0; 839 return (err); 840 } 841 temp = (uint8_t *)buf; 842 843 if (temp[0] < 2) { 844 /* string length is too short */ 845 buf[0] = 0; 846 return (USB_ERR_INVAL); 847 } 848 /* reserve one byte for terminating zero */ 849 len--; 850 851 /* find maximum length */ 852 s = buf; 853 n = (temp[0] / 2) - 1; 854 if (n > len) { 855 n = len; 856 } 857 /* skip descriptor header */ 858 temp += 2; 859 860 /* reset swap state */ 861 swap = 3; 862 863 /* convert and filter */ 864 for (i = 0; (i != n); i++) { 865 c = UGETW(temp + (2 * i)); 866 867 /* convert from Unicode, handle buggy strings */ 868 if (((c & 0xff00) == 0) && (swap & 1)) { 869 /* Little Endian, default */ 870 *s = c; 871 swap = 1; 872 } else if (((c & 0x00ff) == 0) && (swap & 2)) { 873 /* Big Endian */ 874 *s = c >> 8; 875 swap = 2; 876 } else { 877 /* silently skip bad character */ 878 continue; 879 } 880 881 /* 882 * Filter by default - we don't allow greater and less than 883 * signs because they might confuse the dmesg printouts! 884 */ 885 if ((*s == '<') || (*s == '>') || (!isprint(*s))) { 886 /* silently skip bad character */ 887 continue; 888 } 889 s++; 890 } 891 *s = 0; /* zero terminate resulting string */ 892 return (USB_ERR_NORMAL_COMPLETION); 893} 894 895/*------------------------------------------------------------------------* 896 * usbd_req_get_string_desc 897 * 898 * If you don't know the language ID, consider using 899 * "usbd_req_get_string_any()". 900 * 901 * Returns: 902 * 0: Success 903 * Else: Failure 904 *------------------------------------------------------------------------*/ 905usb_error_t 906usbd_req_get_string_desc(struct usb_device *udev, struct mtx *mtx, void *sdesc, 907 uint16_t max_len, uint16_t lang_id, 908 uint8_t string_index) 909{ 910 return (usbd_req_get_desc(udev, mtx, NULL, sdesc, 2, max_len, lang_id, 911 UDESC_STRING, string_index, 0)); 912} 913 914/*------------------------------------------------------------------------* 915 * usbd_req_get_config_desc_ptr 916 * 917 * This function is used in device side mode to retrieve the pointer 918 * to the generated config descriptor. This saves allocating space for 919 * an additional config descriptor when setting the configuration. 920 * 921 * Returns: 922 * 0: Success 923 * Else: Failure 924 *------------------------------------------------------------------------*/ 925usb_error_t 926usbd_req_get_descriptor_ptr(struct usb_device *udev, 927 struct usb_config_descriptor **ppcd, uint16_t wValue) 928{ 929 struct usb_device_request req; 930 usb_handle_req_t *hr_func; 931 const void *ptr; 932 uint16_t len; 933 usb_error_t err; 934 935 req.bmRequestType = UT_READ_DEVICE; 936 req.bRequest = UR_GET_DESCRIPTOR; 937 USETW(req.wValue, wValue); 938 USETW(req.wIndex, 0); 939 USETW(req.wLength, 0); 940 941 ptr = NULL; 942 len = 0; 943 944 hr_func = usbd_get_hr_func(udev); 945 946 if (hr_func == NULL) 947 err = USB_ERR_INVAL; 948 else { 949 USB_BUS_LOCK(udev->bus); 950 err = (hr_func) (udev, &req, &ptr, &len); 951 USB_BUS_UNLOCK(udev->bus); 952 } 953 954 if (err) 955 ptr = NULL; 956 else if (ptr == NULL) 957 err = USB_ERR_INVAL; 958 959 *ppcd = __DECONST(struct usb_config_descriptor *, ptr); 960 961 return (err); 962} 963 964/*------------------------------------------------------------------------* 965 * usbd_req_get_config_desc 966 * 967 * Returns: 968 * 0: Success 969 * Else: Failure 970 *------------------------------------------------------------------------*/ 971usb_error_t 972usbd_req_get_config_desc(struct usb_device *udev, struct mtx *mtx, 973 struct usb_config_descriptor *d, uint8_t conf_index) 974{ 975 usb_error_t err; 976 977 DPRINTFN(4, "confidx=%d\n", conf_index); 978 979 err = usbd_req_get_desc(udev, mtx, NULL, d, sizeof(*d), 980 sizeof(*d), 0, UDESC_CONFIG, conf_index, 0); 981 if (err) { 982 goto done; 983 } 984 /* Extra sanity checking */ 985 if (UGETW(d->wTotalLength) < sizeof(*d)) { 986 err = USB_ERR_INVAL; 987 } 988done: 989 return (err); 990} 991 992/*------------------------------------------------------------------------* 993 * usbd_req_get_config_desc_full 994 * 995 * This function gets the complete USB configuration descriptor and 996 * ensures that "wTotalLength" is correct. 997 * 998 * Returns: 999 * 0: Success 1000 * Else: Failure 1001 *------------------------------------------------------------------------*/ 1002usb_error_t 1003usbd_req_get_config_desc_full(struct usb_device *udev, struct mtx *mtx, 1004 struct usb_config_descriptor **ppcd, struct malloc_type *mtype, 1005 uint8_t index) 1006{ 1007 struct usb_config_descriptor cd; 1008 struct usb_config_descriptor *cdesc; 1009 uint16_t len; 1010 usb_error_t err; 1011 1012 DPRINTFN(4, "index=%d\n", index); 1013 1014 *ppcd = NULL; 1015 1016 err = usbd_req_get_config_desc(udev, mtx, &cd, index); 1017 if (err) { 1018 return (err); 1019 } 1020 /* get full descriptor */ 1021 len = UGETW(cd.wTotalLength); 1022 if (len < sizeof(*cdesc)) { 1023 /* corrupt descriptor */ 1024 return (USB_ERR_INVAL); 1025 } 1026 cdesc = malloc(len, mtype, M_WAITOK); 1027 if (cdesc == NULL) { 1028 return (USB_ERR_NOMEM); 1029 } 1030 err = usbd_req_get_desc(udev, mtx, NULL, cdesc, len, len, 0, 1031 UDESC_CONFIG, index, 3); 1032 if (err) { 1033 free(cdesc, mtype); 1034 return (err); 1035 } 1036 /* make sure that the device is not fooling us: */ 1037 USETW(cdesc->wTotalLength, len); 1038 1039 *ppcd = cdesc; 1040 1041 return (0); /* success */ 1042} 1043 1044/*------------------------------------------------------------------------* 1045 * usbd_req_get_device_desc 1046 * 1047 * Returns: 1048 * 0: Success 1049 * Else: Failure 1050 *------------------------------------------------------------------------*/ 1051usb_error_t 1052usbd_req_get_device_desc(struct usb_device *udev, struct mtx *mtx, 1053 struct usb_device_descriptor *d) 1054{ 1055 DPRINTFN(4, "\n"); 1056 return (usbd_req_get_desc(udev, mtx, NULL, d, sizeof(*d), 1057 sizeof(*d), 0, UDESC_DEVICE, 0, 3)); 1058} 1059 1060/*------------------------------------------------------------------------* 1061 * usbd_req_get_alt_interface_no 1062 * 1063 * Returns: 1064 * 0: Success 1065 * Else: Failure 1066 *------------------------------------------------------------------------*/ 1067usb_error_t 1068usbd_req_get_alt_interface_no(struct usb_device *udev, struct mtx *mtx, 1069 uint8_t *alt_iface_no, uint8_t iface_index) 1070{ 1071 struct usb_interface *iface = usbd_get_iface(udev, iface_index); 1072 struct usb_device_request req; 1073 1074 if ((iface == NULL) || (iface->idesc == NULL)) 1075 return (USB_ERR_INVAL); 1076 1077 req.bmRequestType = UT_READ_INTERFACE; 1078 req.bRequest = UR_GET_INTERFACE; 1079 USETW(req.wValue, 0); 1080 req.wIndex[0] = iface->idesc->bInterfaceNumber; 1081 req.wIndex[1] = 0; 1082 USETW(req.wLength, 1); 1083 return (usbd_do_request(udev, mtx, &req, alt_iface_no)); 1084} 1085 1086/*------------------------------------------------------------------------* 1087 * usbd_req_set_alt_interface_no 1088 * 1089 * Returns: 1090 * 0: Success 1091 * Else: Failure 1092 *------------------------------------------------------------------------*/ 1093usb_error_t 1094usbd_req_set_alt_interface_no(struct usb_device *udev, struct mtx *mtx, 1095 uint8_t iface_index, uint8_t alt_no) 1096{ 1097 struct usb_interface *iface = usbd_get_iface(udev, iface_index); 1098 struct usb_device_request req; 1099 1100 if ((iface == NULL) || (iface->idesc == NULL)) 1101 return (USB_ERR_INVAL); 1102 1103 req.bmRequestType = UT_WRITE_INTERFACE; 1104 req.bRequest = UR_SET_INTERFACE; 1105 req.wValue[0] = alt_no; 1106 req.wValue[1] = 0; 1107 req.wIndex[0] = iface->idesc->bInterfaceNumber; 1108 req.wIndex[1] = 0; 1109 USETW(req.wLength, 0); 1110 return (usbd_do_request(udev, mtx, &req, 0)); 1111} 1112 1113/*------------------------------------------------------------------------* 1114 * usbd_req_get_device_status 1115 * 1116 * Returns: 1117 * 0: Success 1118 * Else: Failure 1119 *------------------------------------------------------------------------*/ 1120usb_error_t 1121usbd_req_get_device_status(struct usb_device *udev, struct mtx *mtx, 1122 struct usb_status *st) 1123{ 1124 struct usb_device_request req; 1125 1126 req.bmRequestType = UT_READ_DEVICE; 1127 req.bRequest = UR_GET_STATUS; 1128 USETW(req.wValue, 0); 1129 USETW(req.wIndex, 0); 1130 USETW(req.wLength, sizeof(*st)); 1131 return (usbd_do_request(udev, mtx, &req, st)); 1132} 1133 1134/*------------------------------------------------------------------------* 1135 * usbd_req_get_hub_descriptor 1136 * 1137 * Returns: 1138 * 0: Success 1139 * Else: Failure 1140 *------------------------------------------------------------------------*/ 1141usb_error_t 1142usbd_req_get_hub_descriptor(struct usb_device *udev, struct mtx *mtx, 1143 struct usb_hub_descriptor *hd, uint8_t nports) 1144{ 1145 struct usb_device_request req; 1146 uint16_t len = (nports + 7 + (8 * 8)) / 8; 1147 1148 req.bmRequestType = UT_READ_CLASS_DEVICE; 1149 req.bRequest = UR_GET_DESCRIPTOR; 1150 USETW2(req.wValue, UDESC_HUB, 0); 1151 USETW(req.wIndex, 0); 1152 USETW(req.wLength, len); 1153 return (usbd_do_request(udev, mtx, &req, hd)); 1154} 1155 1156/*------------------------------------------------------------------------* 1157 * usbd_req_get_hub_status 1158 * 1159 * Returns: 1160 * 0: Success 1161 * Else: Failure 1162 *------------------------------------------------------------------------*/ 1163usb_error_t 1164usbd_req_get_hub_status(struct usb_device *udev, struct mtx *mtx, 1165 struct usb_hub_status *st) 1166{ 1167 struct usb_device_request req; 1168 1169 req.bmRequestType = UT_READ_CLASS_DEVICE; 1170 req.bRequest = UR_GET_STATUS; 1171 USETW(req.wValue, 0); 1172 USETW(req.wIndex, 0); 1173 USETW(req.wLength, sizeof(struct usb_hub_status)); 1174 return (usbd_do_request(udev, mtx, &req, st)); 1175} 1176 1177/*------------------------------------------------------------------------* 1178 * usbd_req_set_address 1179 * 1180 * This function is used to set the address for an USB device. After 1181 * port reset the USB device will respond at address zero. 1182 * 1183 * Returns: 1184 * 0: Success 1185 * Else: Failure 1186 *------------------------------------------------------------------------*/ 1187usb_error_t 1188usbd_req_set_address(struct usb_device *udev, struct mtx *mtx, uint16_t addr) 1189{ 1190 struct usb_device_request req; 1191 1192 DPRINTFN(6, "setting device address=%d\n", addr); 1193 1194 req.bmRequestType = UT_WRITE_DEVICE; 1195 req.bRequest = UR_SET_ADDRESS; 1196 USETW(req.wValue, addr); 1197 USETW(req.wIndex, 0); 1198 USETW(req.wLength, 0); 1199 1200 /* Setting the address should not take more than 1 second ! */ 1201 return (usbd_do_request_flags(udev, mtx, &req, NULL, 1202 USB_DELAY_STATUS_STAGE, NULL, 1000)); 1203} 1204 1205/*------------------------------------------------------------------------* 1206 * usbd_req_get_port_status 1207 * 1208 * Returns: 1209 * 0: Success 1210 * Else: Failure 1211 *------------------------------------------------------------------------*/ 1212usb_error_t 1213usbd_req_get_port_status(struct usb_device *udev, struct mtx *mtx, 1214 struct usb_port_status *ps, uint8_t port) 1215{ 1216 struct usb_device_request req; 1217 1218 req.bmRequestType = UT_READ_CLASS_OTHER; 1219 req.bRequest = UR_GET_STATUS; 1220 USETW(req.wValue, 0); 1221 req.wIndex[0] = port; 1222 req.wIndex[1] = 0; 1223 USETW(req.wLength, sizeof *ps); 1224 return (usbd_do_request(udev, mtx, &req, ps)); 1225} 1226 1227/*------------------------------------------------------------------------* 1228 * usbd_req_clear_hub_feature 1229 * 1230 * Returns: 1231 * 0: Success 1232 * Else: Failure 1233 *------------------------------------------------------------------------*/ 1234usb_error_t 1235usbd_req_clear_hub_feature(struct usb_device *udev, struct mtx *mtx, 1236 uint16_t sel) 1237{ 1238 struct usb_device_request req; 1239 1240 req.bmRequestType = UT_WRITE_CLASS_DEVICE; 1241 req.bRequest = UR_CLEAR_FEATURE; 1242 USETW(req.wValue, sel); 1243 USETW(req.wIndex, 0); 1244 USETW(req.wLength, 0); 1245 return (usbd_do_request(udev, mtx, &req, 0)); 1246} 1247 1248/*------------------------------------------------------------------------* 1249 * usbd_req_set_hub_feature 1250 * 1251 * Returns: 1252 * 0: Success 1253 * Else: Failure 1254 *------------------------------------------------------------------------*/ 1255usb_error_t 1256usbd_req_set_hub_feature(struct usb_device *udev, struct mtx *mtx, 1257 uint16_t sel) 1258{ 1259 struct usb_device_request req; 1260 1261 req.bmRequestType = UT_WRITE_CLASS_DEVICE; 1262 req.bRequest = UR_SET_FEATURE; 1263 USETW(req.wValue, sel); 1264 USETW(req.wIndex, 0); 1265 USETW(req.wLength, 0); 1266 return (usbd_do_request(udev, mtx, &req, 0)); 1267} 1268 1269/*------------------------------------------------------------------------* 1270 * usbd_req_clear_port_feature 1271 * 1272 * Returns: 1273 * 0: Success 1274 * Else: Failure 1275 *------------------------------------------------------------------------*/ 1276usb_error_t 1277usbd_req_clear_port_feature(struct usb_device *udev, struct mtx *mtx, 1278 uint8_t port, uint16_t sel) 1279{ 1280 struct usb_device_request req; 1281 1282 req.bmRequestType = UT_WRITE_CLASS_OTHER; 1283 req.bRequest = UR_CLEAR_FEATURE; 1284 USETW(req.wValue, sel); 1285 req.wIndex[0] = port; 1286 req.wIndex[1] = 0; 1287 USETW(req.wLength, 0); 1288 return (usbd_do_request(udev, mtx, &req, 0)); 1289} 1290 1291/*------------------------------------------------------------------------* 1292 * usbd_req_set_port_feature 1293 * 1294 * Returns: 1295 * 0: Success 1296 * Else: Failure 1297 *------------------------------------------------------------------------*/ 1298usb_error_t 1299usbd_req_set_port_feature(struct usb_device *udev, struct mtx *mtx, 1300 uint8_t port, uint16_t sel) 1301{ 1302 struct usb_device_request req; 1303 1304 req.bmRequestType = UT_WRITE_CLASS_OTHER; 1305 req.bRequest = UR_SET_FEATURE; 1306 USETW(req.wValue, sel); 1307 req.wIndex[0] = port; 1308 req.wIndex[1] = 0; 1309 USETW(req.wLength, 0); 1310 return (usbd_do_request(udev, mtx, &req, 0)); 1311} 1312 1313/*------------------------------------------------------------------------* 1314 * usbd_req_set_protocol 1315 * 1316 * Returns: 1317 * 0: Success 1318 * Else: Failure 1319 *------------------------------------------------------------------------*/ 1320usb_error_t 1321usbd_req_set_protocol(struct usb_device *udev, struct mtx *mtx, 1322 uint8_t iface_index, uint16_t report) 1323{ 1324 struct usb_interface *iface = usbd_get_iface(udev, iface_index); 1325 struct usb_device_request req; 1326 1327 if ((iface == NULL) || (iface->idesc == NULL)) { 1328 return (USB_ERR_INVAL); 1329 } 1330 DPRINTFN(5, "iface=%p, report=%d, endpt=%d\n", 1331 iface, report, iface->idesc->bInterfaceNumber); 1332 1333 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 1334 req.bRequest = UR_SET_PROTOCOL; 1335 USETW(req.wValue, report); 1336 req.wIndex[0] = iface->idesc->bInterfaceNumber; 1337 req.wIndex[1] = 0; 1338 USETW(req.wLength, 0); 1339 return (usbd_do_request(udev, mtx, &req, 0)); 1340} 1341 1342/*------------------------------------------------------------------------* 1343 * usbd_req_set_report 1344 * 1345 * Returns: 1346 * 0: Success 1347 * Else: Failure 1348 *------------------------------------------------------------------------*/ 1349usb_error_t 1350usbd_req_set_report(struct usb_device *udev, struct mtx *mtx, void *data, uint16_t len, 1351 uint8_t iface_index, uint8_t type, uint8_t id) 1352{ 1353 struct usb_interface *iface = usbd_get_iface(udev, iface_index); 1354 struct usb_device_request req; 1355 1356 if ((iface == NULL) || (iface->idesc == NULL)) { 1357 return (USB_ERR_INVAL); 1358 } 1359 DPRINTFN(5, "len=%d\n", len); 1360 1361 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 1362 req.bRequest = UR_SET_REPORT; 1363 USETW2(req.wValue, type, id); 1364 req.wIndex[0] = iface->idesc->bInterfaceNumber; 1365 req.wIndex[1] = 0; 1366 USETW(req.wLength, len); 1367 return (usbd_do_request(udev, mtx, &req, data)); 1368} 1369 1370/*------------------------------------------------------------------------* 1371 * usbd_req_get_report 1372 * 1373 * Returns: 1374 * 0: Success 1375 * Else: Failure 1376 *------------------------------------------------------------------------*/ 1377usb_error_t 1378usbd_req_get_report(struct usb_device *udev, struct mtx *mtx, void *data, 1379 uint16_t len, uint8_t iface_index, uint8_t type, uint8_t id) 1380{ 1381 struct usb_interface *iface = usbd_get_iface(udev, iface_index); 1382 struct usb_device_request req; 1383 1384 if ((iface == NULL) || (iface->idesc == NULL) || (id == 0)) { 1385 return (USB_ERR_INVAL); 1386 } 1387 DPRINTFN(5, "len=%d\n", len); 1388 1389 req.bmRequestType = UT_READ_CLASS_INTERFACE; 1390 req.bRequest = UR_GET_REPORT; 1391 USETW2(req.wValue, type, id); 1392 req.wIndex[0] = iface->idesc->bInterfaceNumber; 1393 req.wIndex[1] = 0; 1394 USETW(req.wLength, len); 1395 return (usbd_do_request(udev, mtx, &req, data)); 1396} 1397 1398/*------------------------------------------------------------------------* 1399 * usbd_req_set_idle 1400 * 1401 * Returns: 1402 * 0: Success 1403 * Else: Failure 1404 *------------------------------------------------------------------------*/ 1405usb_error_t 1406usbd_req_set_idle(struct usb_device *udev, struct mtx *mtx, 1407 uint8_t iface_index, uint8_t duration, uint8_t id) 1408{ 1409 struct usb_interface *iface = usbd_get_iface(udev, iface_index); 1410 struct usb_device_request req; 1411 1412 if ((iface == NULL) || (iface->idesc == NULL)) { 1413 return (USB_ERR_INVAL); 1414 } 1415 DPRINTFN(5, "%d %d\n", duration, id); 1416 1417 req.bmRequestType = UT_WRITE_CLASS_INTERFACE; 1418 req.bRequest = UR_SET_IDLE; 1419 USETW2(req.wValue, duration, id); 1420 req.wIndex[0] = iface->idesc->bInterfaceNumber; 1421 req.wIndex[1] = 0; 1422 USETW(req.wLength, 0); 1423 return (usbd_do_request(udev, mtx, &req, 0)); 1424} 1425 1426/*------------------------------------------------------------------------* 1427 * usbd_req_get_report_descriptor 1428 * 1429 * Returns: 1430 * 0: Success 1431 * Else: Failure 1432 *------------------------------------------------------------------------*/ 1433usb_error_t 1434usbd_req_get_report_descriptor(struct usb_device *udev, struct mtx *mtx, 1435 void *d, uint16_t size, uint8_t iface_index) 1436{ 1437 struct usb_interface *iface = usbd_get_iface(udev, iface_index); 1438 struct usb_device_request req; 1439 1440 if ((iface == NULL) || (iface->idesc == NULL)) { 1441 return (USB_ERR_INVAL); 1442 } 1443 req.bmRequestType = UT_READ_INTERFACE; 1444 req.bRequest = UR_GET_DESCRIPTOR; 1445 USETW2(req.wValue, UDESC_REPORT, 0); /* report id should be 0 */ 1446 req.wIndex[0] = iface->idesc->bInterfaceNumber; 1447 req.wIndex[1] = 0; 1448 USETW(req.wLength, size); 1449 return (usbd_do_request(udev, mtx, &req, d)); 1450} 1451 1452/*------------------------------------------------------------------------* 1453 * usbd_req_set_config 1454 * 1455 * This function is used to select the current configuration number in 1456 * both USB device side mode and USB host side mode. When setting the 1457 * configuration the function of the interfaces can change. 1458 * 1459 * Returns: 1460 * 0: Success 1461 * Else: Failure 1462 *------------------------------------------------------------------------*/ 1463usb_error_t 1464usbd_req_set_config(struct usb_device *udev, struct mtx *mtx, uint8_t conf) 1465{ 1466 struct usb_device_request req; 1467 1468 DPRINTF("setting config %d\n", conf); 1469 1470 /* do "set configuration" request */ 1471 1472 req.bmRequestType = UT_WRITE_DEVICE; 1473 req.bRequest = UR_SET_CONFIG; 1474 req.wValue[0] = conf; 1475 req.wValue[1] = 0; 1476 USETW(req.wIndex, 0); 1477 USETW(req.wLength, 0); 1478 return (usbd_do_request(udev, mtx, &req, 0)); 1479} 1480 1481/*------------------------------------------------------------------------* 1482 * usbd_req_get_config 1483 * 1484 * Returns: 1485 * 0: Success 1486 * Else: Failure 1487 *------------------------------------------------------------------------*/ 1488usb_error_t 1489usbd_req_get_config(struct usb_device *udev, struct mtx *mtx, uint8_t *pconf) 1490{ 1491 struct usb_device_request req; 1492 1493 req.bmRequestType = UT_READ_DEVICE; 1494 req.bRequest = UR_GET_CONFIG; 1495 USETW(req.wValue, 0); 1496 USETW(req.wIndex, 0); 1497 USETW(req.wLength, 1); 1498 return (usbd_do_request(udev, mtx, &req, pconf)); 1499} 1500 1501/*------------------------------------------------------------------------* 1502 * usbd_req_re_enumerate 1503 * 1504 * NOTE: After this function returns the hardware is in the 1505 * unconfigured state! The application is responsible for setting a 1506 * new configuration. 1507 * 1508 * Returns: 1509 * 0: Success 1510 * Else: Failure 1511 *------------------------------------------------------------------------*/ 1512usb_error_t 1513usbd_req_re_enumerate(struct usb_device *udev, struct mtx *mtx) 1514{ 1515 struct usb_device *parent_hub; 1516 usb_error_t err; 1517 uint8_t old_addr; 1518 uint8_t do_retry = 1; 1519 1520 if (udev->flags.usb_mode != USB_MODE_HOST) { 1521 return (USB_ERR_INVAL); 1522 } 1523 old_addr = udev->address; 1524 parent_hub = udev->parent_hub; 1525 if (parent_hub == NULL) { 1526 return (USB_ERR_INVAL); 1527 } 1528retry: 1529 err = usbd_req_reset_port(parent_hub, mtx, udev->port_no); 1530 if (err) { 1531 DPRINTFN(0, "addr=%d, port reset failed, %s\n", 1532 old_addr, usbd_errstr(err)); 1533 goto done; 1534 } 1535 /* 1536 * After that the port has been reset our device should be at 1537 * address zero: 1538 */ 1539 udev->address = USB_START_ADDR; 1540 1541 /* reset "bMaxPacketSize" */ 1542 udev->ddesc.bMaxPacketSize = USB_MAX_IPACKET; 1543 1544 /* 1545 * Restore device address: 1546 */ 1547 err = usbd_req_set_address(udev, mtx, old_addr); 1548 if (err) { 1549 /* XXX ignore any errors! */ 1550 DPRINTFN(0, "addr=%d, set address failed! (%s, ignored)\n", 1551 old_addr, usbd_errstr(err)); 1552 } 1553 /* restore device address */ 1554 udev->address = old_addr; 1555 1556 /* allow device time to set new address */ 1557 usb_pause_mtx(mtx, USB_MS_TO_TICKS(USB_SET_ADDRESS_SETTLE)); 1558 1559 /* get the device descriptor */ 1560 err = usbd_req_get_desc(udev, mtx, NULL, &udev->ddesc, 1561 USB_MAX_IPACKET, USB_MAX_IPACKET, 0, UDESC_DEVICE, 0, 0); 1562 if (err) { 1563 DPRINTFN(0, "getting device descriptor " 1564 "at addr %d failed, %s\n", udev->address, 1565 usbd_errstr(err)); 1566 goto done; 1567 } 1568 /* get the full device descriptor */ 1569 err = usbd_req_get_device_desc(udev, mtx, &udev->ddesc); 1570 if (err) { 1571 DPRINTFN(0, "addr=%d, getting device " 1572 "descriptor failed, %s\n", old_addr, 1573 usbd_errstr(err)); 1574 goto done; 1575 } 1576done: 1577 if (err && do_retry) { 1578 /* give the USB firmware some time to load */ 1579 usb_pause_mtx(mtx, hz / 2); 1580 /* no more retries after this retry */ 1581 do_retry = 0; 1582 /* try again */ 1583 goto retry; 1584 } 1585 /* restore address */ 1586 udev->address = old_addr; 1587 return (err); 1588} 1589 1590/*------------------------------------------------------------------------* 1591 * usbd_req_clear_device_feature 1592 * 1593 * Returns: 1594 * 0: Success 1595 * Else: Failure 1596 *------------------------------------------------------------------------*/ 1597usb_error_t 1598usbd_req_clear_device_feature(struct usb_device *udev, struct mtx *mtx, 1599 uint16_t sel) 1600{ 1601 struct usb_device_request req; 1602 1603 req.bmRequestType = UT_WRITE_DEVICE; 1604 req.bRequest = UR_CLEAR_FEATURE; 1605 USETW(req.wValue, sel); 1606 USETW(req.wIndex, 0); 1607 USETW(req.wLength, 0); 1608 return (usbd_do_request(udev, mtx, &req, 0)); 1609} 1610 1611/*------------------------------------------------------------------------* 1612 * usbd_req_set_device_feature 1613 * 1614 * Returns: 1615 * 0: Success 1616 * Else: Failure 1617 *------------------------------------------------------------------------*/ 1618usb_error_t 1619usbd_req_set_device_feature(struct usb_device *udev, struct mtx *mtx, 1620 uint16_t sel) 1621{ 1622 struct usb_device_request req; 1623 1624 req.bmRequestType = UT_WRITE_DEVICE; 1625 req.bRequest = UR_SET_FEATURE; 1626 USETW(req.wValue, sel); 1627 USETW(req.wIndex, 0); 1628 USETW(req.wLength, 0); 1629 return (usbd_do_request(udev, mtx, &req, 0)); 1630} 1631