1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * USB device layer File: usbd.c 5 * 6 * This module deals with devices (things connected to USB buses) 7 * 8 * Author: Mitch Lichtenberg 9 * 10 ********************************************************************* 11 * 12 * Copyright 2000,2001,2002,2003,2005 13 * Broadcom Corporation. All rights reserved. 14 * 15 * This software is furnished under license and may be used and 16 * copied only in accordance with the following terms and 17 * conditions. Subject to these conditions, you may download, 18 * copy, install, use, modify and distribute modified or unmodified 19 * copies of this software in source and/or binary form. No title 20 * or ownership is transferred hereby. 21 * 22 * 1) Any source code used, modified or distributed must reproduce 23 * and retain this copyright notice and list of conditions 24 * as they appear in the source file. 25 * 26 * 2) No right is granted to use any trade name, trademark, or 27 * logo of Broadcom Corporation. The "Broadcom Corporation" 28 * name may not be used to endorse or promote products derived 29 * from this software without the prior written permission of 30 * Broadcom Corporation. 31 * 32 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 33 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 34 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 35 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 36 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 37 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 38 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 39 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 40 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 41 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 42 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 43 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 44 * THE POSSIBILITY OF SUCH DAMAGE. 45 ********************************************************************* */ 46 47 48#ifndef _CFE_ 49#include <stdio.h> 50#include <time.h> 51#include <memory.h> 52#include <stdint.h> 53#include "usbhack.h" 54#include "lib_malloc.h" 55#include "lib_queue.h" 56#else 57#include "cfe.h" 58#endif 59 60#include "usbchap9.h" 61#include "usbd.h" 62 63 64/* For systems with non-coherent DMA, allocate all buffers to be 65 cache-aligned and multiples of a cache line in size, so that they 66 can be safely flushed or invalidated. */ 67 68#define CACHE_ALIGN 32 /* XXX place holder, big enough to now. */ 69#define ALIGN(n,align) (((n)+((align)-1)) & ~((align)-1)) 70 71#define usb_dma_alloc(n) (KMALLOC(ALIGN((n),CACHE_ALIGN),CACHE_ALIGN)) 72 73 74/* ********************************************************************* 75 * Globals 76 ********************************************************************* */ 77 78int usb_noisy = 0; 79 80//#define _USBREQTRACE_ 81#ifdef _USBREQTRACE_ 82#define REQTRACE(x) x 83 84static char *devname(usbreq_t *ur) 85{ 86 if (ur->ur_dev == NULL) return "unkdev"; 87 if (ur->ur_dev->ud_drv == NULL) return "unkdrv"; 88 return ur->ur_dev->ud_drv->udrv_name; 89} 90static char *eptname(usbreq_t *ur) 91{ 92 static char buf[16]; 93 94 if (ur->ur_pipe == NULL) return "unkpipe"; 95 sprintf(buf,"pipe%02X/%02X",ur->ur_pipe->up_flags,ur->ur_pipe->up_num); 96 return buf; 97} 98 99#else 100#define REQTRACE(x) 101#endif 102 103extern usb_driver_t usbroothub_driver; 104 105 106/* ********************************************************************* 107 * usb_create_pipe(dev,epaddr,mps,flags) 108 * 109 * Create a pipe, causing the corresponding endpoint to 110 * be created in the host controller driver. Pipes form the 111 * basic "handle" for unidirectional communications with a 112 * USB device. 113 * 114 * Input parameters: 115 * dev - device we're talking about 116 * epaddr - endpoint address open, usually from the endpoint 117 * descriptor 118 * mps - maximum packet size understood by the device 119 * flags - flags for this pipe (UP_xxx flags) 120 * 121 * Return value: 122 * <0 if error 123 * 0 if ok 124 ********************************************************************* */ 125 126int usb_create_pipe(usbdev_t *dev,int epaddr,int mps,int flags) 127{ 128 usbpipe_t *pipe; 129 int pipeidx; 130 131 pipeidx = USB_EPADDR_TO_IDX(epaddr); 132 133 if (dev->ud_pipes[pipeidx] != NULL) { 134 printf("Trying to create a pipe that was already created!\n"); 135 return 0; 136 } 137 138 pipe = KMALLOC(sizeof(usbpipe_t),0); 139 140 if (!pipe) return -1; 141 142 pipe->up_flags = flags; 143 pipe->up_num = pipeidx; 144 pipe->up_mps = mps; 145 pipe->up_dev = dev; 146 if (dev->ud_flags & UD_FLAG_LOWSPEED) flags |= UP_TYPE_LOWSPEED; 147 pipe->up_hwendpoint = UBEPTCREATE(dev->ud_bus, 148 dev->ud_address, 149 USB_ENDPOINT_ADDRESS(epaddr), 150 mps, 151 flags); 152 153 dev->ud_pipes[pipeidx] = pipe; 154 155 return 0; 156} 157 158/* ********************************************************************* 159 * usb_open_pipe(dev,epdesc) 160 * 161 * Open a pipe given an endpoint descriptor - this is the 162 * normal way pipes get open, since you've just selected a 163 * configuration and have the descriptors handy with all 164 * the information you need. 165 * 166 * Input parameters: 167 * dev - device we're talking to 168 * epdesc - endpoint descriptor 169 * 170 * Return value: 171 * <0 if error 172 * else endpoint/pipe number (from descriptor) 173 ********************************************************************* */ 174 175int usb_open_pipe(usbdev_t *dev,usb_endpoint_descr_t *epdesc) 176{ 177 int res; 178 int flags = 0; 179 180 if (USB_ENDPOINT_DIR_IN(epdesc->bEndpointAddress)) flags |= UP_TYPE_IN; 181 else flags |= UP_TYPE_OUT; 182 183 switch (epdesc->bmAttributes & USB_ENDPOINT_TYPE_MASK) { 184 case USB_ENDPOINT_TYPE_CONTROL: 185 flags |= UP_TYPE_CONTROL; 186 break; 187 case USB_ENDPOINT_TYPE_ISOCHRONOUS: 188 flags |= UP_TYPE_ISOC; 189 break; 190 case USB_ENDPOINT_TYPE_BULK: 191 flags |= UP_TYPE_BULK; 192 break; 193 case USB_ENDPOINT_TYPE_INTERRUPT: 194 flags |= UP_TYPE_INTR; 195 break; 196 } 197 198 res = usb_create_pipe(dev, 199 epdesc->bEndpointAddress, 200 GETUSBFIELD(epdesc,wMaxPacketSize), 201 flags); 202 203 if (res < 0) return res; 204 205 return epdesc->bEndpointAddress; 206} 207 208 209/* ********************************************************************* 210 * usb_destroy_pipe(dev,epaddr) 211 * 212 * Close(destroy) an open pipe and remove endpoint descriptor 213 * 214 * Input parameters: 215 * dev - device we're talking to 216 * epaddr - pipe to close 217 * 218 * Return value: 219 * nothing 220 ********************************************************************* */ 221 222void usb_destroy_pipe(usbdev_t *dev,int epaddr) 223{ 224 usbpipe_t *pipe; 225 int pipeidx; 226 227 pipeidx = USB_EPADDR_TO_IDX(epaddr); 228 229 pipe = dev->ud_pipes[pipeidx]; 230 if (!pipe) return; 231 232 if (dev->ud_pipes[pipeidx]) { 233 UBEPTDELETE(dev->ud_bus, 234 dev->ud_pipes[pipeidx]->up_hwendpoint); 235 } 236 237 KFREE(dev->ud_pipes[pipeidx]); 238 dev->ud_pipes[pipeidx] = NULL; 239} 240 241 242/* ********************************************************************* 243 * usb_destroy_all_pipes(dev) 244 * 245 * Destroy all pipes related to this device. 246 * 247 * Input parameters: 248 * dev - device we're clearing out 249 * 250 * Return value: 251 * nothing 252 ********************************************************************* */ 253 254void usb_destroy_all_pipes(usbdev_t *dev) 255{ 256 int idx; 257 258 for (idx = 0; idx < UD_MAX_PIPES; idx++) { 259 if (dev->ud_pipes[idx]) { 260 UBEPTDELETE(dev->ud_bus, 261 dev->ud_pipes[idx]->up_hwendpoint); 262 KFREE(dev->ud_pipes[idx]); 263 dev->ud_pipes[idx] = NULL; 264 } 265 } 266} 267 268/* ********************************************************************* 269 * usb_destroy_device(dev) 270 * 271 * Delete an entire USB device, closing its pipes and freeing 272 * the device data structure 273 * 274 * Input parameters: 275 * dev - device to destroy 276 * 277 * Return value: 278 * nothing 279 ********************************************************************* */ 280 281void usb_destroy_device(usbdev_t *dev) 282{ 283 usb_destroy_all_pipes(dev); 284 285 dev->ud_bus->ub_devices[dev->ud_address] = NULL; 286 287 KFREE(dev); 288} 289 290 291/* ********************************************************************* 292 * usb_create_device(bus,lowspeed) 293 * 294 * Create a new USB device. This device will be set to 295 * communicate on address zero (default address) and will be 296 * ready for basic stuff so we can figure out what it is. 297 * The control pipe will be open, so you can start requesting 298 * descriptors right away. 299 * 300 * Input parameters: 301 * bus - bus to create device on 302 * lowspeed - true if it's a lowspeed device (the hubs tell 303 * us these things) 304 * 305 * Return value: 306 * usb device structure, or NULL 307 ********************************************************************* */ 308 309usbdev_t *usb_create_device(usbbus_t *bus,int lowspeed) 310{ 311 usbdev_t *dev; 312 int pipeflags; 313 314 /* 315 * Create the device structure. 316 */ 317 318 dev = KMALLOC(sizeof(usbdev_t),0); 319 memset(dev,0,sizeof(usbdev_t)); 320 321 dev->ud_bus = bus; 322 dev->ud_address = 0; /* default address */ 323 dev->ud_parent = NULL; 324 dev->ud_flags = 0; 325 326 /* 327 * Adjust things based on the target device speed 328 */ 329 330 pipeflags = UP_TYPE_CONTROL; 331 if (lowspeed) { 332 pipeflags |= UP_TYPE_LOWSPEED; 333 dev->ud_flags |= UD_FLAG_LOWSPEED; 334 } 335 336 /* 337 * Create the control pipe. 338 */ 339 340 usb_create_pipe(dev,0, 341 USB_CONTROL_ENDPOINT_MIN_SIZE, 342 pipeflags); 343 344 return dev; 345} 346 347/* ********************************************************************* 348 * usb_make_request(dev,epaddr,buf,len,flags) 349 * 350 * Create a template request structure with basic fields 351 * ready to go. A shorthand routine. 352 * 353 * Input parameters: 354 * dev- device we're talking to 355 * epaddr - endpoint address, from usb_open_pipe() 356 * buf,length - user buffer and buffer length 357 * flags - transfer direction, etc. (UR_xxx flags) 358 * 359 * Return value: 360 * usbreq_t pointer, or NULL 361 ********************************************************************* */ 362 363usbreq_t *usb_make_request(usbdev_t *dev,int epaddr,uint8_t *buf,int length,int flags) 364{ 365 usbreq_t *ur; 366 usbpipe_t *pipe; 367 int pipeidx; 368 369 pipeidx = USB_EPADDR_TO_IDX(epaddr); 370 371 pipe = dev->ud_pipes[pipeidx]; 372 373 if (pipe == NULL) return NULL; 374 375 ur = KMALLOC(sizeof(usbreq_t),0); 376 memset(ur,0,sizeof(usbreq_t)); 377 378 ur->ur_dev = dev; 379 ur->ur_pipe = pipe; 380 ur->ur_buffer = buf; 381 ur->ur_length = length; 382 ur->ur_flags = flags; 383 ur->ur_callback = NULL; 384 385 return ur; 386 387} 388 389/* ********************************************************************* 390 * usb_poll(bus) 391 * 392 * Handle device-driver polling - simply vectors to host controller 393 * driver. 394 * 395 * Input parameters: 396 * bus - bus structure 397 * 398 * Return value: 399 * nothing 400 ********************************************************************* */ 401 402void usb_poll(usbbus_t *bus) 403{ 404 UBINTR(bus); 405} 406 407/* ********************************************************************* 408 * usb_daemon(bus) 409 * 410 * Polls for topology changes and initiates a bus scan if 411 * necessary. 412 * 413 * Input parameters: 414 * bus - bus to watch 415 * 416 * Return value: 417 * nothing 418 ********************************************************************* */ 419 420void usb_daemon(usbbus_t *bus) 421{ 422 /* 423 * Just see if someone flagged a need for a scan here 424 * and start the bus scan if necessary. 425 * 426 * The actual scanning is a hub function, starting at the 427 * root hub, so the code for that is over there. 428 */ 429 430 if (bus->ub_flags & UB_FLG_NEEDSCAN) { 431 bus->ub_flags &= ~UB_FLG_NEEDSCAN; 432 usb_scan(bus); 433 } 434} 435 436/* ********************************************************************* 437 * usb_cancel_request(ur) 438 * 439 * Cancel a pending usb transfer request. 440 * 441 * Input parameters: 442 * ur - request to cancel 443 * 444 * Return value: 445 * 0 if ok 446 * else error (could not find request) 447 ********************************************************************* */ 448 449int usb_cancel_request(usbreq_t *ur) 450{ 451 printf("usb_cancel_request is not implemented.\n"); 452 return 0; 453} 454 455/* ********************************************************************* 456 * usb_free_request(ur) 457 * 458 * Return a transfer request to the free pool. 459 * 460 * Input parameters: 461 * ur - request to return 462 * 463 * Return value: 464 * nothing 465 ********************************************************************* */ 466 467void usb_free_request(usbreq_t *ur) 468{ 469 REQTRACE(printf("Free %p (%s,%s)\n",ur,eptname(ur),devname(ur))); 470 471 if (ur->ur_inprogress) { 472 printf("Yow! Tried to free a request that was in progress!\n"); 473 return; 474 } 475 KFREE(ur); 476} 477 478/* ********************************************************************* 479 * usb_delay_ms(bus,ms) 480 * 481 * Wait a while, calling the polling routine as we go. 482 * 483 * Input parameters: 484 * bus - bus we're talking to 485 * ms - how long to wait 486 * 487 * Return value: 488 * nothing 489 ********************************************************************* */ 490 491 492void usb_delay_ms(usbbus_t *bus,int ms) 493{ 494#ifdef _CFE_ 495 cfe_sleep(1+((ms*CFE_HZ)/1000)); 496#else 497 mydelay(ms); 498#endif 499} 500 501/* ********************************************************************* 502 * usb_queue_request(ur) 503 * 504 * Call the transfer handler in the host controller driver to 505 * set up a transfer descriptor 506 * 507 * Input parameters: 508 * ur - request to queue 509 * 510 * Return value: 511 * 0 if ok 512 * else error 513 ********************************************************************* */ 514 515 516int usb_queue_request(usbreq_t *ur) 517{ 518 int res; 519 520 REQTRACE(printf("Queue %p (%s,%s)\n",ur,eptname(ur),devname(ur))); 521 522 ur->ur_inprogress = 1; 523 ur->ur_xferred = 0; 524 res = UBXFER(ur->ur_dev->ud_bus, 525 ur->ur_pipe->up_hwendpoint, 526 ur); 527 return res; 528} 529 530/* ********************************************************************* 531 * usb_wait_request(ur) 532 * 533 * Wait until a request completes, calling the polling routine 534 * as we wait. 535 * 536 * Input parameters: 537 * ur - request to wait for 538 * 539 * Return value: 540 * request status 541 ********************************************************************* */ 542 543int usb_wait_request(usbreq_t *ur) 544{ 545 while ((volatile int) (ur->ur_inprogress)) { 546 usb_poll(ur->ur_dev->ud_bus); 547 } 548 549 return ur->ur_status; 550} 551 552/* ********************************************************************* 553 * usb_sync_request(ur) 554 * 555 * Synchronous request - call usb_queue and then usb_wait 556 * 557 * Input parameters: 558 * ur - request to submit 559 * 560 * Return value: 561 * status of request 562 ********************************************************************* */ 563 564int usb_sync_request(usbreq_t *ur) 565{ 566 usb_queue_request(ur); 567 return usb_wait_request(ur); 568} 569 570/* ********************************************************************* 571 * usb_make_sync_request(dev,epaddr,buf,len,flags) 572 * 573 * Create a request, wait for it to complete, and delete 574 * the request. A shorthand**2 routine. 575 * 576 * Input parameters: 577 * dev- device we're talking to 578 * epaddr - endpoint address, from usb_open_pipe() 579 * buf,length - user buffer and buffer length 580 * flags - transfer direction, etc. (UR_xxx flags) 581 * 582 * Return value: 583 * status of request 584 ********************************************************************* */ 585 586int usb_make_sync_request(usbdev_t *dev,int epaddr,uint8_t *buf,int length,int flags) 587{ 588 usbreq_t *ur; 589 int res; 590 591 ur = usb_make_request(dev,epaddr,buf,length,flags); 592 res = usb_sync_request(ur); 593 usb_free_request(ur); 594 return res; 595} 596 597/* ********************************************************************* 598 * usb_simple_request(dev,reqtype,bRequest,wValue,wIndex) 599 * 600 * Handle a simple USB control pipe request. These are OUT 601 * requests with no data phase. 602 * 603 * Input parameters: 604 * dev - device we're talking to 605 * reqtype - request type (bmRequestType) for descriptor 606 * wValue - wValue for descriptor 607 * wIndex - wIndex for descriptor 608 * 609 * Return value: 610 * 0 if ok 611 * else error 612 ********************************************************************* */ 613 614int usb_simple_request(usbdev_t *dev,uint8_t reqtype,int bRequest,int wValue,int wIndex) 615{ 616 return usb_std_request(dev,reqtype,bRequest,wValue,wIndex,NULL,0); 617} 618 619 620/* ********************************************************************* 621 * usb_set_configuration(dev,config) 622 * 623 * Set the current configuration for a USB device. 624 * 625 * Input parameters: 626 * dev - device we're talking to 627 * config - bConfigValue for the device 628 * 629 * Return value: 630 * request status 631 ********************************************************************* */ 632 633int usb_set_configuration(usbdev_t *dev,int config) 634{ 635 int res; 636 637 res = usb_simple_request(dev,0x00,USB_REQUEST_SET_CONFIGURATION,config,0); 638 639 return res; 640} 641 642 643/* ********************************************************************* 644 * usb_new_address(bus) 645 * 646 * Return the next available address for the specified bus 647 * 648 * Input parameters: 649 * bus - bus to assign an address for 650 * 651 * Return value: 652 * new address, <0 if error 653 ********************************************************************* */ 654 655int usb_new_address(usbbus_t *bus) 656{ 657 int idx; 658 659 for (idx = 1; idx < USB_MAX_DEVICES; idx++) { 660 if (bus->ub_devices[idx] == NULL) return idx; 661 } 662 663 return -1; 664} 665 666/* ********************************************************************* 667 * usb_set_address(dev,address) 668 * 669 * Set the address of a device. This also puts the device 670 * in the master device table for the bus and reconfigures the 671 * address of the control pipe. 672 * 673 * Input parameters: 674 * dev - device we're talking to 675 * address - new address (1..127) 676 * 677 * Return value: 678 * request status 679 ********************************************************************* */ 680 681int usb_set_address(usbdev_t *dev,int address) 682{ 683 int res; 684 int idx; 685 usbpipe_t *pipe; 686 687 res = usb_simple_request(dev,0x00,USB_REQUEST_SET_ADDRESS,address,0); 688 689 if (res == 0) { 690 dev->ud_bus->ub_devices[address] = dev; 691 dev->ud_address = address; 692 for (idx = 0; idx < UD_MAX_PIPES; idx++) { 693 pipe = dev->ud_pipes[idx]; 694 if (pipe && pipe->up_hwendpoint) { 695 UBEPTSETADDR(dev->ud_bus,pipe->up_hwendpoint,address); 696 } 697 } 698 } 699 700 return res; 701} 702 703/* ********************************************************************* 704 * usb_set_ep0mps(dev,mps) 705 * 706 * Set the maximum packet size of endpoint zero (mucks with the 707 * endpoint in the host controller) 708 * 709 * Input parameters: 710 * dev - device we're talking to 711 * mps - max packet size for endpoint zero 712 * 713 * Return value: 714 * request status 715 ********************************************************************* */ 716 717int usb_set_ep0mps(usbdev_t *dev,int mps) 718{ 719 usbpipe_t *pipe; 720 721 pipe = dev->ud_pipes[0]; 722 if (pipe && pipe->up_hwendpoint) { 723 UBEPTSETMPS(dev->ud_bus,pipe->up_hwendpoint,mps); 724 } 725 if (pipe) { 726 pipe->up_mps = mps; 727 } 728 729 return 0; 730} 731 732/* ********************************************************************* 733 * usb_clear_stall(dev,epaddr) 734 * 735 * Clear a stall condition on the specified pipe 736 * 737 * Input parameters: 738 * dev - device we're talking to 739 * epaddr - endpoint address 740 * 741 * Return value: 742 * 0 if ok 743 * else error 744 ********************************************************************* */ 745int usb_clear_stall(usbdev_t *dev,int epaddr) 746{ 747 uint8_t *requestbuf; 748 usb_device_request_t *req; 749 usbreq_t *ur; 750 int res; 751 int pipeidx; 752 753 /* 754 * Clear the stall in the hardware. 755 */ 756 757 pipeidx = USB_EPADDR_TO_IDX(epaddr); 758 759 UBEPTCLEARTOGGLE(dev->ud_bus,dev->ud_pipes[pipeidx]->up_hwendpoint); 760 761 /* 762 * Do the "clear stall" request. Note that we should do this 763 * without calling usb_simple_request, since usb_simple_request 764 * may itself stall. 765 */ 766 767 requestbuf = usb_dma_alloc(32); 768 req = (usb_device_request_t *) requestbuf; 769 770 req->bmRequestType = 0x02; 771 req->bRequest = USB_REQUEST_CLEAR_FEATURE; 772 PUTUSBFIELD(req,wValue,0); /* ENDPOINT_HALT */ 773 PUTUSBFIELD(req,wIndex,epaddr); 774 PUTUSBFIELD(req,wLength,0); 775 776 ur = usb_make_request(dev,0,requestbuf, 777 sizeof(usb_device_request_t), 778 UR_FLAG_SETUP); 779 res = usb_sync_request(ur); 780 usb_free_request(ur); 781 ur = usb_make_request(dev,0,requestbuf,0,UR_FLAG_STATUS_IN); 782 res = usb_sync_request(ur); 783 usb_free_request(ur); 784 785 KFREE(requestbuf); 786 787 return 0; 788} 789 790 791 792/* ********************************************************************* 793 * usb_std_request(dev,bmRequestType,bRequest,wValue, 794 * wIndex,buffer,length) 795 * 796 * Do a standard control request on the control pipe, 797 * with the appropriate setup, data, and status phases. 798 * 799 * Input parameters: 800 * dev - dev we're talking to 801 * bmRequestType,bRequest,wValue,wIndex - fields for the 802 * USB request structure 803 * buffer - user buffer 804 * length - length of user buffer 805 * 806 * Return value: 807 * number of bytes transferred 808 ********************************************************************* */ 809 810int usb_std_request(usbdev_t *dev,uint8_t bmRequestType, 811 uint8_t bRequest,uint16_t wValue, 812 uint16_t wIndex,uint8_t *buffer,int length) 813{ 814 usbpipe_t *pipe = dev->ud_pipes[0]; 815 usbreq_t *ur; 816 int res; 817 usb_device_request_t *req; 818 uint8_t *databuf = NULL; 819 820 req = usb_dma_alloc(32); 821 822 if ((buffer != NULL) && (length !=0)) { 823 databuf = usb_dma_alloc(length); 824 if (!(bmRequestType & USBREQ_DIR_IN)) { 825 memcpy(databuf,buffer,length); 826 } 827 else { 828 memset(databuf,0,length); 829 } 830 } 831 832 req->bmRequestType = bmRequestType; 833 req->bRequest = bRequest; 834 PUTUSBFIELD(req,wValue,wValue); 835 PUTUSBFIELD(req,wIndex,wIndex); 836 PUTUSBFIELD(req,wLength,length); 837 838 ur = usb_make_request(dev,0,(uint8_t *)req,sizeof(usb_device_request_t),UR_FLAG_SETUP); 839 res = usb_sync_request(ur); 840 usb_free_request(ur); 841 842 if (length != 0) { 843 if (bmRequestType & USBREQ_DIR_IN) { 844 ur = usb_make_request(dev,0,databuf,length,UR_FLAG_IN); 845 } 846 else { 847 ur = usb_make_request(dev,0,databuf,length,UR_FLAG_OUT); 848 } 849 850 res = usb_sync_request(ur); 851 852 if (res == 4) { /* STALL */ 853 usb_clear_stall(dev,pipe->up_num); 854 usb_free_request(ur); 855 if (databuf) KFREE(databuf); 856 KFREE(req); 857 return 0; 858 } 859 860 length = ur->ur_xferred; 861 usb_free_request(ur); 862 } 863 864 if ((length != 0) && (databuf != NULL) && (bmRequestType & USBREQ_DIR_IN)) { 865 memcpy(buffer,databuf,length); 866 } 867 868 if (bmRequestType & USBREQ_DIR_IN) { 869 ur = usb_make_request(dev,0,(uint8_t *)req,0,UR_FLAG_STATUS_OUT); 870 } 871 else { 872 ur = usb_make_request(dev,0,(uint8_t *)req,0,UR_FLAG_STATUS_IN); 873 } 874 875 res = usb_sync_request(ur); 876 usb_free_request(ur); 877 878 if (res == 4) { /* STALL */ 879 usb_clear_stall(dev,pipe->up_num); 880 if (databuf) KFREE(databuf); 881 KFREE(req); 882 return 0; 883 } 884 885 if (databuf) KFREE(databuf); 886 KFREE(req); 887 888 return length; 889} 890 891 892 893 894/* ********************************************************************* 895 * usb_get_descriptor(dev,reqtype,dsctype,dscidx,respbuf,buflen) 896 * 897 * Request a descriptor from the device. 898 * 899 * Input parameters: 900 * dev - device we're talking to 901 * reqtype - bmRequestType field for descriptor we want 902 * dsctype - descriptor type we want 903 * dscidx - index of descriptor we want (often zero) 904 * respbuf - response buffer 905 * buflen - length of response buffer 906 * 907 * Return value: 908 * number of bytes transferred 909 ********************************************************************* */ 910 911int usb_get_descriptor(usbdev_t *dev,uint8_t reqtype,int dsctype,int dscidx, 912 uint8_t *respbuf,int buflen) 913{ 914 return usb_std_request(dev, 915 reqtype,USB_REQUEST_GET_DESCRIPTOR, 916 USB_DESCRIPTOR_TYPEINDEX(dsctype,dscidx), 917 0, 918 respbuf,buflen); 919} 920 921/* ********************************************************************* 922 * usb_get_string_descriptor(dev,reqtype,dsctype,dscidx,respbuf,buflen) 923 * 924 * Request a descriptor from the device. 925 * 926 * Input parameters: 927 * dev - device we're talking to 928 * dscidx - index of descriptor we want 929 * respbuf - response buffer 930 * buflen - length of response buffer 931 * 932 * Return value: 933 * number of bytes transferred 934 ********************************************************************* */ 935 936static int usb_get_string_descriptor(usbdev_t *dev,int dscidx, 937 uint8_t *respbuf,int buflen) 938{ 939 return usb_std_request(dev, 940 USBREQ_DIR_IN,USB_REQUEST_GET_DESCRIPTOR, 941 USB_DESCRIPTOR_TYPEINDEX(USB_STRING_DESCRIPTOR_TYPE,dscidx), 942 0x0409, /* Microsoft lang code for English */ 943 respbuf,buflen); 944} 945 946/* ********************************************************************* 947 * usb_get_string(dev,id,buf,maxlen) 948 * 949 * Request a string from the device, converting it from 950 * unicode to ascii (brutally). 951 * 952 * Input parameters: 953 * dev - device we're talking to 954 * id - string ID 955 * buf - buffer to receive string (null terminated) 956 * maxlen - length of buffer 957 * 958 * Return value: 959 * number of characters in returned string 960 ********************************************************************* */ 961 962int usb_get_string(usbdev_t *dev,int id,char *buf,int maxlen) 963{ 964 int amtcopy; 965 uint8_t *respbuf; 966 int idx; 967 usb_string_descr_t *sdscr; 968 969 respbuf = usb_dma_alloc(maxlen*2+2); 970 sdscr = (usb_string_descr_t *) respbuf; 971 972 /* 973 * First time just get the header of the descriptor so we can 974 * get the string length 975 */ 976 977 amtcopy = usb_get_string_descriptor(dev,id,respbuf,2); 978 979 /* 980 * now do it again to get the whole string. 981 */ 982 983 if (maxlen > sdscr->bLength) maxlen = sdscr->bLength; 984 985 amtcopy = usb_get_string_descriptor(dev,id,respbuf,maxlen); 986 987 *buf = '\0'; 988 amtcopy = sdscr->bLength - 2; 989 if (amtcopy <= 0) return amtcopy; 990 991 for (idx = 0; idx < amtcopy; idx+=2) { 992 *buf++ = sdscr->bString[idx]; 993 } 994 995 *buf = '\0'; 996 997 KFREE(respbuf); 998 999 return amtcopy; 1000} 1001 1002 1003 1004/* ********************************************************************* 1005 * usb_get_device_descriptor(dev,dscr,smallflg) 1006 * 1007 * Request the device descriptor for the device. This is often 1008 * the first descriptor requested, so it needs to be done in 1009 * stages so we can find out how big the control pipe is. 1010 * 1011 * Input parameters: 1012 * dev - device we're talking to 1013 * dscr - pointer to buffer to receive descriptor 1014 * smallflg - TRUE to request just 8 bytes. 1015 * 1016 * Return value: 1017 * number of bytes copied 1018 ********************************************************************* */ 1019 1020int usb_get_device_descriptor(usbdev_t *dev,usb_device_descr_t *dscr,int smallflg) 1021{ 1022 int res; 1023 uint8_t *respbuf; 1024 int amtcopy; 1025 1026 /* 1027 * Smallflg truncates the request 8 bytes. We need to do this for 1028 * the very first transaction to a USB device in order to determine 1029 * the size of its control pipe. Bad things will happen if you 1030 * try to retrieve more data than the control pipe will hold. 1031 * 1032 * So, be conservative at first and get the first 8 bytes of the 1033 * descriptor. Byte 7 is bMaxPacketSize0, the size of the control 1034 * pipe. Then you can go back and submit a bigger request for 1035 * everything else. 1036 */ 1037 1038 amtcopy = smallflg ? USB_CONTROL_ENDPOINT_MIN_SIZE : sizeof(usb_device_descr_t); 1039 1040 respbuf = usb_dma_alloc(64); 1041 res = usb_get_descriptor(dev,USBREQ_DIR_IN,USB_DEVICE_DESCRIPTOR_TYPE,0,respbuf,amtcopy); 1042 memcpy(dscr,respbuf,amtcopy); 1043 KFREE(respbuf); 1044 return res; 1045 1046} 1047 1048/* ********************************************************************* 1049 * usb_get_config_descriptor(dev,dscr,idx,maxlen) 1050 * 1051 * Request the configuration descriptor from the device. 1052 * 1053 * Input parameters: 1054 * dev - device we're talking to 1055 * dscr - descriptor buffer (receives data from device) 1056 * idx - index of config we want (usually zero) 1057 * maxlen - total size of buffer to receive descriptor 1058 * 1059 * Return value: 1060 * number of bytes copied 1061 ********************************************************************* */ 1062 1063int usb_get_config_descriptor(usbdev_t *dev,usb_config_descr_t *dscr,int idx,int maxlen) 1064{ 1065 int res; 1066 uint8_t *respbuf; 1067 1068 respbuf = usb_dma_alloc(maxlen); 1069 res = usb_get_descriptor(dev,USBREQ_DIR_IN, 1070 USB_CONFIGURATION_DESCRIPTOR_TYPE,idx, 1071 respbuf,maxlen); 1072 memcpy(dscr,respbuf,maxlen); 1073 KFREE(respbuf); 1074 return res; 1075 1076} 1077 1078 1079 1080/* ********************************************************************* 1081 * usb_get_device_status(dev,status) 1082 * 1083 * Request status from the device (status descriptor) 1084 * 1085 * Input parameters: 1086 * dev - device we're talking to 1087 * status - receives device_status structure 1088 * 1089 * Return value: 1090 * number of bytes returned 1091 ********************************************************************* */ 1092 1093int usb_get_device_status(usbdev_t *dev,usb_device_status_t *status) 1094{ 1095 return usb_std_request(dev, 1096 USBREQ_DIR_IN, 1097 0, 1098 0, 1099 0, 1100 (uint8_t *) status, 1101 sizeof(usb_device_status_t)); 1102} 1103 1104 1105/* ********************************************************************* 1106 * usb_complete_request(ur,status) 1107 * 1108 * Called when a usb request completes - pass status to 1109 * caller and call the callback if there is one. 1110 * 1111 * Input parameters: 1112 * ur - usbreq_t to complete 1113 * status - completion status 1114 * 1115 * Return value: 1116 * nothing 1117 ********************************************************************* */ 1118 1119void usb_complete_request(usbreq_t *ur,int status) 1120{ 1121 REQTRACE(printf("Complete %p (%s,%s) Status=%d\n",ur,eptname(ur),devname(ur),status)); 1122 1123 ur->ur_status = status; 1124 ur->ur_inprogress = 0; 1125 if (ur->ur_callback) (*(ur->ur_callback))(ur); 1126} 1127 1128 1129/* ********************************************************************* 1130 * usb_initroot(bus) 1131 * 1132 * Initialize the root hub for the bus - we need to do this 1133 * each time a bus is configured. 1134 * 1135 * Input parameters: 1136 * bus - bus to initialize 1137 * 1138 * Return value: 1139 * nothing 1140 ********************************************************************* */ 1141 1142void usb_initroot(usbbus_t *bus) 1143{ 1144 usbdev_t *dev; 1145 usb_driver_t *drv; 1146 int addr; 1147 int res; 1148 uint8_t *buf; 1149 int len; 1150 usb_config_descr_t cfgdescr; 1151 1152 /* 1153 * Create a device for the root hub. 1154 */ 1155 1156 dev = usb_create_device(bus,0); 1157 bus->ub_roothub = dev; 1158 dev->ud_drv = &usbroothub_driver; 1159 1160 /* 1161 * Get the device descriptor. Make sure it's a hub. 1162 */ 1163 1164 res = usb_get_device_descriptor(dev,&(dev->ud_devdescr),TRUE); 1165 1166 if (dev->ud_devdescr.bDeviceClass != USB_DEVICE_CLASS_HUB) { 1167 printf("Error! Root device is not a hub!\n"); 1168 return; 1169 } 1170 1171 /* 1172 * Set up the max packet size for the control endpoint, 1173 * then get the rest of the descriptor. 1174 */ 1175 1176 usb_set_ep0mps(dev,dev->ud_devdescr.bMaxPacketSize0); 1177 res = usb_get_device_descriptor(dev,&(dev->ud_devdescr),FALSE); 1178 1179 /* 1180 * Obtain a new address and set the address of the 1181 * root hub to this address. 1182 */ 1183 1184 addr = usb_new_address(dev->ud_bus); 1185 res = usb_set_address(dev,addr); 1186 1187 /* 1188 * Get the configuration descriptor and all the 1189 * associated interface and endpoint descriptors. 1190 */ 1191 1192 res = usb_get_config_descriptor(dev,&cfgdescr,0, 1193 sizeof(usb_config_descr_t)); 1194 if (res != sizeof(usb_config_descr_t)) { 1195 printf("[a]usb_get_config_descriptor returns %d\n",res); 1196 } 1197 1198 len = GETUSBFIELD(&cfgdescr,wTotalLength); 1199 buf = usb_dma_alloc(len); 1200 1201 res = usb_get_config_descriptor(dev,(usb_config_descr_t *)buf,0,len); 1202 if (res != len) { 1203 printf("[b]usb_get_config_descriptor returns %d\n",res); 1204 } 1205 1206 dev->ud_cfgdescr = (usb_config_descr_t *) buf; 1207 1208 /* 1209 * Select the configuration. Not really needed for our poor 1210 * imitation root hub, but it's the right thing to do. 1211 */ 1212 1213 usb_set_configuration(dev,cfgdescr.bConfigurationValue); 1214 1215 /* 1216 * Find the driver for this. It had better be the hub 1217 * driver. 1218 */ 1219 1220 drv = usb_find_driver(dev); 1221 1222 /* 1223 * Call the attach method. 1224 */ 1225 1226 (*(drv->udrv_attach))(dev,drv); 1227 1228 /* 1229 * Hub should now be operational. 1230 */ 1231 1232} 1233 1234 1235/* ********************************************************************* 1236 * usb_find_cfg_descr(dev,dtype,idx) 1237 * 1238 * Find a configuration descriptor - we retrieved all the config 1239 * descriptors during discovery, this lets us dig out the one 1240 * we want. 1241 * 1242 * Input parameters: 1243 * dev - device we are talking to 1244 * dtype - descriptor type to find 1245 * idx - index of descriptor if there's more than one 1246 * 1247 * Return value: 1248 * pointer to descriptor or NULL if not found 1249 ********************************************************************* */ 1250 1251void *usb_find_cfg_descr(usbdev_t *dev,int dtype,int idx) 1252{ 1253 uint8_t *endptr; 1254 uint8_t *ptr; 1255 usb_config_descr_t *cfgdscr; 1256 1257 if (dev->ud_cfgdescr == NULL) return NULL; 1258 1259 ptr = (uint8_t *) dev->ud_cfgdescr; 1260 endptr = ptr + GETUSBFIELD((dev->ud_cfgdescr),wTotalLength); 1261 1262 while (ptr < endptr) { 1263 1264 cfgdscr = (usb_config_descr_t *) ptr; 1265 1266 if (cfgdscr->bDescriptorType == dtype) { 1267 if (idx == 0) return (void *) ptr; 1268 else idx--; 1269 } 1270 1271 ptr += cfgdscr->bLength; 1272 1273 } 1274 1275 return NULL; 1276} 1277