Changeset df6ded8 in mainline for uspace/lib/usbdev/src/devdrv.c


Ignore:
Timestamp:
2018-02-28T16:37:50Z (6 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1b20da0
Parents:
f5e5f73 (diff), b2dca8de (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.
git-author:
Jakub Jermar <jakub@…> (2018-02-28 16:06:42)
git-committer:
Jakub Jermar <jakub@…> (2018-02-28 16:37:50)
Message:

Merge github.com:helenos-xhci-team/helenos

This commit merges support for USB 3 and generally refactors, fixes,
extends and cleans up the existing USB framework.

Notable additions and features:

  • new host controller driver has been implemented to control various xHC models (among others, NEC Renesas uPD720200)
  • isochronous data transfer mode
  • support for explicit USB device removal
  • USB tablet driver
File:
1 edited

Legend:

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

    rf5e5f73 rdf6ded8  
    22 * Copyright (c) 2011 Vojtech Horky
    33 * Copyright (c) 2011 Jan Vesely
     4 * Copyright (c) 2018 Ondrej Hlavaty, Petr Manek, Michal Staruch
    45 * All rights reserved.
    56 *
     
    4849#include <devman.h>
    4950#include <errno.h>
     51#include <str_error.h>
    5052#include <stdlib.h>
    5153
     
    5658        /** Connection to device on USB bus */
    5759        usb_dev_session_t *bus_session;
    58        
     60
    5961        /** devman handle */
    6062        devman_handle_t handle;
    61        
     63
    6264        /** The default control pipe. */
    6365        usb_pipe_t ctrl_pipe;
    64        
     66
    6567        /** Other endpoint pipes.
    6668         *
     
    6971         */
    7072        usb_endpoint_mapping_t *pipes;
    71        
     73
    7274        /** Number of other endpoint pipes. */
    7375        size_t pipes_count;
    74        
     76
     77        /** USB address of this device */
     78        usb_address_t address;
     79
     80        /** Depth in the USB hub hiearchy */
     81        unsigned depth;
     82
     83        /** USB speed of this device */
     84        usb_speed_t speed;
     85
    7586        /** Current interface.
    7687         *
     
    7990         */
    8091        int interface_no;
    81        
     92
    8293        /** Alternative interfaces. */
    8394        usb_alternate_interfaces_t alternate_interfaces;
    84        
     95
    8596        /** Some useful descriptors for USB device. */
    8697        usb_device_descriptors_t descriptors;
    87        
     98
    8899        /** Generic DDF device backing this one. DO NOT TOUCH! */
    89100        ddf_dev_t *ddf_dev;
    90        
     101
    91102        /** Custom driver data.
    92103         *
     
    146157                return rc;
    147158        }
    148        
     159
    149160        /* Change current alternative */
    150161        usb_dev->alternate_interfaces.current = alternate_setting;
     
    255266
    256267        /* Register created pipes. */
     268        unsigned pipes_registered = 0;
    257269        for (size_t i = 0; i < pipe_count; i++) {
    258270                if (pipes[i].present) {
    259                         rc = usb_pipe_register(&pipes[i].pipe,
    260                             pipes[i].descriptor->poll_interval);
     271                        rc = usb_pipe_register(&pipes[i].pipe, pipes[i].descriptor, pipes[i].companion_descriptor);
    261272                        if (rc != EOK) {
    262273                                goto rollback_unregister_endpoints;
    263274                        }
    264275                }
     276                pipes_registered++;
    265277        }
    266278
     
    277289         */
    278290rollback_unregister_endpoints:
    279         for (size_t i = 0; i < pipe_count; i++) {
     291        for (size_t i = 0; i < pipes_registered; i++) {
    280292                if (pipes[i].present) {
    281293                        usb_pipe_unregister(&pipes[i].pipe);
     
    296308        assert(usb_dev);
    297309        assert(usb_dev->pipes || usb_dev->pipes_count == 0);
    298        
     310
    299311        /* Destroy the pipes. */
     312        int rc;
    300313        for (size_t i = 0; i < usb_dev->pipes_count; ++i) {
    301                 usb_log_debug2("Unregistering pipe %zu: %spresent.\n",
     314                usb_log_debug2("Unregistering pipe %zu: %spresent.",
    302315                    i, usb_dev->pipes[i].present ? "" : "not ");
    303                 if (usb_dev->pipes[i].present)
    304                         usb_pipe_unregister(&usb_dev->pipes[i].pipe);
    305         }
    306        
     316
     317                rc = usb_device_unmap_ep(usb_dev->pipes + i);
     318                if (rc != EOK && rc != ENOENT)
     319                        usb_log_warning("Unregistering pipe %zu failed: %s", i, str_error(rc));
     320        }
     321
    307322        free(usb_dev->pipes);
    308323        usb_dev->pipes = NULL;
     
    327342}
    328343
    329 usb_endpoint_mapping_t * usb_device_get_mapped_ep(
    330     usb_device_t *usb_dev, usb_endpoint_t ep)
    331 {
    332         assert(usb_dev);
    333         for (unsigned i = 0; i < usb_dev->pipes_count; ++i) {
    334                 if (usb_dev->pipes[i].pipe.endpoint_no == ep)
    335                         return &usb_dev->pipes[i];
    336         }
    337         return NULL;
    338 }
    339 
    340 int usb_device_get_iface_number(usb_device_t *usb_dev)
     344int usb_device_unmap_ep(usb_endpoint_mapping_t *epm)
     345{
     346        assert(epm);
     347
     348        if (!epm->present)
     349                return ENOENT;
     350
     351        const int rc = usb_pipe_unregister(&epm->pipe);
     352        if (rc != EOK)
     353                return rc;
     354
     355        epm->present = false;
     356        return EOK;
     357}
     358
     359usb_address_t usb_device_get_address(const usb_device_t *usb_dev)
     360{
     361        assert(usb_dev);
     362        return usb_dev->depth;
     363}
     364
     365unsigned usb_device_get_depth(const usb_device_t *usb_dev)
     366{
     367        assert(usb_dev);
     368        return usb_dev->depth;
     369}
     370
     371usb_speed_t usb_device_get_speed(const usb_device_t *usb_dev)
     372{
     373        assert(usb_dev);
     374        return usb_dev->speed;
     375}
     376
     377int usb_device_get_iface_number(const usb_device_t *usb_dev)
    341378{
    342379        assert(usb_dev);
     
    344381}
    345382
    346 devman_handle_t usb_device_get_devman_handle(usb_device_t *usb_dev)
     383devman_handle_t usb_device_get_devman_handle(const usb_device_t *usb_dev)
    347384{
    348385        assert(usb_dev);
     
    394431 */
    395432static errno_t usb_device_init(usb_device_t *usb_dev, ddf_dev_t *ddf_dev,
    396     const usb_endpoint_description_t **endpoints, const char **errstr_ptr,
    397     devman_handle_t handle, int interface_no)
     433    const usb_endpoint_description_t **endpoints, const char **errstr_ptr)
    398434{
    399435        assert(usb_dev != NULL);
     
    403439
    404440        usb_dev->ddf_dev = ddf_dev;
    405         usb_dev->handle = handle;
    406         usb_dev->interface_no = interface_no;
    407441        usb_dev->driver_data = NULL;
    408442        usb_dev->descriptors.full_config = NULL;
     
    411445        usb_dev->pipes = NULL;
    412446
    413         usb_dev->bus_session = usb_dev_connect(handle);
     447        usb_dev->bus_session = usb_dev_connect(usb_dev->handle);
    414448
    415449        if (!usb_dev->bus_session) {
     
    420454        /* This pipe was registered by the hub driver,
    421455         * during device initialization. */
    422         errno_t rc = usb_pipe_initialize_default_control(
    423             &usb_dev->ctrl_pipe, usb_dev->bus_session);
     456        errno_t rc = usb_pipe_initialize_default_control(&usb_dev->ctrl_pipe, usb_dev->bus_session);
    424457        if (rc != EOK) {
    425458                usb_dev_disconnect(usb_dev->bus_session);
     
    440473         * it makes no sense to speak about alternate interfaces when
    441474         * controlling a device. */
    442         rc = usb_alternate_interfaces_init(&usb_dev->alternate_interfaces,
     475        usb_alternate_interfaces_init(&usb_dev->alternate_interfaces,
    443476            usb_dev->descriptors.full_config,
    444477            usb_dev->descriptors.full_config_size, usb_dev->interface_no);
     
    457490}
    458491
    459 static errno_t usb_device_get_info(async_sess_t *sess, devman_handle_t *handle,
    460         int *iface_no)
    461 {
    462         assert(handle);
    463         assert(iface_no);
    464        
     492static errno_t usb_device_get_info(async_sess_t *sess, usb_device_t *dev)
     493{
     494        assert(dev);
     495
    465496        async_exch_t *exch = async_exchange_begin(sess);
    466497        if (!exch)
    467498                return EPARTY;
    468        
    469         errno_t ret = usb_get_my_device_handle(exch, handle);
     499
     500        usb_device_desc_t dev_desc;
     501        const errno_t ret = usb_get_my_description(exch, &dev_desc);
     502
    470503        if (ret == EOK) {
    471                 ret = usb_get_my_interface(exch, iface_no);
    472                 if (ret == ENOTSUP) {
    473                         *iface_no = -1;
    474                         ret = EOK;
    475                 }
    476         }
    477        
     504                dev->address = dev_desc.address;
     505                dev->depth = dev_desc.depth;
     506                dev->speed = dev_desc.speed;
     507                dev->handle = dev_desc.handle;
     508                dev->interface_no = dev_desc.iface;
     509        }
     510
    478511        async_exchange_end(exch);
    479512        return ret;
     
    485518        assert(ddf_dev);
    486519        assert(err);
    487 
    488         devman_handle_t h = 0;
    489         int iface_no = -1;
    490520
    491521        async_sess_t *sess = ddf_dev_parent_sess_get(ddf_dev);
    492522        if (sess == NULL)
    493523                return ENOMEM;
    494         const errno_t ret = usb_device_get_info(sess, &h, &iface_no);
    495         if (ret != EOK)
    496                 return ret;
    497524
    498525        usb_device_t *usb_dev =
     
    502529                return ENOMEM;
    503530        }
    504        
    505         return usb_device_init(usb_dev, ddf_dev, desc, err, h, iface_no);
     531
     532        const errno_t ret = usb_device_get_info(sess, usb_dev);
     533        if (ret != EOK)
     534                return ret;
     535
     536        return usb_device_init(usb_dev, ddf_dev, desc, err);
    506537}
    507538
     
    517548usb_device_t * usb_device_create(devman_handle_t handle)
    518549{
    519         devman_handle_t h = 0;
    520         int iface_no = -1;
    521 
    522         async_sess_t *sess = devman_device_connect(handle, IPC_FLAG_BLOCKING);
    523         errno_t ret = usb_device_get_info(sess, &h, &iface_no);
    524         if (sess)
    525                 async_hangup(sess);
    526         if (ret != EOK)
    527                 return NULL;
    528 
    529550        usb_device_t *usb_dev = malloc(sizeof(usb_device_t));
    530551        if (!usb_dev)
    531552                return NULL;
    532553
     554        async_sess_t *sess = devman_device_connect(handle, IPC_FLAG_BLOCKING);
     555        errno_t ret = usb_device_get_info(sess, usb_dev);
     556        if (sess)
     557                async_hangup(sess);
     558        if (ret != EOK) {
     559                free(usb_dev);
     560                return NULL;
     561        }
     562
    533563        const char* dummy = NULL;
    534         ret = usb_device_init(usb_dev, NULL, NULL, &dummy, handle, iface_no);
     564        ret = usb_device_init(usb_dev, NULL, NULL, &dummy);
    535565        if (ret != EOK) {
    536566                free(usb_dev);
Note: See TracChangeset for help on using the changeset viewer.