Changeset 56257ba in mainline for uspace/lib/usbhost/src/usb2_bus.c


Ignore:
Timestamp:
2018-01-07T01:01:42Z (8 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
63431db2
Parents:
9efad54
git-author:
Ondřej Hlavatý <aearsis@…> (2018-01-07 01:01:41)
git-committer:
Ondřej Hlavatý <aearsis@…> (2018-01-07 01:01:42)
Message:

usbhost: manage endpoints by library + get/set_toggle → reset_toggle

That simplifies things A LOT. Now you can find endpoints for device in
an array inside device. This array is managed automatically in
register/unregister endpoint. HC drivers still needs to write to it when
setting up/tearing down the device.

Sorry for these two changes being in one commit, but splitting them
would be simply more work for no benefit.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbhost/src/usb2_bus.c

    r9efad54 r56257ba  
    5757}
    5858
    59 /** Get list that holds endpoints for given address.
    60  * @param bus usb2_bus structure, non-null.
    61  * @param addr USB address, must be >= 0.
    62  * @return Pointer to the appropriate list.
    63  */
    64 static list_t * get_list(usb2_bus_t *bus, usb_address_t addr)
    65 {
    66         assert(bus);
    67         assert(addr >= 0);
    68         return &bus->devices[addr % ARRAY_SIZE(bus->devices)].endpoint_list;
    69 }
    70 
    71 /** Get speed assigned to USB address.
    72  *
    73  * @param[in] bus Device manager structure to use.
    74  * @param[in] address Address the caller wants to find.
    75  * @param[out] speed Assigned speed.
    76  * @return Error code.
    77  */
    78 static int get_speed(usb2_bus_t *bus, usb_address_t address, usb_speed_t *speed)
    79 {
    80         if (!usb_address_is_valid(address))
    81                 return EINVAL;
    82 
    83         if (!bus->devices[address].occupied)
    84                 return ENOENT;
    85 
    86         if (speed)
    87                 *speed = bus->devices[address].speed;
    88 
    89         return EOK;
    90 }
    91 
    9259/** Get a free USB address
    9360 *
     
    10471                if (new_address == bus->last_address)
    10572                        return ENOSPC;
    106         } while (bus->devices[new_address].occupied);
     73        } while (bus->address_occupied[new_address]);
    10774
    10875        assert(new_address != USB_ADDRESS_DEFAULT);
     
    12592                return EINVAL;
    12693
    127         const int ret = bus->devices[address].occupied ? EOK : ENOENT;
    128         bus->devices[address].occupied = false;
    129 
    130         list_t *list = get_list(bus, address);
    131         for (link_t *link = list_first(list); link != NULL; ) {
    132                 endpoint_t *ep = list_get_instance(link, endpoint_t, link);
    133                 link = list_next(link, list);
    134 
    135                 assert(ep->device->address == address);
    136                 list_remove(&ep->link);
    137 
    138                 usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n",
    139                     address, ep->endpoint, usb_str_direction(ep->direction));
    140 
    141                 /* Drop bus reference */
    142                 endpoint_del_ref(ep);
    143         }
    144 
     94        const int ret = bus->address_occupied[address] ? EOK : ENOENT;
     95        bus->address_occupied[address] = false;
    14596        return ret;
    14697}
     
    153104 * @note Default address is only available in strict mode.
    154105 */
    155 static int request_address(usb2_bus_t *bus, usb_address_t *addr, bool strict, usb_speed_t speed)
     106static int request_address(usb2_bus_t *bus, usb_address_t *addr, bool strict)
    156107{
    157108        int err;
     
    168119                        return err;
    169120        }
    170         else if (bus->devices[*addr].occupied) {
     121        else if (bus->address_occupied[*addr]) {
    171122                if (strict) {
    172123                        return ENOENT;
     
    177128
    178129        assert(usb_address_is_valid(*addr));
    179         assert(bus->devices[*addr].occupied == false);
     130        assert(bus->address_occupied[*addr] == false);
    180131        assert(*addr != USB_ADDRESS_DEFAULT || strict);
    181132
    182         bus->devices[*addr].occupied = true;
    183         bus->devices[*addr].speed = speed;
     133        bus->address_occupied[*addr] = true;
    184134
    185135        return EOK;
     
    202152        /** Reserve address early, we want pretty log messages */
    203153        usb_address_t address = USB_ADDRESS_DEFAULT;
    204         if ((err = request_address(bus, &address, false, dev->speed))) {
     154        if ((err = request_address(bus, &address, false))) {
    205155                usb_log_error("Failed to reserve new address: %s.",
    206156                    str_error(err));
     
    281231         * default address.
    282232         */
    283         if ((err = get_speed(bus, USB_ADDRESS_DEFAULT, &dev->speed))) {
    284                 usb_log_error("Failed to verify speed: %s.", str_error(err));
    285                 return err;
    286         }
     233        dev->speed = bus->default_address_speed;
    287234        usb_log_debug("Found new %s speed USB device.", usb_str_speed(dev->speed));
    288235
     
    313260}
    314261
    315 /** Find endpoint.
    316  * @param bus usb_bus structure, non-null.
    317  * @param target Endpoint address.
    318  * @param direction Communication direction.
    319  * @return Pointer to endpoint_t structure representing given communication
    320  * target, NULL if there is no such endpoint registered.
    321  * @note Assumes that the internal mutex is locked.
    322  */
    323 static endpoint_t *usb2_bus_find_ep(device_t *device, usb_target_t target, usb_direction_t direction)
    324 {
    325         usb2_bus_t *bus = bus_to_usb2_bus(device->bus);
    326 
    327         assert(device->address == target.address);
    328 
    329         list_foreach(*get_list(bus, target.address), link, endpoint_t, ep) {
    330                 if (((direction == ep->direction)
    331                        || (ep->direction == USB_DIRECTION_BOTH)
    332                        || (direction == USB_DIRECTION_BOTH))
    333                     && (target.endpoint == ep->endpoint))
    334                         return ep;
    335         }
    336         return NULL;
    337 }
    338 
    339262static endpoint_t *usb2_bus_create_ep(device_t *dev, const usb_endpoint_descriptors_t *desc)
    340263{
     
    347270}
    348271
    349 static usb_target_t usb2_ep_to_target(endpoint_t *ep)
    350 {
    351         assert(ep);
    352         assert(ep->device);
    353 
    354         return (usb_target_t) {{
    355                 .address = ep->device->address,
    356                 .endpoint = ep->endpoint,
    357         }};
    358 }
    359 
    360272/** Register an endpoint to the bus. Reserves bandwidth.
    361273 * @param bus usb_bus structure, non-null.
     
    368280        assert(ep);
    369281
    370         /* Check for existence */
    371         if (usb2_bus_find_ep(ep->device, usb2_ep_to_target(ep), ep->direction))
    372                 return EEXIST;
    373 
    374282        /* Check for available bandwidth */
    375283        if (ep->bandwidth > bus->free_bw)
    376284                return ENOSPC;
    377285
    378         endpoint_add_ref(ep);
    379         list_append(&ep->link, get_list(bus, ep->device->address));
    380286        bus->free_bw -= ep->bandwidth;
    381287
     
    390296        assert(ep);
    391297
    392         list_remove(&ep->link);
    393 
    394298        bus->free_bw += ep->bandwidth;
    395         endpoint_del_ref(ep);
    396 
    397         return EOK;
    398 }
    399 
    400 static int usb2_bus_reset_toggle(bus_t *bus_base, usb_target_t target, toggle_reset_mode_t mode)
    401 {
    402         usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
    403 
    404         if (!usb_target_is_valid(target))
    405                 return EINVAL;
    406 
    407         if (mode == RESET_NONE)
    408                 return EOK;
    409 
    410         int ret = ENOENT;
    411 
    412         list_foreach(*get_list(bus, target.address), link, endpoint_t, ep) {
    413                 assert(ep->device->address == target.address);
    414 
    415                 if (mode == RESET_ALL || ep->endpoint == target.endpoint) {
    416                         endpoint_toggle_set(ep, 0);
    417                         ret = EOK;
    418                 }
    419         }
    420         return ret;
     299
     300        return EOK;
    421301}
    422302
     
    425305        usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
    426306        usb_address_t addr = USB_ADDRESS_DEFAULT;
    427         return request_address(bus, &addr, true, speed);
     307        const int err = request_address(bus, &addr, true);
     308        if (err)
     309                return err;
     310        bus->default_address_speed = speed;
     311        return EOK;
    428312}
    429313
     
    437321        .reserve_default_address = usb2_bus_register_default_address,
    438322        .release_default_address = usb2_bus_release_default_address,
    439         .reset_toggle = usb2_bus_reset_toggle,
    440323        .device_enumerate = usb2_bus_device_enumerate,
    441         .device_find_endpoint = usb2_bus_find_ep,
    442324        .endpoint_create = usb2_bus_create_ep,
    443325        .endpoint_register = usb2_bus_register_ep,
     
    460342
    461343        bus->free_bw = available_bandwidth;
    462         bus->last_address = 0;
    463         for (unsigned i = 0; i < ARRAY_SIZE(bus->devices); ++i) {
    464                 list_initialize(&bus->devices[i].endpoint_list);
    465                 bus->devices[i].speed = USB_SPEED_MAX;
    466                 bus->devices[i].occupied = false;
    467         }
     344
    468345        return EOK;
    469346}
Note: See TracChangeset for help on using the changeset viewer.