usb_handle_request.c revision 246122
1/* $FreeBSD: head/sys/dev/usb/usb_handle_request.c 246122 2013-01-30 15:26:04Z 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 /* automatic locking */ 195 if (usbd_enum_is_locked(udev)) { 196 do_unlock = 0; 197 } else { 198 do_unlock = 1; 199 usbd_enum_lock(udev); 200 } 201 202 if (alt_index >= usbd_get_no_alts(udev->cdesc, iface->idesc)) 203 err = USB_ERR_INVAL; 204 205 if (do_unlock) 206 usbd_enum_unlock(udev); 207 208 return (err); 209} 210 211/*------------------------------------------------------------------------* 212 * usb_handle_iface_request 213 * 214 * Returns: 215 * 0: Success 216 * Else: Failure 217 *------------------------------------------------------------------------*/ 218static usb_error_t 219usb_handle_iface_request(struct usb_xfer *xfer, 220 void **ppdata, uint16_t *plen, 221 struct usb_device_request req, uint16_t off, uint8_t state) 222{ 223 struct usb_interface *iface; 224 struct usb_interface *iface_parent; /* parent interface */ 225 struct usb_device *udev = xfer->xroot->udev; 226 int error; 227 uint8_t iface_index; 228 uint8_t temp_state; 229 230 if ((req.bmRequestType & 0x1F) == UT_INTERFACE) { 231 iface_index = req.wIndex[0]; /* unicast */ 232 } else { 233 iface_index = 0; /* broadcast */ 234 } 235 236 /* 237 * We need to protect against other threads doing probe and 238 * attach: 239 */ 240 USB_XFER_UNLOCK(xfer); 241 242 usbd_enum_lock(udev); 243 244 error = ENXIO; 245 246tr_repeat: 247 iface = usbd_get_iface(udev, iface_index); 248 if ((iface == NULL) || 249 (iface->idesc == NULL)) { 250 /* end of interfaces non-existing interface */ 251 goto tr_stalled; 252 } 253 /* set initial state */ 254 255 temp_state = state; 256 257 /* forward request to interface, if any */ 258 259 if ((error != 0) && 260 (error != ENOTTY) && 261 (iface->subdev != NULL) && 262 device_is_attached(iface->subdev)) { 263#if 0 264 DEVMETHOD(usb_handle_request, NULL); /* dummy */ 265#endif 266 error = USB_HANDLE_REQUEST(iface->subdev, 267 &req, ppdata, plen, 268 off, &temp_state); 269 } 270 iface_parent = usbd_get_iface(udev, iface->parent_iface_index); 271 272 if ((iface_parent == NULL) || 273 (iface_parent->idesc == NULL)) { 274 /* non-existing interface */ 275 iface_parent = NULL; 276 } 277 /* forward request to parent interface, if any */ 278 279 if ((error != 0) && 280 (error != ENOTTY) && 281 (iface_parent != NULL) && 282 (iface_parent->subdev != NULL) && 283 ((req.bmRequestType & 0x1F) == UT_INTERFACE) && 284 (iface_parent->subdev != iface->subdev) && 285 device_is_attached(iface_parent->subdev)) { 286 error = USB_HANDLE_REQUEST(iface_parent->subdev, 287 &req, ppdata, plen, off, &temp_state); 288 } 289 if (error == 0) { 290 /* negativly adjust pointer and length */ 291 *ppdata = ((uint8_t *)(*ppdata)) - off; 292 *plen += off; 293 294 if ((state == USB_HR_NOT_COMPLETE) && 295 (temp_state == USB_HR_COMPLETE_OK)) 296 goto tr_short; 297 else 298 goto tr_valid; 299 } else if (error == ENOTTY) { 300 goto tr_stalled; 301 } 302 if ((req.bmRequestType & 0x1F) != UT_INTERFACE) { 303 iface_index++; /* iterate */ 304 goto tr_repeat; 305 } 306 if (state != USB_HR_NOT_COMPLETE) { 307 /* we are complete */ 308 goto tr_valid; 309 } 310 switch (req.bmRequestType) { 311 case UT_WRITE_INTERFACE: 312 switch (req.bRequest) { 313 case UR_SET_INTERFACE: 314 /* 315 * We assume that the endpoints are the same 316 * accross the alternate settings. 317 * 318 * Reset the endpoints, because re-attaching 319 * only a part of the device is not possible. 320 */ 321 error = usb_check_alt_setting(udev, 322 iface, req.wValue[0]); 323 if (error) { 324 DPRINTF("alt setting does not exist %s\n", 325 usbd_errstr(error)); 326 goto tr_stalled; 327 } 328 error = usb_reset_iface_endpoints(udev, iface_index); 329 if (error) { 330 DPRINTF("alt setting failed %s\n", 331 usbd_errstr(error)); 332 goto tr_stalled; 333 } 334 /* update the current alternate setting */ 335 iface->alt_index = req.wValue[0]; 336 break; 337 338 default: 339 goto tr_stalled; 340 } 341 break; 342 343 case UT_READ_INTERFACE: 344 switch (req.bRequest) { 345 case UR_GET_INTERFACE: 346 *ppdata = &iface->alt_index; 347 *plen = 1; 348 break; 349 350 default: 351 goto tr_stalled; 352 } 353 break; 354 default: 355 goto tr_stalled; 356 } 357tr_valid: 358 usbd_enum_unlock(udev); 359 USB_XFER_LOCK(xfer); 360 return (0); 361 362tr_short: 363 usbd_enum_unlock(udev); 364 USB_XFER_LOCK(xfer); 365 return (USB_ERR_SHORT_XFER); 366 367tr_stalled: 368 usbd_enum_unlock(udev); 369 USB_XFER_LOCK(xfer); 370 return (USB_ERR_STALLED); 371} 372 373/*------------------------------------------------------------------------* 374 * usb_handle_stall 375 * 376 * Returns: 377 * 0: Success 378 * Else: Failure 379 *------------------------------------------------------------------------*/ 380static usb_error_t 381usb_handle_set_stall(struct usb_xfer *xfer, uint8_t ep, uint8_t do_stall) 382{ 383 struct usb_device *udev = xfer->xroot->udev; 384 usb_error_t err; 385 386 USB_XFER_UNLOCK(xfer); 387 err = usbd_set_endpoint_stall(udev, 388 usbd_get_ep_by_addr(udev, ep), do_stall); 389 USB_XFER_LOCK(xfer); 390 return (err); 391} 392 393/*------------------------------------------------------------------------* 394 * usb_handle_get_stall 395 * 396 * Returns: 397 * 0: Success 398 * Else: Failure 399 *------------------------------------------------------------------------*/ 400static uint8_t 401usb_handle_get_stall(struct usb_device *udev, uint8_t ea_val) 402{ 403 struct usb_endpoint *ep; 404 uint8_t halted; 405 406 ep = usbd_get_ep_by_addr(udev, ea_val); 407 if (ep == NULL) { 408 /* nothing to do */ 409 return (0); 410 } 411 USB_BUS_LOCK(udev->bus); 412 halted = ep->is_stalled; 413 USB_BUS_UNLOCK(udev->bus); 414 415 return (halted); 416} 417 418/*------------------------------------------------------------------------* 419 * usb_handle_remote_wakeup 420 * 421 * Returns: 422 * 0: Success 423 * Else: Failure 424 *------------------------------------------------------------------------*/ 425static usb_error_t 426usb_handle_remote_wakeup(struct usb_xfer *xfer, uint8_t is_on) 427{ 428 struct usb_device *udev; 429 struct usb_bus *bus; 430 431 udev = xfer->xroot->udev; 432 bus = udev->bus; 433 434 USB_BUS_LOCK(bus); 435 436 if (is_on) { 437 udev->flags.remote_wakeup = 1; 438 } else { 439 udev->flags.remote_wakeup = 0; 440 } 441 442 USB_BUS_UNLOCK(bus); 443 444#if USB_HAVE_POWERD 445 /* In case we are out of sync, update the power state. */ 446 usb_bus_power_update(udev->bus); 447#endif 448 return (0); /* success */ 449} 450 451/*------------------------------------------------------------------------* 452 * usb_handle_request 453 * 454 * Internal state sequence: 455 * 456 * USB_HR_NOT_COMPLETE -> USB_HR_COMPLETE_OK v USB_HR_COMPLETE_ERR 457 * 458 * Returns: 459 * 0: Ready to start hardware 460 * Else: Stall current transfer, if any 461 *------------------------------------------------------------------------*/ 462static usb_error_t 463usb_handle_request(struct usb_xfer *xfer) 464{ 465 struct usb_device_request req; 466 struct usb_device *udev; 467 const void *src_zcopy; /* zero-copy source pointer */ 468 const void *src_mcopy; /* non zero-copy source pointer */ 469 uint16_t off; /* data offset */ 470 uint16_t rem; /* data remainder */ 471 uint16_t max_len; /* max fragment length */ 472 uint16_t wValue; 473 uint8_t state; 474 uint8_t is_complete = 1; 475 usb_error_t err; 476 union { 477 uWord wStatus; 478 uint8_t buf[2]; 479 } temp; 480 481 /* 482 * Filter the USB transfer state into 483 * something which we understand: 484 */ 485 486 switch (USB_GET_STATE(xfer)) { 487 case USB_ST_SETUP: 488 state = USB_HR_NOT_COMPLETE; 489 490 if (!xfer->flags_int.control_act) { 491 /* nothing to do */ 492 goto tr_stalled; 493 } 494 break; 495 case USB_ST_TRANSFERRED: 496 if (!xfer->flags_int.control_act) { 497 state = USB_HR_COMPLETE_OK; 498 } else { 499 state = USB_HR_NOT_COMPLETE; 500 } 501 break; 502 default: 503 state = USB_HR_COMPLETE_ERR; 504 break; 505 } 506 507 /* reset frame stuff */ 508 509 usbd_xfer_set_frame_len(xfer, 0, 0); 510 511 usbd_xfer_set_frame_offset(xfer, 0, 0); 512 usbd_xfer_set_frame_offset(xfer, sizeof(req), 1); 513 514 /* get the current request, if any */ 515 516 usbd_copy_out(xfer->frbuffers, 0, &req, sizeof(req)); 517 518 if (xfer->flags_int.control_rem == 0xFFFF) { 519 /* first time - not initialised */ 520 rem = UGETW(req.wLength); 521 off = 0; 522 } else { 523 /* not first time - initialised */ 524 rem = xfer->flags_int.control_rem; 525 off = UGETW(req.wLength) - rem; 526 } 527 528 /* set some defaults */ 529 530 max_len = 0; 531 src_zcopy = NULL; 532 src_mcopy = NULL; 533 udev = xfer->xroot->udev; 534 535 /* get some request fields decoded */ 536 537 wValue = UGETW(req.wValue); 538 539 DPRINTF("req 0x%02x 0x%02x 0x%04x 0x%04x " 540 "off=0x%x rem=0x%x, state=%d\n", req.bmRequestType, 541 req.bRequest, wValue, UGETW(req.wIndex), off, rem, state); 542 543 /* demultiplex the control request */ 544 545 switch (req.bmRequestType) { 546 case UT_READ_DEVICE: 547 if (state != USB_HR_NOT_COMPLETE) { 548 break; 549 } 550 switch (req.bRequest) { 551 case UR_GET_DESCRIPTOR: 552 goto tr_handle_get_descriptor; 553 case UR_GET_CONFIG: 554 goto tr_handle_get_config; 555 case UR_GET_STATUS: 556 goto tr_handle_get_status; 557 default: 558 goto tr_stalled; 559 } 560 break; 561 562 case UT_WRITE_DEVICE: 563 switch (req.bRequest) { 564 case UR_SET_ADDRESS: 565 goto tr_handle_set_address; 566 case UR_SET_CONFIG: 567 goto tr_handle_set_config; 568 case UR_CLEAR_FEATURE: 569 switch (wValue) { 570 case UF_DEVICE_REMOTE_WAKEUP: 571 goto tr_handle_clear_wakeup; 572 default: 573 goto tr_stalled; 574 } 575 break; 576 case UR_SET_FEATURE: 577 switch (wValue) { 578 case UF_DEVICE_REMOTE_WAKEUP: 579 goto tr_handle_set_wakeup; 580 default: 581 goto tr_stalled; 582 } 583 break; 584 default: 585 goto tr_stalled; 586 } 587 break; 588 589 case UT_WRITE_ENDPOINT: 590 switch (req.bRequest) { 591 case UR_CLEAR_FEATURE: 592 switch (wValue) { 593 case UF_ENDPOINT_HALT: 594 goto tr_handle_clear_halt; 595 default: 596 goto tr_stalled; 597 } 598 break; 599 case UR_SET_FEATURE: 600 switch (wValue) { 601 case UF_ENDPOINT_HALT: 602 goto tr_handle_set_halt; 603 default: 604 goto tr_stalled; 605 } 606 break; 607 default: 608 goto tr_stalled; 609 } 610 break; 611 612 case UT_READ_ENDPOINT: 613 switch (req.bRequest) { 614 case UR_GET_STATUS: 615 goto tr_handle_get_ep_status; 616 default: 617 goto tr_stalled; 618 } 619 break; 620 default: 621 /* we use "USB_ADD_BYTES" to de-const the src_zcopy */ 622 err = usb_handle_iface_request(xfer, 623 USB_ADD_BYTES(&src_zcopy, 0), 624 &max_len, req, off, state); 625 if (err == 0) { 626 is_complete = 0; 627 goto tr_valid; 628 } else if (err == USB_ERR_SHORT_XFER) { 629 goto tr_valid; 630 } 631 /* 632 * Reset zero-copy pointer and max length 633 * variable in case they were unintentionally 634 * set: 635 */ 636 src_zcopy = NULL; 637 max_len = 0; 638 639 /* 640 * Check if we have a vendor specific 641 * descriptor: 642 */ 643 goto tr_handle_get_descriptor; 644 } 645 goto tr_valid; 646 647tr_handle_get_descriptor: 648 err = (usb_temp_get_desc_p) (udev, &req, &src_zcopy, &max_len); 649 if (err) 650 goto tr_stalled; 651 if (src_zcopy == NULL) 652 goto tr_stalled; 653 goto tr_valid; 654 655tr_handle_get_config: 656 temp.buf[0] = udev->curr_config_no; 657 src_mcopy = temp.buf; 658 max_len = 1; 659 goto tr_valid; 660 661tr_handle_get_status: 662 663 wValue = 0; 664 665 USB_BUS_LOCK(udev->bus); 666 if (udev->flags.remote_wakeup) { 667 wValue |= UDS_REMOTE_WAKEUP; 668 } 669 if (udev->flags.self_powered) { 670 wValue |= UDS_SELF_POWERED; 671 } 672 USB_BUS_UNLOCK(udev->bus); 673 674 USETW(temp.wStatus, wValue); 675 src_mcopy = temp.wStatus; 676 max_len = sizeof(temp.wStatus); 677 goto tr_valid; 678 679tr_handle_set_address: 680 if (state == USB_HR_NOT_COMPLETE) { 681 if (wValue >= 0x80) { 682 /* invalid value */ 683 goto tr_stalled; 684 } else if (udev->curr_config_no != 0) { 685 /* we are configured ! */ 686 goto tr_stalled; 687 } 688 } else if (state != USB_HR_NOT_COMPLETE) { 689 udev->address = (wValue & 0x7F); 690 goto tr_bad_context; 691 } 692 goto tr_valid; 693 694tr_handle_set_config: 695 if (state == USB_HR_NOT_COMPLETE) { 696 if (usb_handle_set_config(xfer, req.wValue[0])) { 697 goto tr_stalled; 698 } 699 } 700 goto tr_valid; 701 702tr_handle_clear_halt: 703 if (state == USB_HR_NOT_COMPLETE) { 704 if (usb_handle_set_stall(xfer, req.wIndex[0], 0)) { 705 goto tr_stalled; 706 } 707 } 708 goto tr_valid; 709 710tr_handle_clear_wakeup: 711 if (state == USB_HR_NOT_COMPLETE) { 712 if (usb_handle_remote_wakeup(xfer, 0)) { 713 goto tr_stalled; 714 } 715 } 716 goto tr_valid; 717 718tr_handle_set_halt: 719 if (state == USB_HR_NOT_COMPLETE) { 720 if (usb_handle_set_stall(xfer, req.wIndex[0], 1)) { 721 goto tr_stalled; 722 } 723 } 724 goto tr_valid; 725 726tr_handle_set_wakeup: 727 if (state == USB_HR_NOT_COMPLETE) { 728 if (usb_handle_remote_wakeup(xfer, 1)) { 729 goto tr_stalled; 730 } 731 } 732 goto tr_valid; 733 734tr_handle_get_ep_status: 735 if (state == USB_HR_NOT_COMPLETE) { 736 temp.wStatus[0] = 737 usb_handle_get_stall(udev, req.wIndex[0]); 738 temp.wStatus[1] = 0; 739 src_mcopy = temp.wStatus; 740 max_len = sizeof(temp.wStatus); 741 } 742 goto tr_valid; 743 744tr_valid: 745 if (state != USB_HR_NOT_COMPLETE) { 746 goto tr_stalled; 747 } 748 /* subtract offset from length */ 749 750 max_len -= off; 751 752 /* Compute the real maximum data length */ 753 754 if (max_len > xfer->max_data_length) { 755 max_len = usbd_xfer_max_len(xfer); 756 } 757 if (max_len > rem) { 758 max_len = rem; 759 } 760 /* 761 * If the remainder is greater than the maximum data length, 762 * we need to truncate the value for the sake of the 763 * comparison below: 764 */ 765 if (rem > xfer->max_data_length) { 766 rem = usbd_xfer_max_len(xfer); 767 } 768 if ((rem != max_len) && (is_complete != 0)) { 769 /* 770 * If we don't transfer the data we can transfer, then 771 * the transfer is short ! 772 */ 773 xfer->flags.force_short_xfer = 1; 774 xfer->nframes = 2; 775 } else { 776 /* 777 * Default case 778 */ 779 xfer->flags.force_short_xfer = 0; 780 xfer->nframes = max_len ? 2 : 1; 781 } 782 if (max_len > 0) { 783 if (src_mcopy) { 784 src_mcopy = USB_ADD_BYTES(src_mcopy, off); 785 usbd_copy_in(xfer->frbuffers + 1, 0, 786 src_mcopy, max_len); 787 usbd_xfer_set_frame_len(xfer, 1, max_len); 788 } else { 789 usbd_xfer_set_frame_data(xfer, 1, 790 USB_ADD_BYTES(src_zcopy, off), max_len); 791 } 792 } else { 793 /* the end is reached, send status */ 794 xfer->flags.manual_status = 0; 795 usbd_xfer_set_frame_len(xfer, 1, 0); 796 } 797 DPRINTF("success\n"); 798 return (0); /* success */ 799 800tr_stalled: 801 DPRINTF("%s\n", (state != USB_HR_NOT_COMPLETE) ? 802 "complete" : "stalled"); 803 return (USB_ERR_STALLED); 804 805tr_bad_context: 806 DPRINTF("bad context\n"); 807 return (USB_ERR_BAD_CONTEXT); 808} 809