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