Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 10cd715 in mainline


Ignore:
Timestamp:
2017-12-14T14:25:40Z (4 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master
Children:
bd05140
Parents:
6455d39
git-author:
Ondřej Hlavatý <aearsis@…> (2017-12-14 14:24:28)
git-committer:
Ondřej Hlavatý <aearsis@…> (2017-12-14 14:25:40)
Message:

usbhost bus: request_address → reserve_default_address

It doesn't make sense to expose requesting addresses other than the
default one from the bus.

Location:
uspace
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/xhci/bus.c

    r6455d39 r10cd715  
    209209
    210210err_address:
    211         bus_release_address(&bus->base, dev->address);
     211        // TODO: deaddress device
    212212        return err;
    213213}
     
    505505}
    506506
    507 static int request_address(bus_t *bus_base, usb_address_t *addr, bool strict, usb_speed_t speed)
    508 {
    509         assert(addr);
    510 
    511         if (*addr != USB_ADDRESS_DEFAULT)
    512                 /* xHCI does not allow software to assign addresses. */
    513                 return ENOTSUP;
    514 
    515         assert(strict);
    516 
     507static int reserve_default_address(bus_t *bus_base, usb_speed_t speed)
     508{
    517509        xhci_bus_t *xhci_bus = bus_to_xhci_bus(bus_base);
    518510
     
    525517}
    526518
    527 static int release_address(bus_t *bus_base, usb_address_t addr)
    528 {
    529         if (addr != USB_ADDRESS_DEFAULT)
    530                 return ENOTSUP;
    531 
     519static int release_default_address(bus_t *bus_base)
     520{
    532521        xhci_bus_t *xhci_bus = bus_to_xhci_bus(bus_base);
    533522
     
    562551        BIND_OP(find_endpoint)
    563552
    564         BIND_OP(request_address)
    565         BIND_OP(release_address)
     553        BIND_OP(reserve_default_address)
     554        BIND_OP(release_default_address)
     555
    566556        BIND_OP(reset_toggle)
    567 
    568557        BIND_OP(count_bw)
    569558
  • uspace/lib/usbhost/include/usb/host/bus.h

    r6455d39 r10cd715  
    9696        void (*endpoint_set_toggle)(endpoint_t *, bool);        /**< Optional */
    9797
    98         int (*request_address)(bus_t *, usb_address_t*, bool, usb_speed_t);
    99         int (*release_address)(bus_t *, usb_address_t);
     98        int (*reserve_default_address)(bus_t *, usb_speed_t);
     99        int (*release_default_address)(bus_t *);
    100100
    101101        int (*reset_toggle)(bus_t *, usb_target_t, toggle_reset_mode_t);
     
    137137size_t bus_count_bw(endpoint_t *, size_t);
    138138
    139 int bus_request_address(bus_t *, usb_address_t *, bool, usb_speed_t);
    140 int bus_release_address(bus_t *, usb_address_t);
    141 
    142 
    143 static inline int bus_reserve_default_address(bus_t *bus, usb_speed_t speed) {
    144         usb_address_t addr = USB_ADDRESS_DEFAULT;
    145 
    146         const int r = bus_request_address(bus, &addr, true, speed);
    147         assert(addr == USB_ADDRESS_DEFAULT);
    148         return r;
    149 }
    150 
    151 static inline int bus_release_default_address(bus_t *bus) {
    152         return bus_release_address(bus, USB_ADDRESS_DEFAULT);
    153 }
     139int bus_reserve_default_address(bus_t *, usb_speed_t);
     140int bus_release_default_address(bus_t *);
    154141
    155142int bus_reset_toggle(bus_t *, usb_target_t, bool);
  • uspace/lib/usbhost/src/bus.c

    r6455d39 r10cd715  
    199199}
    200200
    201 int bus_request_address(bus_t *bus, usb_address_t *hint, bool strict, usb_speed_t speed)
    202 {
    203         assert(bus);
    204 
    205         if (!bus->ops.request_address)
    206                 return ENOTSUP;
    207 
    208         fibril_mutex_lock(&bus->guard);
    209         const int r = bus->ops.request_address(bus, hint, strict, speed);
     201int bus_reserve_default_address(bus_t *bus, usb_speed_t speed)
     202{
     203        assert(bus);
     204
     205        if (!bus->ops.reserve_default_address)
     206                return ENOTSUP;
     207
     208        fibril_mutex_lock(&bus->guard);
     209        const int r = bus->ops.reserve_default_address(bus, speed);
    210210        fibril_mutex_unlock(&bus->guard);
    211211        return r;
    212212}
    213213
    214 int bus_release_address(bus_t *bus, usb_address_t address)
    215 {
    216         assert(bus);
    217 
    218         if (!bus->ops.release_address)
    219                 return ENOTSUP;
    220 
    221         fibril_mutex_lock(&bus->guard);
    222         const int r = bus->ops.release_address(bus, address);
     214int bus_release_default_address(bus_t *bus)
     215{
     216        assert(bus);
     217
     218        /* If this op is not set, allow everything */
     219        if (!bus->ops.release_default_address)
     220                return ENOTSUP;
     221
     222        fibril_mutex_lock(&bus->guard);
     223        const int r = bus->ops.release_default_address(bus);
    223224        fibril_mutex_unlock(&bus->guard);
    224225        return r;
  • uspace/lib/usbhost/src/ddf_helpers.c

    r6455d39 r10cd715  
    362362                const int ret = ddf_fun_unbind(victim->fun);
    363363                if (ret == EOK) {
    364                         usb_address_t address = victim->address;
    365364                        bus_remove_device(hcd->bus, hcd, victim);
    366365                        ddf_fun_destroy(victim->fun);
    367                         bus_release_address(hcd->bus, address);
    368366                } else {
    369367                        usb_log_warning("Failed to unbind device `%s': %s\n",
  • uspace/lib/usbhost/src/usb2_bus.c

    r6455d39 r10cd715  
    7676 * @return Error code.
    7777 */
    78 static int usb2_bus_get_speed(bus_t *bus_base, usb_address_t address, usb_speed_t *speed)
    79 {
    80         usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
    81 
    82         if (!usb_address_is_valid(address)) {
     78static int get_speed(usb2_bus_t *bus, usb_address_t address, usb_speed_t *speed)
     79{
     80        if (!usb_address_is_valid(address))
    8381                return EINVAL;
    84         }
     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
     92/** Get a free USB address
     93 *
     94 * @param[in] bus Device manager structure to use.
     95 * @return Free address, or error code.
     96 */
     97static int get_free_address(usb2_bus_t *bus, usb_address_t *addr)
     98{
     99        usb_address_t new_address = bus->last_address;
     100        do {
     101                new_address = (new_address + 1) % USB_ADDRESS_COUNT;
     102                if (new_address == USB_ADDRESS_DEFAULT)
     103                        new_address = 1;
     104                if (new_address == bus->last_address)
     105                        return ENOSPC;
     106        } while (bus->devices[new_address].occupied);
     107
     108        assert(new_address != USB_ADDRESS_DEFAULT);
     109        bus->last_address = new_address;
     110
     111        *addr = new_address;
     112        return EOK;
     113}
     114
     115/** Unregister and destroy all endpoints using given address.
     116 * @param bus usb_bus structure, non-null.
     117 * @param address USB address.
     118 * @param endpoint USB endpoint number.
     119 * @param direction Communication direction.
     120 * @return Error code.
     121 */
     122static int release_address(usb2_bus_t *bus, usb_address_t address)
     123{
     124        if (!usb_address_is_valid(address))
     125                return EINVAL;
    85126
    86127        const int ret = bus->devices[address].occupied ? EOK : ENOENT;
    87         if (speed && bus->devices[address].occupied) {
    88                 *speed = bus->devices[address].speed;
     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);
    89143        }
    90144
    91145        return ret;
     146}
     147
     148/** Request USB address.
     149 * @param bus usb_device_manager
     150 * @param addr Pointer to requested address value, place to store new address
     151 * @parma strict Fail if the requested address is not available.
     152 * @return Error code.
     153 * @note Default address is only available in strict mode.
     154 */
     155static int request_address(usb2_bus_t *bus, usb_address_t *addr, bool strict, usb_speed_t speed)
     156{
     157        int err;
     158
     159        assert(bus);
     160        assert(addr);
     161
     162        if (!usb_address_is_valid(*addr))
     163                return EINVAL;
     164
     165        /* Only grant default address to strict requests */
     166        if ((*addr == USB_ADDRESS_DEFAULT) && !strict) {
     167                if ((err = get_free_address(bus, addr)))
     168                        return err;
     169        }
     170        else if (bus->devices[*addr].occupied) {
     171                if (strict) {
     172                        return ENOENT;
     173                }
     174                if ((err = get_free_address(bus, addr)))
     175                        return err;
     176        }
     177
     178        assert(usb_address_is_valid(*addr));
     179        assert(bus->devices[*addr].occupied == false);
     180        assert(*addr != USB_ADDRESS_DEFAULT || strict);
     181
     182        bus->devices[*addr].occupied = true;
     183        bus->devices[*addr].speed = speed;
     184
     185        return EOK;
    92186}
    93187
     
    106200}};
    107201
    108 static int usb2_bus_address_device(bus_t *bus, hcd_t *hcd, device_t *dev)
     202static int address_device(usb2_bus_t *bus, hcd_t *hcd, device_t *dev)
    109203{
    110204        int err;
     
    115209        /** Reserve address early, we want pretty log messages */
    116210        usb_address_t address;
    117         if ((err = bus_request_address(bus, &address, false, dev->speed))) {
     211        if ((err = request_address(bus, &address, false, dev->speed))) {
    118212                usb_log_error("Failed to reserve new address: %s.",
    119213                    str_error(err));
     
    126220
    127221        endpoint_t *default_ep;
    128         err = bus_add_endpoint(bus, dev, &usb2_default_control_ep, &default_ep);
     222        err = bus_add_endpoint(&bus->base, dev, &usb2_default_control_ep, &default_ep);
    129223        if (err != EOK) {
    130224                usb_log_error("Device(%d): Failed to add default target: %s.",
     
    150244
    151245        /* We need to remove ep before we change the address */
    152         if ((err = bus_remove_endpoint(bus, default_ep))) {
     246        if ((err = bus_remove_endpoint(&bus->base, default_ep))) {
    153247                usb_log_error("Device(%d): Failed to unregister default target: %s", address, str_error(err));
    154248                goto err_address;
     
    168262        /* Register EP on the new address */
    169263        usb_log_debug("Device(%d): Registering control EP.", address);
    170         err = bus_add_endpoint(bus, dev, &control_ep, NULL);
     264        err = bus_add_endpoint(&bus->base, dev, &control_ep, NULL);
    171265        if (err != EOK) {
    172266                usb_log_error("Device(%d): Failed to register EP0: %s",
     
    178272
    179273err_default_control_ep:
    180         bus_remove_endpoint(bus, default_ep);
     274        bus_remove_endpoint(&bus->base, default_ep);
    181275        endpoint_del_ref(default_ep);
    182276err_address:
    183         bus_release_address(bus, address);
     277        release_address(bus, address);
    184278        return err;
    185279}
     
    187281/** Enumerate a new USB device
    188282 */
    189 static int usb2_bus_enumerate_device(bus_t *bus, hcd_t *hcd, device_t *dev)
     283static int usb2_bus_enumerate_device(bus_t *bus_base, hcd_t *hcd, device_t *dev)
    190284{
    191285        int err;
     286        usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
    192287
    193288        /* The speed of the new device was reported by the hub when reserving
    194289         * default address.
    195290         */
    196         if ((err = usb2_bus_get_speed(bus, USB_ADDRESS_DEFAULT, &dev->speed))) {
     291        if ((err = get_speed(bus, USB_ADDRESS_DEFAULT, &dev->speed))) {
    197292                usb_log_error("Failed to verify speed: %s.", str_error(err));
    198293                return err;
     
    211306
    212307        /* Assign an address to the device */
    213         if ((err = usb2_bus_address_device(bus, hcd, dev))) {
     308        if ((err = address_device(bus, hcd, dev))) {
    214309                usb_log_error("Failed to setup address of the new device: %s", str_error(err));
    215310                return err;
     
    219314        if ((err = hcd_ddf_device_explore(hcd, dev))) {
    220315                usb_log_error("Device(%d): Failed to explore device: %s", dev->address, str_error(err));
    221                 bus_release_address(bus, dev->address);
     316                release_address(bus, dev->address);
    222317                return err;
    223318        }
    224319
    225         return EOK;
    226 }
    227 
    228 /** Get a free USB address
    229  *
    230  * @param[in] bus Device manager structure to use.
    231  * @return Free address, or error code.
    232  */
    233 static int usb_bus_get_free_address(usb2_bus_t *bus, usb_address_t *addr)
    234 {
    235         usb_address_t new_address = bus->last_address;
    236         do {
    237                 new_address = (new_address + 1) % USB_ADDRESS_COUNT;
    238                 if (new_address == USB_ADDRESS_DEFAULT)
    239                         new_address = 1;
    240                 if (new_address == bus->last_address)
    241                         return ENOSPC;
    242         } while (bus->devices[new_address].occupied);
    243 
    244         assert(new_address != USB_ADDRESS_DEFAULT);
    245         bus->last_address = new_address;
    246 
    247         *addr = new_address;
    248320        return EOK;
    249321}
     
    367439}
    368440
    369 /** Unregister and destroy all endpoints using given address.
    370  * @param bus usb_bus structure, non-null.
    371  * @param address USB address.
    372  * @param endpoint USB endpoint number.
    373  * @param direction Communication direction.
    374  * @return Error code.
    375  */
    376 static int usb2_bus_release_address(bus_t *bus_base, usb_address_t address)
    377 {
    378         usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
    379 
    380         if (!usb_address_is_valid(address))
    381                 return EINVAL;
    382 
    383         const int ret = bus->devices[address].occupied ? EOK : ENOENT;
    384         bus->devices[address].occupied = false;
    385 
    386         list_t *list = get_list(bus, address);
    387         for (link_t *link = list_first(list); link != NULL; ) {
    388                 endpoint_t *ep = list_get_instance(link, endpoint_t, link);
    389                 link = list_next(link, list);
    390 
    391                 assert(ep->device->address == address);
    392                 list_remove(&ep->link);
    393 
    394                 usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n",
    395                     address, ep->endpoint, usb_str_direction(ep->direction));
    396 
    397                 /* Drop bus reference */
    398                 endpoint_del_ref(ep);
    399         }
    400 
    401         return ret;
    402 }
    403 
    404 /** Request USB address.
    405  * @param bus usb_device_manager
    406  * @param addr Pointer to requested address value, place to store new address
    407  * @parma strict Fail if the requested address is not available.
    408  * @return Error code.
    409  * @note Default address is only available in strict mode.
    410  */
    411 static int usb2_bus_request_address(bus_t *bus_base, usb_address_t *addr, bool strict, usb_speed_t speed)
    412 {
    413         int err;
    414 
    415         usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
    416         assert(addr);
    417 
    418         if (!usb_address_is_valid(*addr))
    419                 return EINVAL;
    420 
    421         /* Only grant default address to strict requests */
    422         if ((*addr == USB_ADDRESS_DEFAULT) && !strict) {
    423                 if ((err = usb_bus_get_free_address(bus, addr)))
    424                         return err;
    425         }
    426         else if (bus->devices[*addr].occupied) {
    427                 if (strict) {
    428                         return ENOENT;
    429                 }
    430                 if ((err = usb_bus_get_free_address(bus, addr)))
    431                         return err;
    432         }
    433 
    434         assert(usb_address_is_valid(*addr));
    435         assert(bus->devices[*addr].occupied == false);
    436         assert(*addr != USB_ADDRESS_DEFAULT || strict);
    437 
    438         bus->devices[*addr].occupied = true;
    439         bus->devices[*addr].speed = speed;
    440 
    441         return EOK;
     441static int usb2_bus_register_default_address(bus_t *bus_base, usb_speed_t speed)
     442{
     443        usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
     444        usb_address_t addr = USB_ADDRESS_DEFAULT;
     445        return request_address(bus, &addr, true, speed);
     446}
     447
     448static int usb2_bus_release_default_address(bus_t *bus_base)
     449{
     450        usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
     451        return release_address(bus, USB_ADDRESS_DEFAULT);
    442452}
    443453
    444454static const bus_ops_t usb2_bus_ops = {
     455        .reserve_default_address = usb2_bus_register_default_address,
     456        .release_default_address = usb2_bus_release_default_address,
    445457        .enumerate_device = usb2_bus_enumerate_device,
    446458        .create_endpoint = usb2_bus_create_ep,
     
    448460        .unregister_endpoint = usb2_bus_unregister_ep,
    449461        .register_endpoint = usb2_bus_register_ep,
    450         .request_address = usb2_bus_request_address,
    451         .release_address = usb2_bus_release_address,
    452462        .reset_toggle = usb2_bus_reset_toggle,
    453463};
Note: See TracChangeset for help on using the changeset viewer.