Ignore:
File:
1 edited

Legend:

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

    r58563585 r87a3df7f  
    3434 * Exploration of available interfaces in the USB device.
    3535 */
    36 
     36#include <ddf/driver.h>
    3737#include <errno.h>
    3838#include <str_error.h>
     
    4141#include <usb/dev/request.h>
    4242#include <usb/dev/dp.h>
     43#include <usb/ddfiface.h>
    4344#include "usbmid.h"
     45
     46/** Operations of the device itself. */
     47static ddf_dev_ops_t mid_device_ops = {
     48        .interfaces[USB_DEV_IFACE] = &usb_iface_hub_impl
     49};
    4450
    4551/** Tell whether given interface is already in the list.
     
    5157static bool interface_in_list(const list_t *list, int interface_no)
    5258{
    53         list_foreach(*list, link, const usbmid_interface_t, iface) {
     59        list_foreach(*list, link, usbmid_interface_t, iface) {
    5460                if (iface->interface_no == interface_no) {
    5561                        return true;
     
    6571 * @param config_descriptor_size Size of configuration descriptor in bytes.
    6672 * @param list List where to add the interfaces.
    67  */
    68 static int create_interfaces(const uint8_t *config_descriptor,
    69     size_t config_descriptor_size, list_t *list, usb_device_t *usb_dev)
     73 * @return EOK on success, ENOMEM if out of memory.
     74 */
     75static int create_interfaces(usb_mid_t *mid, const uint8_t *config_descriptor,
     76    size_t config_descriptor_size)
    7077{
    71         assert(config_descriptor);
    72         assert(usb_dev);
    73 
    7478        const usb_dp_parser_data_t data = {
    7579                .data = config_descriptor,
     
    8791        /* Walk all descriptors nested in the current configuration decriptor;
    8892         * i.e. all interface descriptors. */
    89         for (; interface_ptr != NULL;
     93        for (;interface_ptr != NULL;
    9094            interface_ptr = usb_dp_get_sibling_descriptor(
    9195                &parser, &data, config_descriptor, interface_ptr))
     
    99103
    100104                /* Skip alternate interfaces. */
    101                 if (interface_in_list(list, interface->interface_number)) {
     105                if (interface_in_list(&mid->interface_list,
     106                    interface->interface_number)) {
    102107                        /* TODO: add the alternatives and create match ids
    103108                         * for them. */
     
    105110                }
    106111
    107 
    108                 usb_log_info("Creating child for interface %d (%s).\n",
    109                     interface->interface_number,
    110                     usb_str_class(interface->interface_class));
    111 
    112                 usbmid_interface_t *iface = NULL;
    113                 const int rc = usbmid_spawn_interface_child(usb_dev, &iface,
    114                         &usb_device_descriptors(usb_dev)->device, interface);
    115                 if (rc != EOK) {
    116                         //TODO: Do something about that failure.
    117                         usb_log_error("Failed to create interface child for "
    118                             "%d (%s): %s.\n", interface->interface_number,
    119                             usb_str_class(interface->interface_class),
    120                             str_error(rc));
    121                 } else {
    122                         list_append(&iface->link, list);
    123                 }
    124         }
     112                /* Create the function */
     113                ddf_fun_t *fun = ddf_fun_create(mid->dev, fun_inner, NULL);
     114                if (fun == NULL)
     115                        goto error;
     116
     117                usbmid_interface_t *iface = ddf_fun_data_alloc(fun,
     118                    sizeof(usbmid_interface_t));
     119                if (iface == NULL)
     120                        goto error;
     121
     122                link_initialize(&iface->link);
     123                iface->fun = fun;
     124                iface->interface_no = interface->interface_number;
     125                iface->interface = interface;
     126
     127                list_append(&iface->link, &mid->interface_list);
     128        }
     129
    125130        return EOK;
     131error:
     132        while (!list_empty(&mid->interface_list)) {
     133                link_t *link = list_first(&mid->interface_list);
     134                usbmid_interface_t *iface = list_get_instance(link,
     135                    usbmid_interface_t, link);
     136
     137                ddf_fun_destroy(iface->fun);
     138        }
     139
     140        return ENOMEM;
    126141}
    127142
     
    134149 * @return Whether to accept this device from devman.
    135150 */
    136 int usbmid_explore_device(usb_device_t *dev)
     151bool usbmid_explore_device(usb_device_t *dev)
    137152{
    138         assert(dev);
    139         const unsigned dev_class =
    140             usb_device_descriptors(dev)->device.device_class;
     153        int rc;
     154
     155        unsigned dev_class = dev->descriptors.device.device_class;
    141156        if (dev_class != USB_CLASS_USE_INTERFACE) {
    142157                usb_log_warning(
     
    144159                    dev_class, usb_str_class(dev_class),
    145160                    USB_CLASS_USE_INTERFACE);
    146                 usb_log_error("Not a multi-interface device, refusing.\n");
    147                 return ENOTSUP;
    148         }
    149 
    150         /* Get coonfiguration descriptor. */
    151         const size_t config_descriptor_size =
    152             usb_device_descriptors(dev)->full_config_size;
    153         const void *config_descriptor_raw =
    154             usb_device_descriptors(dev)->full_config;
     161                usb_log_error("Not multi interface device, refusing.\n");
     162                return false;
     163        }
     164
     165        /* Shortcuts to save on typing ;-). */
     166        const void *config_descriptor_raw = dev->descriptors.configuration;
     167        size_t config_descriptor_size = dev->descriptors.configuration_size;
    155168        const usb_standard_configuration_descriptor_t *config_descriptor =
    156169            config_descriptor_raw;
    157170
    158171        /* Select the first configuration */
    159         int rc = usb_request_set_configuration(usb_device_get_default_pipe(dev),
     172        rc = usb_request_set_configuration(&dev->ctrl_pipe,
    160173            config_descriptor->configuration_number);
    161174        if (rc != EOK) {
    162175                usb_log_error("Failed to set device configuration: %s.\n",
    163176                    str_error(rc));
    164                 return rc;
    165         }
    166        
     177                return false;
     178        }
     179
    167180        /* Create driver soft-state. */
    168181        usb_mid_t *usb_mid = usb_device_data_alloc(dev, sizeof(usb_mid_t));
    169182        if (!usb_mid) {
    170183                usb_log_error("Failed to create USB MID structure.\n");
    171                 return ENOMEM;
    172         }
     184                return false;
     185        }
     186
     187        usb_mid->dev = dev->ddf_dev;
    173188
    174189        /* Create control function. */
    175         usb_mid->ctl_fun = usb_device_ddf_fun_create(dev, fun_exposed, "ctl");
     190        usb_mid->ctl_fun = ddf_fun_create(dev->ddf_dev, fun_exposed, "ctl");
    176191        if (usb_mid->ctl_fun == NULL) {
    177192                usb_log_error("Failed to create control function.\n");
    178                 return ENOMEM;
    179         }
     193                return false;
     194        }
     195        ddf_fun_set_ops(usb_mid->ctl_fun, &mid_device_ops);
    180196
    181197        /* Bind control function. */
     
    185201                    str_error(rc));
    186202                ddf_fun_destroy(usb_mid->ctl_fun);
    187                 return rc;
     203                return false;
    188204        }
    189205
    190206        /* Create interface children. */
    191207        list_initialize(&usb_mid->interface_list);
    192         create_interfaces(config_descriptor_raw, config_descriptor_size,
    193             &usb_mid->interface_list, dev);
    194 
    195         return EOK;
     208        create_interfaces(usb_mid, config_descriptor_raw, config_descriptor_size);
     209
     210        /* Start child function for every interface. */
     211        list_foreach(usb_mid->interface_list, link, usbmid_interface_t, iface) {
     212                usb_log_info("Creating child for interface %d (%s).\n",
     213                    iface->interface_no,
     214                    usb_str_class(iface->interface->interface_class));
     215
     216                rc = usbmid_spawn_interface_child(dev, iface,
     217                    &dev->descriptors.device, iface->interface);
     218                if (rc != EOK) {
     219                        usb_log_error("Failed to create interface child: %s.\n",
     220                            str_error(rc));
     221                }
     222        }
     223
     224        return true;
    196225}
    197226
Note: See TracChangeset for help on using the changeset viewer.