Ignore:
File:
1 edited

Legend:

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

    r37e4025 r160b75e  
    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[out] child_handle Handle of the child device.
     342 * @param[in] dev_ops Child device ops.
    313343 * @param[in] dev_data Arbitrary pointer to be stored in the child
    314344 *      as @c driver_data.
     
    317347 * @return Error code.
    318348 */
    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)
     349int usb_device_register_child_in_devman(usb_address_t address,
     350    devman_handle_t hc_handle,
     351    ddf_dev_t *parent, devman_handle_t *child_handle,
     352    ddf_dev_ops_t *dev_ops, void *dev_data, ddf_fun_t **child_fun)
    322353{
    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         }
     354        size_t this_device_name_index;
    330355
    331356        fibril_mutex_lock(&device_name_index_mutex);
    332         const size_t this_device_name_index = device_name_index++;
     357        this_device_name_index = device_name_index;
     358        device_name_index++;
    333359        fibril_mutex_unlock(&device_name_index_mutex);
    334360
    335361        ddf_fun_t *child = NULL;
     362        char *child_name = NULL;
    336363        int rc;
     364        usb_device_connection_t dev_connection;
     365        usb_pipe_t ctrl_pipe;
     366
     367        rc = usb_device_connection_initialize(&dev_connection, hc_handle, address);
     368        if (rc != EOK) {
     369                goto failure;
     370        }
     371
     372        rc = usb_pipe_initialize_default_control(&ctrl_pipe,
     373            &dev_connection);
     374        if (rc != EOK) {
     375                goto failure;
     376        }
     377        rc = usb_pipe_probe_default_control(&ctrl_pipe);
     378        if (rc != EOK) {
     379                goto failure;
     380        }
    337381
    338382        /*
     
    340384         * naming etc., something more descriptive could be created.
    341385         */
    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);
     386        rc = asprintf(&child_name, "usb%02zu_a%d",
     387            this_device_name_index, address);
    345388        if (rc < 0) {
    346389                goto failure;
     
    360403
    361404        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);
     405
     406        rc = usb_device_create_match_ids(&ctrl_pipe, &child->match_ids);
    377407        if (rc != EOK) {
    378408                goto failure;
     
    384414        }
    385415
    386         *child_fun = child;
     416        if (child_handle != NULL) {
     417                *child_handle = child->handle;
     418        }
     419
     420        if (child_fun != NULL) {
     421                *child_fun = child;
     422        }
     423
    387424        return EOK;
    388425
    389426failure:
    390427        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                 }
     428                child->name = NULL;
    395429                /* This takes care of match_id deallocation as well. */
    396430                ddf_fun_destroy(child);
    397431        }
     432        if (child_name != NULL) {
     433                free(child_name);
     434        }
    398435
    399436        return rc;
Note: See TracChangeset for help on using the changeset viewer.