Changeset 0b4e7ca in mainline for uspace/lib/usb/src/devdrv.c


Ignore:
Timestamp:
2011-04-03T17:35:53Z (14 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0cec844, c593b21
Parents:
159b91f4
Message:

Add wrapper for changing interface setting

The code needs to be refactored but that can be done later.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usb/src/devdrv.c

    r159b91f4 r0b4e7ca  
    8787 * @return Number of pipes (excluding default control pipe).
    8888 */
    89 static size_t count_other_pipes(usb_driver_t *drv)
     89static size_t count_other_pipes(usb_endpoint_description_t **endpoints)
    9090{
    9191        size_t count = 0;
    92         if (drv->endpoints == NULL) {
     92        if (endpoints == NULL) {
    9393                return 0;
    9494        }
    9595
    96         while (drv->endpoints[count] != NULL) {
     96        while (endpoints[count] != NULL) {
    9797                count++;
    9898        }
     
    107107 * @return Error code.
    108108 */
    109 static int initialize_other_pipes(usb_driver_t *drv, usb_device_t *dev)
     109static int initialize_other_pipes(usb_endpoint_description_t **endpoints,
     110    usb_device_t *dev)
    110111{
    111112        int rc;
    112113
    113         size_t pipe_count = count_other_pipes(drv);
     114        size_t pipe_count = count_other_pipes(endpoints);
     115        if (pipe_count == 0) {
     116                return EOK;
     117        }
     118
    114119        dev->pipes = malloc(sizeof(usb_endpoint_mapping_t) * pipe_count);
    115120        if (dev->pipes == NULL) {
     
    133138                }
    134139
    135                 dev->pipes[i].description = drv->endpoints[i];
     140                dev->pipes[i].description = endpoints[i];
    136141                dev->pipes[i].interface_no = dev->interface_no;
    137142                dev->pipes[i].interface_setting = 0;
     
    179184        usb_hc_connection_close(&hc_conn);
    180185
     186        dev->pipes_count = pipe_count;
     187
    181188        return EOK;
    182189
     
    261268
    262269        if (driver->endpoints != NULL) {
    263                 rc = initialize_other_pipes(driver, dev);
     270                rc = initialize_other_pipes(driver->endpoints, dev);
    264271        }
    265272
     
    429436        dev->descriptors.configuration = NULL;
    430437
     438        dev->pipes_count = 0;
     439        dev->pipes = NULL;
     440
    431441        rc = initialize_pipes(dev);
    432442        if (rc != EOK) {
     
    440450}
    441451
     452/** Destroy existing pipes of a USB device.
     453 *
     454 * @param dev Device where to destroy the pipes.
     455 * @return Error code.
     456 */
     457static int destroy_current_pipes(usb_device_t *dev)
     458{
     459        size_t i;
     460        int rc;
     461
     462        /* TODO: this shall be done under some device mutex. */
     463
     464        /* First check that no session is opened. */
     465        for (i = 0; i < dev->pipes_count; i++) {
     466                if (usb_pipe_is_session_started(dev->pipes[i].pipe)) {
     467                        return EBUSY;
     468                }
     469        }
     470
     471        /* Prepare connection to HC. */
     472        usb_hc_connection_t hc_conn;
     473        rc = usb_hc_connection_initialize_from_device(&hc_conn, dev->ddf_dev);
     474        if (rc != EOK) {
     475                return rc;
     476        }
     477        rc = usb_hc_connection_open(&hc_conn);
     478        if (rc != EOK) {
     479                return rc;
     480        }
     481
     482        /* Destroy the pipes. */
     483        for (i = 0; i < dev->pipes_count; i++) {
     484                usb_pipe_unregister(dev->pipes[i].pipe, &hc_conn);
     485                free(dev->pipes[i].pipe);
     486        }
     487
     488        usb_hc_connection_close(&hc_conn);
     489
     490        free(dev->pipes);
     491        dev->pipes = NULL;
     492        dev->pipes_count = 0;
     493
     494        return EOK;
     495}
     496
     497/** Change interface setting of a device.
     498 * This function selects new alternate setting of an interface by issuing
     499 * proper USB command to the device and also creates new USB pipes
     500 * under @c dev->pipes.
     501 *
     502 * @warning This function is intended for drivers working at interface level.
     503 * For drivers controlling the whole device, you need to change interface
     504 * manually using usb_request_set_interface() and creating new pipes
     505 * with usb_pipe_initialize_from_configuration().
     506 *
     507 * @param dev USB device.
     508 * @param alternate_setting Alternate setting to choose.
     509 * @param endpoints New endpoint descriptions.
     510 * @return Error code.
     511 */
     512int usb_device_select_interface(usb_device_t *dev, uint8_t alternate_setting,
     513    usb_endpoint_description_t **endpoints)
     514{
     515        if (dev->interface_no < 0) {
     516                return EINVAL;
     517        }
     518
     519        int rc;
     520
     521        /* TODO: more transactional behavior. */
     522
     523        /* Destroy existing pipes. */
     524        rc = destroy_current_pipes(dev);
     525        if (rc != EOK) {
     526                return rc;
     527        }
     528
     529        /* Change the interface itself. */
     530        rc = usb_request_set_interface(&dev->ctrl_pipe, dev->interface_no,
     531            alternate_setting);
     532        if (rc != EOK) {
     533                return rc;
     534        }
     535
     536        /* Create new pipes. */
     537        rc = initialize_other_pipes(endpoints, dev);
     538
     539        return rc;
     540}
    442541
    443542/**
Note: See TracChangeset for help on using the changeset viewer.