Ignore:
File:
1 edited

Legend:

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

    r37e4025 r162726b  
    3535#include <sys/types.h>
    3636#include <fibril_synch.h>
    37 #include <usb/debug.h>
    38 #include <usb/dev/hub.h>
    3937#include <usb/dev/pipes.h>
    4038#include <usb/dev/recognise.h>
     
    5250
    5351/** DDF operations of child devices. */
    54 static ddf_dev_ops_t child_ops = {
     52ddf_dev_ops_t child_ops = {
    5553        .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl
    5654};
     
    6664#define BCD_ARGS(a) BCD_INT((a)), BCD_FRAC((a))
    6765
     66/* FIXME: make this dynamic */
     67#define MATCH_STRING_MAX 256
     68
    6869/** Add formatted match id.
    6970 *
     
    7475 */
    7576static int usb_add_match_id(match_id_list_t *matches, int score,
    76     const char *match_str)
     77    const char *format, ...)
    7778{
    78         assert(matches);
    79 
    80         match_id_t *match_id = create_match_id();
     79        char *match_str = NULL;
     80        match_id_t *match_id = NULL;
     81        int rc;
     82       
     83        match_str = malloc(MATCH_STRING_MAX + 1);
     84        if (match_str == NULL) {
     85                rc = ENOMEM;
     86                goto failure;
     87        }
     88
     89        /*
     90         * FIXME: replace with dynamic allocation of exact size
     91         */
     92        va_list args;
     93        va_start(args, format   );
     94        vsnprintf(match_str, MATCH_STRING_MAX, format, args);
     95        match_str[MATCH_STRING_MAX] = 0;
     96        va_end(args);
     97
     98        match_id = create_match_id();
    8199        if (match_id == NULL) {
    82                 return ENOMEM;
     100                rc = ENOMEM;
     101                goto failure;
    83102        }
    84103
     
    88107
    89108        return EOK;
     109       
     110failure:
     111        if (match_str != NULL) {
     112                free(match_str);
     113        }
     114        if (match_id != NULL) {
     115                match_id->id = NULL;
     116                delete_match_id(match_id);
     117        }
     118       
     119        return rc;
    90120}
    91121
     
    99129#define ADD_MATCHID_OR_RETURN(match_ids, score, format, ...) \
    100130        do { \
    101                 char *str = NULL; \
    102                 int __rc = asprintf(&str, format, ##__VA_ARGS__); \
    103                 if (__rc > 0) { \
    104                         __rc = usb_add_match_id((match_ids), (score), str); \
    105                 } \
     131                int __rc = usb_add_match_id((match_ids), (score), \
     132                    format, ##__VA_ARGS__); \
    106133                if (__rc != EOK) { \
    107                         free(str); \
    108134                        return __rc; \
    109135                } \
     
    124150    match_id_list_t *matches)
    125151{
    126         if (desc_interface == NULL || matches == NULL) {
     152        if (desc_interface == NULL) {
     153                return EINVAL;
     154        }
     155        if (matches == NULL) {
    127156                return EINVAL;
    128157        }
     
    285314    match_id_list_t *matches)
    286315{
    287         assert(ctrl_pipe);
    288316        int rc;
    289317        /*
     
    308336/** Probe for device kind and register it in devman.
    309337 *
    310  * @param[in] ctrl_pipe Control pipe to the device.
     338 * @param[in] address Address of the (unknown) attached device.
     339 * @param[in] hc_handle Handle of the host controller.
    311340 * @param[in] parent Parent device.
    312  * @param[in] dev_ops Child device ops. Default child_ops will be used if NULL.
     341 * @param[in] dev_ops Child device ops.
    313342 * @param[in] dev_data Arbitrary pointer to be stored in the child
    314343 *      as @c driver_data.
     
    317346 * @return Error code.
    318347 */
    319 int usb_device_register_child_in_devman(usb_pipe_t *ctrl_pipe,
    320     ddf_dev_t *parent, ddf_dev_ops_t *dev_ops, void *dev_data,
    321     ddf_fun_t **child_fun)
     348int usb_device_register_child_in_devman(usb_address_t address,
     349    devman_handle_t hc_handle, ddf_dev_t *parent,
     350    ddf_dev_ops_t *dev_ops, void *dev_data, ddf_fun_t **child_fun)
    322351{
    323         if (child_fun == NULL || ctrl_pipe == NULL)
    324                 return EINVAL;
    325 
    326         if (!dev_ops && dev_data) {
    327                 usb_log_warning("Using standard fun ops with arbitrary "
    328                     "driver data. This does not have to work.\n");
    329         }
     352        size_t this_device_name_index;
    330353
    331354        fibril_mutex_lock(&device_name_index_mutex);
    332         const size_t this_device_name_index = device_name_index++;
     355        this_device_name_index = device_name_index;
     356        device_name_index++;
    333357        fibril_mutex_unlock(&device_name_index_mutex);
    334358
    335359        ddf_fun_t *child = NULL;
     360        char *child_name = NULL;
    336361        int rc;
     362        usb_device_connection_t dev_connection;
     363        usb_pipe_t ctrl_pipe;
     364
     365        rc = usb_device_connection_initialize(&dev_connection, hc_handle, address);
     366        if (rc != EOK) {
     367                goto failure;
     368        }
     369
     370        rc = usb_pipe_initialize_default_control(&ctrl_pipe,
     371            &dev_connection);
     372        if (rc != EOK) {
     373                goto failure;
     374        }
     375        rc = usb_pipe_probe_default_control(&ctrl_pipe);
     376        if (rc != EOK) {
     377                goto failure;
     378        }
    337379
    338380        /*
     
    340382         * naming etc., something more descriptive could be created.
    341383         */
    342         char child_name[12]; /* The format is: "usbAB_aXYZ", length 11 */
    343         rc = snprintf(child_name, sizeof(child_name),
    344             "usb%02zu_a%d", this_device_name_index, ctrl_pipe->wire->address);
     384        rc = asprintf(&child_name, "usb%02zu_a%d",
     385            this_device_name_index, address);
    345386        if (rc < 0) {
    346387                goto failure;
     
    360401
    361402        child->driver_data = dev_data;
    362         /* Store the attached device in fun driver data if there is no
    363          * other data */
    364         if (!dev_data) {
    365                 usb_hub_attached_device_t *new_device = ddf_fun_data_alloc(
    366                     child, sizeof(usb_hub_attached_device_t));
    367                 if (!new_device) {
    368                         rc = ENOMEM;
    369                         goto failure;
    370                 }
    371                 new_device->address = ctrl_pipe->wire->address;
    372                 new_device->fun = child;
    373         }
    374 
    375 
    376         rc = usb_device_create_match_ids(ctrl_pipe, &child->match_ids);
     403
     404        rc = usb_device_create_match_ids(&ctrl_pipe, &child->match_ids);
    377405        if (rc != EOK) {
    378406                goto failure;
     
    384412        }
    385413
    386         *child_fun = child;
     414        if (child_fun != NULL) {
     415                *child_fun = child;
     416        }
     417
    387418        return EOK;
    388419
    389420failure:
    390421        if (child != NULL) {
    391                 /* We know nothing about the data if it came from outside. */
    392                 if (dev_data) {
    393                         child->driver_data = NULL;
    394                 }
     422                child->name = NULL;
    395423                /* This takes care of match_id deallocation as well. */
    396424                ddf_fun_destroy(child);
    397425        }
     426        if (child_name != NULL) {
     427                free(child_name);
     428        }
    398429
    399430        return rc;
Note: See TracChangeset for help on using the changeset viewer.