Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/src/dev.c

    r5debe97 rb49d872  
    3737#define MAX_DEVICE_PATH 1024
    3838
     39/** Find host controller handle, address and iface number for the device.
     40 *
     41 * @param[in] device_handle Device devman handle.
     42 * @param[out] hc_handle Where to store handle of host controller
     43 *      controlling device with @p device_handle handle.
     44 * @param[out] address Place to store the device's address
     45 * @param[out] iface Place to stoer the assigned USB interface number.
     46 * @return Error code.
     47 */
     48int usb_get_info_by_handle(devman_handle_t device_handle,
     49    devman_handle_t *hc_handle, usb_address_t *address, int *iface)
     50{
     51        async_sess_t *parent_sess =
     52            devman_parent_device_connect(EXCHANGE_ATOMIC, device_handle,
     53                IPC_FLAG_BLOCKING);
     54        if (!parent_sess)
     55                return ENOMEM;
     56
     57        async_exch_t *exch = async_exchange_begin(parent_sess);
     58        if (!exch) {
     59                async_hangup(parent_sess);
     60                return ENOMEM;
     61        }
     62
     63        usb_address_t tmp_address;
     64        devman_handle_t tmp_handle;
     65        int tmp_iface;
     66
     67        if (address) {
     68                const int ret = usb_get_my_address(exch, &tmp_address);
     69                if (ret != EOK) {
     70                        async_exchange_end(exch);
     71                        async_hangup(parent_sess);
     72                        return ret;
     73                }
     74        }
     75
     76        if (hc_handle) {
     77                const int ret = usb_get_hc_handle(exch, &tmp_handle);
     78                if (ret != EOK) {
     79                        async_exchange_end(exch);
     80                        async_hangup(parent_sess);
     81                        return ret;
     82                }
     83        }
     84
     85        if (iface) {
     86                const int ret = usb_get_my_interface(exch, &tmp_iface);
     87                switch (ret) {
     88                case ENOTSUP:
     89                        /* Implementing GET_MY_INTERFACE is voluntary. */
     90                        tmp_iface = -1;
     91                case EOK:
     92                        break;
     93                default:
     94                        async_exchange_end(exch);
     95                        async_hangup(parent_sess);
     96                        return ret;
     97                }
     98        }
     99
     100        if (hc_handle)
     101                *hc_handle = tmp_handle;
     102
     103        if (address)
     104                *address = tmp_address;
     105
     106        if (iface)
     107                *iface = tmp_iface;
     108
     109        async_exchange_end(exch);
     110        async_hangup(parent_sess);
     111
     112        return EOK;
     113}
     114
    39115static bool try_parse_bus_and_address(const char *path,
    40     char **func_start,
     116    const char **func_start,
    41117    devman_handle_t *out_hc_handle, usb_address_t *out_device_address)
    42118{
     
    44120        size_t address;
    45121        int rc;
    46         char *ptr;
     122        const char *ptr;
    47123
    48124        rc = str_uint64_t(path, &ptr, 10, false, &sid);
     
    99175 * @return Error code.
    100176 */
    101 int usb_resolve_device_handle(const char *dev_path, devman_handle_t *dev_handle)
     177int usb_resolve_device_handle(const char *dev_path, devman_handle_t *out_hc_handle,
     178    usb_address_t *out_dev_addr, devman_handle_t *out_dev_handle)
    102179{
    103         if (dev_path == NULL || dev_handle == NULL) {
     180        if (dev_path == NULL) {
    104181                return EBADMEM;
    105182        }
    106183
    107         devman_handle_t hc;
    108         usb_address_t addr = -1;
     184        bool found_hc = false;
     185        bool found_addr = false;
     186        devman_handle_t hc_handle, dev_handle;
     187        usb_address_t dev_addr = -1;
    109188        int rc;
    110         char *func_start = NULL;
     189        bool is_bus_addr;
     190        const char *func_start = NULL;
    111191        char *path = NULL;
    112192
    113193        /* First try the BUS.ADDR format. */
    114         if (try_parse_bus_and_address(dev_path, &func_start, &hc, &addr)) {
     194        is_bus_addr = try_parse_bus_and_address(dev_path, &func_start,
     195            &hc_handle, &dev_addr);
     196        if (is_bus_addr) {
     197                found_hc = true;
     198                found_addr = true;
    115199                /*
    116200                 * Now get the handle of the device. We will need that
     
    124208                 * Otherwise, we will
    125209                 */
    126 
    127                 rc = get_device_handle_by_address(hc, addr, dev_handle);
     210                rc = get_device_handle_by_address(hc_handle, dev_addr,
     211                    &dev_handle);
    128212                if (rc != EOK) {
    129213                        return rc;
     
    131215                if (str_length(func_start) > 0) {
    132216                        char tmp_path[MAX_DEVICE_PATH];
    133                         rc = devman_fun_get_path(*dev_handle,
     217                        rc = devman_fun_get_path(dev_handle,
    134218                            tmp_path, MAX_DEVICE_PATH);
    135219                        if (rc != EOK) {
     
    142226                } else {
    143227                        /* Everything is resolved. Get out of here. */
    144                         return EOK;
     228                        goto copy_out;
    145229                }
    146230        } else {
     
    152236
    153237        /* First try to get the device handle. */
    154         rc = devman_fun_get_handle(path, dev_handle, 0);
     238        rc = devman_fun_get_handle(path, &dev_handle, 0);
    155239        if (rc != EOK) {
    156240                free(path);
     
    169253                }
    170254
     255                /* Try to find its host controller. */
     256                if (!found_hc) {
     257                        rc = usb_get_hc_by_handle(tmp_handle, &hc_handle);
     258                        if (rc == EOK) {
     259                                found_hc = true;
     260                        }
     261                }
     262
     263                /* Try to get its address. */
     264                if (!found_addr) {
     265                        rc = usb_get_address_by_handle(tmp_handle, &dev_addr);
     266                        if (rc == 0) {
     267                                found_addr = true;
     268                        }
     269                }
     270
     271                /* Speed-up. */
     272                if (found_hc && found_addr) {
     273                        break;
     274                }
     275
    171276                /* Remove the last suffix. */
    172277                char *slash_pos = str_rchr(path, '/');
     
    178283        free(path);
    179284
     285        if (!found_addr || !found_hc) {
     286                return ENOENT;
     287        }
     288
     289copy_out:
     290        if (out_dev_addr != NULL) {
     291                *out_dev_addr = dev_addr;
     292        }
     293        if (out_hc_handle != NULL) {
     294                *out_hc_handle = hc_handle;
     295        }
     296        if (out_dev_handle != NULL) {
     297                *out_dev_handle = dev_handle;
     298        }
    180299
    181300        return EOK;
Note: See TracChangeset for help on using the changeset viewer.