uboot/drivers/usb/gadget/core.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * (C) Copyright 2003
   4 * Gerry Hamel, geh@ti.com, Texas Instruments
   5 *
   6 * Based on
   7 * linux/drivers/usbd/usbd.c.c - USB Device Core Layer
   8 *
   9 * Copyright (c) 2000, 2001, 2002 Lineo
  10 * Copyright (c) 2001 Hewlett Packard
  11 *
  12 * By:
  13 *      Stuart Lynne <sl@lineo.com>,
  14 *      Tom Rushworth <tbr@lineo.com>,
  15 *      Bruce Balden <balden@lineo.com>
  16 */
  17
  18#include <log.h>
  19#include <malloc.h>
  20#include <serial.h>
  21#include <usbdevice.h>
  22
  23#define MAX_INTERFACES 2
  24
  25
  26int maxstrings = 20;
  27
  28/* Global variables ************************************************************************** */
  29
  30struct usb_string_descriptor **usb_strings;
  31
  32int usb_devices;
  33
  34extern struct usb_function_driver ep0_driver;
  35
  36int registered_functions;
  37int registered_devices;
  38
  39__maybe_unused static char *usbd_device_events[] = {
  40        "DEVICE_UNKNOWN",
  41        "DEVICE_INIT",
  42        "DEVICE_CREATE",
  43        "DEVICE_HUB_CONFIGURED",
  44        "DEVICE_RESET",
  45        "DEVICE_ADDRESS_ASSIGNED",
  46        "DEVICE_CONFIGURED",
  47        "DEVICE_SET_INTERFACE",
  48        "DEVICE_SET_FEATURE",
  49        "DEVICE_CLEAR_FEATURE",
  50        "DEVICE_DE_CONFIGURED",
  51        "DEVICE_BUS_INACTIVE",
  52        "DEVICE_BUS_ACTIVITY",
  53        "DEVICE_POWER_INTERRUPTION",
  54        "DEVICE_HUB_RESET",
  55        "DEVICE_DESTROY",
  56        "DEVICE_FUNCTION_PRIVATE",
  57};
  58
  59__maybe_unused static char *usbd_device_status[] = {
  60        "USBD_OPENING",
  61        "USBD_OK",
  62        "USBD_SUSPENDED",
  63        "USBD_CLOSING",
  64};
  65
  66#define USBD_DEVICE_STATUS(x) (((unsigned int)x <= USBD_CLOSING) ? usbd_device_status[x] : "UNKNOWN")
  67
  68
  69/* Descriptor support functions ************************************************************** */
  70
  71
  72/**
  73 * usbd_get_string - find and return a string descriptor
  74 * @index: string index to return
  75 *
  76 * Find an indexed string and return a pointer to a it.
  77 */
  78struct usb_string_descriptor *usbd_get_string (__u8 index)
  79{
  80        if (index >= maxstrings) {
  81                return NULL;
  82        }
  83        return usb_strings[index];
  84}
  85
  86
  87/* Access to device descriptor functions ***************************************************** */
  88
  89
  90/* *
  91 * usbd_device_configuration_instance - find a configuration instance for this device
  92 * @device:
  93 * @configuration: index to configuration, 0 - N-1
  94 *
  95 * Get specifed device configuration. Index should be bConfigurationValue-1.
  96 */
  97static struct usb_configuration_instance *usbd_device_configuration_instance (struct usb_device_instance *device,
  98                unsigned int port, unsigned int configuration)
  99{
 100        if (configuration >= device->configurations)
 101                return NULL;
 102
 103        return device->configuration_instance_array + configuration;
 104}
 105
 106
 107/* *
 108 * usbd_device_interface_instance
 109 * @device:
 110 * @configuration: index to configuration, 0 - N-1
 111 * @interface: index to interface
 112 *
 113 * Return the specified interface descriptor for the specified device.
 114 */
 115struct usb_interface_instance *usbd_device_interface_instance (struct usb_device_instance *device, int port, int configuration, int interface)
 116{
 117        struct usb_configuration_instance *configuration_instance;
 118
 119        if ((configuration_instance = usbd_device_configuration_instance (device, port, configuration)) == NULL) {
 120                return NULL;
 121        }
 122        if (interface >= configuration_instance->interfaces) {
 123                return NULL;
 124        }
 125        return configuration_instance->interface_instance_array + interface;
 126}
 127
 128/* *
 129 * usbd_device_alternate_descriptor_list
 130 * @device:
 131 * @configuration: index to configuration, 0 - N-1
 132 * @interface: index to interface
 133 * @alternate: alternate setting
 134 *
 135 * Return the specified alternate descriptor for the specified device.
 136 */
 137struct usb_alternate_instance *usbd_device_alternate_instance (struct usb_device_instance *device, int port, int configuration, int interface, int alternate)
 138{
 139        struct usb_interface_instance *interface_instance;
 140
 141        if ((interface_instance = usbd_device_interface_instance (device, port, configuration, interface)) == NULL) {
 142                return NULL;
 143        }
 144
 145        if (alternate >= interface_instance->alternates) {
 146                return NULL;
 147        }
 148
 149        return interface_instance->alternates_instance_array + alternate;
 150}
 151
 152
 153/* *
 154 * usbd_device_device_descriptor
 155 * @device: which device
 156 * @configuration: index to configuration, 0 - N-1
 157 * @port: which port
 158 *
 159 * Return the specified configuration descriptor for the specified device.
 160 */
 161struct usb_device_descriptor *usbd_device_device_descriptor (struct usb_device_instance *device, int port)
 162{
 163        return (device->device_descriptor);
 164}
 165
 166/**
 167 * usbd_device_configuration_descriptor
 168 * @device: which device
 169 * @port: which port
 170 * @configuration: index to configuration, 0 - N-1
 171 *
 172 * Return the specified configuration descriptor for the specified device.
 173 */
 174struct usb_configuration_descriptor *usbd_device_configuration_descriptor (struct
 175                                                                           usb_device_instance
 176                                                                           *device, int port, int configuration)
 177{
 178        struct usb_configuration_instance *configuration_instance;
 179        if (!(configuration_instance = usbd_device_configuration_instance (device, port, configuration))) {
 180                return NULL;
 181        }
 182        return (configuration_instance->configuration_descriptor);
 183}
 184
 185
 186/**
 187 * usbd_device_interface_descriptor
 188 * @device: which device
 189 * @port: which port
 190 * @configuration: index to configuration, 0 - N-1
 191 * @interface: index to interface
 192 * @alternate: alternate setting
 193 *
 194 * Return the specified interface descriptor for the specified device.
 195 */
 196struct usb_interface_descriptor *usbd_device_interface_descriptor (struct usb_device_instance
 197                                                                   *device, int port, int configuration, int interface, int alternate)
 198{
 199        struct usb_interface_instance *interface_instance;
 200        if (!(interface_instance = usbd_device_interface_instance (device, port, configuration, interface))) {
 201                return NULL;
 202        }
 203        if ((alternate < 0) || (alternate >= interface_instance->alternates)) {
 204                return NULL;
 205        }
 206        return (interface_instance->alternates_instance_array[alternate].interface_descriptor);
 207}
 208
 209/**
 210 * usbd_device_endpoint_descriptor_index
 211 * @device: which device
 212 * @port: which port
 213 * @configuration: index to configuration, 0 - N-1
 214 * @interface: index to interface
 215 * @alternate: index setting
 216 * @index: which index
 217 *
 218 * Return the specified endpoint descriptor for the specified device.
 219 */
 220struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor_index (struct usb_device_instance
 221                                                                       *device, int port, int configuration, int interface, int alternate, int index)
 222{
 223        struct usb_alternate_instance *alternate_instance;
 224
 225        if (!(alternate_instance = usbd_device_alternate_instance (device, port, configuration, interface, alternate))) {
 226                return NULL;
 227        }
 228        if (index >= alternate_instance->endpoints) {
 229                return NULL;
 230        }
 231        return *(alternate_instance->endpoints_descriptor_array + index);
 232}
 233
 234
 235/**
 236 * usbd_device_endpoint_transfersize
 237 * @device: which device
 238 * @port: which port
 239 * @configuration: index to configuration, 0 - N-1
 240 * @interface: index to interface
 241 * @index: which index
 242 *
 243 * Return the specified endpoint transfer size;
 244 */
 245int usbd_device_endpoint_transfersize (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int index)
 246{
 247        struct usb_alternate_instance *alternate_instance;
 248
 249        if (!(alternate_instance = usbd_device_alternate_instance (device, port, configuration, interface, alternate))) {
 250                return 0;
 251        }
 252        if (index >= alternate_instance->endpoints) {
 253                return 0;
 254        }
 255        return *(alternate_instance->endpoint_transfersize_array + index);
 256}
 257
 258
 259/**
 260 * usbd_device_endpoint_descriptor
 261 * @device: which device
 262 * @port: which port
 263 * @configuration: index to configuration, 0 - N-1
 264 * @interface: index to interface
 265 * @alternate: alternate setting
 266 * @endpoint: which endpoint
 267 *
 268 * Return the specified endpoint descriptor for the specified device.
 269 */
 270struct usb_endpoint_descriptor *usbd_device_endpoint_descriptor (struct usb_device_instance *device, int port, int configuration, int interface, int alternate, int endpoint)
 271{
 272        struct usb_endpoint_descriptor *endpoint_descriptor;
 273        int i;
 274
 275        for (i = 0; !(endpoint_descriptor = usbd_device_endpoint_descriptor_index (device, port, configuration, interface, alternate, i)); i++) {
 276                if (endpoint_descriptor->bEndpointAddress == endpoint) {
 277                        return endpoint_descriptor;
 278                }
 279        }
 280        return NULL;
 281}
 282
 283/**
 284 * usbd_endpoint_halted
 285 * @device: point to struct usb_device_instance
 286 * @endpoint: endpoint to check
 287 *
 288 * Return non-zero if endpoint is halted.
 289 */
 290int usbd_endpoint_halted (struct usb_device_instance *device, int endpoint)
 291{
 292        return (device->status == USB_STATUS_HALT);
 293}
 294
 295
 296/**
 297 * usbd_rcv_complete - complete a receive
 298 * @endpoint:
 299 * @len:
 300 * @urb_bad:
 301 *
 302 * Called from rcv interrupt to complete.
 303 */
 304void usbd_rcv_complete(struct usb_endpoint_instance *endpoint, int len, int urb_bad)
 305{
 306        if (endpoint) {
 307                struct urb *rcv_urb;
 308
 309                /*usbdbg("len: %d urb: %p\n", len, endpoint->rcv_urb); */
 310
 311                /* if we had an urb then update actual_length, dispatch if neccessary */
 312                if ((rcv_urb = endpoint->rcv_urb)) {
 313
 314                        /*usbdbg("actual: %d buffer: %d\n", */
 315                        /*rcv_urb->actual_length, rcv_urb->buffer_length); */
 316
 317                        /* check the urb is ok, are we adding data less than the packetsize */
 318                        if (!urb_bad && (len <= endpoint->rcv_packetSize)) {
 319                          /*usbdbg("updating actual_length by %d\n",len); */
 320
 321                                /* increment the received data size */
 322                                rcv_urb->actual_length += len;
 323
 324                        } else {
 325                                usberr(" RECV_ERROR actual: %d buffer: %d urb_bad: %d\n",
 326                                       rcv_urb->actual_length, rcv_urb->buffer_length, urb_bad);
 327
 328                                rcv_urb->actual_length = 0;
 329                                rcv_urb->status = RECV_ERROR;
 330                        }
 331                } else {
 332                        usberr("no rcv_urb!");
 333                }
 334        } else {
 335                usberr("no endpoint!");
 336        }
 337
 338}
 339
 340/**
 341 * usbd_tx_complete - complete a transmit
 342 * @endpoint:
 343 * @resetart:
 344 *
 345 * Called from tx interrupt to complete.
 346 */
 347void usbd_tx_complete (struct usb_endpoint_instance *endpoint)
 348{
 349        if (endpoint) {
 350                struct urb *tx_urb;
 351
 352                /* if we have a tx_urb advance or reset, finish if complete */
 353                if ((tx_urb = endpoint->tx_urb)) {
 354                        int sent = endpoint->last;
 355                        endpoint->sent += sent;
 356                        endpoint->last -= sent;
 357
 358                        if( (endpoint->tx_urb->actual_length - endpoint->sent) <= 0 ) {
 359                                tx_urb->actual_length = 0;
 360                                endpoint->sent = 0;
 361                                endpoint->last = 0;
 362
 363                                /* Remove from active, save for re-use */
 364                                urb_detach(tx_urb);
 365                                urb_append(&endpoint->done, tx_urb);
 366                                /*usbdbg("done->next %p, tx_urb %p, done %p", */
 367                                /*       endpoint->done.next, tx_urb, &endpoint->done); */
 368
 369                                endpoint->tx_urb = first_urb_detached(&endpoint->tx);
 370                                if( endpoint->tx_urb ) {
 371                                        endpoint->tx_queue--;
 372                                        usbdbg("got urb from tx list");
 373                                }
 374                                if( !endpoint->tx_urb ) {
 375                                        /*usbdbg("taking urb from done list"); */
 376                                        endpoint->tx_urb = first_urb_detached(&endpoint->done);
 377                                }
 378                                if( !endpoint->tx_urb ) {
 379                                        usbdbg("allocating new urb for tx_urb");
 380                                        endpoint->tx_urb = usbd_alloc_urb(tx_urb->device, endpoint);
 381                                }
 382                        }
 383                }
 384        }
 385}
 386
 387/* URB linked list functions ***************************************************** */
 388
 389/*
 390 * Initialize an urb_link to be a single element list.
 391 * If the urb_link is being used as a distinguished list head
 392 * the list is empty when the head is the only link in the list.
 393 */
 394void urb_link_init (urb_link * ul)
 395{
 396        if (ul) {
 397                ul->prev = ul->next = ul;
 398        }
 399}
 400
 401/*
 402 * Detach an urb_link from a list, and set it
 403 * up as a single element list, so no dangling
 404 * pointers can be followed, and so it can be
 405 * joined to another list if so desired.
 406 */
 407void urb_detach (struct urb *urb)
 408{
 409        if (urb) {
 410                urb_link *ul = &urb->link;
 411                ul->next->prev = ul->prev;
 412                ul->prev->next = ul->next;
 413                urb_link_init (ul);
 414        }
 415}
 416
 417/*
 418 * Return the first urb_link in a list with a distinguished
 419 * head "hd", or NULL if the list is empty.  This will also
 420 * work as a predicate, returning NULL if empty, and non-NULL
 421 * otherwise.
 422 */
 423urb_link *first_urb_link (urb_link * hd)
 424{
 425        urb_link *nx;
 426        if (NULL != hd && NULL != (nx = hd->next) && nx != hd) {
 427                /* There is at least one element in the list */
 428                /* (besides the distinguished head). */
 429                return (nx);
 430        }
 431        /* The list is empty */
 432        return (NULL);
 433}
 434
 435/*
 436 * Return the first urb in a list with a distinguished
 437 * head "hd", or NULL if the list is empty.
 438 */
 439struct urb *first_urb (urb_link * hd)
 440{
 441        urb_link *nx;
 442        if (NULL == (nx = first_urb_link (hd))) {
 443                /* The list is empty */
 444                return (NULL);
 445        }
 446        return (p2surround (struct urb, link, nx));
 447}
 448
 449/*
 450 * Detach and return the first urb in a list with a distinguished
 451 * head "hd", or NULL if the list is empty.
 452 *
 453 */
 454struct urb *first_urb_detached (urb_link * hd)
 455{
 456        struct urb *urb;
 457        if ((urb = first_urb (hd))) {
 458                urb_detach (urb);
 459        }
 460        return urb;
 461}
 462
 463
 464/*
 465 * Append an urb_link (or a whole list of
 466 * urb_links) to the tail of another list
 467 * of urb_links.
 468 */
 469void urb_append (urb_link * hd, struct urb *urb)
 470{
 471        if (hd && urb) {
 472                urb_link *new = &urb->link;
 473
 474                /* This allows the new urb to be a list of urbs, */
 475                /* with new pointing at the first, but the link */
 476                /* must be initialized. */
 477                /* Order is important here... */
 478                urb_link *pul = hd->prev;
 479                new->prev->next = hd;
 480                hd->prev = new->prev;
 481                new->prev = pul;
 482                pul->next = new;
 483        }
 484}
 485
 486/* URB create/destroy functions ***************************************************** */
 487
 488/**
 489 * usbd_alloc_urb - allocate an URB appropriate for specified endpoint
 490 * @device: device instance
 491 * @endpoint: endpoint
 492 *
 493 * Allocate an urb structure. The usb device urb structure is used to
 494 * contain all data associated with a transfer, including a setup packet for
 495 * control transfers.
 496 *
 497 * NOTE: endpoint_address MUST contain a direction flag.
 498 */
 499struct urb *usbd_alloc_urb (struct usb_device_instance *device,
 500                            struct usb_endpoint_instance *endpoint)
 501{
 502        struct urb *urb;
 503
 504        if (!(urb = (struct urb *) malloc (sizeof (struct urb)))) {
 505                usberr (" F A T A L:  malloc(%zu) FAILED!!!!",
 506                        sizeof (struct urb));
 507                return NULL;
 508        }
 509
 510        /* Fill in known fields */
 511        memset (urb, 0, sizeof (struct urb));
 512        urb->endpoint = endpoint;
 513        urb->device = device;
 514        urb->buffer = (u8 *) urb->buffer_data;
 515        urb->buffer_length = sizeof (urb->buffer_data);
 516
 517        urb_link_init (&urb->link);
 518
 519        return urb;
 520}
 521
 522/**
 523 * usbd_dealloc_urb - deallocate an URB and associated buffer
 524 * @urb: pointer to an urb structure
 525 *
 526 * Deallocate an urb structure and associated data.
 527 */
 528void usbd_dealloc_urb (struct urb *urb)
 529{
 530        if (urb) {
 531                free (urb);
 532        }
 533}
 534
 535/* Event signaling functions ***************************************************** */
 536
 537/**
 538 * usbd_device_event - called to respond to various usb events
 539 * @device: pointer to struct device
 540 * @event: event to respond to
 541 *
 542 * Used by a Bus driver to indicate an event.
 543 */
 544void usbd_device_event_irq (struct usb_device_instance *device, usb_device_event_t event, int data)
 545{
 546        usb_device_state_t state;
 547
 548        if (!device || !device->bus) {
 549                usberr("(%p,%d) NULL device or device->bus", device, event);
 550                return;
 551        }
 552
 553        state = device->device_state;
 554
 555        usbinfo("%s", usbd_device_events[event]);
 556
 557        switch (event) {
 558        case DEVICE_UNKNOWN:
 559                break;
 560        case DEVICE_INIT:
 561                device->device_state = STATE_INIT;
 562                break;
 563
 564        case DEVICE_CREATE:
 565                device->device_state = STATE_ATTACHED;
 566                break;
 567
 568        case DEVICE_HUB_CONFIGURED:
 569                device->device_state = STATE_POWERED;
 570                break;
 571
 572        case DEVICE_RESET:
 573                device->device_state = STATE_DEFAULT;
 574                device->address = 0;
 575                break;
 576
 577        case DEVICE_ADDRESS_ASSIGNED:
 578                device->device_state = STATE_ADDRESSED;
 579                break;
 580
 581        case DEVICE_CONFIGURED:
 582                device->device_state = STATE_CONFIGURED;
 583                break;
 584
 585        case DEVICE_DE_CONFIGURED:
 586                device->device_state = STATE_ADDRESSED;
 587                break;
 588
 589        case DEVICE_BUS_INACTIVE:
 590                if (device->status != USBD_CLOSING) {
 591                        device->status = USBD_SUSPENDED;
 592                }
 593                break;
 594        case DEVICE_BUS_ACTIVITY:
 595                if (device->status != USBD_CLOSING) {
 596                        device->status = USBD_OK;
 597                }
 598                break;
 599
 600        case DEVICE_SET_INTERFACE:
 601                break;
 602        case DEVICE_SET_FEATURE:
 603                break;
 604        case DEVICE_CLEAR_FEATURE:
 605                break;
 606
 607        case DEVICE_POWER_INTERRUPTION:
 608                device->device_state = STATE_POWERED;
 609                break;
 610        case DEVICE_HUB_RESET:
 611                device->device_state = STATE_ATTACHED;
 612                break;
 613        case DEVICE_DESTROY:
 614                device->device_state = STATE_UNKNOWN;
 615                break;
 616
 617        case DEVICE_FUNCTION_PRIVATE:
 618                break;
 619
 620        default:
 621                usbdbg("event %d - not handled",event);
 622                break;
 623        }
 624        debug("%s event: %d oldstate: %d newstate: %d status: %d address: %d",
 625                device->name, event, state,
 626                device->device_state, device->status, device->address);
 627
 628        /* tell the bus interface driver */
 629        if( device->event ) {
 630                /* usbdbg("calling device->event"); */
 631                device->event(device, event, data);
 632        }
 633}
 634