Changeset 69334af in mainline


Ignore:
Timestamp:
2011-03-13T17:18:55Z (14 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4bf94df
Parents:
489c3e7
Message:

Replace asserts with proper checks

Also, added doxygen comments.

Location:
uspace/lib/usb
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/include/usb/devdrv.h

    r489c3e7 r69334af  
    3838#include <usb/pipes.h>
    3939
     40/** USB device structure. */
    4041typedef struct {
     42        /** The default control pipe. */
    4143        usb_endpoint_pipe_t ctrl_pipe;
     44        /** Other endpoint pipes.
     45         * This is an array of other endpoint pipes in the same order as
     46         * in usb_driver_t.
     47         */
    4248        usb_endpoint_mapping_t *pipes;
     49        /** Generic DDF device backing this one. */
    4350        ddf_dev_t *ddf_dev;
     51        /** Custom driver data.
     52         * Do not use the entry in generic device, that is already used
     53         * by the framework.
     54         */
    4455        void *driver_data;
     56
     57        /** Connection backing the pipes.
     58         * Typically, you will not need to use this attribute at all.
     59         */
    4560        usb_device_connection_t wire;
    4661} usb_device_t;
    4762
     63/** USB driver ops. */
    4864typedef struct {
     65        /** Callback when new device is about to be controlled by the driver. */
    4966        int (*add_device)(usb_device_t *);
    5067} usb_driver_ops_t;
    5168
     69/** USB driver structure. */
    5270typedef struct {
     71        /** Driver name.
     72         * This name is copied to the generic driver name and must be exactly
     73         * the same as the directory name where the driver executable resides.
     74         */
    5375        const char *name;
     76        /** Expected endpoints description. */
    5477        usb_endpoint_description_t **endpoints;
     78        /** Driver ops. */
    5579        usb_driver_ops_t *ops;
    5680} usb_driver_t;
  • uspace/lib/usb/src/devdrv.c

    r489c3e7 r69334af  
    3737#include <usb/debug.h>
    3838#include <errno.h>
     39#include <str_error.h>
    3940#include <assert.h>
    4041
     
    5051static usb_driver_t *driver = NULL;
    5152
     53
     54/** Main routine of USB device driver.
     55 *
     56 * Under normal conditions, this function never returns.
     57 *
     58 * @param drv USB device driver structure.
     59 * @return Task exit status.
     60 */
    5261int usb_driver_main(usb_driver_t *drv)
    5362{
     63        assert(drv != NULL);
     64
    5465        /* Prepare the generic driver. */
    5566        generic_driver.name = drv->name;
     
    6071}
    6172
     73/** Log out of memory error on given device.
     74 *
     75 * @param dev Device causing the trouble.
     76 */
     77static void usb_log_oom(ddf_dev_t *dev)
     78{
     79        usb_log_error("Out of memory when adding device `%s'.\n",
     80            dev->name);
     81}
     82
     83/** Count number of pipes the driver expects.
     84 *
     85 * @param drv USB driver.
     86 * @return Number of pipes (excluding default control pipe).
     87 */
    6288static size_t count_other_pipes(usb_driver_t *drv)
    6389{
     
    74100}
    75101
     102/** Initialize endpoint pipes, excluding default control one.
     103 *
     104 * @param drv The device driver.
     105 * @param dev Device to be initialized.
     106 * @return Error code.
     107 */
    76108static int initialize_other_pipes(usb_driver_t *drv, usb_device_t *dev)
    77109{
     110        int rc;
    78111        int my_interface = usb_device_get_assigned_interface(dev->ddf_dev);
    79112
    80113        size_t pipe_count = count_other_pipes(drv);
    81114        dev->pipes = malloc(sizeof(usb_endpoint_mapping_t) * pipe_count);
    82         assert(dev->pipes != NULL);
     115        if (dev->pipes == NULL) {
     116                usb_log_oom(dev->ddf_dev);
     117                return ENOMEM;
     118        }
    83119
    84120        size_t i;
     121
     122        /* Initialize to NULL first for rollback purposes. */
     123        for (i = 0; i < pipe_count; i++) {
     124                dev->pipes[i].pipe = NULL;
     125        }
     126
    85127        for (i = 0; i < pipe_count; i++) {
    86128                dev->pipes[i].pipe = malloc(sizeof(usb_endpoint_pipe_t));
    87                 assert(dev->pipes[i].pipe != NULL);
     129                if (dev->pipes[i].pipe == NULL) {
     130                        usb_log_oom(dev->ddf_dev);
     131                        rc = ENOMEM;
     132                        goto rollback;
     133                }
     134
    88135                dev->pipes[i].description = drv->endpoints[i];
    89136                dev->pipes[i].interface_no = my_interface;
     
    92139        void *config_descriptor;
    93140        size_t config_descriptor_size;
    94         int rc = usb_request_get_full_configuration_descriptor_alloc(
    95            &dev->ctrl_pipe, 0, &config_descriptor, &config_descriptor_size);
    96         assert(rc == EOK);
     141        rc = usb_request_get_full_configuration_descriptor_alloc(
     142            &dev->ctrl_pipe, 0, &config_descriptor, &config_descriptor_size);
     143        if (rc != EOK) {
     144                usb_log_error("Failed retrieving configuration of `%s': %s.\n",
     145                    dev->ddf_dev->name, str_error(rc));
     146                goto rollback;
     147        }
    97148
    98149        rc = usb_endpoint_pipe_initialize_from_configuration(dev->pipes,
    99150           pipe_count, config_descriptor, config_descriptor_size, &dev->wire);
    100         assert(rc == EOK);
    101 
     151        if (rc != EOK) {
     152                usb_log_error("Failed initializing USB endpoints: %s.\n",
     153                    str_error(rc));
     154                goto rollback;
     155        }
    102156
    103157        return EOK;
    104 }
    105 
     158
     159rollback:
     160        for (i = 0; i < pipe_count; i++) {
     161                if (dev->pipes[i].pipe != NULL) {
     162                        free(dev->pipes[i].pipe);
     163                }
     164        }
     165        free(dev->pipes);
     166
     167        return rc;
     168}
     169
     170/** Initialize all endpoint pipes.
     171 *
     172 * @param drv The driver.
     173 * @param dev The device to be initialized.
     174 * @return Error code.
     175 */
     176static int initialize_pipes(usb_driver_t *drv, usb_device_t *dev)
     177{
     178        int rc;
     179
     180        rc = usb_device_connection_initialize_from_device(&dev->wire,
     181            dev->ddf_dev);
     182        if (rc != EOK) {
     183                usb_log_error(
     184                    "Failed initializing connection on device `%s'. %s.\n",
     185                    dev->ddf_dev->name, str_error(rc));
     186                return rc;
     187        }
     188
     189        rc = usb_endpoint_pipe_initialize_default_control(&dev->ctrl_pipe,
     190            &dev->wire);
     191        if (rc != EOK) {
     192                usb_log_error("Failed to initialize default control pipe " \
     193                    "on device `%s': %s.\n",
     194                    dev->ddf_dev->name, str_error(rc));
     195                return rc;
     196        }
     197
     198        /*
     199         * Initialization of other pipes requires open session on
     200         * default control pipe.
     201         */
     202        rc = usb_endpoint_pipe_start_session(&dev->ctrl_pipe);
     203        if (rc != EOK) {
     204                usb_log_error("Failed to start an IPC session: %s.\n",
     205                    str_error(rc));
     206                return rc;
     207        }
     208
     209        if (driver->endpoints != NULL) {
     210                rc = initialize_other_pipes(driver, dev);
     211        }
     212
     213        /* No checking here. */
     214        usb_endpoint_pipe_end_session(&dev->ctrl_pipe);
     215
     216        return rc;
     217}
     218
     219/** Callback when new device is supposed to be controlled by this driver.
     220 *
     221 * This callback is a wrapper for USB specific version of @c add_device.
     222 *
     223 * @param gen_dev Device structure as prepared by DDF.
     224 * @return Error code.
     225 */
    106226int generic_add_device(ddf_dev_t *gen_dev)
    107227{
     
    113233
    114234        usb_device_t *dev = malloc(sizeof(usb_device_t));
    115         assert(dev);
     235        if (dev == NULL) {
     236                usb_log_error("Out of memory when adding device `%s'.\n",
     237                    gen_dev->name);
     238                return ENOMEM;
     239        }
     240
    116241
    117242        dev->ddf_dev = gen_dev;
     243        dev->ddf_dev->driver_data = dev;
    118244        dev->driver_data = NULL;
    119245
    120         /* Initialize the backing wire abstraction. */
    121         rc = usb_device_connection_initialize_from_device(&dev->wire, gen_dev);
    122         assert(rc == EOK);
    123 
    124         /* Initialize the default control pipe. */
    125         rc = usb_endpoint_pipe_initialize_default_control(&dev->ctrl_pipe,
    126             &dev->wire);
    127         assert(rc == EOK);
    128 
    129         rc = usb_endpoint_pipe_start_session(&dev->ctrl_pipe);
    130         assert(rc == EOK);
    131 
    132         /* Initialize remaining pipes. */
    133         if (driver->endpoints != NULL) {
    134                 initialize_other_pipes(driver, dev);
    135         }
    136 
    137         rc = usb_endpoint_pipe_end_session(&dev->ctrl_pipe);
    138         assert(rc == EOK);
     246        rc = initialize_pipes(driver, dev);
     247        if (rc != EOK) {
     248                free(dev);
     249                return rc;
     250        }
    139251
    140252        return driver->ops->add_device(dev);
Note: See TracChangeset for help on using the changeset viewer.