Changeset 747ef72 in mainline for uspace/lib/usbdev/src/recognise.c


Ignore:
Timestamp:
2011-11-10T11:29:10Z (13 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
54464f6a, c2245a3, c6f189f7
Parents:
2e1b9dc (diff), 2d1ba51 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge USB changes.

Interface changes:

  • GET_ADDRESS has been renamed to GET_MY_ADDRESS and the handle parameter was dropped. Tis call no longer cascades up to the root hub, but it is answered in the first place the information is available (nearest hub)
  • Reintroduced address reservation for USB_DEFAULT_ADDRESS. The interface now enables device drivers to request specific address on initialization and either insists on that address or accept any other if the address is not available. Note that it is not possible to get the default address if the driver does not insist.
  • Any endpoint registered is removed when address is released and a warning is produced if there were any such endpoints.
  • It is no longer necessary or possible to pass device speed information when registering endpoints.

Driver fixes: memory leaks and crashes (not only) in error paths.
Fixes or removes flaky device_remove implementation in device drivers.

File:
1 edited

Legend:

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

    r2e1b9dc r747ef72  
    3535#include <sys/types.h>
    3636#include <fibril_synch.h>
     37#include <usb/debug.h>
     38#include <usb/dev/hub.h>
    3739#include <usb/dev/pipes.h>
    3840#include <usb/dev/recognise.h>
     
    5052
    5153/** DDF operations of child devices. */
    52 ddf_dev_ops_t child_ops = {
     54static ddf_dev_ops_t child_ops = {
    5355        .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl
    5456};
     
    6466#define BCD_ARGS(a) BCD_INT((a)), BCD_FRAC((a))
    6567
    66 /* FIXME: make this dynamic */
    67 #define MATCH_STRING_MAX 256
    68 
    6968/** Add formatted match id.
    7069 *
     
    7574 */
    7675static int usb_add_match_id(match_id_list_t *matches, int score,
    77     const char *format, ...)
     76    const char *match_str)
    7877{
    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();
     78        assert(matches);
     79
     80        match_id_t *match_id = create_match_id();
    9981        if (match_id == NULL) {
    100                 rc = ENOMEM;
    101                 goto failure;
     82                return ENOMEM;
    10283        }
    10384
     
    10788
    10889        return EOK;
    109        
    110 failure:
    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;
    12090}
    12191
     
    12999#define ADD_MATCHID_OR_RETURN(match_ids, score, format, ...) \
    130100        do { \
    131                 int __rc = usb_add_match_id((match_ids), (score), \
    132                     format, ##__VA_ARGS__); \
     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                } \
    133106                if (__rc != EOK) { \
     107                        free(str); \
    134108                        return __rc; \
    135109                } \
     
    150124    match_id_list_t *matches)
    151125{
    152         if (desc_interface == NULL) {
    153                 return EINVAL;
    154         }
    155         if (matches == NULL) {
     126        if (desc_interface == NULL || matches == NULL) {
    156127                return EINVAL;
    157128        }
     
    314285    match_id_list_t *matches)
    315286{
     287        assert(ctrl_pipe);
    316288        int rc;
    317289        /*
     
    336308/** Probe for device kind and register it in devman.
    337309 *
    338  * @param[in] address Address of the (unknown) attached device.
    339  * @param[in] hc_handle Handle of the host controller.
     310 * @param[in] ctrl_pipe Control pipe to the device.
    340311 * @param[in] parent Parent device.
    341  * @param[in] dev_ops Child device ops.
     312 * @param[in] dev_ops Child device ops. Default child_ops will be used if NULL.
    342313 * @param[in] dev_data Arbitrary pointer to be stored in the child
    343314 *      as @c driver_data.
     
    346317 * @return Error code.
    347318 */
    348 int 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)
     319int 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)
    351322{
    352         size_t this_device_name_index;
     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        }
    353330
    354331        fibril_mutex_lock(&device_name_index_mutex);
    355         this_device_name_index = device_name_index;
    356         device_name_index++;
     332        const size_t this_device_name_index = device_name_index++;
    357333        fibril_mutex_unlock(&device_name_index_mutex);
    358334
    359335        ddf_fun_t *child = NULL;
    360         char *child_name = NULL;
    361336        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         }
    379337
    380338        /*
     
    382340         * naming etc., something more descriptive could be created.
    383341         */
    384         rc = asprintf(&child_name, "usb%02zu_a%d",
    385             this_device_name_index, address);
     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);
    386345        if (rc < 0) {
    387346                goto failure;
     
    401360
    402361        child->driver_data = dev_data;
    403 
    404         rc = usb_device_create_match_ids(&ctrl_pipe, &child->match_ids);
     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);
    405377        if (rc != EOK) {
    406378                goto failure;
     
    412384        }
    413385
    414         if (child_fun != NULL) {
    415                 *child_fun = child;
    416         }
    417 
     386        *child_fun = child;
    418387        return EOK;
    419388
    420389failure:
    421390        if (child != NULL) {
    422                 child->name = NULL;
     391                /* We know nothing about the data if it came from outside. */
     392                if (dev_data) {
     393                        child->driver_data = NULL;
     394                }
    423395                /* This takes care of match_id deallocation as well. */
    424396                ddf_fun_destroy(child);
    425397        }
    426         if (child_name != NULL) {
    427                 free(child_name);
    428         }
    429398
    430399        return rc;
Note: See TracChangeset for help on using the changeset viewer.