Ignore:
File:
1 edited

Legend:

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

    rcccd60c3 r41df71f9  
    3535
    3636#include <usb/classes/classes.h>
     37#include <usb/host/bus.h>
    3738#include <usb/debug.h>
    3839#include <usb/descriptor.h>
     
    4950#include <fibril_synch.h>
    5051#include <macros.h>
    51 #include <stdio.h>
    5252#include <stdlib.h>
    5353#include <str_error.h>
    5454#include <usb_iface.h>
     55#include <usbhc_iface.h>
    5556
    5657#include "ddf_helpers.h"
    57 
    58 #define CTRL_PIPE_MIN_PACKET_SIZE 8
    59 
    60 typedef struct usb_dev {
    61         link_t link;
    62         list_t devices;
    63         fibril_mutex_t guard;
    64         ddf_fun_t *fun;
    65         usb_address_t address;
    66         usb_speed_t speed;
    67         usb_address_t tt_address;
    68         unsigned port;
    69 } usb_dev_t;
    7058
    7159typedef struct hc_dev {
    7260        ddf_fun_t *ctl_fun;
    7361        hcd_t hcd;
    74         usb_dev_t *root_hub;
    7562} hc_dev_t;
    7663
     
    9178
    9279
    93 static int hcd_ddf_new_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port);
    94 static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port);
     80static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, device_t *hub_dev, unsigned port);
     81static int hcd_ddf_remove_device(ddf_dev_t *device, device_t *hub, unsigned port);
    9582
    9683
     
    9986/** Register endpoint interface function.
    10087 * @param fun DDF function.
    101  * @param address USB address of the device.
    102  * @param endpoint USB endpoint number to be registered.
    103  * @param transfer_type Endpoint's transfer type.
    104  * @param direction USB communication direction the endpoint is capable of.
    105  * @param max_packet_size Maximu size of packets the endpoint accepts.
    106  * @param interval Preferred timeout between communication.
     88 * @param endpoint_desc Endpoint description.
    10789 * @return Error code.
    10890 */
    10991static int register_endpoint(
    110     ddf_fun_t *fun, usb_endpoint_t endpoint,
    111     usb_transfer_type_t transfer_type, usb_direction_t direction,
    112     size_t max_packet_size, unsigned packets, unsigned interval)
     92        ddf_fun_t *fun, usb_endpoint_desc_t *endpoint_desc)
    11393{
    11494        assert(fun);
    11595        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
    116         usb_dev_t *dev = ddf_fun_data_get(fun);
     96        device_t *dev = ddf_fun_data_get(fun);
    11797        assert(hcd);
    118         assert(dev);
    119         const size_t size = max_packet_size;
    120         const usb_target_t target =
    121             {{.address = dev->address, .endpoint = endpoint}};
     98        assert(hcd->bus);
     99        assert(dev);
    122100
    123101        usb_log_debug("Register endpoint %d:%d %s-%s %zuB %ums.\n",
    124             dev->address, endpoint, usb_str_transfer_type(transfer_type),
    125             usb_str_direction(direction), max_packet_size, interval);
    126 
    127         return hcd_add_ep(hcd, target, direction, transfer_type,
    128             max_packet_size, packets, size, dev->tt_address, dev->port);
    129 }
    130 
    131 /** Unregister endpoint interface function.
    132  * @param fun DDF function.
    133  * @param address USB address of the endpoint.
    134  * @param endpoint USB endpoint number.
    135  * @param direction Communication direction of the enpdoint to unregister.
    136  * @return Error code.
    137  */
     102                dev->address, endpoint_desc->endpoint_no,
     103                usb_str_transfer_type(endpoint_desc->transfer_type),
     104                usb_str_direction(endpoint_desc->direction),
     105                endpoint_desc->max_packet_size, endpoint_desc->usb2.polling_interval);
     106
     107        return bus_add_endpoint(hcd->bus, dev, endpoint_desc, NULL);
     108}
     109
     110 /** Unregister endpoint interface function.
     111  * @param fun DDF function.
     112  * @param endpoint_desc Endpoint description.
     113  * @return Error code.
     114  */
    138115static int unregister_endpoint(
    139     ddf_fun_t *fun, usb_endpoint_t endpoint, usb_direction_t direction)
     116        ddf_fun_t *fun, usb_endpoint_desc_t *endpoint_desc)
    140117{
    141118        assert(fun);
    142119        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
    143         usb_dev_t *dev = ddf_fun_data_get(fun);
     120        device_t *dev = ddf_fun_data_get(fun);
    144121        assert(hcd);
    145         assert(dev);
    146         const usb_target_t target =
    147             {{.address = dev->address, .endpoint = endpoint}};
     122        assert(hcd->bus);
     123        assert(dev);
     124
     125        const usb_target_t target = {{
     126                .address = dev->address,
     127                .endpoint = endpoint_desc->endpoint_no
     128        }};
     129
    148130        usb_log_debug("Unregister endpoint %d:%d %s.\n",
    149             dev->address, endpoint, usb_str_direction(direction));
    150         return hcd_remove_ep(hcd, target, direction);
     131                dev->address, endpoint_desc->endpoint_no,
     132                usb_str_direction(endpoint_desc->direction));
     133
     134        endpoint_t *ep = bus_find_endpoint(hcd->bus, dev, target, endpoint_desc->direction);
     135        if (!ep)
     136                return ENOENT;
     137
     138        return bus_remove_endpoint(hcd->bus, ep);
    151139}
    152140
     
    155143        assert(fun);
    156144        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
    157         usb_dev_t *dev = ddf_fun_data_get(fun);
     145        device_t *dev = ddf_fun_data_get(fun);
    158146        assert(hcd);
     147        assert(hcd->bus);
    159148        assert(dev);
    160149
    161150        usb_log_debug("Device %d requested default address at %s speed\n",
    162151            dev->address, usb_str_speed(speed));
    163         return hcd_reserve_default_address(hcd, speed);
     152        return bus_reserve_default_address(hcd->bus, speed);
    164153}
    165154
     
    168157        assert(fun);
    169158        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
    170         usb_dev_t *dev = ddf_fun_data_get(fun);
     159        device_t *dev = ddf_fun_data_get(fun);
    171160        assert(hcd);
     161        assert(hcd->bus);
    172162        assert(dev);
    173163
    174164        usb_log_debug("Device %d released default address\n", dev->address);
    175         return hcd_release_default_address(hcd);
     165        return bus_release_default_address(hcd->bus);
    176166}
    177167
     
    179169{
    180170        assert(fun);
     171        ddf_dev_t *hc = ddf_fun_get_dev(fun);
     172        assert(hc);
     173        hcd_t *hcd = dev_to_hcd(hc);
     174        assert(hcd);
     175        device_t *hub = ddf_fun_data_get(fun);
     176        assert(hub);
     177
     178        usb_log_debug("Hub %d reported a new USB device on port: %u\n",
     179            hub->address, port);
     180        return hcd_ddf_new_device(hcd, hc, hub, port);
     181}
     182
     183static int device_remove(ddf_fun_t *fun, unsigned port)
     184{
     185        assert(fun);
    181186        ddf_dev_t *ddf_dev = ddf_fun_get_dev(fun);
    182         usb_dev_t *dev = ddf_fun_data_get(fun);
    183         assert(ddf_dev);
    184         assert(dev);
    185         usb_log_debug("Hub %d reported a new USB device on port: %u\n",
    186             dev->address, port);
    187         return hcd_ddf_new_device(ddf_dev, dev, port);
    188 }
    189 
    190 static int device_remove(ddf_fun_t *fun, unsigned port)
    191 {
    192         assert(fun);
    193         ddf_dev_t *ddf_dev = ddf_fun_get_dev(fun);
    194         usb_dev_t *dev = ddf_fun_data_get(fun);
     187        device_t *dev = ddf_fun_data_get(fun);
    195188        assert(ddf_dev);
    196189        assert(dev);
     
    224217 * @return Error code.
    225218 */
    226 static int dev_read(ddf_fun_t *fun, usb_endpoint_t endpoint,
    227     uint64_t setup_data, uint8_t *data, size_t size,
    228     usbhc_iface_transfer_in_callback_t callback, void *arg)
    229 {
    230         assert(fun);
    231         usb_dev_t *usb_dev = ddf_fun_data_get(fun);
    232         assert(usb_dev);
    233         const usb_target_t target = {{
    234             .address =  usb_dev->address,
    235             .endpoint = endpoint,
    236         }};
    237         return hcd_send_batch(dev_to_hcd(ddf_fun_get_dev(fun)), target,
    238             USB_DIRECTION_IN, data, size, setup_data, callback, NULL, arg,
    239             "READ");
     219static int dev_read(ddf_fun_t *fun, usb_target_t target,
     220    uint64_t setup_data, char *data, size_t size,
     221    usbhc_iface_transfer_callback_t callback, void *arg)
     222{
     223        assert(fun);
     224        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
     225        device_t *dev = ddf_fun_data_get(fun);
     226        assert(dev);
     227
     228        target.address = dev->address;
     229
     230        return hcd_send_batch(hcd, dev, target, USB_DIRECTION_IN,
     231            data, size, setup_data,
     232            callback, arg, "READ");
    240233}
    241234
     
    250243 * @return Error code.
    251244 */
    252 static int dev_write(ddf_fun_t *fun, usb_endpoint_t endpoint,
    253     uint64_t setup_data, const uint8_t *data, size_t size,
    254     usbhc_iface_transfer_out_callback_t callback, void *arg)
    255 {
    256         assert(fun);
    257         usb_dev_t *usb_dev = ddf_fun_data_get(fun);
    258         assert(usb_dev);
    259         const usb_target_t target = {{
    260             .address =  usb_dev->address,
    261             .endpoint = endpoint,
    262         }};
    263         return hcd_send_batch(dev_to_hcd(ddf_fun_get_dev(fun)),
    264             target, USB_DIRECTION_OUT, (uint8_t*)data, size, setup_data, NULL,
     245static int dev_write(ddf_fun_t *fun, usb_target_t target,
     246    uint64_t setup_data, const char *data, size_t size,
     247    usbhc_iface_transfer_callback_t callback, void *arg)
     248{
     249        assert(fun);
     250        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
     251        device_t *dev = ddf_fun_data_get(fun);
     252        assert(dev);
     253
     254        target.address = dev->address;
     255
     256        return hcd_send_batch(hcd, dev, target, USB_DIRECTION_OUT,
     257            (char *) data, size, setup_data,
    265258            callback, arg, "WRITE");
    266259}
     
    269262static usb_iface_t usb_iface = {
    270263        .get_my_device_handle = get_my_device_handle,
    271 
     264};
     265
     266/** USB host controller interface */
     267static usbhc_iface_t usbhc_iface = {
    272268        .reserve_default_address = reserve_default_address,
    273269        .release_default_address = release_default_address,
     
    286282static ddf_dev_ops_t usb_ops = {
    287283        .interfaces[USB_DEV_IFACE] = &usb_iface,
     284        .interfaces[USBHC_DEV_IFACE] = &usbhc_iface,
    288285};
    289286
    290287
    291288/* DDF HELPERS */
    292 
    293 #define GET_DEVICE_DESC(size) \
    294 { \
    295         .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST \
    296             | (USB_REQUEST_TYPE_STANDARD << 5) \
    297             | USB_REQUEST_RECIPIENT_DEVICE, \
    298         .request = USB_DEVREQ_GET_DESCRIPTOR, \
    299         .value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8), \
    300         .index = uint16_host2usb(0), \
    301         .length = uint16_host2usb(size), \
    302 };
    303 
    304 #define SET_ADDRESS(address) \
    305 { \
    306         .request_type = SETUP_REQUEST_TYPE_HOST_TO_DEVICE \
    307             | (USB_REQUEST_TYPE_STANDARD << 5) \
    308             | USB_REQUEST_RECIPIENT_DEVICE, \
    309         .request = USB_DEVREQ_SET_ADDRESS, \
    310         .value = uint16_host2usb(address), \
    311         .index = uint16_host2usb(0), \
    312         .length = uint16_host2usb(0), \
    313 };
    314 
    315 static int hcd_ddf_add_device(ddf_dev_t *parent, usb_dev_t *hub_dev,
    316     unsigned port, usb_address_t address, usb_speed_t speed, const char *name,
    317     const match_id_list_t *mids)
    318 {
    319         assert(parent);
    320 
    321         char default_name[10] = { 0 }; /* usbxyz-ss */
    322         if (!name) {
    323                 snprintf(default_name, sizeof(default_name) - 1,
    324                     "usb%u-%cs", address, usb_str_speed(speed)[0]);
    325                 name = default_name;
    326         }
    327 
    328         ddf_fun_t *fun = ddf_fun_create(parent, fun_inner, name);
    329         if (!fun)
    330                 return ENOMEM;
    331         usb_dev_t *info = ddf_fun_data_alloc(fun, sizeof(usb_dev_t));
    332         if (!info) {
    333                 ddf_fun_destroy(fun);
    334                 return ENOMEM;
    335         }
    336         info->address = address;
    337         info->speed = speed;
    338         info->fun = fun;
    339         info->port = port;
    340         info->tt_address = hub_dev ? hub_dev->tt_address : -1;
    341         link_initialize(&info->link);
    342         list_initialize(&info->devices);
    343         fibril_mutex_initialize(&info->guard);
    344 
    345         if (hub_dev && hub_dev->speed == USB_SPEED_HIGH && usb_speed_is_11(speed))
    346                 info->tt_address = hub_dev->address;
    347 
    348         ddf_fun_set_ops(fun, &usb_ops);
    349         list_foreach(mids->ids, link, const match_id_t, mid) {
    350                 ddf_fun_add_match_id(fun, mid->id, mid->score);
    351         }
    352 
    353         int ret = ddf_fun_bind(fun);
    354         if (ret != EOK) {
    355                 ddf_fun_destroy(fun);
    356                 return ret;
    357         }
    358 
    359         if (hub_dev) {
    360                 fibril_mutex_lock(&hub_dev->guard);
    361                 list_append(&info->link, &hub_dev->devices);
    362                 fibril_mutex_unlock(&hub_dev->guard);
    363         } else {
    364                 hc_dev_t *hc_dev = dev_to_hc_dev(parent);
    365                 assert(hc_dev->root_hub == NULL);
    366                 hc_dev->root_hub = info;
    367         }
    368         return EOK;
    369 }
    370289
    371290#define ADD_MATCHID_OR_RETURN(list, sc, str, ...) \
     
    394313        assert(l);
    395314        assert(d);
    396        
     315
    397316        if (d->vendor_id != 0) {
    398317                /* First, with release number. */
     
    401320                    d->vendor_id, d->product_id, (d->device_version >> 8),
    402321                    (d->device_version & 0xff));
    403        
     322
    404323                /* Next, without release number. */
    405324                ADD_MATCHID_OR_RETURN(l, 90, "usb&vendor=%#04x&product=%#04x",
     
    415334
    416335        return EOK;
    417 
    418 }
    419 
    420 static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub,
     336}
     337
     338static int hcd_ddf_remove_device(ddf_dev_t *device, device_t *hub,
    421339    unsigned port)
    422340{
     
    425343        hcd_t *hcd = dev_to_hcd(device);
    426344        assert(hcd);
     345        assert(hcd->bus);
    427346
    428347        hc_dev_t *hc_dev = dev_to_hc_dev(device);
     
    431350        fibril_mutex_lock(&hub->guard);
    432351
    433         usb_dev_t *victim = NULL;
    434 
    435         list_foreach(hub->devices, link, usb_dev_t, it) {
     352        device_t *victim = NULL;
     353
     354        list_foreach(hub->devices, link, device_t, it) {
    436355                if (it->port == port) {
    437356                        victim = it;
     
    440359        }
    441360        if (victim) {
     361                assert(victim->fun);
    442362                assert(victim->port == port);
     363                assert(victim->hub == hub);
    443364                list_remove(&victim->link);
    444365                fibril_mutex_unlock(&hub->guard);
     
    446367                if (ret == EOK) {
    447368                        usb_address_t address = victim->address;
     369                        bus_remove_device(hcd->bus, hcd, victim);
    448370                        ddf_fun_destroy(victim->fun);
    449                         hcd_release_address(hcd, address);
     371                        bus_release_address(hcd->bus, address);
    450372                } else {
    451373                        usb_log_warning("Failed to unbind device `%s': %s\n",
     
    458380}
    459381
    460 static int hcd_ddf_new_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port)
    461 {
    462         assert(device);
    463 
    464         hcd_t *hcd = dev_to_hcd(device);
    465         assert(hcd);
    466 
    467         usb_speed_t speed = USB_SPEED_MAX;
    468 
    469         /* This checks whether the default address is reserved and gets speed */
    470         int ret = usb_bus_get_speed(&hcd->bus, USB_ADDRESS_DEFAULT, &speed);
    471         if (ret != EOK) {
    472                 usb_log_error("Failed to verify speed: %s.", str_error(ret));
    473                 return ret;
    474         }
    475 
    476         usb_log_debug("Found new %s speed USB device.", usb_str_speed(speed));
    477 
    478         static const usb_target_t default_target = {{
    479                 .address = USB_ADDRESS_DEFAULT,
     382device_t *hcd_ddf_device_create(ddf_dev_t *hc, size_t device_size)
     383{
     384        /* Create DDF function for the new device */
     385        ddf_fun_t *fun = ddf_fun_create(hc, fun_inner, NULL);
     386        if (!fun)
     387                return NULL;
     388
     389        ddf_fun_set_ops(fun, &usb_ops);
     390
     391        /* Create USB device node for the new device */
     392        device_t *dev = ddf_fun_data_alloc(fun, device_size);
     393        if (!dev) {
     394                ddf_fun_destroy(fun);
     395                return NULL;
     396        }
     397
     398        device_init(dev);
     399        dev->fun = fun;
     400        return dev;
     401}
     402
     403void hcd_ddf_device_destroy(device_t *dev)
     404{
     405        assert(dev);
     406        assert(dev->fun);
     407        ddf_fun_destroy(dev->fun);
     408}
     409
     410int hcd_ddf_device_explore(hcd_t *hcd, device_t *device)
     411{
     412        int err;
     413        match_id_list_t mids;
     414        usb_standard_device_descriptor_t desc = { 0 };
     415
     416        init_match_ids(&mids);
     417
     418        const usb_target_t control_ep = {{
     419                .address = device->address,
    480420                .endpoint = 0,
    481421        }};
    482 
    483         const usb_address_t address = hcd_request_address(hcd, speed);
    484         if (address < 0) {
    485                 usb_log_error("Failed to reserve new address: %s.",
    486                     str_error(address));
    487                 return address;
    488         }
    489 
    490         usb_log_debug("Reserved new address: %d\n", address);
    491 
    492         const usb_target_t target = {{
    493                 .address = address,
    494                 .endpoint = 0,
    495         }};
    496 
    497         const usb_address_t tt_address = hub ? hub->tt_address : -1;
    498 
    499         /* Add default pipe on default address */
    500         usb_log_debug("Device(%d): Adding default target(0:0)\n", address);
    501         ret = hcd_add_ep(hcd,
    502             default_target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL,
    503             CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE, 1,
    504             tt_address, port);
    505         if (ret != EOK) {
    506                 usb_log_error("Device(%d): Failed to add default target: %s.",
    507                     address, str_error(ret));
    508                 hcd_release_address(hcd, address);
    509                 return ret;
    510         }
    511 
    512         /* Get max packet size for default pipe */
    513         usb_standard_device_descriptor_t desc = { 0 };
    514         const usb_device_request_setup_packet_t get_device_desc_8 =
    515             GET_DEVICE_DESC(CTRL_PIPE_MIN_PACKET_SIZE);
    516 
    517         // TODO CALLBACKS
    518         usb_log_debug("Device(%d): Requesting first 8B of device descriptor.",
    519             address);
    520         ssize_t got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_IN,
    521             &desc, CTRL_PIPE_MIN_PACKET_SIZE, *(uint64_t *)&get_device_desc_8,
    522             "read first 8 bytes of dev descriptor");
    523 
    524         if (got != CTRL_PIPE_MIN_PACKET_SIZE) {
    525                 ret = got < 0 ? got : EOVERFLOW;
    526                 usb_log_error("Device(%d): Failed to get 8B of dev descr: %s.",
    527                     address, str_error(ret));
    528                 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH);
    529                 hcd_release_address(hcd, address);
    530                 return ret;
    531         }
    532 
    533         /* Register EP on the new address */
    534         usb_log_debug("Device(%d): Registering control EP.", address);
    535         ret = hcd_add_ep(hcd, target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL,
    536             ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)),
    537             ED_MPS_TRANS_OPPORTUNITIES_GET(uint16_usb2host(desc.max_packet_size)),
    538             ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)),
    539             tt_address, port);
    540         if (ret != EOK) {
    541                 usb_log_error("Device(%d): Failed to register EP0: %s",
    542                     address, str_error(ret));
    543                 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH);
    544                 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
    545                 hcd_release_address(hcd, address);
    546                 return ret;
    547         }
    548 
    549         /* Set new address */
    550         const usb_device_request_setup_packet_t set_address =
    551             SET_ADDRESS(target.address);
    552 
    553         usb_log_debug("Device(%d): Setting USB address.", address);
    554         got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_OUT,
    555             NULL, 0, *(uint64_t *)&set_address, "set address");
    556 
    557         usb_log_debug("Device(%d): Removing default (0:0) EP.", address);
    558         hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH);
    559 
    560         if (got != 0) {
    561                 usb_log_error("Device(%d): Failed to set new address: %s.",
    562                     address, str_error(got));
    563                 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
    564                 hcd_release_address(hcd, address);
    565                 return got;
    566         }
    567422
    568423        /* Get std device descriptor */
     
    571426
    572427        usb_log_debug("Device(%d): Requesting full device descriptor.",
    573             address);
    574         got = hcd_send_batch_sync(hcd, target, USB_DIRECTION_IN,
    575             &desc, sizeof(desc), *(uint64_t *)&get_device_desc,
     428            device->address);
     429        ssize_t got = hcd_send_batch_sync(hcd, device, control_ep, USB_DIRECTION_IN,
     430            (char *) &desc, sizeof(desc), *(uint64_t *)&get_device_desc,
    576431            "read device descriptor");
    577         if (ret != EOK) {
     432        if (got < 0) {
     433                err = got < 0 ? got : EOVERFLOW;
    578434                usb_log_error("Device(%d): Failed to set get dev descriptor: %s",
    579                     address, str_error(ret));
    580                 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
    581                 hcd_release_address(hcd, target.address);
    582                 return ret;
     435                    device->address, str_error(err));
     436                goto out;
    583437        }
    584438
    585439        /* Create match ids from the device descriptor */
    586         match_id_list_t mids;
    587         init_match_ids(&mids);
    588 
    589         usb_log_debug("Device(%d): Creating match IDs.", address);
    590         ret = create_match_ids(&mids, &desc);
    591         if (ret != EOK) {
    592                 usb_log_error("Device(%d): Failed to create match ids: %s",
    593                     address, str_error(ret));
    594                 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
    595                 hcd_release_address(hcd, target.address);
    596                 return ret;
    597         }
    598 
    599         /* Register device */
    600         usb_log_debug("Device(%d): Registering DDF device.", address);
    601         ret = hcd_ddf_add_device(device, hub, port, address, speed, NULL, &mids);
     440        usb_log_debug("Device(%d): Creating match IDs.", device->address);
     441        if ((err = create_match_ids(&mids, &desc))) {
     442                usb_log_error("Device(%d): Failed to create match ids: %s", device->address, str_error(err));
     443                goto out;
     444        }
     445
     446        list_foreach(mids.ids, link, const match_id_t, mid) {
     447                ddf_fun_add_match_id(device->fun, mid->id, mid->score);
     448        }
     449
     450out:
    602451        clean_match_ids(&mids);
    603         if (ret != EOK) {
    604                 usb_log_error("Device(%d): Failed to register: %s.",
    605                     address, str_error(ret));
    606                 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
    607                 hcd_release_address(hcd, target.address);
    608         }
    609 
    610         return ret;
     452        return err;
     453}
     454
     455int hcd_ddf_device_online(ddf_fun_t *fun)
     456{
     457        assert(fun);
     458
     459        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
     460        device_t *dev = ddf_fun_data_get(fun);
     461        assert(dev);
     462        assert(hcd->bus);
     463
     464        usb_log_info("Device(%d): Requested to be brought online.", dev->address);
     465
     466        return bus_online_device(hcd->bus, hcd, dev);
     467}
     468
     469int hcd_ddf_device_offline(ddf_fun_t *fun)
     470{
     471        assert(fun);
     472
     473        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
     474        device_t *dev = ddf_fun_data_get(fun);
     475        assert(dev);
     476        assert(hcd->bus);
     477
     478        usb_log_info("Device(%d): Requested to be taken offline.", dev->address);
     479
     480        return bus_offline_device(hcd->bus, hcd, dev);
     481}
     482
     483static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, device_t *hub, unsigned port)
     484{
     485        int err;
     486        assert(hcd);
     487        assert(hcd->bus);
     488        assert(hub);
     489        assert(hc);
     490
     491        device_t *dev = hcd_ddf_device_create(hc, hcd->bus->device_size);
     492        if (!dev) {
     493                usb_log_error("Failed to create USB device function.");
     494                return ENOMEM;
     495        }
     496
     497        dev->hub = hub;
     498        dev->port = port;
     499
     500        if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) {
     501                usb_log_error("Failed to initialize USB dev memory structures.");
     502                return err;
     503        }
     504
     505        /* If the driver didn't name the dev when enumerating,
     506         * do it in some generic way.
     507         */
     508        if (!ddf_fun_get_name(dev->fun)) {
     509                device_set_default_name(dev);
     510        }
     511
     512        if ((err = ddf_fun_bind(dev->fun))) {
     513                usb_log_error("Device(%d): Failed to register: %s.", dev->address, str_error(err));
     514                goto err_usb_dev;
     515        }
     516
     517        fibril_mutex_lock(&hub->guard);
     518        list_append(&dev->link, &hub->devices);
     519        fibril_mutex_unlock(&hub->guard);
     520
     521        return EOK;
     522
     523err_usb_dev:
     524        hcd_ddf_device_destroy(dev);
     525        return err;
    611526}
    612527
     
    616531 * @return Error code
    617532 */
    618 int hcd_ddf_setup_root_hub(ddf_dev_t *device)
    619 {
    620         assert(device);
    621         hcd_t *hcd = dev_to_hcd(device);
     533int hcd_setup_virtual_root_hub(hcd_t *hcd, ddf_dev_t *hc)
     534{
     535        int err;
     536
     537        assert(hc);
    622538        assert(hcd);
    623 
    624         hcd_reserve_default_address(hcd, hcd->bus.max_speed);
    625         const int ret = hcd_ddf_new_device(device, NULL, 0);
    626         hcd_release_default_address(hcd);
    627         return ret;
     539        assert(hcd->bus);
     540
     541        if ((err = bus_reserve_default_address(hcd->bus, USB_SPEED_MAX))) {
     542                usb_log_error("Failed to reserve default address for roothub setup: %s", str_error(err));
     543                return err;
     544        }
     545
     546        device_t *dev = hcd_ddf_device_create(hc, hcd->bus->device_size);
     547        if (!dev) {
     548                usb_log_error("Failed to create function for the root hub.");
     549                goto err_default_address;
     550        }
     551
     552        ddf_fun_set_name(dev->fun, "roothub");
     553
     554        /* Assign an address to the device */
     555        if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) {
     556                usb_log_error("Failed to enumerate roothub device: %s", str_error(err));
     557                goto err_usb_dev;
     558        }
     559
     560        if ((err = ddf_fun_bind(dev->fun))) {
     561                usb_log_error("Failed to register roothub: %s.", str_error(err));
     562                goto err_usb_dev;
     563        }
     564
     565        bus_release_default_address(hcd->bus);
     566        return EOK;
     567
     568err_usb_dev:
     569        hcd_ddf_device_destroy(dev);
     570err_default_address:
     571        bus_release_default_address(hcd->bus);
     572        return err;
    628573}
    629574
     
    638583 * This function does all the ddf work for hc driver.
    639584 */
    640 int hcd_ddf_setup_hc(ddf_dev_t *device, usb_speed_t max_speed,
    641     size_t bw, bw_count_func_t bw_count)
     585int hcd_ddf_setup_hc(ddf_dev_t *device)
    642586{
    643587        assert(device);
     
    648592                return ENOMEM;
    649593        }
    650         instance->root_hub = NULL;
    651         hcd_init(&instance->hcd, max_speed, bw, bw_count);
     594        hcd_init(&instance->hcd);
    652595
    653596        int ret = ENOMEM;
     
    748691    const hw_res_list_parsed_t *hw_res,
    749692    interrupt_handler_t handler,
    750     int (*gen_irq_code)(irq_code_t *, const hw_res_list_parsed_t *hw_res))
    751 {
    752 
     693    irq_code_gen_t gen_irq_code)
     694{
    753695        assert(device);
     696
     697        hcd_t *hcd = dev_to_hcd(device);
     698
    754699        if (!handler || !gen_irq_code)
    755700                return ENOTSUP;
     
    757702        irq_code_t irq_code = {0};
    758703
    759         const int irq = gen_irq_code(&irq_code, hw_res);
     704        const int irq = gen_irq_code(&irq_code, hcd, hw_res);
    760705        if (irq < 0) {
    761706                usb_log_error("Failed to generate IRQ code: %s.\n",
     
    777722        int ret = hcd_ddf_enable_interrupt(device, irq);
    778723        if (ret != EOK) {
    779                 usb_log_error("Failed to register interrupt handler: %s.\n",
     724                usb_log_error("Failed to enable interrupts: %s.\n",
    780725                    str_error(ret));
    781726                unregister_interrupt_handler(device, irq_cap);
     
    844789{
    845790        assert(driver);
    846         static const struct { size_t bw; bw_count_func_t bw_count; }bw[] = {
    847             [USB_SPEED_FULL] = { .bw = BANDWIDTH_AVAILABLE_USB11,
    848                                  .bw_count = bandwidth_count_usb11 },
    849             [USB_SPEED_HIGH] = { .bw = BANDWIDTH_AVAILABLE_USB11,
    850                                  .bw_count = bandwidth_count_usb11 },
    851         };
    852791
    853792        int ret = EOK;
    854         const usb_speed_t speed = driver->hc_speed;
    855         if (speed >= ARRAY_SIZE(bw) || bw[speed].bw == 0) {
    856                 usb_log_error("Driver `%s' reported unsupported speed: %s",
    857                     driver->name, usb_str_speed(speed));
    858                 return ENOTSUP;
    859         }
    860793
    861794        hw_res_list_parsed_t hw_res;
     
    868801        }
    869802
    870         ret = hcd_ddf_setup_hc(device, speed, bw[speed].bw, bw[speed].bw_count);
     803        ret = hcd_ddf_setup_hc(device);
    871804        if (ret != EOK) {
    872805                usb_log_error("Failed to setup generic HCD.\n");
    873                 hw_res_list_parsed_clean(&hw_res);
    874                 return ret;
    875         }
    876 
     806                goto err_hw_res;
     807        }
     808
     809        hcd_t *hcd = dev_to_hcd(device);
     810
     811        if (driver->init)
     812                ret = driver->init(hcd, &hw_res, device);
     813        if (ret != EOK) {
     814                usb_log_error("Failed to init HCD.\n");
     815                goto err_hcd;
     816        }
     817
     818        /* Setup interrupts  */
    877819        interrupt_handler_t *irq_handler =
    878820            driver->irq_handler ? driver->irq_handler : ddf_hcd_gen_irq_handler;
     
    884826        }
    885827
     828        /* Claim the device from BIOS */
    886829        if (driver->claim)
    887                 ret = driver->claim(device);
     830                ret = driver->claim(hcd, device);
    888831        if (ret != EOK) {
    889                 usb_log_error("Failed to claim `%s' for driver `%s'",
    890                     ddf_dev_get_name(device), driver->name);
    891                 return ret;
    892         }
    893 
    894 
    895         /* Init hw driver */
    896         hcd_t *hcd = dev_to_hcd(device);
    897         ret = driver->init(hcd, &hw_res, irqs_enabled);
    898         hw_res_list_parsed_clean(&hw_res);
     832                usb_log_error("Failed to claim `%s' for driver `%s': %s",
     833                    ddf_dev_get_name(device), driver->name, str_error(ret));
     834                goto err_irq;
     835        }
     836
     837        /* Start hw driver */
     838        if (driver->start)
     839                ret = driver->start(hcd, irqs_enabled);
    899840        if (ret != EOK) {
    900                 usb_log_error("Failed to init HCD: %s.\n", str_error(ret));
    901                 goto irq_unregister;
     841                usb_log_error("Failed to start HCD: %s.\n", str_error(ret));
     842                goto err_irq;
    902843        }
    903844
     
    908849                        usb_log_error("Failed to create polling fibril\n");
    909850                        ret = ENOMEM;
    910                         goto irq_unregister;
     851                        goto err_started;
    911852                }
    912853                fibril_add_ready(hcd->polling_fibril);
     
    919860         * needs to be ready at this time.
    920861         */
    921         ret = hcd_ddf_setup_root_hub(device);
     862        if (driver->setup_root_hub)
     863                ret = driver->setup_root_hub(hcd, device);
    922864        if (ret != EOK) {
    923865                usb_log_error("Failed to setup HC root hub: %s.\n",
    924866                    str_error(ret));
    925                 driver->fini(dev_to_hcd(device));
    926 irq_unregister:
    927                 /* Unregistering non-existent should be ok */
    928                 unregister_interrupt_handler(device, irq_cap);
    929                 hcd_ddf_clean_hc(device);
    930                 return ret;
     867                goto err_polling;
    931868        }
    932869
     
    934871            driver->name, ddf_dev_get_name(device));
    935872        return EOK;
    936 }
     873
     874err_polling:
     875        // TODO: Stop the polling fibril (refactor the interrupt_polling func)
     876        //
     877err_started:
     878        if (driver->stop)
     879                driver->stop(hcd);
     880err_irq:
     881        unregister_interrupt_handler(device, irq_cap);
     882        if (driver->fini)
     883                driver->fini(hcd);
     884err_hcd:
     885        hcd_ddf_clean_hc(device);
     886err_hw_res:
     887        hw_res_list_parsed_clean(&hw_res);
     888        return ret;
     889}
     890
    937891/**
    938892 * @}
Note: See TracChangeset for help on using the changeset viewer.