usb_handle_request.c revision 246616
1/* $FreeBSD: head/sys/dev/usb/usb_handle_request.c 246616 2013-02-10 10:56:13Z hselasky $ */ 2/*- 3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#ifdef USB_GLOBAL_INCLUDE_FILE 28#include USB_GLOBAL_INCLUDE_FILE 29#else 30#include <sys/stdint.h> 31#include <sys/stddef.h> 32#include <sys/param.h> 33#include <sys/queue.h> 34#include <sys/types.h> 35#include <sys/systm.h> 36#include <sys/kernel.h> 37#include <sys/bus.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 "usb_if.h" 53 54#define USB_DEBUG_VAR usb_debug 55 56#include <dev/usb/usb_core.h> 57#include <dev/usb/usb_process.h> 58#include <dev/usb/usb_busdma.h> 59#include <dev/usb/usb_transfer.h> 60#include <dev/usb/usb_device.h> 61#include <dev/usb/usb_debug.h> 62#include <dev/usb/usb_dynamic.h> 63#include <dev/usb/usb_hub.h> 64 65#include <dev/usb/usb_controller.h> 66#include <dev/usb/usb_bus.h> 67#endif /* USB_GLOBAL_INCLUDE_FILE */ 68 69/* function prototypes */ 70 71static uint8_t usb_handle_get_stall(struct usb_device *, uint8_t); 72static usb_error_t usb_handle_remote_wakeup(struct usb_xfer *, uint8_t); 73static usb_error_t usb_handle_request(struct usb_xfer *); 74static usb_error_t usb_handle_set_config(struct usb_xfer *, uint8_t); 75static usb_error_t usb_handle_set_stall(struct usb_xfer *, uint8_t, 76 uint8_t); 77static usb_error_t usb_handle_iface_request(struct usb_xfer *, void **, 78 uint16_t *, struct usb_device_request, uint16_t, 79 uint8_t); 80 81/*------------------------------------------------------------------------* 82 * usb_handle_request_callback 83 * 84 * This function is the USB callback for generic USB Device control 85 * transfers. 86 *------------------------------------------------------------------------*/ 87void 88usb_handle_request_callback(struct usb_xfer *xfer, usb_error_t error) 89{ 90 usb_error_t err; 91 92 /* check the current transfer state */ 93 94 switch (USB_GET_STATE(xfer)) { 95 case USB_ST_SETUP: 96 case USB_ST_TRANSFERRED: 97 98 /* handle the request */ 99 err = usb_handle_request(xfer); 100 101 if (err) { 102 103 if (err == USB_ERR_BAD_CONTEXT) { 104 /* we need to re-setup the control transfer */ 105 usb_needs_explore(xfer->xroot->bus, 0); 106 break; 107 } 108 goto tr_restart; 109 } 110 usbd_transfer_submit(xfer); 111 break; 112 113 default: 114 /* check if a control transfer is active */ 115 if (xfer->flags_int.control_rem != 0xFFFF) { 116 /* handle the request */ 117 err = usb_handle_request(xfer); 118 } 119 if (xfer->error != USB_ERR_CANCELLED) { 120 /* should not happen - try stalling */ 121 goto tr_restart; 122 } 123 break; 124 } 125 return; 126 127tr_restart: 128 /* 129 * If a control transfer is active, stall it, and wait for the 130 * next control transfer. 131 */ 132 usbd_xfer_set_frame_len(xfer, 0, sizeof(struct usb_device_request)); 133 xfer->nframes = 1; 134 xfer->flags.manual_status = 1; 135 xfer->flags.force_short_xfer = 0; 136 usbd_xfer_set_stall(xfer); /* cancel previous transfer, if any */ 137 usbd_transfer_submit(xfer); 138} 139 140/*------------------------------------------------------------------------* 141 * usb_handle_set_config 142 * 143 * Returns: 144 * 0: Success 145 * Else: Failure 146 *------------------------------------------------------------------------*/ 147static usb_error_t 148usb_handle_set_config(struct usb_xfer *xfer, uint8_t conf_no) 149{ 150 struct usb_device *udev = xfer->xroot->udev; 151 usb_error_t err = 0; 152 153 /* 154 * We need to protect against other threads doing probe and 155 * attach: 156 */ 157 USB_XFER_UNLOCK(xfer); 158 159 usbd_enum_lock(udev); 160 161 if (conf_no == USB_UNCONFIG_NO) { 162 conf_no = USB_UNCONFIG_INDEX; 163 } else { 164 /* 165 * The relationship between config number and config index 166 * is very simple in our case: 167 */ 168 conf_no--; 169 } 170 171 if (usbd_set_config_index(udev, conf_no)) { 172 DPRINTF("set config %d failed\n", conf_no); 173 err = USB_ERR_STALLED; 174 goto done; 175 } 176 if (usb_probe_and_attach(udev, USB_IFACE_INDEX_ANY)) { 177 DPRINTF("probe and attach failed\n"); 178 err = USB_ERR_STALLED; 179 goto done; 180 } 181done: 182 usbd_enum_unlock(udev); 183 USB_XFER_LOCK(xfer); 184 return (err); 185} 186 187static usb_error_t 188usb_check_alt_setting(struct usb_device *udev, 189 struct usb_interface *iface, uint8_t alt_index) 190{ 191 uint8_t do_unlock; 192 usb_error_t err = 0; 193 194 /* Prevent re-enumeration */ 195 do_unlock = usbd_enum_lock(udev); 196 197 if (alt_index >= usbd_get_no_alts(udev->cdesc, iface->idesc)) 198 err = USB_ERR_INVAL; 199 200 if (do_unlock) 201 usbd_enum_unlock(udev); 202 203 return (err); 204} 205 206/*------------------------------------------------------------------------* 207 * usb_handle_iface_request 208 * 209 * Returns: 210 * 0: Success 211 * Else: Failure 212 *------------------------------------------------------------------------*/ 213static usb_error_t 214usb_handle_iface_request(struct usb_xfer *xfer, 215 void **ppdata, uint16_t *plen, 216 struct usb_device_request req, uint16_t off, uint8_t state) 217{ 218 struct usb_interface *iface; 219 struct usb_interface *iface_parent; /* parent interface */ 220 struct usb_device *udev = xfer->xroot->udev; 221 int error; 222 uint8_t iface_index; 223 uint8_t temp_state; 224 225 if ((req.bmRequestType & 0x1F) == UT_INTERFACE) { 226 iface_index = req.wIndex[0]; /* unicast */ 227 } else { 228 iface_index = 0; /* broadcast */ 229 } 230 231 /* 232 * We need to protect against other threads doing probe and 233 * attach: 234 */ 235 USB_XFER_UNLOCK(xfer); 236 237 usbd_enum_lock(udev); 238 239 error = ENXIO; 240 241tr_repeat: 242 iface = usbd_get_iface(udev, iface_index); 243 if ((iface == NULL) || 244 (iface->idesc == NULL)) { 245 /* end of interfaces non-existing interface */ 246 goto tr_stalled; 247 } 248 /* set initial state */ 249 250 temp_state = state; 251 252 /* forward request to interface, if any */ 253 254 if ((error != 0) && 255 (error != ENOTTY) && 256 (iface->subdev != NULL) && 257 device_is_attached(iface->subdev)) { 258#if 0 259 DEVMETHOD(usb_handle_request, NULL); /* dummy */ 260#endif 261 error = USB_HANDLE_REQUEST(iface->subdev, 262 &req, ppdata, plen, 263 off, &temp_state); 264 } 265 iface_parent = usbd_get_iface(udev, iface->parent_iface_index); 266 267 if ((iface_parent == NULL) || 268 (iface_parent->idesc == NULL)) { 269 /* non-existing interface */ 270 iface_parent = NULL; 271 } 272 /* forward request to parent interface, if any */ 273 274 if ((error != 0) && 275 (error != ENOTTY) && 276 (iface_parent != NULL) && 277 (iface_parent->subdev != NULL) && 278 ((req.bmRequestType & 0x1F) == UT_INTERFACE) && 279 (iface_parent->subdev != iface->subdev) && 280 device_is_attached(iface_parent->subdev)) { 281 error = USB_HANDLE_REQUEST(iface_parent->subdev, 282 &req, ppdata, plen, off, &temp_state); 283 } 284 if (error == 0) { 285 /* negativly adjust pointer and length */ 286 *ppdata = ((uint8_t *)(*ppdata)) - off; 287 *plen += off; 288 289 if ((state == USB_HR_NOT_COMPLETE) && 290 (temp_state == USB_HR_COMPLETE_OK)) 291 goto tr_short; 292 else 293 goto tr_valid; 294 } else if (error == ENOTTY) { 295 goto tr_stalled; 296 } 297 if ((req.bmRequestType & 0x1F) != UT_INTERFACE) { 298 iface_index++; /* iterate */ 299 goto tr_repeat; 300 } 301 if (state != USB_HR_NOT_COMPLETE) { 302 /* we are complete */ 303 goto tr_valid; 304 } 305 switch (req.bmRequestType) { 306 case UT_WRITE_INTERFACE: 307 switch (req.bRequest) { 308 case UR_SET_INTERFACE: 309 /* 310 * We assume that the endpoints are the same 311 * accross the alternate settings. 312 * 313 * Reset the endpoints, because re-attaching 314 * only a part of the device is not possible. 315 */ 316 error = usb_check_alt_setting(udev, 317 iface, req.wValue[0]); 318 if (error) { 319 DPRINTF("alt setting does not exist %s\n", 320 usbd_errstr(error)); 321 goto tr_stalled; 322 } 323 error = usb_reset_iface_endpoints(udev, iface_index); 324 if (error) { 325 DPRINTF("alt setting failed %s\n", 326 usbd_errstr(error)); 327 goto tr_stalled; 328 } 329 /* update the current alternate setting */ 330 iface->alt_index = req.wValue[0]; 331 break; 332 333 default: 334 goto tr_stalled; 335 } 336 break; 337 338 case UT_READ_INTERFACE: 339 switch (req.bRequest) { 340 case UR_GET_INTERFACE: 341 *ppdata = &iface->alt_index; 342 *plen = 1; 343 break; 344 345 default: 346 goto tr_stalled; 347 } 348 break; 349 default: 350 goto tr_stalled; 351 } 352tr_valid: 353 usbd_enum_unlock(udev); 354 USB_XFER_LOCK(xfer); 355 return (0); 356 357tr_short: 358 usbd_enum_unlock(udev); 359 USB_XFER_LOCK(xfer); 360 return (USB_ERR_SHORT_XFER); 361 362tr_stalled: 363 usbd_enum_unlock(udev); 364 USB_XFER_LOCK(xfer); 365 return (USB_ERR_STALLED); 366} 367 368/*------------------------------------------------------------------------* 369 * usb_handle_stall 370 * 371 * Returns: 372 * 0: Success 373 * Else: Failure 374 *------------------------------------------------------------------------*/ 375static usb_error_t 376usb_handle_set_stall(struct usb_xfer *xfer, uint8_t ep, uint8_t do_stall) 377{ 378 struct usb_device *udev = xfer->xroot->udev; 379 usb_error_t err; 380 381 USB_XFER_UNLOCK(xfer); 382 err = usbd_set_endpoint_stall(udev, 383 usbd_get_ep_by_addr(udev, ep), do_stall); 384 USB_XFER_LOCK(xfer); 385 return (err); 386} 387 388/*------------------------------------------------------------------------* 389 * usb_handle_get_stall 390 * 391 * Returns: 392 * 0: Success 393 * Else: Failure 394 *------------------------------------------------------------------------*/ 395static uint8_t 396usb_handle_get_stall(struct usb_device *udev, uint8_t ea_val) 397{ 398 struct usb_endpoint *ep; 399 uint8_t halted; 400 401 ep = usbd_get_ep_by_addr(udev, ea_val); 402 if (ep == NULL) { 403 /* nothing to do */ 404 return (0); 405 } 406 USB_BUS_LOCK(udev->bus); 407 halted = ep->is_stalled; 408 USB_BUS_UNLOCK(udev->bus); 409 410 return (halted); 411} 412 413/*------------------------------------------------------------------------* 414 * usb_handle_remote_wakeup 415 * 416 * Returns: 417 * 0: Success 418 * Else: Failure 419 *------------------------------------------------------------------------*/ 420static usb_error_t 421usb_handle_remote_wakeup(struct usb_xfer *xfer, uint8_t is_on) 422{ 423 struct usb_device *udev; 424 struct usb_bus *bus; 425 426 udev = xfer->xroot->udev; 427 bus = udev->bus; 428 429 USB_BUS_LOCK(bus); 430 431 if (is_on) { 432 udev->flags.remote_wakeup = 1; 433 } else { 434 udev->flags.remote_wakeup = 0; 435 } 436 437 USB_BUS_UNLOCK(bus); 438 439#if USB_HAVE_POWERD 440 /* In case we are out of sync, update the power state. */ 441 usb_bus_power_update(udev->bus); 442#endif 443 return (0); /* success */ 444} 445 446/*------------------------------------------------------------------------* 447 * usb_handle_request 448 * 449 * Internal state sequence: 450 * 451 * USB_HR_NOT_COMPLETE -> USB_HR_COMPLETE_OK v USB_HR_COMPLETE_ERR 452 * 453 * Returns: 454 * 0: Ready to start hardware 455 * Else: Stall current transfer, if any 456 *------------------------------------------------------------------------*/ 457static usb_error_t 458usb_handle_request(struct usb_xfer *xfer) 459{ 460 struct usb_device_request req; 461 struct usb_device *udev; 462 const void *src_zcopy; /* zero-copy source pointer */ 463 const void *src_mcopy; /* non zero-copy source pointer */ 464 uint16_t off; /* data offset */ 465 uint16_t rem; /* data remainder */ 466 uint16_t max_len; /* max fragment length */ 467 uint16_t wValue; 468 uint8_t state; 469 uint8_t is_complete = 1; 470 usb_error_t err; 471 union { 472 uWord wStatus; 473 uint8_t buf[2]; 474 } temp; 475 476 /* 477 * Filter the USB transfer state into 478 * something which we understand: 479 */ 480 481 switch (USB_GET_STATE(xfer)) { 482 case USB_ST_SETUP: 483 state = USB_HR_NOT_COMPLETE; 484 485 if (!xfer->flags_int.control_act) { 486 /* nothing to do */ 487 goto tr_stalled; 488 } 489 break; 490 case USB_ST_TRANSFERRED: 491 if (!xfer->flags_int.control_act) { 492 state = USB_HR_COMPLETE_OK; 493 } else { 494 state = USB_HR_NOT_COMPLETE; 495 } 496 break; 497 default: 498 state = USB_HR_COMPLETE_ERR; 499 break; 500 } 501 502 /* reset frame stuff */ 503 504 usbd_xfer_set_frame_len(xfer, 0, 0); 505 506 usbd_xfer_set_frame_offset(xfer, 0, 0); 507 usbd_xfer_set_frame_offset(xfer, sizeof(req), 1); 508 509 /* get the current request, if any */ 510 511 usbd_copy_out(xfer->frbuffers, 0, &req, sizeof(req)); 512 513 if (xfer->flags_int.control_rem == 0xFFFF) { 514 /* first time - not initialised */ 515 rem = UGETW(req.wLength); 516 off = 0; 517 } else { 518 /* not first time - initialised */ 519 rem = xfer->flags_int.control_rem; 520 off = UGETW(req.wLength) - rem; 521 } 522 523 /* set some defaults */ 524 525 max_len = 0; 526 src_zcopy = NULL; 527 src_mcopy = NULL; 528 udev = xfer->xroot->udev; 529 530 /* get some request fields decoded */ 531 532 wValue = UGETW(req.wValue); 533 534 DPRINTF("req 0x%02x 0x%02x 0x%04x 0x%04x " 535 "off=0x%x rem=0x%x, state=%d\n", req.bmRequestType, 536 req.bRequest, wValue, UGETW(req.wIndex), off, rem, state); 537 538 /* demultiplex the control request */ 539 540 switch (req.bmRequestType) { 541 case UT_READ_DEVICE: 542 if (state != USB_HR_NOT_COMPLETE) { 543 break; 544 } 545 switch (req.bRequest) { 546 case UR_GET_DESCRIPTOR: 547 goto tr_handle_get_descriptor; 548 case UR_GET_CONFIG: 549 goto tr_handle_get_config; 550 case UR_GET_STATUS: 551 goto tr_handle_get_status; 552 default: 553 goto tr_stalled; 554 } 555 break; 556 557 case UT_WRITE_DEVICE: 558 switch (req.bRequest) { 559 case UR_SET_ADDRESS: 560 goto tr_handle_set_address; 561 case UR_SET_CONFIG: 562 goto tr_handle_set_config; 563 case UR_CLEAR_FEATURE: 564 switch (wValue) { 565 case UF_DEVICE_REMOTE_WAKEUP: 566 goto tr_handle_clear_wakeup; 567 default: 568 goto tr_stalled; 569 } 570 break; 571 case UR_SET_FEATURE: 572 switch (wValue) { 573 case UF_DEVICE_REMOTE_WAKEUP: 574 goto tr_handle_set_wakeup; 575 default: 576 goto tr_stalled; 577 } 578 break; 579 default: 580 goto tr_stalled; 581 } 582 break; 583 584 case UT_WRITE_ENDPOINT: 585 switch (req.bRequest) { 586 case UR_CLEAR_FEATURE: 587 switch (wValue) { 588 case UF_ENDPOINT_HALT: 589 goto tr_handle_clear_halt; 590 default: 591 goto tr_stalled; 592 } 593 break; 594 case UR_SET_FEATURE: 595 switch (wValue) { 596 case UF_ENDPOINT_HALT: 597 goto tr_handle_set_halt; 598 default: 599 goto tr_stalled; 600 } 601 break; 602 default: 603 goto tr_stalled; 604 } 605 break; 606 607 case UT_READ_ENDPOINT: 608 switch (req.bRequest) { 609 case UR_GET_STATUS: 610 goto tr_handle_get_ep_status; 611 default: 612 goto tr_stalled; 613 } 614 break; 615 default: 616 /* we use "USB_ADD_BYTES" to de-const the src_zcopy */ 617 err = usb_handle_iface_request(xfer, 618 USB_ADD_BYTES(&src_zcopy, 0), 619 &max_len, req, off, state); 620 if (err == 0) { 621 is_complete = 0; 622 goto tr_valid; 623 } else if (err == USB_ERR_SHORT_XFER) { 624 goto tr_valid; 625 } 626 /* 627 * Reset zero-copy pointer and max length 628 * variable in case they were unintentionally 629 * set: 630 */ 631 src_zcopy = NULL; 632 max_len = 0; 633 634 /* 635 * Check if we have a vendor specific 636 * descriptor: 637 */ 638 goto tr_handle_get_descriptor; 639 } 640 goto tr_valid; 641 642tr_handle_get_descriptor: 643 err = (usb_temp_get_desc_p) (udev, &req, &src_zcopy, &max_len); 644 if (err) 645 goto tr_stalled; 646 if (src_zcopy == NULL) 647 goto tr_stalled; 648 goto tr_valid; 649 650tr_handle_get_config: 651 temp.buf[0] = udev->curr_config_no; 652 src_mcopy = temp.buf; 653 max_len = 1; 654 goto tr_valid; 655 656tr_handle_get_status: 657 658 wValue = 0; 659 660 USB_BUS_LOCK(udev->bus); 661 if (udev->flags.remote_wakeup) { 662 wValue |= UDS_REMOTE_WAKEUP; 663 } 664 if (udev->flags.self_powered) { 665 wValue |= UDS_SELF_POWERED; 666 } 667 USB_BUS_UNLOCK(udev->bus); 668 669 USETW(temp.wStatus, wValue); 670 src_mcopy = temp.wStatus; 671 max_len = sizeof(temp.wStatus); 672 goto tr_valid; 673 674tr_handle_set_address: 675 if (state == USB_HR_NOT_COMPLETE) { 676 if (wValue >= 0x80) { 677 /* invalid value */ 678 goto tr_stalled; 679 } else if (udev->curr_config_no != 0) { 680 /* we are configured ! */ 681 goto tr_stalled; 682 } 683 } else if (state != USB_HR_NOT_COMPLETE) { 684 udev->address = (wValue & 0x7F); 685 goto tr_bad_context; 686 } 687 goto tr_valid; 688 689tr_handle_set_config: 690 if (state == USB_HR_NOT_COMPLETE) { 691 if (usb_handle_set_config(xfer, req.wValue[0])) { 692 goto tr_stalled; 693 } 694 } 695 goto tr_valid; 696 697tr_handle_clear_halt: 698 if (state == USB_HR_NOT_COMPLETE) { 699 if (usb_handle_set_stall(xfer, req.wIndex[0], 0)) { 700 goto tr_stalled; 701 } 702 } 703 goto tr_valid; 704 705tr_handle_clear_wakeup: 706 if (state == USB_HR_NOT_COMPLETE) { 707 if (usb_handle_remote_wakeup(xfer, 0)) { 708 goto tr_stalled; 709 } 710 } 711 goto tr_valid; 712 713tr_handle_set_halt: 714 if (state == USB_HR_NOT_COMPLETE) { 715 if (usb_handle_set_stall(xfer, req.wIndex[0], 1)) { 716 goto tr_stalled; 717 } 718 } 719 goto tr_valid; 720 721tr_handle_set_wakeup: 722 if (state == USB_HR_NOT_COMPLETE) { 723 if (usb_handle_remote_wakeup(xfer, 1)) { 724 goto tr_stalled; 725 } 726 } 727 goto tr_valid; 728 729tr_handle_get_ep_status: 730 if (state == USB_HR_NOT_COMPLETE) { 731 temp.wStatus[0] = 732 usb_handle_get_stall(udev, req.wIndex[0]); 733 temp.wStatus[1] = 0; 734 src_mcopy = temp.wStatus; 735 max_len = sizeof(temp.wStatus); 736 } 737 goto tr_valid; 738 739tr_valid: 740 if (state != USB_HR_NOT_COMPLETE) { 741 goto tr_stalled; 742 } 743 /* subtract offset from length */ 744 745 max_len -= off; 746 747 /* Compute the real maximum data length */ 748 749 if (max_len > xfer->max_data_length) { 750 max_len = usbd_xfer_max_len(xfer); 751 } 752 if (max_len > rem) { 753 max_len = rem; 754 } 755 /* 756 * If the remainder is greater than the maximum data length, 757 * we need to truncate the value for the sake of the 758 * comparison below: 759 */ 760 if (rem > xfer->max_data_length) { 761 rem = usbd_xfer_max_len(xfer); 762 } 763 if ((rem != max_len) && (is_complete != 0)) { 764 /* 765 * If we don't transfer the data we can transfer, then 766 * the transfer is short ! 767 */ 768 xfer->flags.force_short_xfer = 1; 769 xfer->nframes = 2; 770 } else { 771 /* 772 * Default case 773 */ 774 xfer->flags.force_short_xfer = 0; 775 xfer->nframes = max_len ? 2 : 1; 776 } 777 if (max_len > 0) { 778 if (src_mcopy) { 779 src_mcopy = USB_ADD_BYTES(src_mcopy, off); 780 usbd_copy_in(xfer->frbuffers + 1, 0, 781 src_mcopy, max_len); 782 usbd_xfer_set_frame_len(xfer, 1, max_len); 783 } else { 784 usbd_xfer_set_frame_data(xfer, 1, 785 USB_ADD_BYTES(src_zcopy, off), max_len); 786 } 787 } else { 788 /* the end is reached, send status */ 789 xfer->flags.manual_status = 0; 790 usbd_xfer_set_frame_len(xfer, 1, 0); 791 } 792 DPRINTF("success\n"); 793 return (0); /* success */ 794 795tr_stalled: 796 DPRINTF("%s\n", (state != USB_HR_NOT_COMPLETE) ? 797 "complete" : "stalled"); 798 return (USB_ERR_STALLED); 799 800tr_bad_context: 801 DPRINTF("bad context\n"); 802 return (USB_ERR_BAD_CONTEXT); 803} 804