Ignore:
File:
1 edited

Legend:

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

    ra66225f3 r692c0d3e  
    3333 * @brief Functions for recognising kind of attached devices.
    3434 */
     35#include <usb_iface.h>
    3536#include <usb/usbdrv.h>
    3637#include <usb/classes/classes.h>
     
    3839#include <errno.h>
    3940
     41static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
     42{
     43        assert(dev);
     44        assert(dev->parent != NULL);
     45
     46        device_t *parent = dev->parent;
     47
     48        if (parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) {
     49                usb_iface_t *usb_iface
     50                    = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE];
     51                assert(usb_iface != NULL);
     52                if (usb_iface->get_hc_handle) {
     53                        int rc = usb_iface->get_hc_handle(parent, handle);
     54                        return rc;
     55                }
     56        }
     57
     58        return ENOTSUP;
     59}
     60
     61static usb_iface_t usb_iface = {
     62        .get_hc_handle = usb_iface_get_hc_handle
     63};
     64
     65static device_ops_t child_ops = {
     66        .interfaces[USB_DEV_IFACE] = &usb_iface
     67};
    4068
    4169#define BCD_INT(a) (((unsigned int)(a)) / 256)
     
    99127       
    100128        return rc;
     129}
     130
     131/** Create DDF match ids from USB device descriptor.
     132 *
     133 * @param matches List of match ids to extend.
     134 * @param device_descriptor Device descriptor returned by given device.
     135 * @return Error code.
     136 */
     137int usb_drv_create_match_ids_from_device_descriptor(
     138    match_id_list_t *matches,
     139    const usb_standard_device_descriptor_t *device_descriptor)
     140{
     141        int rc;
     142       
     143        /*
     144         * Unless the vendor id is 0, the pair idVendor-idProduct
     145         * quite uniquely describes the device.
     146         */
     147        if (device_descriptor->vendor_id != 0) {
     148                /* First, with release number. */
     149                rc = usb_add_match_id(matches, 100,
     150                    "usb&vendor=%d&product=%d&release=" BCD_FMT,
     151                    (int) device_descriptor->vendor_id,
     152                    (int) device_descriptor->product_id,
     153                    BCD_ARGS(device_descriptor->device_version));
     154                if (rc != EOK) {
     155                        return rc;
     156                }
     157               
     158                /* Next, without release number. */
     159                rc = usb_add_match_id(matches, 90, "usb&vendor=%d&product=%d",
     160                    (int) device_descriptor->vendor_id,
     161                    (int) device_descriptor->product_id);
     162                if (rc != EOK) {
     163                        return rc;
     164                }
     165        }       
     166
     167        /*
     168         * If the device class points to interface we skip adding
     169         * class directly.
     170         */
     171        if (device_descriptor->device_class != USB_CLASS_USE_INTERFACE) {
     172                rc = usb_add_match_id(matches, 50, "usb&class=%s",
     173                    usb_str_class(device_descriptor->device_class));
     174                if (rc != EOK) {
     175                        return rc;
     176                }
     177        }
     178       
     179        return EOK;
     180}
     181
     182/** Create DDF match ids from USB configuration descriptor.
     183 * The configuration descriptor is expected to be in the complete form,
     184 * i.e. including interface, endpoint etc. descriptors.
     185 *
     186 * @param matches List of match ids to extend.
     187 * @param config_descriptor Configuration descriptor returned by given device.
     188 * @param total_size Size of the @p config_descriptor.
     189 * @return Error code.
     190 */
     191int usb_drv_create_match_ids_from_configuration_descriptor(
     192    match_id_list_t *matches,
     193    const void *config_descriptor, size_t total_size)
     194{
     195        /*
     196         * Iterate through config descriptor to find the interface
     197         * descriptors.
     198         */
     199        size_t position = sizeof(usb_standard_configuration_descriptor_t);
     200        while (position + 1 < total_size) {
     201                uint8_t *current_descriptor
     202                    = ((uint8_t *) config_descriptor) + position;
     203                uint8_t cur_descr_len = current_descriptor[0];
     204                uint8_t cur_descr_type = current_descriptor[1];
     205               
     206                position += cur_descr_len;
     207               
     208                if (cur_descr_type != USB_DESCTYPE_INTERFACE) {
     209                        continue;
     210                }
     211               
     212                /*
     213                 * Finally, we found an interface descriptor.
     214                 */
     215                usb_standard_interface_descriptor_t *interface
     216                    = (usb_standard_interface_descriptor_t *)
     217                    current_descriptor;
     218               
     219                int rc = usb_add_match_id(matches, 50,
     220                    "usb&interface&class=%s",
     221                    usb_str_class(interface->interface_class));
     222                if (rc != EOK) {
     223                        return rc;
     224                }
     225        }
     226       
     227        return EOK;
    101228}
    102229
     
    141268                        continue;
    142269                }
    143 
    144                 /*
    145                  * Iterate through config descriptor to find the interface
    146                  * descriptors.
    147                  */
    148                 size_t position = sizeof(config_descriptor);
    149                 while (position + 1 < full_config_descriptor_size) {
    150                         uint8_t *current_descriptor
    151                             = ((uint8_t *) full_config_descriptor) + position;
    152                         uint8_t cur_descr_len = current_descriptor[0];
    153                         uint8_t cur_descr_type = current_descriptor[1];
    154                        
    155                         position += cur_descr_len;
    156                        
    157                         if (cur_descr_type != USB_DESCTYPE_INTERFACE) {
    158                                 continue;
    159                         }
    160                         /*
    161                          * Finally, we found an interface descriptor.
    162                          */
    163                         usb_standard_interface_descriptor_t *interface
    164                             = (usb_standard_interface_descriptor_t *)
    165                             current_descriptor;
    166                        
    167                         rc = usb_add_match_id(matches, 50,
    168                             "usb&interface&class=%s",
    169                             usb_str_class(interface->interface_class));
    170                         if (rc != EOK) {
    171                                 final_rc = rc;
    172                                 break;
    173                         }
    174                 }
     270               
     271                rc = usb_drv_create_match_ids_from_configuration_descriptor(
     272                    matches,
     273                    full_config_descriptor, full_config_descriptor_size);
     274                if (rc != EOK) {
     275                        final_rc = rc;
     276                        continue;
     277                }
     278               
    175279        }
    176280       
     
    192296{
    193297        int rc;
     298       
     299        /*
     300         * Retrieve device descriptor and add matches from it.
     301         */
    194302        usb_standard_device_descriptor_t device_descriptor;
    195303
     
    199307                return rc;
    200308        }
    201 
    202         /*
    203          * Unless the vendor id is 0, the pair idVendor-idProduct
    204          * quite uniquely describes the device.
    205          */
    206         if (device_descriptor.vendor_id != 0) {
    207                 /* First, with release number. */
    208                 rc = usb_add_match_id(matches, 100,
    209                     "usb&vendor=%d&product=%d&release=" BCD_FMT,
    210                     (int) device_descriptor.vendor_id,
    211                     (int) device_descriptor.product_id,
    212                     BCD_ARGS(device_descriptor.device_version));
    213                 if (rc != EOK) {
    214                         return rc;
    215                 }
    216                
    217                 /* Next, without release number. */
    218                 rc = usb_add_match_id(matches, 90, "usb&vendor=%d&product=%d",
    219                     (int) device_descriptor.vendor_id,
    220                     (int) device_descriptor.product_id);
    221                 if (rc != EOK) {
    222                         return rc;
    223                 }
    224 
    225         }       
    226 
    227         /*
    228          * If the device class points to interface we skip adding
    229          * class directly.
    230          */
    231         if (device_descriptor.device_class != USB_CLASS_USE_INTERFACE) {
    232                 rc = usb_add_match_id(matches, 50, "usb&class=%s",
    233                     usb_str_class(device_descriptor.device_class));
    234                 if (rc != EOK) {
    235                         return rc;
    236                 }
    237         }
     309       
     310        rc = usb_drv_create_match_ids_from_device_descriptor(matches,
     311            &device_descriptor);
     312        if (rc != EOK) {
     313                return rc;
     314        }
     315       
    238316        /*
    239317         * Go through all configurations and add matches
     
    285363                goto failure;
    286364        }
     365        child->parent = parent;
    287366        child->name = child_name;
     367        child->ops = &child_ops;
    288368       
    289369        rc = usb_drv_create_device_match_ids(hc, &child->match_ids, address);
Note: See TracChangeset for help on using the changeset viewer.