Changeset 231748a in mainline for uspace/lib/usb/src/devdrv.c


Ignore:
Timestamp:
2011-04-10T13:57:27Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
3f2af64
Parents:
4fa0a384
Message:

libusb: alternate interfaces in separate file

File:
1 edited

Legend:

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

    r4fa0a384 r231748a  
    120120        dev->pipes = pipes;
    121121        dev->pipes_count = pipes_count;
    122 
    123         return EOK;
    124 }
    125 
    126 /** Count number of alternate settings of a interface.
    127  *
    128  * @param config_descr Full configuration descriptor.
    129  * @param config_descr_size Size of @p config_descr in bytes.
    130  * @param interface_no Interface number.
    131  * @return Number of alternate interfaces for @p interface_no interface.
    132  */
    133 size_t usb_interface_count_alternates(uint8_t *config_descr,
    134     size_t config_descr_size, uint8_t interface_no)
    135 {
    136         assert(config_descr != NULL);
    137         assert(config_descr_size > 0);
    138 
    139         usb_dp_parser_t dp_parser = {
    140                 .nesting = usb_dp_standard_descriptor_nesting
    141         };
    142         usb_dp_parser_data_t dp_data = {
    143                 .data = config_descr,
    144                 .size = config_descr_size,
    145                 .arg = NULL
    146         };
    147 
    148         size_t alternate_count = 0;
    149 
    150         uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser,
    151             &dp_data, config_descr);
    152         while (iface_ptr != NULL) {
    153                 usb_standard_interface_descriptor_t *iface
    154                     = (usb_standard_interface_descriptor_t *) iface_ptr;
    155                 if (iface->descriptor_type == USB_DESCTYPE_INTERFACE) {
    156                         if (iface->interface_number == interface_no) {
    157                                 alternate_count++;
    158                         }
    159                 }
    160                 iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data,
    161                     config_descr, iface_ptr);
    162         }
    163 
    164         return alternate_count;
    165 }
    166 
    167 /** Initialize structures related to alternate interfaces.
    168  *
    169  * @param dev Device where alternate settings shall be initialized.
    170  * @return Error code.
    171  */
    172 static int initialize_alternate_interfaces(usb_device_t *dev)
    173 {
    174         if (dev->interface_no < 0) {
    175                 dev->alternate_interfaces = NULL;
    176                 return EOK;
    177         }
    178 
    179         usb_alternate_interfaces_t *alternates
    180             = malloc(sizeof(usb_alternate_interfaces_t));
    181 
    182         if (alternates == NULL) {
    183                 return ENOMEM;
    184         }
    185 
    186         alternates->alternative_count
    187             = usb_interface_count_alternates(dev->descriptors.configuration,
    188             dev->descriptors.configuration_size, dev->interface_no);
    189 
    190         if (alternates->alternative_count == 0) {
    191                 free(alternates);
    192                 return ENOENT;
    193         }
    194 
    195         alternates->alternatives = malloc(alternates->alternative_count
    196             * sizeof(usb_alternate_interface_descriptors_t));
    197         if (alternates->alternatives == NULL) {
    198                 free(alternates);
    199                 return ENOMEM;
    200         }
    201 
    202         alternates->current = 0;
    203 
    204         usb_dp_parser_t dp_parser = {
    205                 .nesting = usb_dp_standard_descriptor_nesting
    206         };
    207         usb_dp_parser_data_t dp_data = {
    208                 .data = dev->descriptors.configuration,
    209                 .size = dev->descriptors.configuration_size,
    210                 .arg = NULL
    211         };
    212 
    213         usb_alternate_interface_descriptors_t *cur_alt_iface
    214             = &alternates->alternatives[0];
    215 
    216         uint8_t *iface_ptr = usb_dp_get_nested_descriptor(&dp_parser,
    217             &dp_data, dp_data.data);
    218         while (iface_ptr != NULL) {
    219                 usb_standard_interface_descriptor_t *iface
    220                     = (usb_standard_interface_descriptor_t *) iface_ptr;
    221                 if ((iface->descriptor_type != USB_DESCTYPE_INTERFACE)
    222                     || (iface->interface_number != dev->interface_no)) {
    223                         iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser,
    224                             &dp_data,
    225                             dp_data.data, iface_ptr);
    226                         continue;
    227                 }
    228 
    229                 cur_alt_iface->interface = iface;
    230                 cur_alt_iface->nested_descriptors = iface_ptr + sizeof(*iface);
    231 
    232                 /* Find next interface to count size of nested descriptors. */
    233                 iface_ptr = usb_dp_get_sibling_descriptor(&dp_parser, &dp_data,
    234                     dp_data.data, iface_ptr);
    235                 if (iface_ptr == NULL) {
    236                         uint8_t *next = dp_data.data + dp_data.size;
    237                         cur_alt_iface->nested_descriptors_size
    238                             = next - cur_alt_iface->nested_descriptors;
    239                 } else {
    240                         cur_alt_iface->nested_descriptors_size
    241                             = iface_ptr - cur_alt_iface->nested_descriptors;
    242                 }
    243 
    244                 cur_alt_iface++;
    245         }
    246 
    247         dev->alternate_interfaces = alternates;
    248122
    249123        return EOK;
     
    628502        }
    629503
    630         rc = initialize_alternate_interfaces(dev);
     504        rc = usb_alternate_interfaces_create(dev->descriptors.configuration,
     505            dev->descriptors.configuration_size, dev->interface_no,
     506            &dev->alternate_interfaces);
    631507        if (rc != EOK) {
    632508                /* We will try to silently ignore this. */
Note: See TracChangeset for help on using the changeset viewer.