Changeset ecb107b in mainline


Ignore:
Timestamp:
2011-03-30T21:21:56Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
9bc276b
Parents:
48d4231
Message:

USB MID does not spawn alternate interfaces

Location:
uspace/drv/usbmid
Files:
3 edited

Legend:

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

    r48d4231 recb107b  
    4848};
    4949
    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  */
    59 static size_t find_interface_descriptors(uint8_t *config_descriptor,
    60     size_t config_descriptor_size,
    61     size_t *interface_positions, size_t interface_count)
     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 */
     56static bool interface_in_list(link_t *list, int interface_no)
    6257{
    63         if (interface_count == 0) {
    64                 return (size_t) -1;
    65         }
    66 
     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 */
     76static void create_interfaces(uint8_t *config_descriptor,
     77    size_t config_descriptor_size, link_t *list)
     78{
    6779        usb_dp_parser_data_t data = {
    6880                .data = config_descriptor,
     
    7587        };
    7688
    77         uint8_t *interface = usb_dp_get_nested_descriptor(&parser, &data,
     89        uint8_t *interface_ptr = usb_dp_get_nested_descriptor(&parser, &data,
    7890            data.data);
    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++;
    99                 }
    100         }
    101 
    102         return found_interfaces;
     91        if (interface_ptr == NULL) {
     92                return;
     93        }
     94
     95        do {
     96                if (interface_ptr[1] != USB_DESCTYPE_INTERFACE) {
     97                        goto next_descriptor;
     98                }
     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
     122next_descriptor:
     123                interface_ptr = usb_dp_get_sibling_descriptor(&parser, &data,
     124                    data.data, interface_ptr);
     125
     126        } while (interface_ptr != NULL);
     127
    103128}
    104129
     
    130155            (usb_standard_configuration_descriptor_t *) config_descriptor_raw;
    131156
    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 
    151157        /* Select the first configuration */
    152158        rc = usb_request_set_configuration(&dev->ctrl_pipe,
     
    155161                usb_log_error("Failed to set device configuration: %s.\n",
    156162                    str_error(rc));
    157                 free(interface_descriptors);
    158                 return false;
    159         }
    160 
     163                return false;
     164        }
    161165
    162166        /* Create control function */
     
    164168        if (ctl_fun == NULL) {
    165169                usb_log_error("Failed to create control function.\n");
    166                 free(interface_descriptors);
    167170                return false;
    168171        }
     
    174177                usb_log_error("Failed to bind control function: %s.\n",
    175178                    str_error(rc));
    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);
     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
    188194                usb_log_info("Creating child for interface %d (%s).\n",
    189                     (int) interface->interface_number,
    190                     usb_str_class(interface->interface_class));
    191                 rc = usbmid_spawn_interface_child(dev, &dev->descriptors.device,
    192                     interface);
     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);
    193200                if (rc != EOK) {
    194201                        usb_log_error("Failed to create interface child: %s.\n",
  • uspace/drv/usbmid/usbmid.c

    r48d4231 recb107b  
    7979};
    8080
    81 /** Create new interface for USB MID device.
    82  *
    83  * @param fun Backing generic DDF device function (representing interface).
    84  * @param iface_no Interface number.
    85  * @return New interface.
    86  * @retval NULL Error occured.
    87  */
    88 usbmid_interface_t *usbmid_interface_create(ddf_fun_t *fun, int iface_no)
    89 {
    90         usbmid_interface_t *iface = malloc(sizeof(usbmid_interface_t));
    91         if (iface == NULL) {
    92                 usb_log_error("Out of memory (wanted %zuB).\n",
    93                     sizeof(usbmid_interface_t));
    94                 return NULL;
    95         }
    96 
    97         iface->fun = fun;
    98         iface->interface_no = iface_no;
    99 
    100         return iface;
    101 }
    102 
    10381
    10482/** Spawn new child device from one interface.
    10583 *
    10684 * @param parent Parent MID device.
     85 * @param iface Interface information.
    10786 * @param device_descriptor Device descriptor.
    10887 * @param interface_descriptor Interface descriptor.
     
    11089 */
    11190int usbmid_spawn_interface_child(usb_device_t *parent,
     91    usbmid_interface_t *iface,
    11292    const usb_standard_device_descriptor_t *device_descriptor,
    11393    const usb_standard_interface_descriptor_t *interface_descriptor)
     
    11595        ddf_fun_t *child = NULL;
    11696        char *child_name = NULL;
    117         usbmid_interface_t *child_as_interface = NULL;
    11897        int rc;
    11998
     
    137116        }
    138117
     118        iface->fun = child;
    139119
    140 
    141         child_as_interface = usbmid_interface_create(child,
    142             (int) interface_descriptor->interface_number);
    143         if (child_as_interface == NULL) {
    144                 rc = ENOMEM;
    145                 goto error_leave;
    146         }
    147 
    148         child->driver_data = child_as_interface;
     120        child->driver_data = iface;
    149121        child->ops = &child_device_ops;
    150122
     
    172144                free(child_name);
    173145        }
    174         if (child_as_interface != NULL) {
    175                 free(child_as_interface);
    176         }
    177146
    178147        return rc;
  • uspace/drv/usbmid/usbmid.h

    r48d4231 recb107b  
    3737#define USBMID_H_
    3838
     39#include <adt/list.h>
    3940#include <ddf/driver.h>
    4041#include <usb/usb.h>
     
    4950        /** Function container. */
    5051        ddf_fun_t *fun;
    51 
     52        /** Interface descriptor. */
     53        usb_standard_interface_descriptor_t *interface;
    5254        /** Interface number. */
    5355        int interface_no;
     56        /** List link. */
     57        link_t link;
    5458} usbmid_interface_t;
    5559
    56 usbmid_interface_t *usbmid_interface_create(ddf_fun_t *, int);
    5760bool usbmid_explore_device(usb_device_t *);
    58 int usbmid_spawn_interface_child(usb_device_t *,
     61int usbmid_spawn_interface_child(usb_device_t *, usbmid_interface_t *,
    5962    const usb_standard_device_descriptor_t *,
    6063    const usb_standard_interface_descriptor_t *);
Note: See TracChangeset for help on using the changeset viewer.