Changeset 237df2f in mainline for uspace/lib/usbhost/src/ddf_helpers.c


Ignore:
Timestamp:
2013-01-04T16:49:53Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0e97b4b5
Parents:
daf199f
Message:

libusbhost: Add host side device initialization.

Add new roothub initialization functions (the old one is going away).
change usb device names created by host controller to be less awkward.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/usbhost/src/ddf_helpers.c

    rdaf199f r237df2f  
    3535
    3636#include <usb_iface.h>
     37#include <usb/classes/classes.h>
    3738#include <usb/debug.h>
     39#include <usb/descriptor.h>
     40#include <usb/request.h>
    3841#include <errno.h>
    3942#include <str_error.h>
    4043
    4144#include "ddf_helpers.h"
     45
     46#define CTRL_PIPE_MIN_PACKET_SIZE 8
    4247
    4348extern usbhc_iface_t hcd_iface;
     
    119124};
    120125
     126#define GET_DEVICE_DESC(size) \
     127{ \
     128        .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST \
     129            | (USB_REQUEST_TYPE_STANDARD << 5) \
     130            | USB_REQUEST_RECIPIENT_DEVICE, \
     131        .request = USB_DEVREQ_GET_DESCRIPTOR, \
     132        .value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8), \
     133        .index = uint16_host2usb(0), \
     134        .length = uint16_host2usb(size), \
     135};
     136
     137#define SET_ADDRESS(address) \
     138{ \
     139        .request_type = SETUP_REQUEST_TYPE_HOST_TO_DEVICE \
     140            | (USB_REQUEST_TYPE_STANDARD << 5) \
     141            | USB_REQUEST_RECIPIENT_DEVICE, \
     142        .request = USB_DEVREQ_SET_ADDRESS, \
     143        .value = uint16_host2usb(address), \
     144        .index = uint16_host2usb(0), \
     145        .length = uint16_host2usb(0), \
     146};
     147
     148static const usb_device_request_setup_packet_t set_address = {
     149        .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST
     150            | (USB_REQUEST_TYPE_STANDARD << 5)
     151            | USB_REQUEST_RECIPIENT_DEVICE,
     152        .request = USB_DEVREQ_GET_DESCRIPTOR,
     153        .value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8),
     154        .index = uint16_host2usb(0),
     155        .length = uint16_host2usb(CTRL_PIPE_MIN_PACKET_SIZE),
     156};
     157
    121158int hcd_ddf_add_usb_device(ddf_dev_t *parent,
    122159    usb_address_t address, usb_speed_t speed, const char *name,
     
    127164        devman_handle_t hc_handle = ddf_fun_get_handle(hc_dev->hc_fun);
    128165
    129         char default_name[8]; /* usbxyzs */
     166        char default_name[10] = { 0 }; /* usbxyz-ss */
    130167        if (!name) {
    131168                snprintf(default_name, sizeof(default_name) - 1,
    132                     "usb%u%c", address, usb_str_speed(speed)[0]);
     169                    "usb%u-%cs", address, usb_str_speed(speed)[0]);
    133170                name = default_name;
    134171        }
     
    169206        list_append(&info->link, &hc_dev->devices);
    170207        return EOK;
     208}
     209
     210
     211#define ADD_MATCHID_OR_RETURN(list, sc, str, ...) \
     212do { \
     213        match_id_t *mid = malloc(sizeof(match_id_t)); \
     214        if (!mid) { \
     215                clean_match_ids(list); \
     216                return ENOMEM; \
     217        } \
     218        char *id = NULL; \
     219        int ret = asprintf(&id, str, ##__VA_ARGS__); \
     220        if (ret < 0) { \
     221                clean_match_ids(list); \
     222                free(mid); \
     223                return ENOMEM; \
     224        } \
     225        mid->score = sc; \
     226        mid->id = id; \
     227        add_match_id(list, mid); \
     228} while (0)
     229               
     230
     231/* This is a copy of lib/usbdev/src/recognise.c */
     232static int create_match_ids(match_id_list_t *l,
     233    usb_standard_device_descriptor_t *d)
     234{
     235        assert(l);
     236        assert(d);
     237       
     238        if (d->vendor_id != 0) {
     239                /* First, with release number. */
     240                ADD_MATCHID_OR_RETURN(l, 100,
     241                    "usb&vendor=%#04x&product=%#04x&release=%x.%x",
     242                    d->vendor_id, d->product_id, (d->device_version >> 8),
     243                    (d->device_version & 0xff));
     244       
     245                /* Next, without release number. */     
     246                ADD_MATCHID_OR_RETURN(l, 90, "usb&vendor=%#04x&product=%#04x",
     247                    d->vendor_id, d->product_id);
     248        }
     249
     250        /* Class match id */
     251        ADD_MATCHID_OR_RETURN(l, 50, "usb&class=%s",
     252            usb_str_class(d->device_class));
     253
     254        /* As a last resort, try fallback driver. */
     255        ADD_MATCHID_OR_RETURN(l, 10, "usb&fallback");
     256
     257        return EOK;
     258
     259}
     260
     261int hcd_ddf_new_device(ddf_dev_t *device)
     262{
     263        assert(device);
     264
     265        hcd_t *hcd = dev_to_hcd(device);
     266        assert(hcd);
     267       
     268        usb_speed_t speed = USB_SPEED_MAX;
     269
     270        /* This checks whether the default address is reserved and gets speed */
     271        int ret = usb_device_manager_get_info_by_address(&hcd->dev_manager,
     272                USB_ADDRESS_DEFAULT, NULL, &speed);
     273        if (ret != EOK) {
     274                return ret;
     275        }
     276
     277        static const usb_target_t default_target = {{
     278                .address = USB_ADDRESS_DEFAULT,
     279                .endpoint = 0,
     280        }};
     281
     282        const usb_address_t address = hcd_request_address(hcd, speed);
     283        if (address < 0)
     284                return address;
     285
     286        const usb_target_t target = {{
     287                .address = address,
     288                .endpoint = 0,
     289        }};
     290
     291        /* Add default pipe on default address */
     292        ret = hcd_add_ep(hcd,
     293            default_target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL,
     294            CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE);
     295
     296        if (ret != EOK) {
     297                hcd_release_address(hcd, address);
     298                return ret;
     299        }
     300
     301        /* Get max packet size for default pipe */
     302        usb_standard_device_descriptor_t desc = { 0 };
     303        static const usb_device_request_setup_packet_t get_device_desc_8 =
     304            GET_DEVICE_DESC(CTRL_PIPE_MIN_PACKET_SIZE);
     305
     306        // TODO CALLBACKS
     307        ssize_t got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_IN,
     308            &desc, CTRL_PIPE_MIN_PACKET_SIZE, *(uint64_t *)&get_device_desc_8,
     309            "read first 8 bytes of dev descriptor");
     310
     311        if (got != CTRL_PIPE_MIN_PACKET_SIZE) {
     312                hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH);
     313                hcd_release_address(hcd, address);
     314                return got < 0 ? got : EOVERFLOW;
     315        }
     316
     317        /* Register EP on the new address */
     318        ret = hcd_add_ep(hcd, target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL,
     319            desc.max_packet_size, desc.max_packet_size);
     320        if (ret != EOK) {
     321                hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH);
     322                hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
     323                hcd_release_address(hcd, address);
     324                return ret;
     325        }
     326
     327        /* Set new address */
     328        const usb_device_request_setup_packet_t set_address =
     329            SET_ADDRESS(target.address);
     330
     331        // TODO CALLBACKS
     332        got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_OUT,
     333            NULL, 0, *(uint64_t *)&set_address, "set address");
     334
     335        hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH);
     336
     337        if (got != 0) {
     338                hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
     339                hcd_release_address(hcd, address);
     340                return got;
     341        }
     342       
     343        /* Get std device descriptor */
     344        static const usb_device_request_setup_packet_t get_device_desc =
     345            GET_DEVICE_DESC(sizeof(desc));
     346
     347        // TODO CALLBACKS
     348        got = hcd_send_batch_sync(hcd, target, USB_DIRECTION_IN,
     349            &desc, sizeof(desc), *(uint64_t *)&get_device_desc,
     350            "read device descriptor");
     351        if (ret != EOK) {
     352                hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
     353                hcd_release_address(hcd, target.address);
     354                return got < 0 ? got : EOVERFLOW;
     355        }
     356       
     357        /* Create match ids from the device descriptor */
     358        match_id_list_t mids;
     359        init_match_ids(&mids);
     360
     361        ret = create_match_ids(&mids, &desc);
     362        if (ret != EOK) {
     363                hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
     364                hcd_release_address(hcd, target.address);
     365                return ret;
     366        }
     367       
     368               
     369
     370        /* Register device */   
     371        ret = hcd_ddf_add_usb_device(device, address, speed, NULL, &mids);
     372        clean_match_ids(&mids);
     373        if (ret != EOK) {
     374                hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
     375                hcd_release_address(hcd, target.address);
     376                return ret;
     377        }
     378
     379        return ret;
     380}
     381
     382/** Announce root hub to the DDF
     383 *
     384 * @param[in] device Host controller ddf device
     385 * @param[in] speed roothub communication speed
     386 * @return Error code
     387 */
     388int hcd_ddf_setup_root_hub(ddf_dev_t *device, usb_speed_t speed)
     389{
     390        assert(device);
     391        hcd_t *hcd = dev_to_hcd(device);
     392        assert(hcd);
     393
     394        hcd_reserve_default_address(hcd, speed);
     395        int ret = hcd_ddf_new_device(device);
     396        hcd_release_default_address(hcd);
     397        return ret;
    171398}
    172399
Note: See TracChangeset for help on using the changeset viewer.