Changeset 747ef72 in mainline for uspace/lib/usbdev/src/devdrv.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/devdrv.c

    r2e1b9dc r747ef72  
    8181 * @return Number of pipes (excluding default control pipe).
    8282 */
    83 static size_t count_other_pipes(const usb_endpoint_description_t **endpoints)
    84 {
    85         size_t count = 0;
    86         if (endpoints == NULL) {
    87                 return 0;
    88         }
    89 
    90         while (endpoints[count] != NULL) {
    91                 count++;
    92         }
    93 
     83static inline size_t count_other_pipes(
     84    const usb_endpoint_description_t **endpoints)
     85{
     86        size_t count;
     87        for (count = 0; endpoints && endpoints[count] != NULL; ++count);
    9488        return count;
    9589}
     
    10498    usb_device_t *dev, int alternate_setting)
    10599{
     100        assert(dev);
     101
    106102        if (endpoints == NULL) {
    107103                dev->pipes = NULL;
     
    300296
    301297        return rc;
     298}
     299
     300/** Cleanup structure initialized via usb_device_retrieve_descriptors.
     301 *
     302 * @param[in] descriptors Where to store the descriptors.
     303 */
     304void usb_device_release_descriptors(usb_device_descriptors_t *descriptors)
     305{
     306        assert(descriptors);
     307        free(descriptors->configuration);
     308        descriptors->configuration = NULL;
    302309}
    303310
     
    319326 *      (not NULL terminated).
    320327 * @param[out] pipes_count_ptr Where to store number of pipes
    321  *      (set to if you wish to ignore the count).
     328 *      (set to NULL if you wish to ignore the count).
    322329 * @return Error code.
    323330 */
     
    340347        const size_t pipe_count = count_other_pipes(endpoints);
    341348        if (pipe_count == 0) {
    342                 *pipes_count_ptr = pipe_count;
     349                if (pipes_count_ptr)
     350                        *pipes_count_ptr = pipe_count;
    343351                *pipes_ptr = NULL;
    344352                return EOK;
     
    346354
    347355        usb_endpoint_mapping_t *pipes
    348             = malloc(sizeof(usb_endpoint_mapping_t) * pipe_count);
     356            = calloc(pipe_count, sizeof(usb_endpoint_mapping_t));
    349357        if (pipes == NULL) {
    350358                return ENOMEM;
    351359        }
    352360
    353         /* Initialize to NULL to allow smooth rollback. */
    354         for (i = 0; i < pipe_count; i++) {
    355                 pipes[i].pipe = NULL;
    356         }
    357 
    358361        /* Now allocate and fully initialize. */
    359362        for (i = 0; i < pipe_count; i++) {
    360                 pipes[i].pipe = malloc(sizeof(usb_pipe_t));
    361                 if (pipes[i].pipe == NULL) {
    362                         rc = ENOMEM;
    363                         goto rollback_free_only;
    364                 }
    365363                pipes[i].description = endpoints[i];
    366364                pipes[i].interface_no = interface_no;
     
    389387        for (i = 0; i < pipe_count; i++) {
    390388                if (pipes[i].present) {
    391                         rc = usb_pipe_register(pipes[i].pipe,
     389                        rc = usb_pipe_register(&pipes[i].pipe,
    392390                            pipes[i].descriptor->poll_interval, &hc_conn);
    393391                        if (rc != EOK) {
     
    398396
    399397        if (usb_hc_connection_close(&hc_conn) != EOK)
    400                 usb_log_warning("usb_device_create_pipes(): "
    401                     "Failed to close connection.\n");
     398                usb_log_warning("%s: Failed to close connection.\n",
     399                    __FUNCTION__);
    402400
    403401        *pipes_ptr = pipes;
     
    417415        for (i = 0; i < pipe_count; i++) {
    418416                if (pipes[i].present) {
    419                         usb_pipe_unregister(pipes[i].pipe, &hc_conn);
     417                        usb_pipe_unregister(&pipes[i].pipe, &hc_conn);
    420418                }
    421419        }
     
    431429         */
    432430rollback_free_only:
    433         for (i = 0; i < pipe_count; i++) {
    434                 if (pipes[i].pipe != NULL) {
    435                         free(pipes[i].pipe);
    436                 }
    437         }
    438431        free(pipes);
    439432
     
    477470                    i, pipes[i].present ? "" : "not ");
    478471                if (pipes[i].present)
    479                         usb_pipe_unregister(pipes[i].pipe, &hc_conn);
    480                 free(pipes[i].pipe);
     472                        usb_pipe_unregister(&pipes[i].pipe, &hc_conn);
    481473        }
    482474
     
    489481        return EOK;
    490482}
    491 
    492 /** Initialize control pipe in a device.
    493  *
    494  * @param dev USB device in question.
    495  * @param errmsg Where to store error context.
    496  * @return
    497  */
    498 static int init_wire_and_ctrl_pipe(usb_device_t *dev, const char **errmsg)
    499 {
    500         int rc;
    501 
    502         rc = usb_device_connection_initialize_from_device(&dev->wire,
    503             dev->ddf_dev);
    504         if (rc != EOK) {
    505                 *errmsg = "device connection initialization";
    506                 return rc;
    507         }
    508 
    509         rc = usb_pipe_initialize_default_control(&dev->ctrl_pipe,
    510             &dev->wire);
    511         if (rc != EOK) {
    512                 *errmsg = "default control pipe initialization";
    513                 return rc;
    514         }
    515 
    516         return EOK;
    517 }
    518 
    519483
    520484/** Initialize new instance of USB device.
     
    533497        assert(ddf_dev != NULL);
    534498
     499        *errstr_ptr = NULL;
     500
    535501        usb_dev->ddf_dev = ddf_dev;
    536502        usb_dev->driver_data = NULL;
    537503        usb_dev->descriptors.configuration = NULL;
    538         usb_dev->alternate_interfaces = NULL;
    539504        usb_dev->pipes_count = 0;
    540505        usb_dev->pipes = NULL;
    541506
    542507        /* Initialize backing wire and control pipe. */
    543         int rc = init_wire_and_ctrl_pipe(usb_dev, errstr_ptr);
    544         if (rc != EOK) {
     508        int rc = usb_device_connection_initialize_from_device(
     509            &usb_dev->wire, ddf_dev);
     510        if (rc != EOK) {
     511                *errstr_ptr = "device connection initialization";
     512                return rc;
     513        }
     514
     515        /* This pipe was registered by the hub driver,
     516         * during device initialization. */
     517        rc = usb_pipe_initialize_default_control(&usb_dev->ctrl_pipe,
     518            &usb_dev->wire);
     519        if (rc != EOK) {
     520                *errstr_ptr = "default control pipe initialization";
    545521                return rc;
    546522        }
     
    553529            &usb_dev->descriptors);
    554530        if (rc != EOK) {
    555                 /* Nothing allocated, nothing to free. */
    556531                *errstr_ptr = "descriptor retrieval";
    557532                return rc;
    558533        }
    559534
    560         /* Create alternate interfaces. We will silently ignore failure. */
    561         //TODO Why ignore?
    562         usb_alternate_interfaces_create(usb_dev->descriptors.configuration,
    563             usb_dev->descriptors.configuration_size, usb_dev->interface_no,
    564             &usb_dev->alternate_interfaces);
    565 
    566         rc = initialize_other_pipes(endpoints, usb_dev, 0);
     535        /* Create alternate interfaces. We will silently ignore failure.
     536         * We might either control one interface or an entire device,
     537         * it makes no sense to speak about alternate interfaces when
     538         * controlling a device. */
     539        rc = usb_alternate_interfaces_init(&usb_dev->alternate_interfaces,
     540            usb_dev->descriptors.configuration,
     541            usb_dev->descriptors.configuration_size, usb_dev->interface_no);
     542        const int alternate_iface =
     543            (rc == EOK) ? usb_dev->alternate_interfaces.current : 0;
     544
     545        /* TODO Add comment here. */
     546        rc = initialize_other_pipes(endpoints, usb_dev, alternate_iface);
    567547        if (rc != EOK) {
    568548                /* Full configuration descriptor is allocated. */
    569                 free(usb_dev->descriptors.configuration);
     549                usb_device_release_descriptors(&usb_dev->descriptors);
    570550                /* Alternate interfaces may be allocated */
    571                 usb_alternate_interfaces_destroy(usb_dev->alternate_interfaces);
     551                usb_alternate_interfaces_deinit(&usb_dev->alternate_interfaces);
    572552                *errstr_ptr = "pipes initialization";
    573553                return rc;
    574554        }
    575 
    576         *errstr_ptr = NULL;
    577555
    578556        return EOK;
     
    591569                destroy_current_pipes(dev);
    592570
    593                 usb_alternate_interfaces_destroy(dev->alternate_interfaces);
    594                 free(dev->descriptors.configuration);
     571                usb_alternate_interfaces_deinit(&dev->alternate_interfaces);
     572                usb_device_release_descriptors(&dev->descriptors);
    595573                free(dev->driver_data);
    596574        }
Note: See TracChangeset for help on using the changeset viewer.