Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/usbmid/explore.c

    recb107b rfcafa04  
    4848};
    4949
    50 /** Tell whether given interface is already in the list.
    51  *
    52  * @param list List of usbmid_interface_t members to be searched.
    53  * @param interface_no Interface number caller is looking for.
    54  * @return Interface @p interface_no is already present in the list.
    55  */
    56 static bool interface_in_list(link_t *list, int interface_no)
     50/** Find starting indexes of all interface descriptors in a configuration.
     51 *
     52 * @param config_descriptor Full configuration descriptor.
     53 * @param config_descriptor_size Size of @p config_descriptor in bytes.
     54 * @param interface_positions Array where to store indexes of interfaces.
     55 * @param interface_count Size of @p interface_positions array.
     56 * @return Number of found interfaces.
     57 * @retval (size_t)-1 Error occured.
     58 */
     59static size_t find_interface_descriptors(uint8_t *config_descriptor,
     60    size_t config_descriptor_size,
     61    size_t *interface_positions, size_t interface_count)
    5762{
    58         link_t *l;
    59         for (l = list->next; l != list; l = l->next) {
    60                 usbmid_interface_t *iface
    61                     = list_get_instance(l, usbmid_interface_t, link);
    62                 if (iface->interface_no == interface_no) {
    63                         return true;
    64                 }
    65         }
    66 
    67         return false;
    68 }
    69 
    70 /** Create list of interfaces from configuration descriptor.
    71  *
    72  * @param config_descriptor Configuration descriptor.
    73  * @param config_descriptor_size Size of configuration descriptor in bytes.
    74  * @param list List where to add the interfaces.
    75  */
    76 static void create_interfaces(uint8_t *config_descriptor,
    77     size_t config_descriptor_size, link_t *list)
    78 {
     63        if (interface_count == 0) {
     64                return (size_t) -1;
     65        }
     66
    7967        usb_dp_parser_data_t data = {
    8068                .data = config_descriptor,
     
    8775        };
    8876
    89         uint8_t *interface_ptr = usb_dp_get_nested_descriptor(&parser, &data,
     77        uint8_t *interface = usb_dp_get_nested_descriptor(&parser, &data,
    9078            data.data);
    91         if (interface_ptr == NULL) {
    92                 return;
    93         }
    94 
    95         do {
    96                 if (interface_ptr[1] != USB_DESCTYPE_INTERFACE) {
    97                         goto next_descriptor;
     79        if (interface == NULL) {
     80                return (size_t) -1;
     81        }
     82        if (interface[1] != USB_DESCTYPE_INTERFACE) {
     83                return (size_t) -1;
     84        }
     85
     86        size_t found_interfaces = 0;
     87        interface_positions[found_interfaces] = interface - config_descriptor;
     88        found_interfaces++;
     89
     90        while (interface != NULL) {
     91                interface = usb_dp_get_sibling_descriptor(&parser, &data,
     92                    data.data, interface);
     93                if ((interface != NULL)
     94                    && (found_interfaces < interface_count)
     95                    && (interface[1] == USB_DESCTYPE_INTERFACE)) {
     96                        interface_positions[found_interfaces]
     97                            = interface - config_descriptor;
     98                        found_interfaces++;
    9899                }
    99 
    100                 usb_standard_interface_descriptor_t *interface
    101                     = (usb_standard_interface_descriptor_t *) interface_ptr;
    102 
    103                 /* Skip alternate interfaces. */
    104                 if (!interface_in_list(list, interface->interface_number)) {
    105                         usbmid_interface_t *iface
    106                             = malloc(sizeof(usbmid_interface_t));
    107                         if (iface == NULL) {
    108                                 break;
    109                         }
    110                         link_initialize(&iface->link);
    111                         iface->fun = NULL;
    112                         iface->interface_no = interface->interface_number;
    113                         iface->interface = interface;
    114 
    115                         list_append(&iface->link, list);
    116                 }
    117 
    118                 /* TODO: add the alternatives and create match ids from them
    119                  * as well.
    120                  */
    121 
    122 next_descriptor:
    123                 interface_ptr = usb_dp_get_sibling_descriptor(&parser, &data,
    124                     data.data, interface_ptr);
    125 
    126         } while (interface_ptr != NULL);
    127 
     100        }
     101
     102        return found_interfaces;
    128103}
    129104
     
    155130            (usb_standard_configuration_descriptor_t *) config_descriptor_raw;
    156131
     132        size_t *interface_descriptors
     133            = malloc(sizeof(size_t) * config_descriptor->interface_count);
     134        if (interface_descriptors == NULL) {
     135                usb_log_error("Out of memory (wanted %zuB).\n",
     136                    sizeof(size_t) * config_descriptor->interface_count);
     137                free(config_descriptor_raw);
     138                return false;
     139        }
     140        size_t interface_descriptors_count
     141            = find_interface_descriptors(
     142            config_descriptor_raw, config_descriptor_size,
     143            interface_descriptors, config_descriptor->interface_count);
     144
     145        if (interface_descriptors_count == (size_t) -1) {
     146                usb_log_error("Problem parsing configuration descriptor.\n");
     147                free(interface_descriptors);
     148                return false;
     149        }
     150
    157151        /* Select the first configuration */
    158152        rc = usb_request_set_configuration(&dev->ctrl_pipe,
     
    161155                usb_log_error("Failed to set device configuration: %s.\n",
    162156                    str_error(rc));
    163                 return false;
    164         }
     157                free(interface_descriptors);
     158                return false;
     159        }
     160
    165161
    166162        /* Create control function */
     
    168164        if (ctl_fun == NULL) {
    169165                usb_log_error("Failed to create control function.\n");
     166                free(interface_descriptors);
    170167                return false;
    171168        }
     
    177174                usb_log_error("Failed to bind control function: %s.\n",
    178175                    str_error(rc));
    179                 return false;
    180         }
    181 
    182         /* Create interface children. */
    183         link_t interface_list;
    184         list_initialize(&interface_list);
    185         create_interfaces(config_descriptor_raw, config_descriptor_size,
    186             &interface_list);
    187 
    188         link_t *link;
    189         for (link = interface_list.next; link != &interface_list;
    190             link = link->next) {
    191                 usbmid_interface_t *iface = list_get_instance(link,
    192                     usbmid_interface_t, link);
    193 
     176                free(interface_descriptors);
     177                return false;
     178        }
     179
     180        /* Spawn interface children */
     181        size_t i;
     182        for (i = 0; i < interface_descriptors_count; i++) {
     183                usb_standard_interface_descriptor_t *interface
     184                    = (usb_standard_interface_descriptor_t *)
     185                    (config_descriptor_raw + interface_descriptors[i]);
     186                usb_log_debug2("Interface descriptor at index %zu (type %d).\n",
     187                    interface_descriptors[i], (int) interface->descriptor_type);
    194188                usb_log_info("Creating child for interface %d (%s).\n",
    195                     (int) iface->interface_no,
    196                     usb_str_class(iface->interface->interface_class));
    197 
    198                 rc = usbmid_spawn_interface_child(dev, iface,
    199                     &dev->descriptors.device, iface->interface);
     189                    (int) interface->interface_number,
     190                    usb_str_class(interface->interface_class));
     191                rc = usbmid_spawn_interface_child(dev, &dev->descriptors.device,
     192                    interface);
    200193                if (rc != EOK) {
    201194                        usb_log_error("Failed to create interface child: %s.\n",
Note: See TracChangeset for help on using the changeset viewer.