Ignore:
File:
1 edited

Legend:

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

    r692c0d3e ra66225f3  
    3333 * @brief Functions for recognising kind of attached devices.
    3434 */
    35 #include <usb_iface.h>
    3635#include <usb/usbdrv.h>
    3736#include <usb/classes/classes.h>
     
    3938#include <errno.h>
    4039
    41 static 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 
    61 static usb_iface_t usb_iface = {
    62         .get_hc_handle = usb_iface_get_hc_handle
    63 };
    64 
    65 static device_ops_t child_ops = {
    66         .interfaces[USB_DEV_IFACE] = &usb_iface
    67 };
    6840
    6941#define BCD_INT(a) (((unsigned int)(a)) / 256)
     
    12799       
    128100        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  */
    137 int 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  */
    191 int 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;
    228101}
    229102
     
    268141                        continue;
    269142                }
    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                
     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                }
    279175        }
    280176       
     
    296192{
    297193        int rc;
    298        
    299         /*
    300          * Retrieve device descriptor and add matches from it.
    301          */
    302194        usb_standard_device_descriptor_t device_descriptor;
    303195
     
    307199                return rc;
    308200        }
    309        
    310         rc = usb_drv_create_match_ids_from_device_descriptor(matches,
    311             &device_descriptor);
    312         if (rc != EOK) {
    313                 return rc;
    314         }
    315        
     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        }
    316238        /*
    317239         * Go through all configurations and add matches
     
    363285                goto failure;
    364286        }
    365         child->parent = parent;
    366287        child->name = child_name;
    367         child->ops = &child_ops;
    368288       
    369289        rc = usb_drv_create_device_match_ids(hc, &child->match_ids, address);
Note: See TracChangeset for help on using the changeset viewer.