Changeset ca56afa in mainline for uspace/lib/usb/src


Ignore:
Timestamp:
2011-02-25T09:46:23Z (15 years ago)
Author:
Matus Dekanek <smekideki@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d493ac17
Parents:
15b0432 (diff), a80849c (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 with /usb/development

Location:
uspace/lib/usb/src
Files:
7 edited

Legend:

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

    r15b0432 rca56afa  
    3434 */
    3535#include <ipc/devman.h>
     36#include <devman.h>
     37#include <async.h>
    3638#include <usb/ddfiface.h>
     39#include <usb/debug.h>
    3740#include <errno.h>
     41#include <assert.h>
    3842
    3943/** DDF interface for USB device, implementation for typical hub. */
     
    5660 * @return Error code.
    5761 */
    58 int usb_iface_get_hc_handle_hub_impl(device_t *device, devman_handle_t *handle)
     62int usb_iface_get_hc_handle_hub_impl(ddf_fun_t *fun, devman_handle_t *handle)
    5963{
    60         assert(device);
    61         return usb_hc_find(device->handle, handle);
     64        assert(fun);
     65        return usb_hc_find(fun->handle, handle);
    6266}
    6367
     
    6973 * @return Error code.
    7074 */
    71 int usb_iface_get_hc_handle_hub_child_impl(device_t *device,
     75int usb_iface_get_hc_handle_hub_child_impl(ddf_fun_t *fun,
    7276    devman_handle_t *handle)
    7377{
    74         assert(device);
    75         device_t *parent = device->parent;
     78        assert(fun != NULL);
    7679
    77         /* Default error, device does not support this operation. */
    78         int rc = ENOTSUP;
    79 
    80         if (parent && parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) {
    81                 usb_iface_t *usb_iface
    82                     = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE];
    83                 assert(usb_iface != NULL);
    84 
    85                 if (usb_iface->get_hc_handle) {
    86                         rc = usb_iface->get_hc_handle(parent, handle);
    87                 }
     80        int parent_phone = devman_parent_device_connect(fun->handle,
     81            IPC_FLAG_BLOCKING);
     82        if (parent_phone < 0) {
     83                return parent_phone;
    8884        }
    8985
    90         return rc;
     86        sysarg_t hc_handle;
     87        int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
     88            IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &hc_handle);
     89
     90        if (rc != EOK) {
     91                return rc;
     92        }
     93
     94        *handle = hc_handle;
     95
     96        return EOK;
    9197}
    9298
     
    97103 * @return Always EOK.
    98104 */
    99 int usb_iface_get_hc_handle_hc_impl(device_t *device, devman_handle_t *handle)
     105int usb_iface_get_hc_handle_hc_impl(ddf_fun_t *fun, devman_handle_t *handle)
    100106{
    101         assert(device);
     107        assert(fun);
    102108
    103109        if (handle != NULL) {
    104                 *handle = device->handle;
     110                *handle = fun->handle;
    105111        }
    106112
     
    115121 * @return Error code.
    116122 */
    117 int usb_iface_get_address_hub_impl(device_t *device, devman_handle_t handle,
     123int usb_iface_get_address_hub_impl(ddf_fun_t *fun, devman_handle_t handle,
    118124    usb_address_t *address)
    119125{
    120         assert(device);
    121         int parent_phone = devman_parent_device_connect(device->handle,
     126        assert(fun);
     127        int parent_phone = devman_parent_device_connect(fun->handle,
    122128            IPC_FLAG_BLOCKING);
    123129        if (parent_phone < 0) {
     
    150156 * @return Error code.
    151157 */
    152 int usb_iface_get_address_hub_child_impl(device_t *device,
     158int usb_iface_get_address_hub_child_impl(ddf_fun_t *fun,
    153159    devman_handle_t handle, usb_address_t *address)
    154160{
    155         assert(device);
    156         device_t *parent = device->parent;
    157 
    158         /* Default error, device does not support this operation. */
    159         int rc = ENOTSUP;
    160 
    161         if (parent && parent->ops && parent->ops->interfaces[USB_DEV_IFACE]) {
    162                 usb_iface_t *usb_iface
    163                     = (usb_iface_t *) parent->ops->interfaces[USB_DEV_IFACE];
    164                 assert(usb_iface != NULL);
    165 
    166                 if (usb_iface->get_address) {
    167                         rc = usb_iface->get_address(parent, handle, address);
    168                 }
     161        if (handle == 0) {
     162                handle = fun->handle;
    169163        }
    170 
    171         return rc;
     164        return usb_iface_get_address_hub_impl(fun, handle, address);
    172165}
    173166
  • uspace/lib/usb/src/hub.c

    r15b0432 rca56afa  
    3939#include <usbhc_iface.h>
    4040#include <errno.h>
     41#include <assert.h>
    4142
    4243/** Check that HC connection is alright.
     
    172173 *      request or requests for descriptors when creating match ids).
    173174 */
    174 int usb_hc_new_device_wrapper(device_t *parent, usb_hc_connection_t *connection,
     175int usb_hc_new_device_wrapper(ddf_dev_t *parent, usb_hc_connection_t *connection,
    175176    usb_speed_t dev_speed,
    176177    int (*enable_port)(int port_no, void *arg), int port_no, void *arg,
    177     usb_address_t *assigned_address, devman_handle_t *assigned_handle)
     178    usb_address_t *assigned_address, devman_handle_t *assigned_handle,
     179    ddf_dev_ops_t *dev_ops, void *new_dev_data, ddf_fun_t **new_fun)
    178180{
    179181        CHECK_CONNECTION(connection);
     
    251253        devman_handle_t child_handle;
    252254        rc = usb_device_register_child_in_devman(dev_addr, dev_conn.hc_handle,
    253             parent, &child_handle);
     255            parent, &child_handle,
     256            dev_ops, new_dev_data, new_fun);
    254257        if (rc != EOK) {
    255258                rc = ESTALL;
  • uspace/lib/usb/src/pipes.c

    r15b0432 rca56afa  
    3535#include <usb/usb.h>
    3636#include <usb/pipes.h>
     37#include <usb/debug.h>
    3738#include <usbhc_iface.h>
    3839#include <usb_iface.h>
     40#include <devman.h>
    3941#include <errno.h>
    4042#include <assert.h>
     
    4648 * @return USB address or error code.
    4749 */
    48 static usb_address_t get_my_address(int phone, device_t *dev)
     50static usb_address_t get_my_address(int phone, ddf_dev_t *dev)
    4951{
    5052        sysarg_t address;
     53
     54
     55        /*
     56         * We are sending special value as a handle - zero - to get
     57         * handle of the parent function (that handle was used
     58         * when registering our device @p dev.
     59         */
    5160        int rc = async_req_2_1(phone, DEV_IFACE_ID(USB_DEV_IFACE),
    5261            IPC_M_USB_GET_ADDRESS,
    53             dev->handle, &address);
     62            0, &address);
    5463
    5564        if (rc != EOK) {
     
    6574 * @return Interface number (negative code means any).
    6675 */
    67 int usb_device_get_assigned_interface(device_t *device)
     76int usb_device_get_assigned_interface(ddf_dev_t *device)
    6877{
    6978        int parent_phone = devman_parent_device_connect(device->handle,
     
    94103 */
    95104int usb_device_connection_initialize_from_device(
    96     usb_device_connection_t *connection, device_t *device)
     105    usb_device_connection_t *connection, ddf_dev_t *dev)
    97106{
    98107        assert(connection);
    99         assert(device);
     108        assert(dev);
    100109
    101110        int rc;
     
    103112        usb_address_t my_address;
    104113
    105         rc = usb_hc_find(device->handle, &hc_handle);
     114        rc = usb_hc_find(dev->handle, &hc_handle);
    106115        if (rc != EOK) {
    107116                return rc;
    108117        }
    109118
    110         int parent_phone = devman_parent_device_connect(device->handle,
     119        int parent_phone = devman_parent_device_connect(dev->handle,
    111120            IPC_FLAG_BLOCKING);
    112121        if (parent_phone < 0) {
     
    114123        }
    115124
    116         my_address = get_my_address(parent_phone, device);
     125        my_address = get_my_address(parent_phone, dev);
    117126        if (my_address < 0) {
    118127                rc = my_address;
     
    191200        assert(pipe);
    192201
    193         if (pipe->hc_phone >= 0) {
     202        if (usb_endpoint_pipe_is_session_started(pipe)) {
    194203                return EBUSY;
    195204        }
     
    217226        assert(pipe);
    218227
    219         if (pipe->hc_phone < 0) {
     228        if (!usb_endpoint_pipe_is_session_started(pipe)) {
    220229                return ENOENT;
    221230        }
     
    229238
    230239        return EOK;
     240}
     241
     242/** Tell whether a session is started (open) on the endpoint pipe.
     243 *
     244 * The expected usage of this function is in assertions for some
     245 * nested functions.
     246 *
     247 * @param pipe Endpoint pipe in question.
     248 * @return Whether @p pipe has opened a session.
     249 */
     250bool usb_endpoint_pipe_is_session_started(usb_endpoint_pipe_t *pipe)
     251{
     252        return (pipe->hc_phone >= 0);
    231253}
    232254
  • uspace/lib/usb/src/pipesio.c

    r15b0432 rca56afa  
    148148        }
    149149
    150         if (pipe->hc_phone < 0) {
     150        if (!usb_endpoint_pipe_is_session_started(pipe)) {
    151151                return EBADF;
    152152        }
     
    255255        }
    256256
    257         if (pipe->hc_phone < 0) {
     257        if (!usb_endpoint_pipe_is_session_started(pipe)) {
    258258                return EBADF;
    259259        }
     
    369369        }
    370370
    371         if (pipe->hc_phone < 0) {
     371        if (!usb_endpoint_pipe_is_session_started(pipe)) {
    372372                return EBADF;
    373373        }
     
    481481        }
    482482
    483         if (pipe->hc_phone < 0) {
     483        if (!usb_endpoint_pipe_is_session_started(pipe)) {
    484484                return EBADF;
    485485        }
  • uspace/lib/usb/src/recognise.c

    r15b0432 rca56afa  
    3434 */
    3535#include <sys/types.h>
     36#include <fibril_synch.h>
    3637#include <usb/pipes.h>
    3738#include <usb/recognise.h>
     
    4142#include <stdio.h>
    4243#include <errno.h>
     44#include <assert.h>
    4345
    4446static size_t device_name_index = 0;
    4547static FIBRIL_MUTEX_INITIALIZE(device_name_index_mutex);
    4648
    47 device_ops_t child_ops = {
     49ddf_dev_ops_t child_ops = {
    4850        .interfaces[USB_DEV_IFACE] = &usb_iface_hub_child_impl
    4951};
     
    308310        }
    309311
    310         /*
    311          * As a fallback, provide the simplest match id possible.
    312          */
    313         ADD_MATCHID_OR_RETURN(matches, 1, "usb&fallback");
    314 
    315312        return EOK;
    316313}
     
    326323int usb_device_register_child_in_devman(usb_address_t address,
    327324    devman_handle_t hc_handle,
    328     device_t *parent, devman_handle_t *child_handle)
     325    ddf_dev_t *parent, devman_handle_t *child_handle,
     326    ddf_dev_ops_t *dev_ops, void *dev_data, ddf_fun_t **child_fun)
    329327{
    330328        size_t this_device_name_index;
     
    335333        fibril_mutex_unlock(&device_name_index_mutex);
    336334
    337         device_t *child = NULL;
     335        ddf_fun_t *child = NULL;
    338336        char *child_name = NULL;
    339337        int rc;
     
    352350        }
    353351
    354         child = create_device();
     352        /*
     353         * TODO: Once the device driver framework support persistent
     354         * naming etc., something more descriptive could be created.
     355         */
     356        rc = asprintf(&child_name, "usbdev%02zu", this_device_name_index);
     357        if (rc < 0) {
     358                goto failure;
     359        }
     360
     361        child = ddf_fun_create(parent, fun_inner, child_name);
    355362        if (child == NULL) {
    356363                rc = ENOMEM;
     
    358365        }
    359366
    360         /*
    361          * TODO: Once the device driver framework support persistent
    362          * naming etc., something more descriptive could be created.
    363          */
    364         rc = asprintf(&child_name, "usbdev%02zu", this_device_name_index);
    365         if (rc < 0) {
    366                 goto failure;
    367         }
    368         child->parent = parent;
    369         child->name = child_name;
    370         child->ops = &child_ops;
     367        if (dev_ops != NULL) {
     368                child->ops = dev_ops;
     369        } else {
     370                child->ops = &child_ops;
     371        }
     372
     373        child->driver_data = dev_data;
    371374
    372375        rc = usb_endpoint_pipe_start_session(&ctrl_pipe);
     
    385388        }
    386389
    387         rc = child_device_register(child, parent);
     390        rc = ddf_fun_bind(child);
    388391        if (rc != EOK) {
    389392                goto failure;
     
    392395        if (child_handle != NULL) {
    393396                *child_handle = child->handle;
     397        }
     398
     399        if (child_fun != NULL) {
     400                *child_fun = child;
    394401        }
    395402
     
    400407                child->name = NULL;
    401408                /* This takes care of match_id deallocation as well. */
    402                 delete_device(child);
     409                ddf_fun_destroy(child);
    403410        }
    404411        if (child_name != NULL) {
  • uspace/lib/usb/src/request.c

    r15b0432 rca56afa  
    3535#include <usb/request.h>
    3636#include <errno.h>
     37#include <assert.h>
    3738
    3839#define MAX_DATA_LENGTH ((size_t)(0xFFFF))
     
    229230}
    230231
     232/** Retrieve USB descriptor, allocate space for it.
     233 *
     234 * @param[in] pipe Control endpoint pipe (session must be already started).
     235 * @param[in] request_type Request type (standard/class/vendor).
     236 * @param[in] descriptor_type Descriptor type (device/configuration/HID/...).
     237 * @param[in] descriptor_index Descriptor index.
     238 * @param[in] language Language index.
     239 * @param[out] buffer_ptr Where to store pointer to allocated buffer.
     240 * @param[out] buffer_size Where to store the size of the descriptor.
     241 * @return
     242 */
     243int usb_request_get_descriptor_alloc(usb_endpoint_pipe_t * pipe,
     244    usb_request_type_t request_type,
     245    uint8_t descriptor_type, uint8_t descriptor_index,
     246    uint16_t language,
     247    void **buffer_ptr, size_t *buffer_size)
     248{
     249        if (buffer_ptr == NULL) {
     250                return EBADMEM;
     251        }
     252
     253        int rc;
     254
     255        /*
     256         * Get only first byte to retrieve descriptor length.
     257         */
     258        uint8_t tmp_buffer[1];
     259        size_t bytes_transfered;
     260        rc = usb_request_get_descriptor(pipe, request_type,
     261            descriptor_type, descriptor_index, language,
     262            &tmp_buffer, 1, &bytes_transfered);
     263        if (rc != EOK) {
     264                return rc;
     265        }
     266        if (bytes_transfered != 1) {
     267                /* FIXME: some better error code? */
     268                return ESTALL;
     269        }
     270
     271        size_t size = tmp_buffer[0];
     272        if (size == 0) {
     273                /* FIXME: some better error code? */
     274                return ESTALL;
     275        }
     276
     277        /*
     278         * Allocate buffer and get the descriptor again.
     279         */
     280        void *buffer = malloc(size);
     281        if (buffer == NULL) {
     282                return ENOMEM;
     283        }
     284
     285        rc = usb_request_get_descriptor(pipe, request_type,
     286            descriptor_type, descriptor_index, language,
     287            buffer, size, &bytes_transfered);
     288        if (rc != EOK) {
     289                free(buffer);
     290                return rc;
     291        }
     292        if (bytes_transfered != size) {
     293                free(buffer);
     294                /* FIXME: some better error code? */
     295                return ESTALL;
     296        }
     297
     298        *buffer_ptr = buffer;
     299        if (buffer_size != NULL) {
     300                *buffer_size = size;
     301        }
     302
     303        return EOK;
     304}
     305
    231306/** Retrieve standard device descriptor of a USB device.
    232307 *
     
    354429}
    355430
     431/** Get list of supported languages by USB device.
     432 *
     433 * @param[in] pipe Control endpoint pipe (session must be already started).
     434 * @param[out] languages_ptr Where to store pointer to allocated array of
     435 *      supported languages.
     436 * @param[out] languages_count Number of supported languages.
     437 * @return Error code.
     438 */
     439int usb_request_get_supported_languages(usb_endpoint_pipe_t *pipe,
     440    l18_win_locales_t **languages_ptr, size_t *languages_count)
     441{
     442        int rc;
     443
     444        if (languages_ptr == NULL) {
     445                return EBADMEM;
     446        }
     447        if (languages_count == NULL) {
     448                return EBADMEM;
     449        }
     450
     451        uint8_t *string_descriptor = NULL;
     452        size_t string_descriptor_size = 0;
     453        rc = usb_request_get_descriptor_alloc(pipe,
     454            USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_STRING, 0, 0,
     455            (void **) &string_descriptor, &string_descriptor_size);
     456        if (rc != EOK) {
     457                return rc;
     458        }
     459        if (string_descriptor_size <= 2) {
     460                free(string_descriptor);
     461                return EEMPTY;
     462        }
     463        /* Substract first 2 bytes (length and descriptor type). */
     464        string_descriptor_size -= 2;
     465
     466        /* Odd number of bytes - descriptor is broken? */
     467        if ((string_descriptor_size % 2) != 0) {
     468                /* FIXME: shall we return with error or silently ignore? */
     469                free(string_descriptor);
     470                return ESTALL;
     471        }
     472
     473        size_t langs_count = string_descriptor_size / 2;
     474        l18_win_locales_t *langs
     475            = malloc(sizeof(l18_win_locales_t) * langs_count);
     476        if (langs == NULL) {
     477                free(string_descriptor);
     478                return ENOMEM;
     479        }
     480
     481        size_t i;
     482        for (i = 0; i < langs_count; i++) {
     483                /* Language code from the descriptor is in USB endianess. */
     484                /* FIXME: is this really correct? */
     485                uint16_t lang_code = (string_descriptor[2 + 2 * i + 1] << 8)
     486                    + string_descriptor[2 + 2 * i];
     487                langs[i] = uint16_usb2host(lang_code);
     488        }
     489
     490        free(string_descriptor);
     491
     492        *languages_ptr = langs;
     493        *languages_count =langs_count;
     494
     495        return EOK;
     496}
     497
     498/** Get string (descriptor) from USB device.
     499 *
     500 * The string is returned in native encoding of the operating system.
     501 * For HelenOS, that is UTF-8.
     502 *
     503 * @param[in] pipe Control endpoint pipe (session must be already started).
     504 * @param[in] index String index (in native endianess).
     505 * @param[in] lang String language (in native endianess).
     506 * @param[out] string_ptr Where to store allocated string in native encoding.
     507 * @return Error code.
     508 */
     509int usb_request_get_string(usb_endpoint_pipe_t *pipe,
     510    size_t index, l18_win_locales_t lang, char **string_ptr)
     511{
     512        if (string_ptr == NULL) {
     513                return EBADMEM;
     514        }
     515        /* Index is actually one byte value. */
     516        if (index > 0xFF) {
     517                return ERANGE;
     518        }
     519        /* Language is actually two byte value. */
     520        if (lang > 0xFFFF) {
     521                return ERANGE;
     522        }
     523
     524        int rc;
     525
     526        /* Prepare dynamically allocated variables. */
     527        uint8_t *string = NULL;
     528        wchar_t *string_chars = NULL;
     529
     530        /* Get the actual descriptor. */
     531        size_t string_size;
     532        rc = usb_request_get_descriptor_alloc(pipe,
     533            USB_REQUEST_TYPE_STANDARD, USB_DESCTYPE_STRING,
     534            index, uint16_host2usb(lang),
     535            (void **) &string, &string_size);
     536        if (rc != EOK) {
     537                goto leave;
     538        }
     539
     540        if (string_size <= 2) {
     541                rc =  EEMPTY;
     542                goto leave;
     543        }
     544        /* Substract first 2 bytes (length and descriptor type). */
     545        string_size -= 2;
     546
     547        /* Odd number of bytes - descriptor is broken? */
     548        if ((string_size % 2) != 0) {
     549                /* FIXME: shall we return with error or silently ignore? */
     550                rc = ESTALL;
     551                goto leave;
     552        }
     553
     554        size_t string_char_count = string_size / 2;
     555        string_chars = malloc(sizeof(wchar_t) * (string_char_count + 1));
     556        if (string_chars == NULL) {
     557                rc = ENOMEM;
     558                goto leave;
     559        }
     560
     561        /*
     562         * Build a wide string.
     563         * And do not forget to set NULL terminator (string descriptors
     564         * do not have them).
     565         */
     566        size_t i;
     567        for (i = 0; i < string_char_count; i++) {
     568                uint16_t uni_char = (string[2 + 2 * i + 1] << 8)
     569                    + string[2 + 2 * i];
     570                string_chars[i] = uni_char;
     571        }
     572        string_chars[string_char_count] = 0;
     573
     574
     575        /* Convert to normal string. */
     576        char *str = wstr_to_astr(string_chars);
     577        if (str == NULL) {
     578                rc = ENOMEM;
     579                goto leave;
     580        }
     581
     582        *string_ptr = str;
     583        rc = EOK;
     584
     585leave:
     586        if (string != NULL) {
     587                free(string);
     588        }
     589        if (string_chars != NULL) {
     590                free(string_chars);
     591        }
     592
     593        return rc;
     594}
     595
    356596/**
    357597 * @}
  • uspace/lib/usb/src/usbdevice.c

    r15b0432 rca56afa  
    3737#include <usb_iface.h>
    3838#include <usb/usbdevice.h>
     39#include <usb/debug.h>
    3940#include <errno.h>
     41#include <assert.h>
    4042
    4143/** Find host controller handle that is ancestor of given device.
     
    5557
    5658        devman_handle_t h;
     59        usb_log_debug("asking for HC handle (my handle is %zu).\n", device_handle);
    5760        int rc = async_req_1_1(parent_phone, DEV_IFACE_ID(USB_DEV_IFACE),
    5861            IPC_M_USB_GET_HOST_CONTROLLER_HANDLE, &h);
     
    7881 */
    7982int usb_hc_connection_initialize_from_device(usb_hc_connection_t *connection,
    80     device_t *device)
     83    ddf_dev_t *device)
    8184{
    8285        assert(connection);
Note: See TracChangeset for help on using the changeset viewer.