Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 6832245 in mainline


Ignore:
Timestamp:
2017-12-14T23:01:57Z (4 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master
Children:
837d53d
Parents:
bd05140
git-author:
Ondřej Hlavatý <aearsis@…> (2017-12-14 23:01:54)
git-committer:
Ondřej Hlavatý <aearsis@…> (2017-12-14 23:01:57)
Message:

usbhost bus: refactor the bus ops

This way, method names better represent the entity it is working with.
Their semantics was shifted a bit.

Regarding the tree of structures:

bus ← device ← endpoint ← batch

Previously, devices were kept in DDF function nodes, and endpoints had
pointer to the bus and device. Now, devices have pointer to bus,
endpoints don't.

Pointer to hcd_t in bus is WIP, and will be removed.

Location:
uspace
Files:
33 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/bus/usb/ehci/ehci_bus.c

    rbd05140 r6832245  
    7979/** Creates new hcd endpoint representation.
    8080 */
    81 static endpoint_t *ehci_endpoint_create(bus_t *bus)
     81static endpoint_t *ehci_endpoint_create(device_t *dev, const usb_endpoint_desc_t *desc)
    8282{
    83         assert(bus);
     83        assert(dev);
    8484
    8585        ehci_endpoint_t *ehci_ep = malloc(sizeof(ehci_endpoint_t));
     
    8787                return NULL;
    8888
    89         endpoint_init(&ehci_ep->base, bus);
     89        endpoint_init(&ehci_ep->base, dev, desc);
     90
     91        // TODO: extract USB2 information from desc
    9092
    9193        ehci_ep->qh = malloc32(sizeof(qh_t));
     
    114116
    115117
    116 static int ehci_register_ep(bus_t *bus_base, device_t *dev, endpoint_t *ep, const usb_endpoint_desc_t *desc)
     118static int ehci_register_ep(endpoint_t *ep)
    117119{
     120        bus_t *bus_base = endpoint_get_bus(ep);
    118121        ehci_bus_t *bus = (ehci_bus_t *) bus_base;
    119122        ehci_endpoint_t *ehci_ep = ehci_endpoint_get(ep);
     123        assert(fibril_mutex_is_locked(&bus_base->guard));
    120124
    121         // TODO utilize desc->usb2
    122 
    123         const int err = bus->parent_ops.register_endpoint(bus_base, dev, ep, desc);
     125        const int err = usb2_bus_ops.endpoint_register(ep);
    124126        if (err)
    125127                return err;
     
    131133}
    132134
    133 static int ehci_unregister_ep(bus_t *bus_base, endpoint_t *ep)
     135static int ehci_unregister_ep(endpoint_t *ep)
    134136{
     137        bus_t *bus_base = endpoint_get_bus(ep);
    135138        ehci_bus_t *bus = (ehci_bus_t *) bus_base;
    136139        assert(bus);
    137140        assert(ep);
    138141
    139         const int err = bus->parent_ops.unregister_endpoint(bus_base, ep);
     142        const int err = usb2_bus_ops.endpoint_unregister(ep);
    140143        if (err)
    141144                return err;
     
    145148}
    146149
    147 static usb_transfer_batch_t *ehci_bus_create_batch(bus_t *bus, endpoint_t *ep)
     150static usb_transfer_batch_t *ehci_create_batch(endpoint_t *ep)
    148151{
    149152        ehci_transfer_batch_t *batch = ehci_transfer_batch_create(ep);
     
    151154}
    152155
    153 static void ehci_bus_destroy_batch(usb_transfer_batch_t *batch)
     156static void ehci_destroy_batch(usb_transfer_batch_t *batch)
    154157{
    155158        ehci_transfer_batch_destroy(ehci_transfer_batch_get(batch));
    156159}
    157160
    158 int ehci_bus_init(ehci_bus_t *bus, hc_t *hc)
     161static const bus_ops_t ehci_bus_ops = {
     162        .parent = &usb2_bus_ops,
     163
     164        .endpoint_destroy = ehci_endpoint_destroy,
     165        .endpoint_create = ehci_endpoint_create,
     166        .endpoint_register = ehci_register_ep,
     167        .endpoint_unregister = ehci_unregister_ep,
     168        .endpoint_set_toggle = ehci_ep_toggle_set,
     169        .endpoint_get_toggle = ehci_ep_toggle_get,
     170        .endpoint_count_bw = bandwidth_count_usb11,
     171        .batch_create = ehci_create_batch,
     172        .batch_destroy = ehci_destroy_batch,
     173};
     174
     175int ehci_bus_init(ehci_bus_t *bus, hcd_t *hcd, hc_t *hc)
    159176{
    160177        assert(hc);
    161178        assert(bus);
    162179
    163         // FIXME: Implement the USB2 bw counting.
    164         usb2_bus_init(&bus->base, BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
     180        usb2_bus_t *usb2_bus = (usb2_bus_t *) bus;
     181        bus_t *bus_base = (bus_t *) bus;
    165182
    166         bus_ops_t *ops = &bus->base.base.ops;
    167         bus->parent_ops = *ops;
    168         ops->create_endpoint = ehci_endpoint_create;
    169         ops->destroy_endpoint = ehci_endpoint_destroy;
    170         ops->endpoint_set_toggle = ehci_ep_toggle_set;
    171         ops->endpoint_get_toggle = ehci_ep_toggle_get;
    172 
    173         ops->register_endpoint = ehci_register_ep;
    174         ops->unregister_endpoint = ehci_unregister_ep;
    175 
    176         ops->create_batch = ehci_bus_create_batch;
    177         ops->destroy_batch = ehci_bus_destroy_batch;
     183        usb2_bus_init(usb2_bus, hcd, BANDWIDTH_AVAILABLE_USB11);
     184        bus_base->ops = &ehci_bus_ops;
    178185
    179186        bus->hc = hc;
  • uspace/drv/bus/usb/ehci/ehci_bus.h

    rbd05140 r6832245  
    5959        usb2_bus_t base;
    6060        hc_t *hc;
    61 
    62         /* Stored original ops from base, they are called in our handlers */
    63         bus_ops_t parent_ops;
    6461} ehci_bus_t;
    6562
    66 int ehci_bus_init(ehci_bus_t *, hc_t *);
     63void ehci_bus_prepare_ops(void);
     64
     65int ehci_bus_init(ehci_bus_t *, hcd_t *, hc_t *);
    6766
    6867/** Get and convert assigned ehci_endpoint_t structure
  • uspace/drv/bus/usb/ehci/hc.c

    rbd05140 r6832245  
    149149 * @return Error code
    150150 */
    151 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res)
     151int hc_init(hc_t *instance, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)
    152152{
    153153        assert(instance);
     
    190190            &instance->rh, instance->caps, instance->registers, "ehci rh");
    191191
    192         ehci_bus_init(&instance->bus, instance);
     192        ehci_bus_init(&instance->bus, hcd, instance);
    193193        return EOK;
    194194}
  • uspace/drv/bus/usb/ehci/hc.h

    rbd05140 r6832245  
    8585} hc_t;
    8686
    87 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res);
     87int hc_init(hc_t *instance, hcd_t *hcd, const hw_res_list_parsed_t *hw_res);
    8888int hc_start(hc_t *instance, bool interrupts);
    8989void hc_fini(hc_t *instance);
  • uspace/drv/bus/usb/ehci/main.c

    rbd05140 r6832245  
    8181                return ENOMEM;
    8282
    83         const int ret = hc_init(instance, res);
     83        const int ret = hc_init(instance, hcd, res);
    8484        if (ret == EOK) {
    8585                hcd_set_implementation(hcd, instance, &ehci_hc_driver.ops, &instance->bus.base.base);
  • uspace/drv/bus/usb/ohci/main.c

    rbd05140 r6832245  
    8383                goto err;
    8484
    85         if ((err = ohci_bus_init(&instance->bus, instance)))
     85        if ((err = ohci_bus_init(&instance->bus, hcd, instance)))
    8686                goto err;
    8787
  • uspace/drv/bus/usb/ohci/ohci_bus.c

    rbd05140 r6832245  
    7272/** Creates new hcd endpoint representation.
    7373 */
    74 static endpoint_t *ohci_endpoint_create(bus_t *bus)
     74static endpoint_t *ohci_endpoint_create(device_t *dev, const usb_endpoint_desc_t *desc)
    7575{
    76         assert(bus);
     76        assert(dev);
    7777
    7878        ohci_endpoint_t *ohci_ep = malloc(sizeof(ohci_endpoint_t));
     
    8080                return NULL;
    8181
    82         endpoint_init(&ohci_ep->base, bus);
     82        endpoint_init(&ohci_ep->base, dev, desc);
    8383
    8484        ohci_ep->ed = malloc32(sizeof(ed_t));
     
    115115
    116116
    117 static int ohci_register_ep(bus_t *bus_base, device_t *dev, endpoint_t *ep, const usb_endpoint_desc_t *desc)
     117static int ohci_register_ep(endpoint_t *ep)
    118118{
     119        bus_t *bus_base = endpoint_get_bus(ep);
    119120        ohci_bus_t *bus = (ohci_bus_t *) bus_base;
    120121        ohci_endpoint_t *ohci_ep = ohci_endpoint_get(ep);
    121122
    122         const int err = bus->parent_ops.register_endpoint(bus_base, dev, ep, desc);
     123        const int err = usb2_bus_ops.endpoint_register(ep);
    123124        if (err)
    124125                return err;
     
    130131}
    131132
    132 static int ohci_unregister_ep(bus_t *bus_base, endpoint_t *ep)
     133static int ohci_unregister_ep(endpoint_t *ep)
    133134{
    134         ohci_bus_t *bus = (ohci_bus_t *) bus_base;
    135         assert(bus);
     135        ohci_bus_t *bus = (ohci_bus_t *) endpoint_get_bus(ep);
    136136        assert(ep);
    137137
    138         const int err = bus->parent_ops.unregister_endpoint(bus_base, ep);
     138        const int err = usb2_bus_ops.endpoint_unregister(ep);
    139139        if (err)
    140140                return err;
     
    144144}
    145145
    146 static usb_transfer_batch_t *ohci_bus_create_batch(bus_t *bus, endpoint_t *ep)
     146static usb_transfer_batch_t *ohci_create_batch(endpoint_t *ep)
    147147{
    148148        ohci_transfer_batch_t *batch = ohci_transfer_batch_create(ep);
     
    150150}
    151151
    152 static void ohci_bus_destroy_batch(usb_transfer_batch_t *batch)
     152static void ohci_destroy_batch(usb_transfer_batch_t *batch)
    153153{
    154154        ohci_transfer_batch_destroy(ohci_transfer_batch_get(batch));
    155155}
    156156
    157 int ohci_bus_init(ohci_bus_t *bus, hc_t *hc)
     157static const bus_ops_t ohci_bus_ops = {
     158        .parent = &usb2_bus_ops,
     159
     160        .endpoint_destroy = ohci_endpoint_destroy,
     161        .endpoint_create = ohci_endpoint_create,
     162        .endpoint_register = ohci_register_ep,
     163        .endpoint_unregister = ohci_unregister_ep,
     164        .endpoint_count_bw = bandwidth_count_usb11,
     165        .endpoint_set_toggle = ohci_ep_toggle_set,
     166        .endpoint_get_toggle = ohci_ep_toggle_get,
     167        .batch_create = ohci_create_batch,
     168        .batch_destroy = ohci_destroy_batch,
     169};
     170
     171
     172int ohci_bus_init(ohci_bus_t *bus, hcd_t *hcd, hc_t *hc)
    158173{
    159174        assert(hc);
    160175        assert(bus);
    161176
    162         usb2_bus_init(&bus->base, BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
    163177
    164         bus_ops_t *ops = &bus->base.base.ops;
    165         bus->parent_ops = *ops;
    166         ops->create_endpoint = ohci_endpoint_create;
    167         ops->destroy_endpoint = ohci_endpoint_destroy;
    168         ops->endpoint_set_toggle = ohci_ep_toggle_set;
    169         ops->endpoint_get_toggle = ohci_ep_toggle_get;
     178        usb2_bus_t *usb2_bus = (usb2_bus_t *) bus;
     179        bus_t *bus_base = (bus_t *) bus;
    170180
    171         ops->register_endpoint = ohci_register_ep;
    172         ops->unregister_endpoint = ohci_unregister_ep;
    173 
    174         ops->create_batch = ohci_bus_create_batch;
    175         ops->destroy_batch = ohci_bus_destroy_batch;
     181        usb2_bus_init(usb2_bus, hcd, BANDWIDTH_AVAILABLE_USB11);
     182        bus_base->ops = &ohci_bus_ops;
    176183
    177184        bus->hc = hc;
  • uspace/drv/bus/usb/ohci/ohci_bus.h

    rbd05140 r6832245  
    6060        usb2_bus_t base;
    6161        hc_t *hc;
    62 
    63         /* Stored original ops from base, they are called in our handlers */
    64         bus_ops_t parent_ops;
    6562} ohci_bus_t;
    6663
    67 int ohci_bus_init(ohci_bus_t *, hc_t *);
     64int ohci_bus_init(ohci_bus_t *, hcd_t *, hc_t *);
    6865
    6966/** Get and convert assigned ohci_endpoint_t structure
  • uspace/drv/bus/usb/uhci/hc.c

    rbd05140 r6832245  
    9595
    9696static void hc_init_hw(const hc_t *instance);
    97 static int hc_init_mem_structures(hc_t *instance);
     97static int hc_init_mem_structures(hc_t *instance, hcd_t *);
    9898static int hc_init_transfer_lists(hc_t *instance);
    9999
     
    215215 * interrupt fibrils.
    216216 */
    217 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res)
     217int hc_init(hc_t *instance, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)
    218218{
    219219        assert(instance);
     
    238238            hw_res->io_ranges.ranges[0].size);
    239239
    240         ret = hc_init_mem_structures(instance);
     240        ret = hc_init_mem_structures(instance, hcd);
    241241        if (ret != EOK) {
    242242                usb_log_error("Failed to init UHCI memory structures: %s.\n",
     
    309309}
    310310
    311 static usb_transfer_batch_t *create_transfer_batch(bus_t *bus, endpoint_t *ep)
     311static usb_transfer_batch_t *create_transfer_batch(endpoint_t *ep)
    312312{
    313313        uhci_transfer_batch_t *batch = uhci_transfer_batch_create(ep);
     
    319319        uhci_transfer_batch_destroy(uhci_transfer_batch_get(batch));
    320320}
     321
     322static const bus_ops_t uhci_bus_ops = {
     323        .parent = &usb2_bus_ops,
     324
     325        .endpoint_count_bw = bandwidth_count_usb11,
     326        .batch_create = create_transfer_batch,
     327        .batch_destroy = destroy_transfer_batch,
     328};
    321329
    322330/** Initialize UHCI hc memory structures.
     
    330338 *  - frame list page (needs to be one UHCI hw accessible 4K page)
    331339 */
    332 int hc_init_mem_structures(hc_t *instance)
     340int hc_init_mem_structures(hc_t *instance, hcd_t *hcd)
    333341{
    334342        int err;
    335343        assert(instance);
    336344
    337         if ((err = usb2_bus_init(&instance->bus, BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11)))
     345        if ((err = usb2_bus_init(&instance->bus, hcd, BANDWIDTH_AVAILABLE_USB11)))
    338346                return err;
    339347
    340         instance->bus.base.ops.create_batch = create_transfer_batch;
    341         instance->bus.base.ops.destroy_batch = destroy_transfer_batch;
     348        bus_t *bus = (bus_t *) &instance->bus;
     349        bus->ops = &uhci_bus_ops;
    342350
    343351        /* Init USB frame list page */
  • uspace/drv/bus/usb/uhci/hc.h

    rbd05140 r6832245  
    126126} hc_t;
    127127
    128 extern int hc_init(hc_t *, const hw_res_list_parsed_t *);
     128extern int hc_init(hc_t *, hcd_t *, const hw_res_list_parsed_t *);
    129129extern void hc_start(hc_t *);
    130130extern void hc_fini(hc_t *);
  • uspace/drv/bus/usb/uhci/main.c

    rbd05140 r6832245  
    8080                return ENOMEM;
    8181
    82         if ((err = hc_init(instance, res)) != EOK)
     82        if ((err = hc_init(instance, hcd, res)) != EOK)
    8383                goto err;
    8484
  • uspace/drv/bus/usb/vhc/main.c

    rbd05140 r6832245  
    6969                return ret;
    7070        }
    71         vhc_init(vhc);
     71        vhc_init(vhc, dev_to_hcd(dev));
    7272        return EOK;
    7373}
  • uspace/drv/bus/usb/vhc/transfer.c

    rbd05140 r6832245  
    157157}
    158158
    159 int vhc_init(vhc_data_t *instance)
     159static const bus_ops_t vhc_bus_ops = {
     160        .parent = &usb2_bus_ops,
     161        .endpoint_count_bw = bandwidth_count_usb11,
     162};
     163
     164int vhc_init(vhc_data_t *instance, hcd_t *hcd)
    160165{
    161166        assert(instance);
    162167        list_initialize(&instance->devices);
    163168        fibril_mutex_initialize(&instance->guard);
    164         usb2_bus_init(&instance->bus, BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
     169        usb2_bus_init(&instance->bus, hcd, BANDWIDTH_AVAILABLE_USB11);
     170        instance->bus.base.ops = &vhc_bus_ops;
    165171        instance->magic = 0xDEADBEEF;
    166172        return virthub_init(&instance->hub, "root hub");
  • uspace/drv/bus/usb/vhc/vhcd.h

    rbd05140 r6832245  
    7777void vhc_virtdev_unplug(vhc_data_t *, uintptr_t);
    7878
    79 int vhc_init(vhc_data_t *instance);
     79int vhc_init(vhc_data_t *instance, hcd_t *);
    8080int vhc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
    8181int vhc_transfer_queue_processor(void *arg);
  • uspace/drv/bus/usb/xhci/bus.c

    rbd05140 r6832245  
    5858};
    5959
    60 static int prepare_endpoint(xhci_endpoint_t *ep, const usb_endpoint_desc_t *desc)
    61 {
    62         /* Extract information from endpoint_desc */
    63         ep->base.endpoint = desc->endpoint_no;
    64         ep->base.direction = desc->direction;
    65         ep->base.transfer_type = desc->transfer_type;
    66         ep->base.max_packet_size = desc->max_packet_size;
    67         ep->base.packets = desc->packets;
    68         ep->max_streams = desc->usb3.max_streams;
    69         ep->max_burst = desc->usb3.max_burst;
    70         ep->mult = desc->usb3.mult;
    71 
    72         if (ep->base.transfer_type == USB_TRANSFER_ISOCHRONOUS) {
    73                 if (ep->base.device->speed <= USB_SPEED_HIGH) {
    74                         ep->isoch_max_size = desc->max_packet_size * (desc->packets + 1);
    75                 }
    76                 else if (ep->base.device->speed == USB_SPEED_SUPER) {
    77                         ep->isoch_max_size = desc->usb3.bytes_per_interval;
    78                 }
    79                 /* Technically there could be superspeed plus too. */
    80 
    81                 /* Allocate and setup isochronous-specific structures. */
    82                 ep->isoch_enqueue = 0;
    83                 ep->isoch_dequeue = XHCI_ISOCH_BUFFER_COUNT - 1;
    84                 ep->isoch_started = false;
    85 
    86                 fibril_mutex_initialize(&ep->isoch_guard);
    87                 fibril_condvar_initialize(&ep->isoch_avail);
    88         }
    89 
    90         return xhci_endpoint_alloc_transfer_ds(ep);
    91 }
    92 
    93 static endpoint_t *create_endpoint(bus_t *base);
    94 
    95 static int address_device(xhci_hc_t *hc, xhci_device_t *dev)
     60static endpoint_t *endpoint_create(device_t *, const usb_endpoint_desc_t *);
     61
     62static int address_device(xhci_bus_t *bus, xhci_device_t *dev)
    9663{
    9764        int err;
    9865
    9966        /* Enable new slot. */
    100         if ((err = hc_enable_slot(hc, &dev->slot_id)) != EOK)
     67        if ((err = hc_enable_slot(bus->hc, &dev->slot_id)) != EOK)
    10168                return err;
    10269        usb_log_debug2("Obtained slot ID: %u.\n", dev->slot_id);
    10370
    10471        /* Create and configure control endpoint. */
    105         endpoint_t *ep0_base = create_endpoint(&hc->bus.base);
     72        endpoint_t *ep0_base = endpoint_create(&dev->base, &ep0_initial_desc);
    10673        if (!ep0_base)
    10774                goto err_slot;
     
    11279        xhci_endpoint_t *ep0 = xhci_endpoint_get(ep0_base);
    11380
    114         if ((err = prepare_endpoint(ep0, &ep0_initial_desc)))
     81        if ((err = xhci_endpoint_alloc_transfer_ds(ep0)))
    11582                goto err_ep;
    11683
     
    12087
    12188        /* Address device */
    122         if ((err = hc_address_device(hc, dev, ep0)))
     89        if ((err = hc_address_device(bus->hc, dev, ep0)))
    12390                goto err_added;
    12491
     
    135102        endpoint_del_ref(ep0_base);
    136103err_slot:
    137         hc_disable_slot(hc, dev);
     104        hc_disable_slot(bus->hc, dev);
    138105        return err;
    139106}
     
    164131}
    165132
    166 int xhci_bus_enumerate_device(xhci_bus_t *bus, xhci_hc_t *hc, device_t *dev)
     133int xhci_bus_enumerate_device(xhci_bus_t *bus, device_t *dev)
    167134{
    168135        int err;
     
    184151
    185152        /* Assign an address to the device */
    186         if ((err = address_device(hc, xhci_dev))) {
     153        if ((err = address_device(bus, xhci_dev))) {
    187154                usb_log_error("Failed to setup address of the new device: %s", str_error(err));
    188155                return err;
     
    195162        fibril_mutex_unlock(&bus->base.guard);
    196163
    197         if ((err = setup_ep0_packet_size(hc, xhci_dev))) {
     164        if ((err = setup_ep0_packet_size(bus->hc, xhci_dev))) {
    198165                usb_log_error("Failed to setup control endpoint of the new device: %s", str_error(err));
    199166                goto err_address;
     
    201168
    202169        /* Read the device descriptor, derive the match ids */
    203         if ((err = hcd_ddf_device_explore(hc->hcd, dev))) {
     170        if ((err = hcd_ddf_device_explore(dev))) {
    204171                usb_log_error("Device(%d): Failed to explore device: %s", dev->address, str_error(err));
    205172                goto err_address;
     
    213180}
    214181
    215 static int unregister_endpoint(bus_t *, endpoint_t *);
    216 
    217 int xhci_bus_remove_device(xhci_bus_t *bus, xhci_hc_t *hc, device_t *dev)
     182static int endpoint_unregister(endpoint_t *);
     183
     184int xhci_bus_remove_device(xhci_bus_t *bus, device_t *dev)
    218185{
    219186        int err;
     
    246213        /* Disable the slot, dropping all endpoints. */
    247214        const uint32_t slot_id = xhci_dev->slot_id;
    248         if ((err = hc_disable_slot(hc, xhci_dev))) {
     215        if ((err = hc_disable_slot(bus->hc, xhci_dev))) {
    249216                usb_log_warning("Failed to disable slot of device " XHCI_DEV_FMT ": %s",
    250217                    XHCI_DEV_ARGS(*xhci_dev), str_error(err));
     
    258225                        continue;
    259226
    260                 if ((err = unregister_endpoint(&bus->base, &xhci_dev->endpoints[i]->base))) {
     227                if ((err = endpoint_unregister(&xhci_dev->endpoints[i]->base))) {
    261228                        usb_log_warning("Failed to unregister endpoint " XHCI_EP_FMT ": %s",
    262229                            XHCI_EP_ARGS(*xhci_dev->endpoints[i]), str_error(err));
     
    278245}
    279246
    280 static int enumerate_device(bus_t *bus_base, hcd_t *hcd, device_t *dev)
    281 {
    282         xhci_hc_t *hc = hcd_get_driver_data(hcd);
    283         assert(hc);
    284 
    285         xhci_bus_t *bus = bus_to_xhci_bus(bus_base);
    286         assert(bus);
    287 
    288         return xhci_bus_enumerate_device(bus, hc, dev);
    289 }
    290 
    291 static int remove_device(bus_t *bus_base, hcd_t *hcd, device_t *dev)
    292 {
    293         xhci_hc_t *hc = hcd_get_driver_data(hcd);
    294         assert(hc);
    295 
    296         xhci_bus_t *bus = bus_to_xhci_bus(bus_base);
    297         assert(bus);
    298 
    299         return xhci_bus_remove_device(bus, hc, dev);
    300 }
    301 
    302 static int online_device(bus_t *bus_base, hcd_t *hcd, device_t *dev_base)
    303 {
    304         int err;
    305 
    306         xhci_hc_t *hc = hcd_get_driver_data(hcd);
    307         assert(hc);
    308 
    309         xhci_bus_t *bus = bus_to_xhci_bus(bus_base);
     247static int device_enumerate(device_t *dev)
     248{
     249        xhci_bus_t *bus = bus_to_xhci_bus(dev->bus);
     250        return xhci_bus_enumerate_device(bus, dev);
     251}
     252
     253static int device_remove(device_t *dev)
     254{
     255        xhci_bus_t *bus = bus_to_xhci_bus(dev->bus);
     256        return xhci_bus_remove_device(bus, dev);
     257}
     258
     259static int device_online(device_t *dev_base)
     260{
     261        int err;
     262
     263        xhci_bus_t *bus = bus_to_xhci_bus(dev_base->bus);
    310264        assert(bus);
    311265
     
    314268
    315269        /* Transition the device from the Addressed to the Configured state. */
    316         if ((err = hc_configure_device(hc, dev->slot_id))) {
     270        if ((err = hc_configure_device(bus->hc, dev->slot_id))) {
    317271                usb_log_warning("Failed to configure device " XHCI_DEV_FMT ".", XHCI_DEV_ARGS(*dev));
    318272        }
     
    331285}
    332286
    333 static int offline_device(bus_t *bus_base, hcd_t *hcd, device_t *dev_base)
    334 {
    335         int err;
    336 
    337         xhci_hc_t *hc = hcd_get_driver_data(hcd);
    338         assert(hc);
    339 
    340         xhci_bus_t *bus = bus_to_xhci_bus(bus_base);
     287static int device_offline(device_t *dev_base)
     288{
     289        int err;
     290
     291        xhci_bus_t *bus = bus_to_xhci_bus(dev_base->bus);
    341292        assert(bus);
    342293
     
    370321
    371322        /* Issue one HC command to simultaneously drop all endpoints except zero. */
    372         if ((err = hc_deconfigure_device(hc, dev->slot_id))) {
     323        if ((err = hc_deconfigure_device(bus->hc, dev->slot_id))) {
    373324                usb_log_warning("Failed to deconfigure device " XHCI_DEV_FMT ".",
    374325                    XHCI_DEV_ARGS(*dev));
     
    388339}
    389340
    390 static endpoint_t *create_endpoint(bus_t *base)
    391 {
    392         xhci_bus_t *bus = bus_to_xhci_bus(base);
    393 
     341static endpoint_t *endpoint_create(device_t *dev, const usb_endpoint_desc_t *desc)
     342{
    394343        xhci_endpoint_t *ep = calloc(1, sizeof(xhci_endpoint_t));
    395344        if (!ep)
    396345                return NULL;
    397346
    398         if (xhci_endpoint_init(ep, bus)) {
     347        if (xhci_endpoint_init(ep, dev, desc)) {
    399348                free(ep);
    400349                return NULL;
     
    404353}
    405354
    406 static void destroy_endpoint(endpoint_t *ep)
     355static void endpoint_destroy(endpoint_t *ep)
    407356{
    408357        xhci_endpoint_t *xhci_ep = xhci_endpoint_get(ep);
     
    412361}
    413362
    414 static int register_endpoint(bus_t *bus_base, device_t *device, endpoint_t *ep_base, const usb_endpoint_desc_t *desc)
    415 {
    416         int err;
    417         xhci_bus_t *bus = bus_to_xhci_bus(bus_base);
     363static int endpoint_register(endpoint_t *ep_base)
     364{
     365        int err;
     366        xhci_bus_t *bus = bus_to_xhci_bus(endpoint_get_bus(ep_base));
    418367        xhci_endpoint_t *ep = xhci_endpoint_get(ep_base);
    419368
    420         xhci_device_t *dev = xhci_device_get(device);
    421 
    422         if ((err = prepare_endpoint(ep, desc)))
     369        xhci_device_t *dev = xhci_device_get(ep_base->device);
     370
     371        if ((err = xhci_endpoint_alloc_transfer_ds(ep)))
    423372                return err;
    424373
     
    443392}
    444393
    445 static int unregister_endpoint(bus_t *bus_base, endpoint_t *ep_base)
    446 {
    447         int err;
    448         xhci_bus_t *bus = bus_to_xhci_bus(bus_base);
     394static int endpoint_unregister(endpoint_t *ep_base)
     395{
     396        int err;
     397        xhci_bus_t *bus = bus_to_xhci_bus(endpoint_get_bus(ep_base));
    449398        xhci_endpoint_t *ep = xhci_endpoint_get(ep_base);
    450399        xhci_device_t *dev = xhci_device_get(ep_base->device);
     
    470419}
    471420
    472 static endpoint_t* find_endpoint(bus_t *bus_base, device_t *dev_base, usb_target_t target, usb_direction_t direction)
     421static endpoint_t* device_find_endpoint(device_t *dev_base, usb_target_t target, usb_direction_t direction)
    473422{
    474423        xhci_device_t *dev = xhci_device_get(dev_base);
     
    487436}
    488437
    489 static size_t count_bw(endpoint_t *ep, size_t size)
    490 {
    491         // TODO: Implement me!
    492         return 0;
    493 }
    494 
    495438/* Endpoint ops, optional (have generic fallback) */
    496439static bool endpoint_get_toggle(endpoint_t *ep)
     
    525468}
    526469
    527 static usb_transfer_batch_t *create_batch(bus_t *bus, endpoint_t *ep)
     470static usb_transfer_batch_t *batch_create(endpoint_t *ep)
    528471{
    529472        xhci_transfer_t *transfer = xhci_transfer_create(ep);
     
    531474}
    532475
    533 static void destroy_batch(usb_transfer_batch_t *batch)
     476static void batch_destroy(usb_transfer_batch_t *batch)
    534477{
    535478        xhci_transfer_destroy(xhci_transfer_from_batch(batch));
     
    538481static const bus_ops_t xhci_bus_ops = {
    539482#define BIND_OP(op) .op = op,
    540         BIND_OP(enumerate_device)
    541         BIND_OP(remove_device)
    542 
    543         BIND_OP(online_device)
    544         BIND_OP(offline_device)
    545 
    546         BIND_OP(create_endpoint)
    547         BIND_OP(destroy_endpoint)
    548 
    549         BIND_OP(register_endpoint)
    550         BIND_OP(unregister_endpoint)
    551         BIND_OP(find_endpoint)
    552 
    553483        BIND_OP(reserve_default_address)
    554484        BIND_OP(release_default_address)
    555 
    556485        BIND_OP(reset_toggle)
    557         BIND_OP(count_bw)
    558 
     486
     487        BIND_OP(device_enumerate)
     488        BIND_OP(device_remove)
     489        BIND_OP(device_online)
     490        BIND_OP(device_offline)
     491        BIND_OP(device_find_endpoint)
     492
     493        BIND_OP(endpoint_create)
     494        BIND_OP(endpoint_destroy)
     495        BIND_OP(endpoint_register)
     496        BIND_OP(endpoint_unregister)
    559497        BIND_OP(endpoint_get_toggle)
    560498        BIND_OP(endpoint_set_toggle)
    561499
    562         BIND_OP(create_batch)
    563         BIND_OP(destroy_batch)
     500        BIND_OP(batch_create)
     501        BIND_OP(batch_destroy)
    564502#undef BIND_OP
    565503};
     
    569507        assert(bus);
    570508
    571         bus_init(&bus->base, sizeof(xhci_device_t));
     509        bus_init(&bus->base, hc->hcd, sizeof(xhci_device_t));
    572510
    573511        bus->devices_by_slot = calloc(hc->max_slots, sizeof(xhci_device_t *));
     
    576514
    577515        bus->hc = hc;
    578         bus->base.ops = xhci_bus_ops;
     516        bus->base.ops = &xhci_bus_ops;
    579517        bus->default_address_speed = USB_SPEED_MAX;
    580518        return EOK;
  • uspace/drv/bus/usb/xhci/bus.h

    rbd05140 r6832245  
    5858void xhci_bus_fini(xhci_bus_t *);
    5959
    60 int xhci_bus_enumerate_device(xhci_bus_t *, xhci_hc_t *, device_t *);
    61 int xhci_bus_remove_device(xhci_bus_t *, xhci_hc_t *, device_t *);
     60int xhci_bus_enumerate_device(xhci_bus_t *, device_t *);
     61int xhci_bus_remove_device(xhci_bus_t *, device_t *);
    6262
    6363#endif
  • uspace/drv/bus/usb/xhci/endpoint.c

    rbd05140 r6832245  
    4545#include "endpoint.h"
    4646
    47 int xhci_endpoint_init(xhci_endpoint_t *xhci_ep, xhci_bus_t *xhci_bus)
     47int xhci_endpoint_init(xhci_endpoint_t *xhci_ep, device_t *dev, const usb_endpoint_desc_t *desc)
    4848{
    4949        assert(xhci_ep);
    50         assert(xhci_bus);
    51 
    52         bus_t *bus = &xhci_bus->base;
     50
    5351        endpoint_t *ep = &xhci_ep->base;
    5452
    55         endpoint_init(ep, bus);
     53        endpoint_init(ep, dev, desc);
     54
     55        xhci_ep->max_streams = desc->usb3.max_streams;
     56        xhci_ep->max_burst = desc->usb3.max_burst;
     57        xhci_ep->mult = desc->usb3.mult;
     58
     59        if (xhci_ep->base.transfer_type == USB_TRANSFER_ISOCHRONOUS) {
     60                xhci_ep->isoch_max_size = desc->usb3.bytes_per_interval
     61                        ? desc->usb3.bytes_per_interval
     62                        : desc->max_packet_size * (desc->packets + 1);
     63                /* Technically there could be superspeed plus too. */
     64
     65                /* Allocate and setup isochronous-specific structures. */
     66                xhci_ep->isoch_enqueue = 0;
     67                xhci_ep->isoch_dequeue = XHCI_ISOCH_BUFFER_COUNT - 1;
     68                xhci_ep->isoch_started = false;
     69
     70                fibril_mutex_initialize(&xhci_ep->isoch_guard);
     71                fibril_condvar_initialize(&xhci_ep->isoch_avail);
     72        }
    5673
    5774        return EOK;
  • uspace/drv/bus/usb/xhci/endpoint.h

    rbd05140 r6832245  
    149149#define XHCI_DEV_ARGS(dev)               ddf_fun_get_name((dev).base.fun), (dev).slot_id
    150150
    151 int xhci_endpoint_init(xhci_endpoint_t *, xhci_bus_t *);
     151int xhci_endpoint_init(xhci_endpoint_t *, device_t *, const usb_endpoint_desc_t *);
    152152void xhci_endpoint_fini(xhci_endpoint_t *);
    153153int xhci_endpoint_alloc_transfer_ds(xhci_endpoint_t *);
  • uspace/drv/bus/usb/xhci/hc.c

    rbd05140 r6832245  
    212212                goto err_scratch;
    213213
     214        if ((err = xhci_bus_init(&hc->bus, hc)))
     215                goto err_cmd;
     216
    214217        if ((err = xhci_rh_init(&hc->rh, hc, device)))
    215                 goto err_cmd;
    216 
    217         if ((err = xhci_bus_init(&hc->bus, hc)))
    218                 goto err_rh;
    219 
    220 
    221         return EOK;
    222 
    223 err_rh:
    224         xhci_rh_fini(&hc->rh);
     218                goto err_bus;
     219
     220        return EOK;
     221
     222err_bus:
     223        xhci_bus_fini(&hc->bus);
    225224err_cmd:
    226225        xhci_fini_commands(hc);
  • uspace/drv/bus/usb/xhci/main.c

    rbd05140 r6832245  
    8282                goto err;
    8383
     84        hc->hcd = hcd;
     85
    8486        if ((err = hc_init_memory(hc, device)))
    8587                goto err;
    8688
    8789        hcd_set_implementation(hcd, hc, &xhci_ddf_hc_driver.ops, &hc->bus.base);
    88         hc->hcd = hcd;
    8990
    9091        return EOK;
  • uspace/drv/bus/usb/xhci/rh.c

    rbd05140 r6832245  
    7171        rh->hc_device = device;
    7272
    73         const int err = device_init(&rh->device.base);
     73        const int err = bus_device_init(&rh->device.base, &rh->hc->bus.base);
    7474        if (err)
    7575                return err;
     
    9494        xhci_bus_t *bus = &rh->hc->bus;
    9595
    96         device_t *dev = hcd_ddf_device_create(rh->hc_device, bus->base.device_size);
     96        device_t *dev = hcd_ddf_device_create(rh->hc_device, &bus->base);
    9797        if (!dev) {
    9898                usb_log_error("Failed to create USB device function.");
     
    109109        dev->speed = port_speed->usb_speed;
    110110
    111         if ((err = xhci_bus_enumerate_device(bus, rh->hc, dev))) {
     111        if ((err = xhci_bus_enumerate_device(bus, dev))) {
    112112                usb_log_error("Failed to enumerate USB device: %s", str_error(err));
    113113                return err;
     
    115115
    116116        if (!ddf_fun_get_name(dev->fun)) {
    117                 device_set_default_name(dev);
     117                bus_device_set_default_name(dev);
    118118        }
    119119
     
    196196
    197197        /* Remove device from XHCI bus. */
    198         if ((err = xhci_bus_remove_device(&rh->hc->bus, rh->hc, &dev->base))) {
     198        if ((err = xhci_bus_remove_device(&rh->hc->bus, &dev->base))) {
    199199                usb_log_warning("Failed to remove device " XHCI_DEV_FMT " from XHCI bus: %s",
    200200                    XHCI_DEV_ARGS(*dev), str_error(err));
  • uspace/lib/usbhost/include/usb/host/bandwidth.h

    rbd05140 r6832245  
    5151typedef struct endpoint endpoint_t;
    5252
    53 extern size_t bandwidth_count_usb11(endpoint_t *, size_t);
     53extern ssize_t bandwidth_count_usb11(endpoint_t *, size_t);
    5454
    55 extern size_t bandwidth_count_usb20(endpoint_t *, size_t);
     55extern ssize_t bandwidth_count_usb20(endpoint_t *, size_t);
    5656
    5757#endif
  • uspace/lib/usbhost/include/usb/host/bus.h

    rbd05140 r6832245  
    7777        usb_address_t address;
    7878
     79        /* Managing bus */
     80        bus_t *bus;
     81
    7982        /* This structure is meant to be extended by overriding. */
    8083} device_t;
    8184
    82 typedef struct {
    83         int (*enumerate_device)(bus_t *, hcd_t *, device_t *);
    84         int (*remove_device)(bus_t *, hcd_t *, device_t *);
     85typedef struct bus_ops bus_ops_t;
    8586
    86         int (*online_device)(bus_t *, hcd_t *, device_t *);                     /**< Optional */
    87         int (*offline_device)(bus_t *, hcd_t *, device_t *);                    /**< Optional */
     87/**
     88 * Operations structure serving as an interface of hc driver for the library
     89 * (and the rest of the system).
     90 */
     91struct bus_ops {
     92        /* Undefined operations will be delegated to parent ops */
     93        const bus_ops_t *parent;
    8894
    89         /* The following operations are protected by a bus guard. */
    90         endpoint_t *(*create_endpoint)(bus_t *);
    91         int (*register_endpoint)(bus_t *, device_t *, endpoint_t *, const usb_endpoint_desc_t *);
    92         int (*unregister_endpoint)(bus_t *, endpoint_t *);
    93         endpoint_t *(*find_endpoint)(bus_t *, device_t*, usb_target_t, usb_direction_t);
    94         void (*destroy_endpoint)(endpoint_t *);                 /**< Optional */
     95        /* Global operations on the bus */
     96        int (*reserve_default_address)(bus_t *, usb_speed_t);
     97        int (*release_default_address)(bus_t *);
     98        int (*reset_toggle)(bus_t *, usb_target_t, toggle_reset_mode_t);
     99
     100        /* Operations on device */
     101        int (*device_enumerate)(device_t *);
     102        int (*device_remove)(device_t *);
     103        int (*device_online)(device_t *);                       /**< Optional */
     104        int (*device_offline)(device_t *);                      /**< Optional */
     105        endpoint_t *(*device_find_endpoint)(device_t*, usb_target_t, usb_direction_t);
     106        endpoint_t *(*endpoint_create)(device_t *, const usb_endpoint_desc_t *);
     107
     108        /* Operations on endpoint */
     109        int (*endpoint_register)(endpoint_t *);
     110        int (*endpoint_unregister)(endpoint_t *);
     111        void (*endpoint_destroy)(endpoint_t *);                 /**< Optional */
    95112        bool (*endpoint_get_toggle)(endpoint_t *);              /**< Optional */
    96113        void (*endpoint_set_toggle)(endpoint_t *, bool);        /**< Optional */
     114        ssize_t (*endpoint_count_bw) (endpoint_t *, size_t);
     115        usb_transfer_batch_t *(*batch_create)(endpoint_t *);    /**< Optional */
    97116
    98         int (*reserve_default_address)(bus_t *, usb_speed_t);
    99         int (*release_default_address)(bus_t *);
     117        /* Operations on batch */
     118        void (*batch_destroy)(usb_transfer_batch_t *);  /**< Optional */
     119};
    100120
    101         int (*reset_toggle)(bus_t *, usb_target_t, toggle_reset_mode_t);
    102 
    103         size_t (*count_bw) (endpoint_t *, size_t);
    104 
    105         usb_transfer_batch_t *(*create_batch)(bus_t *, endpoint_t *); /**< Optional */
    106         void (*destroy_batch)(usb_transfer_batch_t *);  /**< Optional */
    107 } bus_ops_t;
     121/**
     122 * Use this macro to lookup virtual function.
     123 */
     124#define BUS_OPS_LOOKUP(start, fn) ({ bus_ops_t const * ops = (start); while (ops && ops->fn == NULL) ops = ops->parent; ops; })
    108125
    109126/** Endpoint management structure */
     
    112129        fibril_mutex_t guard;
    113130
     131        /* TODO: get rid of this one. */
     132        hcd_t *hcd;
     133
    114134        size_t device_size;
    115135
    116136        /* Do not call directly, ops are synchronized. */
    117         bus_ops_t ops;
     137        const bus_ops_t *ops;
    118138
    119139        /* This structure is meant to be extended by overriding. */
    120140} bus_t;
    121141
    122 void bus_init(bus_t *, size_t);
    123 int device_init(device_t *);
     142void bus_init(bus_t *, hcd_t *, size_t);
     143int bus_device_init(device_t *, bus_t *);
    124144
    125 int device_set_default_name(device_t *);
     145int bus_device_set_default_name(device_t *);
    126146
    127 int bus_enumerate_device(bus_t *, hcd_t *, device_t *);
    128 int bus_remove_device(bus_t *, hcd_t *, device_t *);
     147int bus_device_enumerate(device_t *);
     148int bus_device_remove(device_t *);
    129149
    130 int bus_online_device(bus_t *, hcd_t *, device_t *);
    131 int bus_offline_device(bus_t *, hcd_t *, device_t *);
     150int bus_device_online(device_t *);
     151int bus_device_offline(device_t *);
    132152
    133 int bus_add_endpoint(bus_t *, device_t *, const usb_endpoint_desc_t *, endpoint_t **);
    134 endpoint_t *bus_find_endpoint(bus_t *, device_t *, usb_target_t, usb_direction_t);
    135 int bus_remove_endpoint(bus_t *, endpoint_t *);
    136 
    137 size_t bus_count_bw(endpoint_t *, size_t);
     153int bus_endpoint_add(device_t *, const usb_endpoint_desc_t *, endpoint_t **);
     154endpoint_t *bus_find_endpoint(device_t *, usb_target_t, usb_direction_t);
     155int bus_endpoint_remove(endpoint_t *);
    138156
    139157int bus_reserve_default_address(bus_t *, usb_speed_t);
  • uspace/lib/usbhost/include/usb/host/ddf_helpers.h

    rbd05140 r6832245  
    8181int hcd_setup_virtual_root_hub(hcd_t *, ddf_dev_t *);
    8282
    83 device_t *hcd_ddf_device_create(ddf_dev_t *, size_t);
     83device_t *hcd_ddf_device_create(ddf_dev_t *, bus_t *);
    8484void hcd_ddf_device_destroy(device_t *);
    85 int hcd_ddf_device_explore(hcd_t *, device_t *);
     85int hcd_ddf_device_explore(device_t *);
    8686int hcd_ddf_device_online(ddf_fun_t *);
    8787int hcd_ddf_device_offline(ddf_fun_t *);
  • uspace/lib/usbhost/include/usb/host/endpoint.h

    rbd05140 r6832245  
    4545#include <stdbool.h>
    4646#include <usb/usb.h>
     47#include <usb/host/bus.h>
    4748
    4849typedef struct bus bus_t;
     
    5455        /** Part of linked list. */
    5556        link_t link;
    56         /** Managing bus */
    57         bus_t *bus;
     57        /** USB device */
     58        device_t *device;
    5859        /** Reference count. */
    5960        atomic_t refcnt;
    60         /** USB device */
    61         device_t *device;
    6261        /** Enpoint number */
    6362        usb_endpoint_t endpoint;
     
    8483} endpoint_t;
    8584
    86 extern void endpoint_init(endpoint_t *, bus_t *);
     85extern void endpoint_init(endpoint_t *, device_t *, const usb_endpoint_desc_t *);
    8786
    8887extern void endpoint_add_ref(endpoint_t *);
     
    103102void endpoint_abort(endpoint_t *);
    104103
     104/* Manage the toggle bit */
    105105extern int endpoint_toggle_get(endpoint_t *);
    106106extern void endpoint_toggle_set(endpoint_t *, bool);
     107
     108/* Calculate bandwidth */
     109ssize_t endpoint_count_bw(endpoint_t *, size_t);
     110
     111static inline bus_t *endpoint_get_bus(endpoint_t *ep)
     112{
     113        return ep->device->bus;
     114}
    107115
    108116/** list_get_instance wrapper.
  • uspace/lib/usbhost/include/usb/host/usb2_bus.h

    rbd05140 r6832245  
    4646typedef struct endpoint endpoint_t;
    4747
    48 typedef size_t (*count_bw_func_t)(endpoint_t *, size_t);
    49 
    5048/** Endpoint management structure */
    5149typedef struct usb2_bus {
     
    6664} usb2_bus_t;
    6765
    68 extern int usb2_bus_init(usb2_bus_t *, size_t, count_bw_func_t);
     66extern const bus_ops_t usb2_bus_ops;
     67
     68extern int usb2_bus_init(usb2_bus_t *, hcd_t *, size_t);
    6969
    7070#endif
  • uspace/lib/usbhost/src/bandwidth.c

    rbd05140 r6832245  
    4848 * @param max_packet_size Maximum bytes in one packet.
    4949 */
    50 size_t bandwidth_count_usb11(endpoint_t *ep, size_t size)
     50ssize_t bandwidth_count_usb11(endpoint_t *ep, size_t size)
    5151{
    5252        assert(ep);
     
    102102 * @param max_packet_size Maximum bytes in one packet.
    103103 */
    104 size_t bandwidth_count_usb20(endpoint_t *ep, size_t size)
     104ssize_t bandwidth_count_usb20(endpoint_t *ep, size_t size)
    105105{
    106106        assert(ep);
  • uspace/lib/usbhost/src/bus.c

    rbd05140 r6832245  
    4646 * Initializes the bus structure.
    4747 */
    48 void bus_init(bus_t *bus, size_t device_size)
    49 {
    50         assert(bus);
     48void bus_init(bus_t *bus, hcd_t *hcd, size_t device_size)
     49{
     50        assert(bus);
     51        assert(hcd);
    5152        assert(device_size >= sizeof(device_t));
    5253        memset(bus, 0, sizeof(bus_t));
    5354
    5455        fibril_mutex_initialize(&bus->guard);
     56        bus->hcd = hcd;
    5557        bus->device_size = device_size;
    5658}
    5759
    58 int device_init(device_t *dev)
    59 {
     60int bus_device_init(device_t *dev, bus_t *bus)
     61{
     62        assert(bus);
     63        assert(bus->hcd);
     64
    6065        memset(dev, 0, sizeof(*dev));
     66
     67        dev->bus = bus;
    6168
    6269        link_initialize(&dev->link);
     
    6774}
    6875
    69 int device_set_default_name(device_t *dev)
     76int bus_device_set_default_name(device_t *dev)
    7077{
    7178        assert(dev);
     
    7986}
    8087
    81 int bus_enumerate_device(bus_t *bus, hcd_t *hcd, device_t *dev)
    82 {
    83         assert(bus);
    84         assert(hcd);
    85         assert(dev);
    86 
    87         if (!bus->ops.enumerate_device)
    88                 return ENOTSUP;
    89 
    90         return bus->ops.enumerate_device(bus, hcd, dev);
    91 }
    92 
    93 int bus_remove_device(bus_t *bus, hcd_t *hcd, device_t *dev)
    94 {
    95         assert(bus);
    96         assert(dev);
    97 
    98         if (!bus->ops.remove_device)
    99                 return ENOTSUP;
    100 
    101         return bus->ops.remove_device(bus, hcd, dev);
    102 }
    103 
    104 int bus_online_device(bus_t *bus, hcd_t *hcd, device_t *dev)
    105 {
    106         assert(bus);
    107         assert(hcd);
    108         assert(dev);
    109 
    110         if (!bus->ops.online_device)
    111                 return ENOTSUP;
    112 
    113         return bus->ops.online_device(bus, hcd, dev);
    114 }
    115 
    116 int bus_offline_device(bus_t *bus, hcd_t *hcd, device_t *dev)
    117 {
    118         assert(bus);
    119         assert(hcd);
    120         assert(dev);
    121 
    122         if (!bus->ops.offline_device)
    123                 return ENOTSUP;
    124 
    125         return bus->ops.offline_device(bus, hcd, dev);
    126 }
    127 
    128 int bus_add_endpoint(bus_t *bus, device_t *device, const usb_endpoint_desc_t *desc, endpoint_t **out_ep)
    129 {
    130         assert(bus);
     88int bus_device_enumerate(device_t *dev)
     89{
     90        assert(dev);
     91
     92        const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_enumerate);
     93        if (!ops)
     94                return ENOTSUP;
     95
     96        return ops->device_enumerate(dev);
     97}
     98
     99int bus_device_remove(device_t *dev)
     100{
     101        assert(dev);
     102
     103        const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_remove);
     104
     105        if (!ops)
     106                return ENOTSUP;
     107
     108        return ops->device_remove(dev);
     109}
     110
     111int bus_device_online(device_t *dev)
     112{
     113        assert(dev);
     114
     115        const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_online);
     116        if (!ops)
     117                return ENOTSUP;
     118
     119        return ops->device_online(dev);
     120}
     121
     122int bus_device_offline(device_t *dev)
     123{
     124        assert(dev);
     125
     126        const bus_ops_t *ops = BUS_OPS_LOOKUP(dev->bus->ops, device_offline);
     127        if (!ops)
     128                return ENOTSUP;
     129
     130        return ops->device_offline(dev);
     131}
     132
     133int bus_endpoint_add(device_t *device, const usb_endpoint_desc_t *desc, endpoint_t **out_ep)
     134{
     135        int err;
    131136        assert(device);
     137
     138        bus_t *bus = device->bus;
    132139
    133140        if (desc->max_packet_size == 0 || desc->packets == 0) {
     
    136143        }
    137144
    138         fibril_mutex_lock(&bus->guard);
    139 
    140         int err = ENOMEM;
    141         endpoint_t *ep = bus->ops.create_endpoint(bus);
     145        const bus_ops_t *create_ops = BUS_OPS_LOOKUP(bus->ops, endpoint_create);
     146        const bus_ops_t *register_ops = BUS_OPS_LOOKUP(bus->ops, endpoint_register);
     147        if (!create_ops || !register_ops)
     148                return ENOTSUP;
     149
     150        endpoint_t *ep = create_ops->endpoint_create(device, desc);
    142151        if (!ep)
    143                 goto err;
    144 
    145         /* Bus reference */
     152                return ENOMEM;
     153
     154        /* Temporary reference */
    146155        endpoint_add_ref(ep);
    147156
    148         if ((err = bus->ops.register_endpoint(bus, device, ep, desc)))
    149                 goto err_ep;
     157        fibril_mutex_lock(&bus->guard);
     158        err = register_ops->endpoint_register(ep);
     159        fibril_mutex_unlock(&bus->guard);
    150160
    151161        if (out_ep) {
     162                /* Exporting reference */
    152163                endpoint_add_ref(ep);
    153164                *out_ep = ep;
    154165        }
    155166
    156         fibril_mutex_unlock(&bus->guard);
    157         return EOK;
    158 
    159 err_ep:
     167        /* Temporary reference */
    160168        endpoint_del_ref(ep);
    161 err:
    162         fibril_mutex_unlock(&bus->guard);
    163169        return err;
    164170}
     
    166172/** Searches for an endpoint. Returns a reference.
    167173 */
    168 endpoint_t *bus_find_endpoint(bus_t *bus, device_t *device, usb_target_t endpoint, usb_direction_t dir)
    169 {
    170         assert(bus);
    171 
    172         fibril_mutex_lock(&bus->guard);
    173         endpoint_t *ep = bus->ops.find_endpoint(bus, device, endpoint, dir);
     174endpoint_t *bus_find_endpoint(device_t *device, usb_target_t endpoint, usb_direction_t dir)
     175{
     176        assert(device);
     177
     178        bus_t *bus = device->bus;
     179
     180        const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, device_find_endpoint);
     181        if (!ops)
     182                return NULL;
     183
     184        fibril_mutex_lock(&bus->guard);
     185        endpoint_t *ep = ops->device_find_endpoint(device, endpoint, dir);
    174186        if (ep) {
    175187                /* Exporting reference */
     
    181193}
    182194
    183 int bus_remove_endpoint(bus_t *bus, endpoint_t *ep)
    184 {
    185         assert(bus);
     195int bus_endpoint_remove(endpoint_t *ep)
     196{
    186197        assert(ep);
    187198
    188         fibril_mutex_lock(&bus->guard);
    189         const int r = bus->ops.unregister_endpoint(bus, ep);
     199        bus_t *bus = endpoint_get_bus(ep);
     200
     201        const bus_ops_t *ops = BUS_OPS_LOOKUP(ep->device->bus->ops, endpoint_unregister);
     202        if (!ops)
     203                return ENOTSUP;
     204
     205        fibril_mutex_lock(&bus->guard);
     206        const int r = ops->endpoint_unregister(ep);
    190207        fibril_mutex_unlock(&bus->guard);
    191208
     
    203220        assert(bus);
    204221
    205         if (!bus->ops.reserve_default_address)
    206                 return ENOTSUP;
    207 
    208         fibril_mutex_lock(&bus->guard);
    209         const int r = bus->ops.reserve_default_address(bus, speed);
     222        const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, reserve_default_address);
     223        if (!ops)
     224                return ENOTSUP;
     225
     226        fibril_mutex_lock(&bus->guard);
     227        const int r = ops->reserve_default_address(bus, speed);
    210228        fibril_mutex_unlock(&bus->guard);
    211229        return r;
     
    216234        assert(bus);
    217235
    218         /* If this op is not set, allow everything */
    219         if (!bus->ops.release_default_address)
    220                 return ENOTSUP;
    221 
    222         fibril_mutex_lock(&bus->guard);
    223         const int r = bus->ops.release_default_address(bus);
     236        const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, release_default_address);
     237        if (!ops)
     238                return ENOTSUP;
     239
     240        fibril_mutex_lock(&bus->guard);
     241        const int r = ops->release_default_address(bus);
    224242        fibril_mutex_unlock(&bus->guard);
    225243        return r;
     
    230248        assert(bus);
    231249
    232         if (!bus->ops.reset_toggle)
    233                 return ENOTSUP;
    234 
    235         fibril_mutex_lock(&bus->guard);
    236         const int r = bus->ops.reset_toggle(bus, target, all);
     250        const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, reset_toggle);
     251        if (!ops)
     252                return ENOTSUP;
     253
     254        fibril_mutex_lock(&bus->guard);
     255        const int r = ops->reset_toggle(bus, target, all);
    237256        fibril_mutex_unlock(&bus->guard);
    238257        return r;
    239 }
    240 
    241 size_t bus_count_bw(endpoint_t *ep, size_t size)
    242 {
    243         assert(ep);
    244 
    245         fibril_mutex_lock(&ep->guard);
    246         const size_t bw = ep->bus->ops.count_bw(ep, size);
    247         fibril_mutex_unlock(&ep->guard);
    248         return bw;
    249258}
    250259
  • uspace/lib/usbhost/src/ddf_helpers.c

    rbd05140 r6832245  
    101101                endpoint_desc->max_packet_size, endpoint_desc->usb2.polling_interval);
    102102
    103         return bus_add_endpoint(hcd->bus, dev, endpoint_desc, NULL);
     103        return bus_endpoint_add(dev, endpoint_desc, NULL);
    104104}
    105105
     
    128128                usb_str_direction(endpoint_desc->direction));
    129129
    130         endpoint_t *ep = bus_find_endpoint(hcd->bus, dev, target, endpoint_desc->direction);
     130        endpoint_t *ep = bus_find_endpoint(dev, target, endpoint_desc->direction);
    131131        if (!ep)
    132132                return ENOENT;
    133133
    134         return bus_remove_endpoint(hcd->bus, ep);
     134        return bus_endpoint_remove(ep);
    135135}
    136136
     
    362362                const int ret = ddf_fun_unbind(victim->fun);
    363363                if (ret == EOK) {
    364                         bus_remove_device(hcd->bus, hcd, victim);
     364                        bus_device_remove(victim);
    365365                        ddf_fun_destroy(victim->fun);
    366366                } else {
     
    374374}
    375375
    376 device_t *hcd_ddf_device_create(ddf_dev_t *hc, size_t device_size)
     376device_t *hcd_ddf_device_create(ddf_dev_t *hc, bus_t *bus)
    377377{
    378378        /* Create DDF function for the new device */
     
    384384
    385385        /* Create USB device node for the new device */
    386         device_t *dev = ddf_fun_data_alloc(fun, device_size);
     386        device_t *dev = ddf_fun_data_alloc(fun, bus->device_size);
    387387        if (!dev) {
    388388                ddf_fun_destroy(fun);
     
    390390        }
    391391
    392         device_init(dev);
     392        bus_device_init(dev, bus);
    393393        dev->fun = fun;
    394394        return dev;
     
    402402}
    403403
    404 int hcd_ddf_device_explore(hcd_t *hcd, device_t *device)
     404int hcd_ddf_device_explore(device_t *device)
    405405{
    406406        int err;
     
    421421        usb_log_debug("Device(%d): Requesting full device descriptor.",
    422422            device->address);
    423         ssize_t got = hcd_send_batch_sync(hcd, device, control_ep, USB_DIRECTION_IN,
     423        ssize_t got = hcd_send_batch_sync(device->bus->hcd, device, control_ep, USB_DIRECTION_IN,
    424424            (char *) &desc, sizeof(desc), *(uint64_t *)&get_device_desc,
    425425            "read device descriptor");
     
    458458        usb_log_info("Device(%d): Requested to be brought online.", dev->address);
    459459
    460         return bus_online_device(hcd->bus, hcd, dev);
     460        return bus_device_online(dev);
    461461}
    462462
     
    472472        usb_log_info("Device(%d): Requested to be taken offline.", dev->address);
    473473
    474         return bus_offline_device(hcd->bus, hcd, dev);
     474        return bus_device_offline(dev);
    475475}
    476476
     
    483483        assert(hc);
    484484
    485         device_t *dev = hcd_ddf_device_create(hc, hcd->bus->device_size);
     485        device_t *dev = hcd_ddf_device_create(hc, hcd->bus);
    486486        if (!dev) {
    487487                usb_log_error("Failed to create USB device function.");
     
    492492        dev->port = port;
    493493
    494         if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) {
     494        if ((err = bus_device_enumerate(dev))) {
    495495                usb_log_error("Failed to initialize USB dev memory structures.");
    496496                return err;
     
    501501         */
    502502        if (!ddf_fun_get_name(dev->fun)) {
    503                 device_set_default_name(dev);
     503                bus_device_set_default_name(dev);
    504504        }
    505505
     
    538538        }
    539539
    540         device_t *dev = hcd_ddf_device_create(hc, hcd->bus->device_size);
     540        device_t *dev = hcd_ddf_device_create(hc, hcd->bus);
    541541        if (!dev) {
    542542                usb_log_error("Failed to create function for the root hub.");
     
    547547
    548548        /* Assign an address to the device */
    549         if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) {
     549        if ((err = bus_device_enumerate(dev))) {
    550550                usb_log_error("Failed to enumerate roothub device: %s", str_error(err));
    551551                goto err_usb_dev;
  • uspace/lib/usbhost/src/endpoint.c

    rbd05140 r6832245  
    4747/** Initialize provided endpoint structure.
    4848 */
    49 void endpoint_init(endpoint_t *ep, bus_t *bus)
     49void endpoint_init(endpoint_t *ep, device_t *dev, const usb_endpoint_desc_t *desc)
    5050{
    5151        memset(ep, 0, sizeof(endpoint_t));
    5252
    53         ep->bus = bus;
     53        assert(dev);
     54        ep->device = dev;
     55
    5456        atomic_set(&ep->refcnt, 0);
    5557        link_initialize(&ep->link);
    5658        fibril_mutex_initialize(&ep->guard);
    5759        fibril_condvar_initialize(&ep->avail);
     60
     61        ep->endpoint = desc->endpoint_no;
     62        ep->direction = desc->direction;
     63        ep->transfer_type = desc->transfer_type;
     64        ep->max_packet_size = desc->max_packet_size;
     65        ep->packets = desc->packets;
     66
     67        ep->bandwidth = endpoint_count_bw(ep, desc->max_packet_size);
     68}
     69
     70static inline const bus_ops_t *get_bus_ops(endpoint_t *ep)
     71{
     72        return ep->device->bus->ops;
    5873}
    5974
     
    6378}
    6479
     80static inline void endpoint_destroy(endpoint_t *ep)
     81{
     82        const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_destroy);
     83        if (ops) {
     84                ops->endpoint_destroy(ep);
     85        } else {
     86                assert(ep->active_batch == NULL);
     87
     88                /* Assume mostly the eps will be allocated by malloc. */
     89                free(ep);
     90        }
     91}
     92
    6593void endpoint_del_ref(endpoint_t *ep)
    6694{
    6795        if (atomic_predec(&ep->refcnt) == 0) {
    68                 if (ep->bus->ops.destroy_endpoint) {
    69                         ep->bus->ops.destroy_endpoint(ep);
    70                 }
    71                 else {
    72                         assert(ep->active_batch == NULL);
    73 
    74                         /* Assume mostly the eps will be allocated by malloc. */
    75                         free(ep);
    76                 }
     96                endpoint_destroy(ep);
    7797        }
    7898}
     
    133153        assert(ep);
    134154
    135         return ep->bus->ops.endpoint_get_toggle
    136             ? ep->bus->ops.endpoint_get_toggle(ep)
     155        const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_get_toggle);
     156        return ops
     157            ? ops->endpoint_get_toggle(ep)
    137158            : ep->toggle;
    138159}
     
    146167        assert(ep);
    147168
    148         if (ep->bus->ops.endpoint_set_toggle) {
    149                 ep->bus->ops.endpoint_set_toggle(ep, toggle);
     169        const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_set_toggle);
     170        if (ops) {
     171                ops->endpoint_set_toggle(ep, toggle);
    150172        }
    151173        else {
     
    154176}
    155177
     178ssize_t endpoint_count_bw(endpoint_t *ep, size_t packet_size)
     179{
     180        assert(ep);
     181
     182        const bus_ops_t *ops = BUS_OPS_LOOKUP(get_bus_ops(ep), endpoint_count_bw);
     183        if (!ops)
     184                return 0;
     185
     186        return ops->endpoint_count_bw(ep, packet_size);
     187}
     188
    156189/**
    157190 * @}
  • uspace/lib/usbhost/src/hcd.c

    rbd05140 r6832245  
    208208        }
    209209
    210         endpoint_t *ep = bus_find_endpoint(hcd->bus, device, target, direction);
     210        endpoint_t *ep = bus_find_endpoint(device, target, direction);
    211211        if (ep == NULL) {
    212212                usb_log_error("Endpoint(%d:%d) not registered for %s.\n",
     
    216216
    217217        // TODO cut here aka provide helper to call with instance of endpoint_t in hand
     218        assert(ep->device == device);
    218219
    219220        usb_log_debug2("%s %d:%d %zu(%zu).\n",
    220221            name, target.address, target.endpoint, size, ep->max_packet_size);
    221222
    222         const size_t bw = bus_count_bw(ep, size);
     223        const size_t bw = endpoint_count_bw(ep, size);
    223224        /* Check if we have enough bandwidth reserved */
    224225        if (ep->bandwidth < bw) {
  • uspace/lib/usbhost/src/usb2_bus.c

    rbd05140 r6832245  
    200200}};
    201201
    202 static int address_device(usb2_bus_t *bus, hcd_t *hcd, device_t *dev)
     202static int address_device(device_t *dev)
    203203{
    204204        int err;
     205
     206        usb2_bus_t *bus = (usb2_bus_t *) dev->bus;
     207        hcd_t *hcd = (hcd_t *) bus->base.hcd;
    205208
    206209        /* The default address is currently reserved for this device */
     
    220223
    221224        endpoint_t *default_ep;
    222         err = bus_add_endpoint(&bus->base, dev, &usb2_default_control_ep, &default_ep);
     225        err = bus_endpoint_add(dev, &usb2_default_control_ep, &default_ep);
    223226        if (err != EOK) {
    224227                usb_log_error("Device(%d): Failed to add default target: %s.",
     
    244247
    245248        /* We need to remove ep before we change the address */
    246         if ((err = bus_remove_endpoint(&bus->base, default_ep))) {
     249        if ((err = bus_endpoint_remove(default_ep))) {
    247250                usb_log_error("Device(%d): Failed to unregister default target: %s", address, str_error(err));
    248251                goto err_address;
     
    262265        /* Register EP on the new address */
    263266        usb_log_debug("Device(%d): Registering control EP.", address);
    264         err = bus_add_endpoint(&bus->base, dev, &control_ep, NULL);
     267        err = bus_endpoint_add(dev, &control_ep, NULL);
    265268        if (err != EOK) {
    266269                usb_log_error("Device(%d): Failed to register EP0: %s",
     
    272275
    273276err_default_control_ep:
    274         bus_remove_endpoint(&bus->base, default_ep);
     277        bus_endpoint_remove(default_ep);
    275278        endpoint_del_ref(default_ep);
    276279err_address:
     
    281284/** Enumerate a new USB device
    282285 */
    283 static int usb2_bus_enumerate_device(bus_t *bus_base, hcd_t *hcd, device_t *dev)
     286static int usb2_bus_device_enumerate(device_t *dev)
    284287{
    285288        int err;
    286         usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
     289        usb2_bus_t *bus = bus_to_usb2_bus(dev->bus);
    287290
    288291        /* The speed of the new device was reported by the hub when reserving
     
    306309
    307310        /* Assign an address to the device */
    308         if ((err = address_device(bus, hcd, dev))) {
     311        if ((err = address_device(dev))) {
    309312                usb_log_error("Failed to setup address of the new device: %s", str_error(err));
    310313                return err;
     
    312315
    313316        /* Read the device descriptor, derive the match ids */
    314         if ((err = hcd_ddf_device_explore(hcd, dev))) {
     317        if ((err = hcd_ddf_device_explore(dev))) {
    315318                usb_log_error("Device(%d): Failed to explore device: %s", dev->address, str_error(err));
    316319                release_address(bus, dev->address);
     
    329332 * @note Assumes that the internal mutex is locked.
    330333 */
    331 static endpoint_t *usb2_bus_find_ep(bus_t *bus_base, device_t *device, usb_target_t target, usb_direction_t direction)
    332 {
    333         usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
     334static endpoint_t *usb2_bus_find_ep(device_t *device, usb_target_t target, usb_direction_t direction)
     335{
     336        usb2_bus_t *bus = bus_to_usb2_bus(device->bus);
    334337
    335338        assert(device->address == target.address);
     
    345348}
    346349
    347 static endpoint_t *usb2_bus_create_ep(bus_t *bus)
     350static endpoint_t *usb2_bus_create_ep(device_t *dev, const usb_endpoint_desc_t *desc)
    348351{
    349352        endpoint_t *ep = malloc(sizeof(endpoint_t));
     
    351354                return NULL;
    352355
    353         endpoint_init(ep, bus);
     356        endpoint_init(ep, dev, desc);
    354357        return ep;
    355358}
     
    370373 * @param endpoint USB endpoint number.
    371374 */
    372 static int usb2_bus_register_ep(bus_t *bus_base, device_t *device, endpoint_t *ep, const usb_endpoint_desc_t *desc)
    373 {
    374         usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
     375static int usb2_bus_register_ep(endpoint_t *ep)
     376{
     377        usb2_bus_t *bus = bus_to_usb2_bus(ep->device->bus);
     378        assert(fibril_mutex_is_locked(&bus->base.guard));
    375379        assert(ep);
    376380
    377         ep->device = device;
    378 
    379         /* Extract USB2-related information from endpoint_desc */
    380         ep->endpoint = desc->endpoint_no;
    381         ep->direction = desc->direction;
    382         ep->transfer_type = desc->transfer_type;
    383         ep->max_packet_size = desc->max_packet_size;
    384         ep->packets = desc->packets;
    385 
    386         ep->bandwidth = bus_base->ops.count_bw(ep, desc->max_packet_size);
    387 
    388381        /* Check for existence */
    389         if (usb2_bus_find_ep(bus_base, ep->device, usb2_ep_to_target(ep), ep->direction))
     382        if (usb2_bus_find_ep(ep->device, usb2_ep_to_target(ep), ep->direction))
    390383                return EEXIST;
    391384
     
    394387                return ENOSPC;
    395388
     389        endpoint_add_ref(ep);
    396390        list_append(&ep->link, get_list(bus, ep->device->address));
    397391        bus->free_bw -= ep->bandwidth;
     
    400394}
    401395
    402 
    403396/** Release bandwidth reserved by the given endpoint.
    404397 */
    405 static int usb2_bus_unregister_ep(bus_t *bus_base, endpoint_t *ep)
    406 {
    407         usb2_bus_t *bus = bus_to_usb2_bus(bus_base);
     398static int usb2_bus_unregister_ep(endpoint_t *ep)
     399{
     400        usb2_bus_t *bus = bus_to_usb2_bus(ep->device->bus);
    408401        assert(ep);
    409402
    410403        list_remove(&ep->link);
    411         ep->device = NULL;
    412404
    413405        bus->free_bw += ep->bandwidth;
     406        endpoint_del_ref(ep);
    414407
    415408        return EOK;
     
    452445}
    453446
    454 static const bus_ops_t usb2_bus_ops = {
     447const bus_ops_t usb2_bus_ops = {
    455448        .reserve_default_address = usb2_bus_register_default_address,
    456449        .release_default_address = usb2_bus_release_default_address,
    457         .enumerate_device = usb2_bus_enumerate_device,
    458         .create_endpoint = usb2_bus_create_ep,
    459         .find_endpoint = usb2_bus_find_ep,
    460         .unregister_endpoint = usb2_bus_unregister_ep,
    461         .register_endpoint = usb2_bus_register_ep,
    462450        .reset_toggle = usb2_bus_reset_toggle,
     451        .device_enumerate = usb2_bus_device_enumerate,
     452        .device_find_endpoint = usb2_bus_find_ep,
     453        .endpoint_create= usb2_bus_create_ep,
     454        .endpoint_register= usb2_bus_register_ep,
     455        .endpoint_unregister= usb2_bus_unregister_ep,
    463456};
    464457
     
    470463 * @return Error code.
    471464 */
    472 int usb2_bus_init(usb2_bus_t *bus, size_t available_bandwidth, count_bw_func_t count_bw)
     465int usb2_bus_init(usb2_bus_t *bus, hcd_t *hcd, size_t available_bandwidth)
    473466{
    474467        assert(bus);
    475468
    476         bus_init(&bus->base, sizeof(device_t));
    477 
    478         bus->base.ops = usb2_bus_ops;
    479         bus->base.ops.count_bw = count_bw;
     469        bus_init(&bus->base, hcd, sizeof(device_t));
     470        bus->base.ops = &usb2_bus_ops;
    480471
    481472        bus->free_bw = available_bandwidth;
  • uspace/lib/usbhost/src/usb_transfer_batch.c

    rbd05140 r6832245  
    4949{
    5050        assert(ep);
    51         assert(ep->bus);
    5251
    53         usb_transfer_batch_t *batch;
    54         if (ep->bus->ops.create_batch)
    55                 batch = ep->bus->ops.create_batch(ep->bus, ep);
    56         else
    57                 batch = calloc(1, sizeof(usb_transfer_batch_t));
     52        bus_t *bus = endpoint_get_bus(ep);
     53        const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, batch_create);
    5854
    59         return batch;
     55        if (!ops) {
     56                usb_transfer_batch_t *batch = calloc(1, sizeof(usb_transfer_batch_t));
     57                usb_transfer_batch_init(batch, ep);
     58                return batch;
     59        }
     60
     61        return ops->batch_create(ep);
    6062}
    6163
     
    6466void usb_transfer_batch_init(usb_transfer_batch_t *batch, endpoint_t *ep)
    6567{
     68        assert(ep);
     69        endpoint_add_ref(ep);
    6670        batch->ep = ep;
    6771}
     
    8286            batch->toggle_reset_mode == RESET_ALL ? "all EPs toggle" : "EP toggle");
    8387
    84         return bus_reset_toggle(batch->ep->bus, batch->target, batch->toggle_reset_mode);
     88        return bus_reset_toggle(endpoint_get_bus(batch->ep), batch->target, batch->toggle_reset_mode);
    8589}
    8690
     
    9397        assert(batch);
    9498        assert(batch->ep);
    95         assert(batch->ep->bus);
    9699
    97         bus_t *bus = batch->ep->bus;
    98         if (bus->ops.destroy_batch) {
     100        bus_t *bus = endpoint_get_bus(batch->ep);
     101        const bus_ops_t *ops = BUS_OPS_LOOKUP(bus->ops, batch_destroy);
     102
     103        endpoint_del_ref(batch->ep);
     104
     105        if (ops) {
    99106                usb_log_debug2("Batch %p " USB_TRANSFER_BATCH_FMT " destroying.\n",
    100107                    batch, USB_TRANSFER_BATCH_ARGS(*batch));
    101                 bus->ops.destroy_batch(batch);
     108                ops->batch_destroy(batch);
    102109        }
    103110        else {
Note: See TracChangeset for help on using the changeset viewer.