Changes in / [95c675b:a416d070] in mainline


Ignore:
Files:
6 added
37 deleted
57 edited

Legend:

Unmodified
Added
Removed
  • .bzrignore

    r95c675b ra416d070  
    232232uspace/dist/drv/virt/
    233233uspace/dist/drv/xtkbd/
    234 uspace/dist/drv/xhci/
    235234uspace/dist/inc/_link.ld
    236235uspace/dist/inc/c/
     
    289288uspace/drv/bus/usb/usbmid/usbmid
    290289uspace/drv/bus/usb/vhc/vhc
    291 uspace/drv/bus/usb/xhci/xhci
    292 uspace/drv/bus/usb/xhci/test-xhci
    293290uspace/drv/char/atkbd/atkbd
    294291uspace/drv/char/i8042/i8042
  • boot/Makefile.common

    r95c675b ra416d070  
    237237        $(USPACE_PATH)/lib/posix/test-libposix \
    238238        $(USPACE_PATH)/lib/uri/test-liburi \
    239         $(USPACE_PATH)/drv/bus/usb/xhci/test-xhci \
    240239        $(USPACE_PATH)/app/bdsh/test-bdsh \
    241240        $(USPACE_PATH)/srv/net/tcp/test-tcp
  • boot/arch/amd64/Makefile.inc

    r95c675b ra416d070  
    5656        bus/usb/usbmast \
    5757        bus/usb/usbmid \
    58         bus/usb/vhc \
    59         bus/usb/xhci
     58        bus/usb/vhc
    6059
    6160RD_DRV_CFG += \
  • tools/ew.py

    r95c675b ra416d070  
    160160        return ' -usb'
    161161
    162 def qemu_xhci_options():
    163         if is_override('noxhci'):
    164                 return ''
    165         return ' -device nec-usb-xhci,id=xhci'
    166 
    167162def qemu_audio_options():
    168163        if is_override('nosnd'):
     
    185180        if (not 'usb' in cfg.keys()) or cfg['usb']:
    186181                cmdline += qemu_usb_options()
    187         if (not 'xhci' in cfg.keys()) or cfg['xhci']:
    188                 cmdline += qemu_xhci_options()
    189182        if (not 'audio' in cfg.keys()) or cfg['audio']:
    190183                cmdline += qemu_audio_options()
     
    293286def usage():
    294287        print("%s - emulator wrapper for running HelenOS\n" % os.path.basename(sys.argv[0]))
    295         print("%s [-d] [-h] [-net e1k|rtl8139|ne2k] [-nohdd] [-nokvm] [-nonet] [-nosnd] [-nousb] [-noxhci]\n" %
     288        print("%s [-d] [-h] [-net e1k|rtl8139|ne2k] [-nohdd] [-nokvm] [-nonet] [-nosnd] [-nousb]\n" %
    296289            os.path.basename(sys.argv[0]))
    297290        print("-d\tDry run: do not run the emulation, just print the command line.")
     
    302295        print("-nosnd\tDisable sound, if applicable.")
    303296        print("-nousb\tDisable USB support, if applicable.")
    304         print("-noxhci\tDisable XHCI support, if applicable.")
    305297
    306298def fail(platform, machine):
     
    344336                elif sys.argv[i] == '-nousb':
    345337                        overrides['nousb'] = True
    346                 elif sys.argv[i] == '-noxhci':
    347                         overrides['noxhci'] = True
    348338                else:
    349339                        usage()
  • uspace/Makefile

    r95c675b ra416d070  
    158158        drv/bus/usb/usbmid \
    159159        drv/bus/usb/vhc \
    160         drv/bus/usb/xhci \
    161160        drv/char/i8042 \
    162161        drv/char/ns8250 \
  • uspace/drv/bus/usb/ehci/Makefile

    r95c675b ra416d070  
    4646SOURCES = \
    4747        ehci_batch.c \
    48         ehci_bus.c \
     48        ehci_endpoint.c \
    4949        ehci_rh.c \
    5050        endpoint_list.c \
  • uspace/drv/bus/usb/ehci/ehci_batch.c

    r95c675b ra416d070  
    4545
    4646#include "ehci_batch.h"
    47 #include "ehci_bus.h"
     47#include "ehci_endpoint.h"
    4848
    4949/* The buffer pointer list in the qTD is long enough to support a maximum
  • uspace/drv/bus/usb/ehci/ehci_rh.c

    r95c675b ra416d070  
    144144        assert(instance);
    145145        assert(batch);
    146         const usb_target_t target = batch->ep->target;
     146        const usb_target_t target = {{
     147                .address = batch->ep->address,
     148                .endpoint = batch->ep->endpoint,
     149        }};
    147150        batch->error = virthub_base_request(&instance->base, target,
    148151            usb_transfer_batch_direction(batch), (void*)batch->setup_buffer,
     
    180183            instance, batch);
    181184        if (batch) {
    182                 const usb_target_t target = batch->ep->target;
     185                const usb_target_t target = {{
     186                        .address = batch->ep->address,
     187                        .endpoint = batch->ep->endpoint,
     188                }};
    183189                batch->error = virthub_base_request(&instance->base, target,
    184190                    usb_transfer_batch_direction(batch),
  • uspace/drv/bus/usb/ehci/endpoint_list.h

    r95c675b ra416d070  
    4040#include <usb/host/utils/malloc32.h>
    4141
    42 #include "ehci_bus.h"
     42#include "ehci_endpoint.h"
    4343#include "hw_struct/queue_head.h"
    4444
  • uspace/drv/bus/usb/ehci/hc.c

    r95c675b ra416d070  
    8989};
    9090
     91static void hc_start(hc_t *instance);
    9192static int hc_init_memory(hc_t *instance);
    9293
     
    9798 * @return Error code.
    9899 */
    99 int ehci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)
     100int ehci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res)
    100101{
    101102        assert(code);
    102103        assert(hw_res);
    103 
    104         hc_t *instance = hcd_get_driver_data(hcd);
    105104
    106105        if (hw_res->irqs.count != 1 || hw_res->mem_ranges.count != 1)
     
    129128
    130129        memcpy(code->cmds, ehci_irq_commands, sizeof(ehci_irq_commands));
     130        ehci_caps_regs_t *caps = NULL;
     131
     132        int ret = pio_enable_range(&regs, (void**)&caps);
     133        if (ret != EOK) {
     134                free(code->ranges);
     135                free(code->cmds);
     136                return ret;
     137        }
    131138
    132139        ehci_regs_t *registers =
    133                 (ehci_regs_t *)(RNGABSPTR(regs) + EHCI_RD8(instance->caps->caplength));
     140            (ehci_regs_t *)(RNGABSPTR(regs) + EHCI_RD8(caps->caplength));
    134141        code->cmds[0].addr = (void *) &registers->usbsts;
    135142        code->cmds[3].addr = (void *) &registers->usbsts;
     
    149156 * @return Error code
    150157 */
    151 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res)
     158int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res, bool interrupts)
    152159{
    153160        assert(instance);
     
    165172                return ret;
    166173        }
    167 
    168174        usb_log_info("HC(%p): Device registers at %"PRIx64" (%zuB) accessible.",
    169175            instance, hw_res->mem_ranges.ranges[0].address.absolute,
     
    189195        ehci_rh_init(
    190196            &instance->rh, instance->caps, instance->registers, "ehci rh");
    191 
    192         ehci_bus_init(&instance->bus, instance);
     197        usb_log_debug("HC(%p): Starting HW.", instance);
     198        hc_start(instance);
     199
    193200        return EOK;
    194201}
     
    215222        ehci_endpoint_t *ehci_ep = ehci_endpoint_get(ep);
    216223        usb_log_debug("HC(%p) enqueue EP(%d:%d:%s:%s)\n", instance,
    217             ep->target.address, ep->target.endpoint,
     224            ep->address, ep->endpoint,
    218225            usb_str_transfer_type_short(ep->transfer_type),
    219226            usb_str_direction(ep->direction));
     
    239246        ehci_endpoint_t *ehci_ep = ehci_endpoint_get(ep);
    240247        usb_log_debug("HC(%p) dequeue EP(%d:%d:%s:%s)\n", instance,
    241             ep->target.address, ep->target.endpoint,
     248            ep->address, ep->endpoint,
    242249            usb_str_transfer_type_short(ep->transfer_type),
    243250            usb_str_direction(ep->direction));
     
    291298
    292299        /* Check for root hub communication */
    293         if (batch->ep->target.address == ehci_rh_get_address(&instance->rh)) {
     300        if (batch->ep->address == ehci_rh_get_address(&instance->rh)) {
    294301                usb_log_debug("HC(%p): Scheduling BATCH(%p) for RH(%p)",
    295302                    instance, batch, &instance->rh);
     
    361368 * @param[in] instance EHCI hc driver structure.
    362369 */
    363 int hc_start(hc_t *instance, bool interrupts)
    364 {
    365         assert(instance);
    366         usb_log_debug("HC(%p): Starting HW.", instance);
    367 
     370void hc_start(hc_t *instance)
     371{
     372        assert(instance);
    368373        /* Turn off the HC if it's running, Reseting a running device is
    369374         * undefined */
     
    430435        EHCI_WR(instance->registers->usbsts, EHCI_RD(instance->registers->usbsts));
    431436        EHCI_WR(instance->registers->usbintr, EHCI_USED_INTERRUPTS);
    432 
    433         return EOK;
    434437}
    435438
  • uspace/drv/bus/usb/ehci/hc.h

    r95c675b ra416d070  
    8080        /** USB hub emulation structure */
    8181        ehci_rh_t rh;
    82 
    83         /** USB bookkeeping */
    84         ehci_bus_t bus;
    8582} hc_t;
    8683
    87 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res);
    88 int hc_start(hc_t *instance, bool interrupts);
     84int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res, bool interrupts);
    8985void hc_fini(hc_t *instance);
    9086
     
    9288void hc_dequeue_endpoint(hc_t *instance, const endpoint_t *ep);
    9389
    94 int ehci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res);
     90int ehci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res);
    9591
    9692void ehci_hc_interrupt(hcd_t *hcd, uint32_t status);
  • uspace/drv/bus/usb/ehci/hw_struct/queue_head.c

    r95c675b ra416d070  
    3737#include <mem.h>
    3838#include <macros.h>
    39 #include <usb/host/bus.h>
    4039
    4140#include "mem_access.h"
     
    6665        assert(ep->speed < ARRAY_SIZE(speed));
    6766        EHCI_MEM32_WR(instance->ep_char,
    68             QH_EP_CHAR_ADDR_SET(ep->target.address) |
    69             QH_EP_CHAR_EP_SET(ep->target.endpoint) |
     67            QH_EP_CHAR_ADDR_SET(ep->address) |
     68            QH_EP_CHAR_EP_SET(ep->endpoint) |
    7069            speed[ep->speed] |
    7170            QH_EP_CHAR_MAX_LENGTH_SET(ep->max_packet_size)
     
    8281        if (ep->speed != USB_SPEED_HIGH) {
    8382                ep_cap |=
    84                     QH_EP_CAP_TT_PORT_SET(ep->device->tt.port) |
    85                     QH_EP_CAP_TT_ADDR_SET(ep->device->tt.address);
     83                    QH_EP_CAP_TT_PORT_SET(ep->tt.port) |
     84                    QH_EP_CAP_TT_ADDR_SET(ep->tt.address);
    8685        }
    8786        if (ep->transfer_type == USB_TRANSFER_INTERRUPT) {
  • uspace/drv/bus/usb/ehci/main.c

    r95c675b ra416d070  
    4848#include "res.h"
    4949#include "hc.h"
     50#include "ehci_endpoint.h"
    5051
    5152#define NAME "ehci"
    5253
    53 static int ehci_driver_init(hcd_t *, const hw_res_list_parsed_t *);
    54 static int ehci_driver_claim(hcd_t *, ddf_dev_t *);
    55 static int ehci_driver_start(hcd_t *, bool);
     54static int ehci_driver_init(hcd_t *, const hw_res_list_parsed_t *, bool);
    5655static void ehci_driver_fini(hcd_t *);
    5756
    5857static const ddf_hc_driver_t ehci_hc_driver = {
     58        .claim = disable_legacy,
     59        .hc_speed = USB_SPEED_HIGH,
     60        .irq_code_gen = ehci_hc_gen_irq_code,
     61        .init = ehci_driver_init,
     62        .fini = ehci_driver_fini,
    5963        .name = "EHCI-PCI",
    60         .init = ehci_driver_init,
    61         .irq_code_gen = ehci_hc_gen_irq_code,
    62         .claim = ehci_driver_claim,
    63         .start = ehci_driver_start,
    64         .setup_root_hub = hcd_setup_virtual_root_hub,
    65         .fini = ehci_driver_fini,
    6664        .ops = {
    6765                .schedule       = ehci_hc_schedule,
     66                .ep_add_hook    = ehci_endpoint_init,
     67                .ep_remove_hook = ehci_endpoint_fini,
    6868                .irq_hook       = ehci_hc_interrupt,
    6969                .status_hook    = ehci_hc_status,
     
    7272
    7373
    74 static int ehci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res)
     74static int ehci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res,
     75    bool irq)
    7576{
    7677        assert(hcd);
     
    8182                return ENOMEM;
    8283
    83         const int ret = hc_init(instance, res);
     84        const int ret = hc_init(instance, res, irq);
    8485        if (ret == EOK) {
    85                 hcd_set_implementation(hcd, instance, &ehci_hc_driver.ops, &instance->bus.base.base);
     86                hcd_set_implementation(hcd, instance, &ehci_hc_driver.ops);
    8687        } else {
    8788                free(instance);
    8889        }
    8990        return ret;
    90 }
    91 
    92 static int ehci_driver_claim(hcd_t *hcd, ddf_dev_t *dev)
    93 {
    94         hc_t *instance = hcd_get_driver_data(hcd);
    95         assert(instance);
    96 
    97         return disable_legacy(instance, dev);
    98 }
    99 
    100 static int ehci_driver_start(hcd_t *hcd, bool irq) {
    101         hc_t *instance = hcd_get_driver_data(hcd);
    102         assert(instance);
    103 
    104         return hc_start(instance, irq);
    10591}
    10692
     
    11399
    114100        free(hc);
    115         hcd_set_implementation(hcd, NULL, NULL, NULL);
     101        hcd_set_implementation(hcd, NULL, NULL);
    116102}
    117103
  • uspace/drv/bus/usb/ehci/res.c

    r95c675b ra416d070  
    172172}
    173173
    174 int disable_legacy(hc_t *hc, ddf_dev_t *device)
     174int disable_legacy(ddf_dev_t *device)
    175175{
    176176        assert(device);
     
    182182        usb_log_debug("Disabling EHCI legacy support.\n");
    183183
    184 
    185         const uint32_t hcc_params = EHCI_RD(hc->caps->hccparams);
     184        hw_res_list_parsed_t res;
     185        hw_res_list_parsed_init(&res);
     186        int ret = hw_res_get_list_parsed(parent_sess, &res, 0);
     187        if (ret != EOK) {
     188                usb_log_error("Failed to get resource list: %s\n",
     189                    str_error(ret));
     190                goto clean;
     191        }
     192
     193        if (res.mem_ranges.count < 1) {
     194                usb_log_error("Incorrect mem range count: %zu",
     195                    res.mem_ranges.count);
     196                ret = EINVAL;
     197                goto clean;
     198        }
     199
     200        /* Map EHCI registers */
     201        void *regs = NULL;
     202        ret = pio_enable_range(&res.mem_ranges.ranges[0], &regs);
     203        if (ret != EOK) {
     204                usb_log_error("Failed to map registers %p: %s.\n",
     205                    RNGABSPTR(res.mem_ranges.ranges[0]), str_error(ret));
     206                goto clean;
     207        }
     208
     209        usb_log_debug("Registers mapped at: %p.\n", regs);
     210
     211        ehci_caps_regs_t *ehci_caps = regs;
     212
     213        const uint32_t hcc_params = EHCI_RD(ehci_caps->hccparams);
    186214        usb_log_debug2("Value of hcc params register: %x.\n", hcc_params);
    187215
     
    192220        usb_log_debug2("Value of EECP: %x.\n", eecp);
    193221
    194         int ret = disable_extended_caps(parent_sess, eecp);
     222        ret = disable_extended_caps(parent_sess, eecp);
    195223        if (ret != EOK) {
    196224                usb_log_error("Failed to disable extended capabilities: %s.\n",
     
    199227        }
    200228clean:
    201         async_hangup(parent_sess);
     229        //TODO unmap registers
     230        hw_res_list_parsed_clean(&res);
    202231        return ret;
    203232}
  • uspace/drv/bus/usb/ehci/res.h

    r95c675b ra416d070  
    3939#include <device/hw_res_parsed.h>
    4040
    41 #include "hc.h"
    42 
    43 extern int disable_legacy(hc_t *, ddf_dev_t *);
     41extern int disable_legacy(ddf_dev_t *);
    4442
    4543#endif
  • uspace/drv/bus/usb/ohci/Makefile

    r95c675b ra416d070  
    4949        main.c \
    5050        ohci_batch.c \
    51         ohci_bus.c \
     51        ohci_endpoint.c \
    5252        ohci_rh.c \
    5353        hw_struct/endpoint_descriptor.c \
  • uspace/drv/bus/usb/ohci/endpoint_list.h

    r95c675b ra416d070  
    4141#include <usb/host/utils/malloc32.h>
    4242
    43 #include "ohci_bus.h"
     43#include "ohci_endpoint.h"
    4444#include "hw_struct/endpoint_descriptor.h"
    4545
  • uspace/drv/bus/usb/ohci/hc.c

    r95c675b ra416d070  
    4747#include <usb/usb.h>
    4848
    49 #include "ohci_bus.h"
     49#include "ohci_endpoint.h"
    5050#include "ohci_batch.h"
    5151
     
    8989};
    9090
     91static void hc_gain_control(hc_t *instance);
     92static void hc_start(hc_t *instance);
    9193static int hc_init_transfer_lists(hc_t *instance);
    9294static int hc_init_memory(hc_t *instance);
     
    101103 * @return Error code.
    102104 */
    103 int ohci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)
     105int ohci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res)
    104106{
    105107        assert(code);
     
    149151 * @return Error code
    150152 */
    151 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res)
     153int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res, bool interrupts)
    152154{
    153155        assert(instance);
     
    170172        list_initialize(&instance->pending_batches);
    171173        fibril_mutex_initialize(&instance->guard);
     174        instance->hw_interrupts = interrupts;
    172175
    173176        ret = hc_init_memory(instance);
     
    178181                return ret;
    179182        }
     183
     184        hc_gain_control(instance);
     185
     186        ohci_rh_init(&instance->rh, instance->registers, "ohci rh");
     187        hc_start(instance);
    180188
    181189        return EOK;
     
    287295
    288296        /* Check for root hub communication */
    289         if (batch->ep->target.address == ohci_rh_get_address(&instance->rh)) {
     297        if (batch->ep->address == ohci_rh_get_address(&instance->rh)) {
    290298                usb_log_debug("OHCI root hub request.\n");
    291299                return ohci_rh_schedule(&instance->rh, batch);
     
    435443void hc_start(hc_t *instance)
    436444{
    437         ohci_rh_init(&instance->rh, instance->registers, "ohci rh");
    438 
    439445        /* OHCI guide page 42 */
    440446        assert(instance);
  • uspace/drv/bus/usb/ohci/hc.h

    r95c675b ra416d070  
    5252#include "ohci_regs.h"
    5353#include "ohci_rh.h"
    54 #include "ohci_bus.h"
    5554#include "endpoint_list.h"
    5655#include "hw_struct/hcca.h"
     
    6059        /** Memory mapped I/O registers area */
    6160        ohci_regs_t *registers;
    62        
    6361        /** Host controller communication area structure */
    6462        hcca_t *hcca;
     
    6664        /** Transfer schedules */
    6765        endpoint_list_t lists[4];
    68 
    6966        /** List of active transfers */
    7067        list_t pending_batches;
     
    8178        /** USB hub emulation structure */
    8279        ohci_rh_t rh;
    83 
    84         /** USB bookkeeping */
    85         ohci_bus_t bus;
    8680} hc_t;
    8781
    88 extern int hc_init(hc_t *, const hw_res_list_parsed_t *);
    89 extern void hc_gain_control(hc_t *instance);
    90 extern void hc_start(hc_t *instance);
     82extern int hc_init(hc_t *, const hw_res_list_parsed_t *, bool);
    9183extern void hc_fini(hc_t *);
    9284
     
    9486extern void hc_dequeue_endpoint(hc_t *, const endpoint_t *);
    9587
    96 int ohci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res);
     88int ohci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res);
    9789
    9890extern void ohci_hc_interrupt(hcd_t *, uint32_t);
  • uspace/drv/bus/usb/ohci/hw_struct/endpoint_descriptor.c

    r95c675b ra416d070  
    7979        /* Status: address, endpoint nr, direction mask and max packet size. */
    8080        OHCI_MEM32_WR(instance->status,
    81             ((ep->target.address & ED_STATUS_FA_MASK) << ED_STATUS_FA_SHIFT)
    82             | ((ep->target.endpoint & ED_STATUS_EN_MASK) << ED_STATUS_EN_SHIFT)
     81            ((ep->address & ED_STATUS_FA_MASK) << ED_STATUS_FA_SHIFT)
     82            | ((ep->endpoint & ED_STATUS_EN_MASK) << ED_STATUS_EN_SHIFT)
    8383            | ((dir[ep->direction] & ED_STATUS_D_MASK) << ED_STATUS_D_SHIFT)
    8484            | ((ep->max_packet_size & ED_STATUS_MPS_MASK)
  • uspace/drv/bus/usb/ohci/main.c

    r95c675b ra416d070  
    4545
    4646#include "hc.h"
    47 #include "ohci_bus.h"
    4847
    4948#define NAME "ohci"
    50 static int ohci_driver_init(hcd_t *, const hw_res_list_parsed_t *);
    51 static int ohci_driver_start(hcd_t *, bool);
    52 static int ohci_driver_claim(hcd_t *, ddf_dev_t *);
     49static int ohci_driver_init(hcd_t *, const hw_res_list_parsed_t *, bool);
    5350static void ohci_driver_fini(hcd_t *);
    5451
    5552static const ddf_hc_driver_t ohci_hc_driver = {
     53        .hc_speed = USB_SPEED_FULL,
    5654        .irq_code_gen = ohci_hc_gen_irq_code,
    5755        .init = ohci_driver_init,
    58         .claim = ohci_driver_claim,
    59         .start = ohci_driver_start,
    60         .setup_root_hub = hcd_setup_virtual_root_hub,
    6156        .fini = ohci_driver_fini,
    6257        .name = "OHCI",
    6358        .ops = {
    6459                .schedule       = ohci_hc_schedule,
     60                .ep_add_hook    = ohci_endpoint_init,
     61                .ep_remove_hook = ohci_endpoint_fini,
    6562                .irq_hook       = ohci_hc_interrupt,
    6663                .status_hook    = ohci_hc_status,
     
    6966
    7067
    71 static int ohci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res)
     68static int ohci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, bool irq)
    7269{
    73         int err;
    74 
    7570        assert(hcd);
    7671        assert(hcd_get_driver_data(hcd) == NULL);
     
    8075                return ENOMEM;
    8176
    82         if ((err = hc_init(instance, res)) != EOK)
    83                 goto err;
    84 
    85         if ((err = ohci_bus_init(&instance->bus, instance)))
    86                 goto err;
    87 
    88         hcd_set_implementation(hcd, instance, &ohci_hc_driver.ops, &instance->bus.base.base);
    89 
    90         return EOK;
    91 
    92 err:
    93         free(instance);
    94         return err;
    95 }
    96 
    97 static int ohci_driver_claim(hcd_t *hcd, ddf_dev_t *dev)
    98 {
    99         hc_t *hc = hcd_get_driver_data(hcd);
    100         assert(hc);
    101 
    102         hc_gain_control(hc);
    103 
    104         return EOK;
    105 }
    106 
    107 static int ohci_driver_start(hcd_t *hcd, bool interrupts)
    108 {
    109         hc_t *hc = hcd_get_driver_data(hcd);
    110         assert(hc);
    111 
    112         hc->hw_interrupts = interrupts;
    113         hc_start(hc);
    114         return EOK;
     77        const int ret = hc_init(instance, res, irq);
     78        if (ret == EOK) {
     79                hcd_set_implementation(hcd, instance, &ohci_hc_driver.ops);
     80        } else {
     81                free(instance);
     82        }
     83        return ret;
    11584}
    11685
     
    12291                hc_fini(hc);
    12392
    124         hcd_set_implementation(hcd, NULL, NULL, NULL);
     93        hcd_set_implementation(hcd, NULL, NULL);
    12594        free(hc);
    12695}
  • uspace/drv/bus/usb/ohci/ohci_batch.c

    r95c675b ra416d070  
    4545
    4646#include "ohci_batch.h"
    47 #include "ohci_bus.h"
     47#include "ohci_endpoint.h"
    4848
    4949static void (*const batch_setup[])(ohci_transfer_batch_t*, usb_direction_t);
  • uspace/drv/bus/usb/ohci/ohci_rh.c

    r95c675b ra416d070  
    178178        assert(instance);
    179179        assert(batch);
    180         const usb_target_t target = batch->ep->target;
     180        const usb_target_t target = {{
     181                .address = batch->ep->address,
     182                .endpoint = batch->ep->endpoint,
     183        }};
    181184        batch->error = virthub_base_request(&instance->base, target,
    182185            usb_transfer_batch_direction(batch), (void*)batch->setup_buffer,
     
    208211        instance->unfinished_interrupt_transfer = NULL;
    209212        if (batch) {
    210                 const usb_target_t target = batch->ep->target;
     213                const usb_target_t target = {{
     214                        .address = batch->ep->address,
     215                        .endpoint = batch->ep->endpoint,
     216                }};
    211217                batch->error = virthub_base_request(&instance->base, target,
    212218                    usb_transfer_batch_direction(batch),
  • uspace/drv/bus/usb/uhci/hc.c

    r95c675b ra416d070  
    5050#include <usb/usb.h>
    5151#include <usb/host/utils/malloc32.h>
    52 #include <usb/host/bandwidth.h>
    5352
    5453#include "uhci_batch.h"
     
    107106 * @return Error code.
    108107 */
    109 int uhci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)
     108int uhci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res)
    110109{
    111110        assert(code);
     
    215214 * interrupt fibrils.
    216215 */
    217 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res)
     216int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res, bool interrupts)
    218217{
    219218        assert(instance);
     
    223222            return EINVAL;
    224223
     224        instance->hw_interrupts = interrupts;
    225225        instance->hw_failures = 0;
    226226
     
    246246        }
    247247
    248         return EOK;
    249 }
    250 
    251 void hc_start(hc_t *instance)
    252 {
    253248        hc_init_hw(instance);
    254249        (void)hc_debug_checker;
    255250
    256251        uhci_rh_init(&instance->rh, instance->registers->ports, "uhci");
     252
     253        return EOK;
    257254}
    258255
     
    321318int hc_init_mem_structures(hc_t *instance)
    322319{
    323         int err;
    324         assert(instance);
    325 
    326         if ((err = usb2_bus_init(&instance->bus, BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11)))
    327                 return err;
     320        assert(instance);
    328321
    329322        /* Init USB frame list page */
     
    447440        assert(batch);
    448441
    449         if (batch->ep->target.address == uhci_rh_get_address(&instance->rh))
     442        if (batch->ep->address == uhci_rh_get_address(&instance->rh))
    450443                return uhci_rh_schedule(&instance->rh, batch);
    451444
  • uspace/drv/bus/usb/uhci/hc.h

    r95c675b ra416d070  
    4343#include <ddi.h>
    4444#include <usb/host/hcd.h>
    45 #include <usb/host/usb2_bus.h>
    4645#include <usb/host/usb_transfer_batch.h>
    4746
     
    101100typedef struct hc {
    102101        uhci_rh_t rh;
    103         usb2_bus_t bus;
    104102        /** Addresses of I/O registers */
    105103        uhci_regs_t *registers;
     
    126124} hc_t;
    127125
    128 extern int hc_init(hc_t *, const hw_res_list_parsed_t *);
    129 extern void hc_start(hc_t *);
     126extern int hc_init(hc_t *, const hw_res_list_parsed_t *, bool);
    130127extern void hc_fini(hc_t *);
    131128
    132 extern int uhci_hc_gen_irq_code(irq_code_t *, hcd_t *,const hw_res_list_parsed_t *);
     129extern int uhci_hc_gen_irq_code(irq_code_t *, const hw_res_list_parsed_t *);
    133130
    134131extern void uhci_hc_interrupt(hcd_t *, uint32_t);
  • uspace/drv/bus/usb/uhci/main.c

    r95c675b ra416d070  
    4949#define NAME "uhci"
    5050
    51 static int uhci_driver_init(hcd_t *, const hw_res_list_parsed_t *);
    52 static int uhci_driver_start(hcd_t *, bool);
     51static int uhci_driver_init(hcd_t *, const hw_res_list_parsed_t *, bool);
    5352static void uhci_driver_fini(hcd_t *);
    54 static int disable_legacy(hcd_t *, ddf_dev_t *);
     53static int disable_legacy(ddf_dev_t *);
    5554
    5655static const ddf_hc_driver_t uhci_hc_driver = {
    5756        .claim = disable_legacy,
     57        .hc_speed = USB_SPEED_FULL,
    5858        .irq_code_gen = uhci_hc_gen_irq_code,
    5959        .init = uhci_driver_init,
    60         .start = uhci_driver_start,
    61         .setup_root_hub = hcd_setup_virtual_root_hub,
    6260        .fini = uhci_driver_fini,
    6361        .name = "UHCI",
     
    6967};
    7068
    71 static int uhci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res)
     69static int uhci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, bool irq)
    7270{
    73         int err;
    74 
    7571        assert(hcd);
    7672        assert(hcd_get_driver_data(hcd) == NULL);
     
    8076                return ENOMEM;
    8177
    82         if ((err = hc_init(instance, res)) != EOK)
    83                 goto err;
    84 
    85         hcd_set_implementation(hcd, instance, &uhci_hc_driver.ops, &instance->bus.base);
    86 
    87         return EOK;
    88 
    89 err:
    90         free(instance);
    91         return err;
    92 }
    93 
    94 static int uhci_driver_start(hcd_t *hcd, bool interrupts)
    95 {
    96         assert(hcd);
    97         hc_t *hc = hcd_get_driver_data(hcd);
    98 
    99         hc->hw_interrupts = interrupts;
    100         hc_start(hc);
    101         return EOK;
     78        const int ret = hc_init(instance, res, irq);
     79        if (ret == EOK) {
     80                hcd_set_implementation(hcd, instance, &uhci_hc_driver.ops);
     81        } else {
     82                free(instance);
     83        }
     84        return ret;
    10285}
    10386
     
    10992                hc_fini(hc);
    11093
    111         hcd_set_implementation(hcd, NULL, NULL, NULL);
     94        hcd_set_implementation(hcd, NULL, NULL);
    11295        free(hc);
    11396}
     
    118101 * @return Error code.
    119102 */
    120 static int disable_legacy(hcd_t *hcd, ddf_dev_t *device)
     103static int disable_legacy(ddf_dev_t *device)
    121104{
    122105        assert(device);
  • uspace/drv/bus/usb/uhci/uhci_batch.c

    r95c675b ra416d070  
    228228            uhci_batch->usb_batch->ep->speed == USB_SPEED_LOW;
    229229        const size_t mps = uhci_batch->usb_batch->ep->max_packet_size;
    230         const usb_target_t target = uhci_batch->usb_batch->ep->target;
     230        const usb_target_t target = {{
     231            uhci_batch->usb_batch->ep->address,
     232            uhci_batch->usb_batch->ep->endpoint }};
    231233
    232234        int toggle = endpoint_toggle_get(uhci_batch->usb_batch->ep);
     
    291293            uhci_batch->usb_batch->ep->speed == USB_SPEED_LOW;
    292294        const size_t mps = uhci_batch->usb_batch->ep->max_packet_size;
    293         const usb_target_t target = uhci_batch->usb_batch->ep->target;
     295        const usb_target_t target = {{
     296            uhci_batch->usb_batch->ep->address,
     297            uhci_batch->usb_batch->ep->endpoint }};
    294298
    295299        /* setup stage */
  • uspace/drv/bus/usb/uhci/uhci_rh.c

    r95c675b ra416d070  
    103103        assert(batch);
    104104
    105         const usb_target_t target = batch->ep->target;
     105        const usb_target_t target = {{
     106                .address = batch->ep->address,
     107                .endpoint = batch->ep->endpoint
     108        }};
    106109        do {
    107110                batch->error = virthub_base_request(&instance->base, target,
  • uspace/drv/bus/usb/usbhid/main.c

    r95c675b ra416d070  
    9595           usb_hid_polling_callback,
    9696           /* How much data to request. */
    97            hid_dev->poll_pipe_mapping->pipe.desc.max_packet_size,
     97           hid_dev->poll_pipe_mapping->pipe.max_packet_size,
    9898           /* Delay */
    9999           -1,
  • uspace/drv/bus/usb/usbhub/status.h

    r95c675b ra416d070  
    110110        if ((status & USB_HUB_PORT_STATUS_HIGH_SPEED) != 0)
    111111                return USB_SPEED_HIGH;
    112         /* TODO: add super speed */
    113112        return USB_SPEED_FULL;
    114113}
  • uspace/drv/bus/usb/usbmast/main.c

    r95c675b ra416d070  
    172172            usb_device_get_name(dev));
    173173        usb_log_debug("Bulk in endpoint: %d [%zuB].\n",
    174             epm_in->pipe.desc.endpoint_no, epm_in->pipe.desc.max_packet_size);
     174            epm_in->pipe.endpoint_no, epm_in->pipe.max_packet_size);
    175175        usb_log_debug("Bulk out endpoint: %d [%zuB].\n",
    176             epm_out->pipe.desc.endpoint_no, epm_out->pipe.desc.max_packet_size);
     176            epm_out->pipe.endpoint_no, epm_out->pipe.max_packet_size);
    177177
    178178        usb_log_debug("Get LUN count...\n");
  • uspace/drv/bus/usb/vhc/main.c

    r95c675b ra416d070  
    8989
    9090        /* Initialize generic structures */
    91         ret = hcd_ddf_setup_hc(dev);
     91        ret = hcd_ddf_setup_hc(dev, USB_SPEED_FULL,
     92            BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
    9293        if (ret != EOK) {
    9394                usb_log_error("Failed to init HCD structures: %s.\n",
     
    9798        }
    9899
    99         hcd_set_implementation(dev_to_hcd(dev), data, &vhc_hc_ops, &data->bus.base);
     100        hcd_set_implementation(dev_to_hcd(dev), data, &vhc_hc_ops);
    100101
    101102        /* Add virtual hub device */
     
    111112         * needs to be ready at this time.
    112113         */
    113         ret = hcd_setup_virtual_root_hub(dev_to_hcd(dev), dev);
     114        ret = hcd_ddf_setup_root_hub(dev);
    114115        if (ret != EOK) {
    115116                usb_log_error("Failed to init VHC root hub: %s\n",
  • uspace/drv/bus/usb/vhc/transfer.c

    r95c675b ra416d070  
    3131#include <usb/debug.h>
    3232#include <usbvirt/device.h>
    33 #include <usb/host/bandwidth.h>
    3433#include <usbvirt/ipc.h>
    3534#include "vhcd.h"
     
    3837static bool is_set_address_transfer(vhc_transfer_t *transfer)
    3938{
    40         if (transfer->batch->ep->target.endpoint != 0) {
     39        if (transfer->batch->ep->endpoint != 0) {
    4140                return false;
    4241        }
     
    8180                if (dir == USB_DIRECTION_IN) {
    8281                        rc = usbvirt_data_in(dev, batch->ep->transfer_type,
    83                             batch->ep->target.endpoint,
     82                            batch->ep->endpoint,
    8483                            batch->buffer, batch->buffer_size,
    8584                            actual_data_size);
     
    8786                        assert(dir == USB_DIRECTION_OUT);
    8887                        rc = usbvirt_data_out(dev, batch->ep->transfer_type,
    89                             batch->ep->target.endpoint,
     88                            batch->ep->endpoint,
    9089                            batch->buffer, batch->buffer_size);
    9190                }
     
    116115        } else {
    117116                if (dir == USB_DIRECTION_IN) {
    118                         rc = usbvirt_ipc_send_data_in(sess, batch->ep->target.endpoint,
     117                        rc = usbvirt_ipc_send_data_in(sess, batch->ep->endpoint,
    119118                            batch->ep->transfer_type,
    120119                            batch->buffer, batch->buffer_size,
     
    122121                } else {
    123122                        assert(dir == USB_DIRECTION_OUT);
    124                         rc = usbvirt_ipc_send_data_out(sess, batch->ep->target.endpoint,
     123                        rc = usbvirt_ipc_send_data_out(sess, batch->ep->endpoint,
    125124                            batch->ep->transfer_type,
    126125                            batch->buffer, batch->buffer_size);
     
    160159        list_initialize(&instance->devices);
    161160        fibril_mutex_initialize(&instance->guard);
    162         usb2_bus_init(&instance->bus, BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
    163161        instance->magic = 0xDEADBEEF;
    164162        return virthub_init(&instance->hub, "root hub");
     
    184182        list_foreach(vhc->devices, link, vhc_virtdev_t, dev) {
    185183                fibril_mutex_lock(&dev->guard);
    186                 if (dev->address == transfer->batch->ep->target.address) {
     184                if (dev->address == transfer->batch->ep->address) {
    187185                        if (!targets) {
    188186                                list_append(&transfer->link, &dev->transfer_queue);
  • uspace/drv/bus/usb/vhc/vhcd.h

    r95c675b ra416d070  
    4242
    4343#include <usb/host/hcd.h>
    44 #include <usb/host/usb2_bus.h>
    4544
    4645#define NAME "vhc"
     
    6160        fibril_mutex_t guard;
    6261        usbvirt_device_t hub;
    63         usb2_bus_t bus;
    6462} vhc_data_t;
    6563
  • uspace/lib/c/include/bitops.h

    r95c675b ra416d070  
    5454#define BIT_RANGE_EXTRACT(type, hi, lo, value) \
    5555    (((value) >> (lo)) & BIT_RRANGE(type, (hi) - (lo) + 1))
    56 
    57 /** Insert @a value between bits @a hi .. @a lo. */
    58 #define BIT_RANGE_INSERT(type, hi, lo, value) \
    59     (((value) & BIT_RRANGE(type, (hi) - (lo) + 1)) << (lo))
    6056
    6157/** Return position of first non-zero bit from left (i.e. [log_2(arg)]).
  • uspace/lib/c/include/byteorder.h

    r95c675b ra416d070  
    8585#define ntohl(n)  uint32_t_be2host((n))
    8686
    87 #define uint8_t_be2host(n)  (n)
    88 #define uint8_t_le2host(n)  (n)
    89 #define host2uint8_t_be(n)  (n)
    90 #define host2uint8_t_le(n)  (n)
    91 
    9287static inline uint64_t uint64_t_byteorder_swap(uint64_t n)
    9388{
  • uspace/lib/drv/generic/remote_usb.c

    r95c675b ra416d070  
    175175} pack8_t;
    176176
    177 int usb_register_endpoint(async_exch_t *exch,
    178         usb_endpoint_desc_t *endpoint_desc)
    179 {
    180         if (!exch)
    181                 return EBADMEM;
    182 
    183         aid_t opening_request = async_send_1(exch,
    184             DEV_IFACE_ID(USB_DEV_IFACE), IPC_M_USB_REGISTER_ENDPOINT, NULL);
    185 
    186         if (opening_request == 0) {
    187                 return ENOMEM;
    188         }
    189 
    190         const int ret = async_data_write_start(exch, (void *) endpoint_desc,
    191                 sizeof(usb_endpoint_desc_t));
    192 
    193         if (ret != EOK) {
    194                 async_forget(opening_request);
    195                 return ret;
    196         }
    197 
    198         /* Wait for the answer. */
    199         sysarg_t opening_request_rc;
    200         async_wait_for(opening_request, &opening_request_rc);
    201 
    202         return (int) opening_request_rc;
    203 }
    204 
    205 int usb_unregister_endpoint(async_exch_t *exch,
    206         usb_endpoint_desc_t *endpoint_desc)
    207 {
    208         if (!exch)
    209                 return EBADMEM;
    210 
    211         aid_t opening_request = async_send_1(exch,
    212                 DEV_IFACE_ID(USB_DEV_IFACE), IPC_M_USB_UNREGISTER_ENDPOINT, NULL);
    213 
    214         if (opening_request == 0) {
    215                 return ENOMEM;
    216         }
    217 
    218         const int ret = async_data_write_start(exch, endpoint_desc,
    219                 sizeof(usb_endpoint_desc_t));
    220         if (ret != EOK) {
    221                 async_forget(opening_request);
    222                 return ret;
    223         }
    224 
    225         /* Wait for the answer. */
    226         sysarg_t opening_request_rc;
    227         async_wait_for(opening_request, &opening_request_rc);
    228 
    229         return (int) opening_request_rc;
     177int usb_register_endpoint(async_exch_t *exch, usb_endpoint_t endpoint,
     178    usb_transfer_type_t type, usb_direction_t direction,
     179    size_t mps, unsigned packets, unsigned interval)
     180{
     181        if (!exch)
     182                return EBADMEM;
     183        pack8_t pack;
     184        pack.arr[0] = type;
     185        pack.arr[1] = direction;
     186        pack.arr[2] = interval;
     187        pack.arr[3] = packets;
     188
     189        return async_req_4_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
     190            IPC_M_USB_REGISTER_ENDPOINT, endpoint, pack.arg, mps);
     191
     192}
     193
     194int usb_unregister_endpoint(async_exch_t *exch, usb_endpoint_t endpoint,
     195    usb_direction_t direction)
     196{
     197        if (!exch)
     198                return EBADMEM;
     199        return async_req_3_0(exch, DEV_IFACE_ID(USB_DEV_IFACE),
     200            IPC_M_USB_UNREGISTER_ENDPOINT, endpoint, direction);
    230201}
    231202
     
    346317};
    347318
    348 typedef struct {
    349         ipc_callid_t caller;
    350         ipc_callid_t data_caller;
    351         void *buffer;
    352 } async_transaction_t;
    353 
    354319void remote_usb_get_my_interface(ddf_fun_t *fun, void *iface,
    355320    ipc_callid_t callid, ipc_call_t *call)
     
    452417    ipc_callid_t callid, ipc_call_t *call)
    453418{
    454         assert(fun);
    455         assert(iface);
    456         assert(call);
    457 
    458         const usb_iface_t *usb_iface = iface;
     419        usb_iface_t *usb_iface = (usb_iface_t *) iface;
    459420
    460421        if (!usb_iface->register_endpoint) {
     
    463424        }
    464425
    465         void *buffer = NULL;
    466         size_t size = 0;
    467         int rc = async_data_write_accept(&buffer, false,
    468                 sizeof(usb_endpoint_desc_t), sizeof(usb_endpoint_desc_t), 0, &size);
    469 
    470         if (rc != EOK) {
    471                 free(buffer);
    472                 async_answer_0(callid, rc);
    473                 return;
    474         }
    475 
    476         usb_endpoint_desc_t *endpoint_desc = (usb_endpoint_desc_t *) buffer;
    477         rc = usb_iface->register_endpoint(fun, endpoint_desc);
    478 
    479         free(buffer);
     426        const usb_endpoint_t endpoint = DEV_IPC_GET_ARG1(*call);
     427        const pack8_t pack = { .arg = DEV_IPC_GET_ARG2(*call)};
     428        const size_t max_packet_size = DEV_IPC_GET_ARG3(*call);
     429
     430        const usb_transfer_type_t transfer_type = pack.arr[0];
     431        const usb_direction_t direction = pack.arr[1];
     432        unsigned packets = pack.arr[2];
     433        unsigned interval = pack.arr[3];
     434
     435        const int ret = usb_iface->register_endpoint(fun, endpoint,
     436            transfer_type, direction, max_packet_size, packets, interval);
     437
     438        async_answer_0(callid, ret);
     439}
     440
     441static void remote_usb_unregister_endpoint(ddf_fun_t *fun, void *iface,
     442    ipc_callid_t callid, ipc_call_t *call)
     443{
     444        usb_iface_t *usb_iface = (usb_iface_t *) iface;
     445
     446        if (!usb_iface->unregister_endpoint) {
     447                async_answer_0(callid, ENOTSUP);
     448                return;
     449        }
     450
     451        usb_endpoint_t endpoint = (usb_endpoint_t) DEV_IPC_GET_ARG1(*call);
     452        usb_direction_t direction = (usb_direction_t) DEV_IPC_GET_ARG2(*call);
     453
     454        int rc = usb_iface->unregister_endpoint(fun, endpoint, direction);
     455
    480456        async_answer_0(callid, rc);
    481457}
    482458
    483 static void remote_usb_unregister_endpoint(ddf_fun_t *fun, void *iface,
    484     ipc_callid_t callid, ipc_call_t *call)
    485 {
    486         assert(fun);
    487         assert(iface);
    488         assert(call);
    489 
    490         const usb_iface_t *usb_iface = iface;
    491 
    492         if (!usb_iface->unregister_endpoint) {
    493                 async_answer_0(callid, ENOTSUP);
    494                 return;
    495         }
    496 
    497         void *buffer = NULL;
    498         size_t size = 0;
    499         int rc = async_data_write_accept(&buffer, false,
    500                 sizeof(usb_endpoint_desc_t), sizeof(usb_endpoint_desc_t), 0, &size);
    501 
    502         if (rc != EOK) {
    503                 free(buffer);
    504                 async_answer_0(callid, rc);
    505                 return;
    506         }
    507 
    508         usb_endpoint_desc_t *endpoint_desc = (usb_endpoint_desc_t *) buffer;
    509         usb_iface->unregister_endpoint(fun, endpoint_desc);
    510 
    511         free(buffer);
    512         if (rc != EOK) {
    513                 async_answer_0(callid, rc);
    514         }
    515 }
     459typedef struct {
     460        ipc_callid_t caller;
     461        ipc_callid_t data_caller;
     462        void *buffer;
     463} async_transaction_t;
    516464
    517465static void async_transaction_destroy(async_transaction_t *trans)
  • uspace/lib/drv/include/usb_iface.h

    r95c675b ra416d070  
    5757extern int usb_device_remove(async_exch_t *, unsigned port);
    5858
    59 extern int usb_register_endpoint(async_exch_t *, usb_endpoint_desc_t *);
    60 extern int usb_unregister_endpoint(async_exch_t *, usb_endpoint_desc_t *);
     59extern int usb_register_endpoint(async_exch_t *, usb_endpoint_t,
     60    usb_transfer_type_t, usb_direction_t, size_t, unsigned, unsigned);
     61extern int usb_unregister_endpoint(async_exch_t *, usb_endpoint_t,
     62    usb_direction_t);
    6163extern int usb_read(async_exch_t *, usb_endpoint_t, uint64_t, void *, size_t,
    6264    size_t *);
     
    8183        int (*device_remove)(ddf_fun_t *, unsigned);
    8284
    83         int (*register_endpoint)(ddf_fun_t *, usb_endpoint_desc_t *);
    84         int (*unregister_endpoint)(ddf_fun_t *, usb_endpoint_desc_t *);
     85        int (*register_endpoint)(ddf_fun_t *, usb_endpoint_t,
     86            usb_transfer_type_t, usb_direction_t, size_t, unsigned, unsigned);
     87        int (*unregister_endpoint)(ddf_fun_t *, usb_endpoint_t,
     88            usb_direction_t);
    8589
    8690        int (*read)(ddf_fun_t *, usb_endpoint_t, uint64_t, uint8_t *, size_t,
  • uspace/lib/pcm/src/format.c

    r95c675b ra416d070  
    4141
    4242#include "format.h"
     43
     44#define uint8_t_le2host(x) (x)
     45#define host2uint8_t_le(x) (x)
     46#define uint8_t_be2host(x) (x)
     47#define host2uint8_t_be(x) (x)
    4348
    4449#define int8_t_le2host(x) (x)
  • uspace/lib/usb/include/usb/descriptor.h

    r95c675b ra416d070  
    4949        USB_DESCTYPE_OTHER_SPEED_CONFIGURATION = 7,
    5050        USB_DESCTYPE_INTERFACE_POWER = 8,
    51         /* USB 3.0 types */
    52         USB_DESCTYPE_OTG = 9,
    53         USB_DESCTYPE_DEBUG = 0xa,
    54         USB_DESCTYPE_IFACE_ASSOC = 0xb,
    55         USB_DESCTYPE_BOS = 0xf,
    56         USB_DESCTYPE_DEVICE_CAP = 0x10,
    5751        /* Class specific */
    5852        USB_DESCTYPE_HID = 0x21,
     
    6054        USB_DESCTYPE_HID_PHYSICAL = 0x23,
    6155        USB_DESCTYPE_HUB = 0x29,
    62         USB_DESCTYPE_SSPEED_EP_COMPANION = 0x30
    6356        /* USB_DESCTYPE_ = */
    6457} usb_descriptor_type_t;
     
    224217} __attribute__ ((packed)) usb_standard_endpoint_descriptor_t;
    225218
    226 /** Superspeed USB endpoint companion descriptor.
    227  * See USB 3 specification, section 9.6.7.
    228  */
    229 typedef struct {
    230         /** Size of this descriptor in bytes */
    231         uint8_t length;
    232         /** Descriptor type (USB_DESCTYPE_SSPEED_EP_COMPANION). */
    233         uint8_t descriptor_type;
    234         /** The maximum number of packets the endpoint can send
    235          * or receive as part of a burst. Valid values are from 0 to 15.
    236          * The endpoint can only burst max_burst + 1 packets at a time.
    237          */
    238         uint8_t max_burst;
    239         /** Valid only for bulk and isochronous endpoints.
    240          * For bulk endpoints, this field contains the amount of streams
    241          * supported by the endpoint.
    242          * For isochronous endpoints, this field contains either maximum
    243          * number of packets supported within a service interval, or
    244          * whether an isochronous endpoint companion descriptor follows.
    245          */
    246         uint8_t attributes;
    247         /** The total number of bytes this endpoint will transfer
    248          * every service interval (SI).
    249          * This field is only valid for periodic endpoints.
    250          */
    251         uint16_t bytes_per_interval;
    252 } __attribute__ ((packed)) usb_superspeed_endpoint_companion_descriptor_t;
    253 
    254219/** Part of standard USB HID descriptor specifying one class descriptor.
    255220 *
  • uspace/lib/usb/include/usb/request.h

    r95c675b ra416d070  
    112112    const usb_device_request_setup_packet_t *request);
    113113
    114 #define GET_DEVICE_DESC(size) \
    115 { \
    116         .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST \
    117             | (USB_REQUEST_TYPE_STANDARD << 5) \
    118             | USB_REQUEST_RECIPIENT_DEVICE, \
    119         .request = USB_DEVREQ_GET_DESCRIPTOR, \
    120         .value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8), \
    121         .index = uint16_host2usb(0), \
    122         .length = uint16_host2usb(size), \
    123 };
    124 
    125 #define SET_ADDRESS(address) \
    126 { \
    127         .request_type = SETUP_REQUEST_TYPE_HOST_TO_DEVICE \
    128             | (USB_REQUEST_TYPE_STANDARD << 5) \
    129             | USB_REQUEST_RECIPIENT_DEVICE, \
    130         .request = USB_DEVREQ_SET_ADDRESS, \
    131         .value = uint16_host2usb(address), \
    132         .index = uint16_host2usb(0), \
    133         .length = uint16_host2usb(0), \
    134 };
    135 
    136 #define CTRL_PIPE_MIN_PACKET_SIZE 8
    137 
    138114#endif
    139115/**
  • uspace/lib/usb/include/usb/usb.h

    r95c675b ra416d070  
    8181        /** USB 2.0 high speed (480Mbits/s). */
    8282        USB_SPEED_HIGH,
    83         /** USB 3.0 super speed (5Gbits/s). */
    84         USB_SPEED_SUPER,
    8583        /** Psuedo-speed serving as a boundary. */
    8684        USB_SPEED_MAX
     
    115113typedef int16_t usb_address_t;
    116114
    117 typedef struct {
    118         usb_address_t address;
    119         unsigned port;
    120 } usb_tt_address_t;
    121 
    122115/** Default USB address. */
    123116#define USB_ADDRESS_DEFAULT 0
     
    164157
    165158
    166 /** USB complete address type.
     159/** USB complete address type. 
    167160 * Pair address + endpoint is identification of transaction recipient.
    168161 */
     
    174167        uint32_t packed;
    175168} usb_target_t;
    176 
    177 /** Description of usb endpoint.
    178  */
    179 typedef struct {
    180         /** Endpoint number. */
    181         usb_endpoint_t endpoint_no;
    182 
    183         /** Endpoint transfer type. */
    184         usb_transfer_type_t transfer_type;
    185 
    186         /** Endpoint direction. */
    187         usb_direction_t direction;
    188 
    189         /** Maximum packet size for the endpoint. */
    190         size_t max_packet_size;
    191 
    192         /** Number of packets per frame/uframe.
    193          * Only valid for HS INT and ISO transfers. All others should set to 1*/
    194         unsigned packets;
    195 
    196         struct {
    197                 unsigned polling_interval;
    198         } usb2;
    199 } usb_endpoint_desc_t;
    200169
    201170/** Check USB target for allowed values (address and endpoint).
  • uspace/lib/usb/src/usb.c

    r95c675b ra416d070  
    4444        [USB_SPEED_FULL] = "full",
    4545        [USB_SPEED_HIGH] = "high",
    46         [USB_SPEED_SUPER] = "super",
    4746};
    4847
  • uspace/lib/usbdev/include/usb/dev/pipes.h

    r95c675b ra416d070  
    5050 */
    5151typedef struct {
    52         /** Endpoint description */
    53         usb_endpoint_desc_t desc;
     52        /** Endpoint number. */
     53        usb_endpoint_t endpoint_no;
     54
     55        /** Endpoint transfer type. */
     56        usb_transfer_type_t transfer_type;
     57
     58        /** Endpoint direction. */
     59        usb_direction_t direction;
     60
     61        /** Maximum packet size for the endpoint. */
     62        size_t max_packet_size;
     63
     64        /** Number of packets per frame/uframe.
     65         * Only valid for HS INT and ISO transfers. All others should set to 1*/
     66        unsigned packets;
     67
    5468        /** Whether to automatically reset halt on the endpoint.
    5569         * Valid only for control endpoint zero.
    5670         */
    5771        bool auto_reset_halt;
     72
    5873        /** The connection used for sending the data. */
    5974        usb_dev_session_t *bus_session;
  • uspace/lib/usbdev/src/devdrv.c

    r95c675b ra416d070  
    5656        /** Connection to device on USB bus */
    5757        usb_dev_session_t *bus_session;
    58 
     58       
    5959        /** devman handle */
    6060        devman_handle_t handle;
    61 
     61       
    6262        /** The default control pipe. */
    6363        usb_pipe_t ctrl_pipe;
    64 
     64       
    6565        /** Other endpoint pipes.
    6666         *
     
    6969         */
    7070        usb_endpoint_mapping_t *pipes;
    71 
     71       
    7272        /** Number of other endpoint pipes. */
    7373        size_t pipes_count;
    74 
     74       
    7575        /** Current interface.
    7676         *
     
    7979         */
    8080        int interface_no;
    81 
     81       
    8282        /** Alternative interfaces. */
    8383        usb_alternate_interfaces_t alternate_interfaces;
    84 
     84       
    8585        /** Some useful descriptors for USB device. */
    8686        usb_device_descriptors_t descriptors;
    87 
     87       
    8888        /** Generic DDF device backing this one. DO NOT TOUCH! */
    8989        ddf_dev_t *ddf_dev;
    90 
     90       
    9191        /** Custom driver data.
    9292         *
     
    146146                return rc;
    147147        }
    148 
     148       
    149149        /* Change current alternative */
    150150        usb_dev->alternate_interfaces.current = alternate_setting;
     
    296296        assert(usb_dev);
    297297        assert(usb_dev->pipes || usb_dev->pipes_count == 0);
    298 
     298       
    299299        /* Destroy the pipes. */
    300300        for (size_t i = 0; i < usb_dev->pipes_count; ++i) {
     
    304304                        usb_pipe_unregister(&usb_dev->pipes[i].pipe);
    305305        }
    306 
     306       
    307307        free(usb_dev->pipes);
    308308        usb_dev->pipes = NULL;
     
    332332        assert(usb_dev);
    333333        for (unsigned i = 0; i < usb_dev->pipes_count; ++i) {
    334                 if (usb_dev->pipes[i].pipe.desc.endpoint_no == ep)
     334                if (usb_dev->pipes[i].pipe.endpoint_no == ep)
    335335                        return &usb_dev->pipes[i];
    336336        }
     
    462462        assert(handle);
    463463        assert(iface_no);
    464 
     464       
    465465        async_exch_t *exch = async_exchange_begin(sess);
    466466        if (!exch)
    467467                return EPARTY;
    468 
     468       
    469469        int ret = usb_get_my_device_handle(exch, handle);
    470470        if (ret == EOK) {
     
    475475                }
    476476        }
    477 
     477       
    478478        async_exchange_end(exch);
    479479        return ret;
     
    502502                return ENOMEM;
    503503        }
    504 
     504       
    505505        return usb_device_init(usb_dev, ddf_dev, desc, err, h, iface_no);
    506506}
  • uspace/lib/usbdev/src/devpoll.c

    r95c675b ra416d070  
    9696                    (int) mapping->interface->interface_subclass,
    9797                    (int) mapping->interface->interface_protocol,
    98                     data->request_size, pipe->desc.max_packet_size);
     98                    data->request_size, pipe->max_packet_size);
    9999        }
    100100
     
    128128                        usb_request_clear_endpoint_halt(
    129129                            usb_device_get_default_pipe(data->dev),
    130                             pipe->desc.endpoint_no);
     130                            pipe->endpoint_no);
    131131                }
    132132
     
    156156
    157157                /* Take a rest before next request. */
    158 
     158               
    159159                // FIXME TODO: This is broken, the time is in ms not us.
    160160                // but first we need to fix drivers to actually stop using this,
     
    216216        if (request_size == 0)
    217217                return EINVAL;
    218 
    219         if (!epm || (epm->pipe.desc.transfer_type != USB_TRANSFER_INTERRUPT) ||
    220             (epm->pipe.desc.direction != USB_DIRECTION_IN))
     218       
     219        if (!epm || (epm->pipe.transfer_type != USB_TRANSFER_INTERRUPT) ||
     220            (epm->pipe.direction != USB_DIRECTION_IN))
    221221                return EINVAL;
    222 
     222       
    223223
    224224        polling_data_t *polling_data = malloc(sizeof(polling_data_t));
  • uspace/lib/usbdev/src/pipes.c

    r95c675b ra416d070  
    5151        assert(pipe != NULL);
    5252
    53         if (!pipe->auto_reset_halt || (pipe->desc.endpoint_no != 0)) {
     53        if (!pipe->auto_reset_halt || (pipe->endpoint_no != 0)) {
    5454                return;
    5555        }
     
    8888        }
    8989
    90         if ((pipe->desc.direction != USB_DIRECTION_BOTH)
    91             || (pipe->desc.transfer_type != USB_TRANSFER_CONTROL)) {
     90        if ((pipe->direction != USB_DIRECTION_BOTH)
     91            || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
    9292                return EBADF;
    9393        }
     
    9898        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
    9999        size_t act_size = 0;
    100         const int rc = usb_read(exch, pipe->desc.endpoint_no, setup_packet, buffer,
     100        const int rc = usb_read(exch, pipe->endpoint_no, setup_packet, buffer,
    101101            buffer_size, &act_size);
    102102        async_exchange_end(exch);
     
    142142        }
    143143
    144         if ((pipe->desc.direction != USB_DIRECTION_BOTH)
    145             || (pipe->desc.transfer_type != USB_TRANSFER_CONTROL)) {
     144        if ((pipe->direction != USB_DIRECTION_BOTH)
     145            || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
    146146                return EBADF;
    147147        }
     
    152152        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
    153153        const int rc = usb_write(exch,
    154             pipe->desc.endpoint_no, setup_packet, buffer, buffer_size);
     154            pipe->endpoint_no, setup_packet, buffer, buffer_size);
    155155        async_exchange_end(exch);
    156156
     
    183183        }
    184184
    185         if (pipe->desc.direction != USB_DIRECTION_IN) {
    186                 return EBADF;
    187         }
    188 
    189         if (pipe->desc.transfer_type == USB_TRANSFER_CONTROL) {
     185        if (pipe->direction != USB_DIRECTION_IN) {
     186                return EBADF;
     187        }
     188
     189        if (pipe->transfer_type == USB_TRANSFER_CONTROL) {
    190190                return EBADF;
    191191        }
    192192
    193193        /* Isochronous transfer are not supported (yet) */
    194         if (pipe->desc.transfer_type != USB_TRANSFER_INTERRUPT &&
    195             pipe->desc.transfer_type != USB_TRANSFER_BULK)
     194        if (pipe->transfer_type != USB_TRANSFER_INTERRUPT &&
     195            pipe->transfer_type != USB_TRANSFER_BULK)
    196196            return ENOTSUP;
    197197
     
    199199        size_t act_size = 0;
    200200        const int rc =
    201             usb_read(exch, pipe->desc.endpoint_no, 0, buffer, size, &act_size);
     201            usb_read(exch, pipe->endpoint_no, 0, buffer, size, &act_size);
    202202        async_exchange_end(exch);
    203203
     
    224224        }
    225225
    226         if (pipe->desc.direction != USB_DIRECTION_OUT) {
    227                 return EBADF;
    228         }
    229 
    230         if (pipe->desc.transfer_type == USB_TRANSFER_CONTROL) {
     226        if (pipe->direction != USB_DIRECTION_OUT) {
     227                return EBADF;
     228        }
     229
     230        if (pipe->transfer_type == USB_TRANSFER_CONTROL) {
    231231                return EBADF;
    232232        }
    233233
    234234        /* Isochronous transfer are not supported (yet) */
    235         if (pipe->desc.transfer_type != USB_TRANSFER_INTERRUPT &&
    236             pipe->desc.transfer_type != USB_TRANSFER_BULK)
     235        if (pipe->transfer_type != USB_TRANSFER_INTERRUPT &&
     236            pipe->transfer_type != USB_TRANSFER_BULK)
    237237            return ENOTSUP;
    238238
    239239        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
    240         const int rc = usb_write(exch, pipe->desc.endpoint_no, 0, buffer, size);
     240        const int rc = usb_write(exch, pipe->endpoint_no, 0, buffer, size);
    241241        async_exchange_end(exch);
    242242        return rc;
     
    258258        assert(pipe);
    259259
    260         pipe->desc.endpoint_no = endpoint_no;
    261         pipe->desc.transfer_type = transfer_type;
    262         pipe->desc.packets = packets;
    263         pipe->desc.max_packet_size = max_packet_size;
    264         pipe->desc.direction = direction;
     260        pipe->endpoint_no = endpoint_no;
     261        pipe->transfer_type = transfer_type;
     262        pipe->packets = packets;
     263        pipe->max_packet_size = max_packet_size;
     264        pipe->direction = direction;
    265265        pipe->auto_reset_halt = false;
    266266        pipe->bus_session = bus_session;
     
    297297        assert(pipe);
    298298        assert(pipe->bus_session);
    299 
    300         pipe->desc.usb2.polling_interval = interval;
    301299        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
    302300        if (!exch)
    303301                return ENOMEM;
    304 
    305         const int ret = usb_register_endpoint(exch, &pipe->desc);
    306 
     302        const int ret = usb_register_endpoint(exch, pipe->endpoint_no,
     303            pipe->transfer_type, pipe->direction, pipe->max_packet_size,
     304            pipe->packets, interval);
    307305        async_exchange_end(exch);
    308306        return ret;
     
    321319        if (!exch)
    322320                return ENOMEM;
    323 
    324         const int ret = usb_unregister_endpoint(exch, &pipe->desc);
    325 
     321        const int ret = usb_unregister_endpoint(exch, pipe->endpoint_no,
     322            pipe->direction);
    326323        async_exchange_end(exch);
    327324        return ret;
  • uspace/lib/usbdev/src/pipesinit.c

    r95c675b ra416d070  
    288288        if (config_descriptor == NULL)
    289289                return EBADMEM;
    290 
     290       
    291291        if (config_descriptor_size <
    292292            sizeof(usb_standard_configuration_descriptor_t)) {
     
    343343        static_assert(DEV_DESCR_MAX_PACKET_SIZE_OFFSET < CTRL_PIPE_MIN_PACKET_SIZE);
    344344
    345         if ((pipe->desc.direction != USB_DIRECTION_BOTH) ||
    346             (pipe->desc.transfer_type != USB_TRANSFER_CONTROL) ||
    347             (pipe->desc.endpoint_no != 0)) {
     345        if ((pipe->direction != USB_DIRECTION_BOTH) ||
     346            (pipe->transfer_type != USB_TRANSFER_CONTROL) ||
     347            (pipe->endpoint_no != 0)) {
    348348                return EINVAL;
    349349        }
     
    369369        }
    370370
    371         pipe->desc.max_packet_size
     371        pipe->max_packet_size
    372372            = dev_descr_start[DEV_DESCR_MAX_PACKET_SIZE_OFFSET];
    373373
  • uspace/lib/usbdev/src/request.c

    r95c675b ra416d070  
    844844        }
    845845        return usb_request_clear_endpoint_halt(ctrl_pipe,
    846             target_pipe->desc.endpoint_no);
     846            target_pipe->endpoint_no);
    847847}
    848848
     
    858858{
    859859        uint16_t status_tmp;
    860         uint16_t pipe_index = (uint16_t) pipe->desc.endpoint_no;
     860        uint16_t pipe_index = (uint16_t) pipe->endpoint_no;
    861861        int rc = usb_request_get_status(ctrl_pipe,
    862862            USB_REQUEST_RECIPIENT_ENDPOINT, uint16_host2usb(pipe_index),
  • uspace/lib/usbhost/Makefile

    r95c675b ra416d070  
    3939        src/endpoint.c \
    4040        src/hcd.c \
    41         src/bus.c \
    42         src/usb2_bus.c \
    43         src/bandwidth.c \
     41        src/usb_bus.c \
    4442        src/usb_transfer_batch.c
    4543
  • uspace/lib/usbhost/include/usb/host/ddf_helpers.h

    r95c675b ra416d070  
    3838
    3939#include <usb/host/hcd.h>
    40 #include <usb/host/bus.h>
     40#include <usb/host/usb_bus.h>
    4141#include <usb/usb.h>
    4242
     
    4545#include <device/hw_res_parsed.h>
    4646
    47 typedef int (*driver_init_t)(hcd_t *, const hw_res_list_parsed_t *);
    48 typedef int (*irq_code_gen_t)(irq_code_t *, hcd_t *, const hw_res_list_parsed_t *);
    49 typedef int (*claim_t)(hcd_t *, ddf_dev_t *);
    50 typedef int (*driver_start_t)(hcd_t *, bool irq);
    51 typedef int (*setup_root_hub_t)(hcd_t *, ddf_dev_t *);
     47typedef int (*driver_init_t)(hcd_t *, const hw_res_list_parsed_t *, bool);
     48typedef void (*driver_fini_t)(hcd_t *);
     49typedef int (*claim_t)(ddf_dev_t *);
     50typedef int (*irq_code_gen_t)(irq_code_t *, const hw_res_list_parsed_t *);
    5251
    53 typedef void (*driver_stop_t)(hcd_t *);
    54 typedef void (*driver_fini_t)(hcd_t *);
    55 
    56 /**
    57  * All callbacks are optional.
    58  */
    5952typedef struct {
    6053        hcd_ops_t ops;
     54        claim_t claim;
     55        usb_speed_t hc_speed;
     56        driver_init_t init;
     57        driver_fini_t fini;
     58        interrupt_handler_t *irq_handler;
     59        irq_code_gen_t irq_code_gen;
    6160        const char *name;
    62 
    63         interrupt_handler_t *irq_handler;  /**< Handler of IRQ. Do have generic implementation. */
    64 
    65         /* Initialization sequence: */
    66         driver_init_t init;                /**< Initialize internal structures, memory */
    67         claim_t claim;                     /**< Claim device from BIOS */
    68         irq_code_gen_t irq_code_gen;       /**< Generate IRQ handling code */
    69         driver_start_t start;              /**< Start the HC */
    70         setup_root_hub_t setup_root_hub;   /**< Setup the root hub */
    71 
    72         /* Destruction sequence: */
    73         driver_stop_t stop;                /**< Stop the HC (counterpart of start) */
    74         driver_fini_t fini;                /**< Destroy internal structures (counterpart of init) */
    7561} ddf_hc_driver_t;
    7662
    7763int hcd_ddf_add_hc(ddf_dev_t *device, const ddf_hc_driver_t *driver);
    7864
    79 int hcd_ddf_setup_hc(ddf_dev_t *device);
     65int hcd_ddf_setup_hc(ddf_dev_t *device, usb_speed_t max_speed,
     66    size_t bw, bw_count_func_t bw_count);
    8067void hcd_ddf_clean_hc(ddf_dev_t *device);
    81 
    82 int hcd_setup_virtual_root_hub(hcd_t *, ddf_dev_t *);
    83 
    84 device_t *hcd_ddf_device_create(ddf_dev_t *, size_t);
    85 void hcd_ddf_device_destroy(device_t *);
    86 int hcd_ddf_device_explore(hcd_t *, device_t *);
     68int hcd_ddf_setup_root_hub(ddf_dev_t *device);
    8769
    8870hcd_t *dev_to_hcd(ddf_dev_t *dev);
     
    9375    const hw_res_list_parsed_t *hw_res,
    9476    interrupt_handler_t handler,
    95     irq_code_gen_t gen_irq_code);
     77    int (*gen_irq_code)(irq_code_t *, const hw_res_list_parsed_t *));
    9678void ddf_hcd_gen_irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev);
    9779
  • uspace/lib/usbhost/include/usb/host/endpoint.h

    r95c675b ra416d070  
    3232/** @file
    3333 *
    34  * Endpoint structure is tightly coupled to the bus. The bus controls the
    35  * life-cycle of endpoint. In order to keep endpoints lightweight, operations
    36  * on endpoints are part of the bus structure.
    37  *
    3834 */
    3935#ifndef LIBUSBHOST_HOST_ENDPOINT_H
     
    4642#include <atomic.h>
    4743
    48 typedef struct bus bus_t;
    49 typedef struct device device_t;
    50 
    5144/** Host controller side endpoint structure. */
    5245typedef struct endpoint {
    53         /** Managing bus */
    54         bus_t *bus;
    5546        /** Reference count. */
    56         atomic_t refcnt;
     47        atomic_t refcnt;       
    5748        /** Part of linked list. */
    5849        link_t link;
    59         /** USB device */
    60         device_t *device;
    6150        /** USB address. */
    62         usb_target_t target;
     51        usb_address_t address;
     52        /** USB endpoint number. */
     53        usb_endpoint_t endpoint;
    6354        /** Communication direction. */
    6455        usb_direction_t direction;
     
    7162        /** Additional opportunities per uframe */
    7263        unsigned packets;
    73         /** Reserved bandwidth. */
     64        /** Necessary bandwidth. */
    7465        size_t bandwidth;
    7566        /** Value of the toggle bit. */
    7667        unsigned toggle:1;
    7768        /** True if there is a batch using this scheduled for this endpoint. */
    78         bool active;
     69        volatile bool active;
    7970        /** Protects resources and active status changes. */
    8071        fibril_mutex_t guard;
    8172        /** Signals change of active status. */
    8273        fibril_condvar_t avail;
    83 
    84         /* This structure is meant to be extended by overriding. */
     74        /** High speed TT data */
     75        struct {
     76                usb_address_t address;
     77                unsigned port;
     78        } tt;
     79        /** Optional device specific data. */
     80        struct {
     81                /** Device specific data. */
     82                void *data;
     83                /** Callback to get the value of toggle bit. */
     84                int (*toggle_get)(void *);
     85                /** Callback to set the value of toggle bit. */
     86                void (*toggle_set)(void *, int);
     87        } hc_data;
    8588} endpoint_t;
    8689
    87 extern void endpoint_init(endpoint_t *, bus_t *);
     90extern endpoint_t *endpoint_create(usb_address_t, usb_endpoint_t,
     91    usb_direction_t, usb_transfer_type_t, usb_speed_t, size_t, unsigned int,
     92    size_t, usb_address_t, unsigned int);
     93extern void endpoint_destroy(endpoint_t *);
    8894
    8995extern void endpoint_add_ref(endpoint_t *);
    9096extern void endpoint_del_ref(endpoint_t *);
     97
     98extern void endpoint_set_hc_data(endpoint_t *, void *, int (*)(void *),
     99    void (*)(void *, int));
     100extern void endpoint_clear_hc_data(endpoint_t *);
    91101
    92102extern void endpoint_use(endpoint_t *);
     
    94104
    95105extern int endpoint_toggle_get(endpoint_t *);
    96 extern void endpoint_toggle_set(endpoint_t *, unsigned);
     106extern void endpoint_toggle_set(endpoint_t *, int);
    97107
    98108/** list_get_instance wrapper.
  • uspace/lib/usbhost/include/usb/host/hcd.h

    r95c675b ra416d070  
    3838
    3939#include <usb/host/endpoint.h>
    40 #include <usb/host/bus.h>
     40#include <usb/host/usb_bus.h>
    4141#include <usb/host/usb_transfer_batch.h>
    4242#include <usb/usb.h>
     
    5050
    5151typedef int (*schedule_hook_t)(hcd_t *, usb_transfer_batch_t *);
     52typedef int (*ep_add_hook_t)(hcd_t *, endpoint_t *);
     53typedef void (*ep_remove_hook_t)(hcd_t *, endpoint_t *);
    5254typedef void (*interrupt_hook_t)(hcd_t *, uint32_t);
    5355typedef int (*status_hook_t)(hcd_t *, uint32_t *);
    54 typedef int (*address_device_hook_t)(hcd_t *, usb_speed_t, usb_tt_address_t, usb_address_t *);
    5556
    5657typedef struct {
    5758        /** Transfer scheduling, implement in device driver. */
    5859        schedule_hook_t schedule;
     60        /** Hook called upon registering new endpoint. */
     61        ep_add_hook_t ep_add_hook;
     62        /** Hook called upon removing of an endpoint. */
     63        ep_remove_hook_t ep_remove_hook;
    5964        /** Hook to be called on device interrupt, passes ARG1 */
    6065        interrupt_hook_t irq_hook;
    6166        /** Periodic polling hook */
    6267        status_hook_t status_hook;
    63         /** Hook to setup device address */
    64         address_device_hook_t address_device;
    6568} hcd_ops_t;
    6669
     
    6871struct hcd {
    6972        /** Endpoint manager. */
    70         bus_t *bus;
     73        usb_bus_t bus;
    7174
    7275        /** Interrupt replacement fibril */
     
    7578        /** Driver implementation */
    7679        hcd_ops_t ops;
    77 
    7880        /** Device specific driver data. */
    7981        void * driver_data;
    8082};
    8183
    82 extern void hcd_init(hcd_t *);
     84extern void hcd_init(hcd_t *, usb_speed_t, size_t, bw_count_func_t);
    8385
    8486static inline void hcd_set_implementation(hcd_t *hcd, void *data,
    85     const hcd_ops_t *ops, bus_t *bus)
     87    const hcd_ops_t *ops)
    8688{
    8789        assert(hcd);
     
    8991                hcd->driver_data = data;
    9092                hcd->ops = *ops;
    91                 hcd->bus = bus;
    9293        } else {
    9394                memset(&hcd->ops, 0, sizeof(hcd->ops));
     
    103104extern usb_address_t hcd_request_address(hcd_t *, usb_speed_t);
    104105
     106extern int hcd_release_address(hcd_t *, usb_address_t);
     107
     108extern int hcd_reserve_default_address(hcd_t *, usb_speed_t);
     109
     110static inline int hcd_release_default_address(hcd_t *hcd)
     111{
     112        return hcd_release_address(hcd, USB_ADDRESS_DEFAULT);
     113}
     114
    105115extern int hcd_add_ep(hcd_t *, usb_target_t, usb_direction_t,
    106     usb_transfer_type_t, size_t, unsigned int, size_t, usb_tt_address_t);
     116    usb_transfer_type_t, size_t, unsigned int, size_t, usb_address_t,
     117    unsigned int);
    107118
    108119extern int hcd_remove_ep(hcd_t *, usb_target_t, usb_direction_t);
  • uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h

    r95c675b ra416d070  
    8989 */
    9090#define USB_TRANSFER_BATCH_ARGS(batch) \
    91         (batch).ep->target.address, (batch).ep->target.endpoint, \
     91        (batch).ep->address, (batch).ep->endpoint, \
    9292        usb_str_speed((batch).ep->speed), \
    9393        usb_str_transfer_type_short((batch).ep->transfer_type), \
  • uspace/lib/usbhost/src/ddf_helpers.c

    r95c675b ra416d070  
    3535
    3636#include <usb/classes/classes.h>
    37 #include <usb/host/bus.h>
    3837#include <usb/debug.h>
    3938#include <usb/descriptor.h>
     
    5049#include <fibril_synch.h>
    5150#include <macros.h>
     51#include <stdio.h>
    5252#include <stdlib.h>
    5353#include <str_error.h>
     
    5656#include "ddf_helpers.h"
    5757
     58#define CTRL_PIPE_MIN_PACKET_SIZE 8
     59
     60typedef 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;
     70
    5871typedef struct hc_dev {
    5972        ddf_fun_t *ctl_fun;
    6073        hcd_t hcd;
     74        usb_dev_t *root_hub;
    6175} hc_dev_t;
    6276
     
    7791
    7892
    79 static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, device_t *hub_dev, unsigned port);
    80 static int hcd_ddf_remove_device(ddf_dev_t *device, device_t *hub, unsigned port);
     93static int hcd_ddf_new_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port);
     94static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port);
    8195
    8296
     
    8599/** Register endpoint interface function.
    86100 * @param fun DDF function.
    87  * @param endpoint_desc Endpoint description.
     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.
    88107 * @return Error code.
    89108 */
    90109static int register_endpoint(
    91         ddf_fun_t *fun, usb_endpoint_desc_t *endpoint_desc)
     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)
    92113{
    93114        assert(fun);
    94115        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
    95         device_t *dev = ddf_fun_data_get(fun);
     116        usb_dev_t *dev = ddf_fun_data_get(fun);
    96117        assert(hcd);
    97         assert(hcd->bus);
    98118        assert(dev);
    99 
    100         const size_t size = endpoint_desc->max_packet_size;
     119        const size_t size = max_packet_size;
     120        const usb_target_t target =
     121            {{.address = dev->address, .endpoint = endpoint}};
    101122
    102123        usb_log_debug("Register endpoint %d:%d %s-%s %zuB %ums.\n",
    103                 dev->address, endpoint_desc->endpoint_no,
    104                 usb_str_transfer_type(endpoint_desc->transfer_type),
    105                 usb_str_direction(endpoint_desc->direction),
    106                 endpoint_desc->max_packet_size, endpoint_desc->usb2.polling_interval);
    107 
    108         return bus_add_ep(hcd->bus, dev, endpoint_desc->endpoint_no,
    109                 endpoint_desc->direction, endpoint_desc->transfer_type,
    110                 endpoint_desc->max_packet_size, endpoint_desc->packets,
    111                 size);
    112 }
    113 
    114  /** Unregister endpoint interface function.
    115   * @param fun DDF function.
    116   * @param endpoint_desc Endpoint description.
    117   * @return Error code.
    118   */
     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 */
    119138static int unregister_endpoint(
    120         ddf_fun_t *fun, usb_endpoint_desc_t *endpoint_desc)
     139    ddf_fun_t *fun, usb_endpoint_t endpoint, usb_direction_t direction)
    121140{
    122141        assert(fun);
    123142        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
    124         device_t *dev = ddf_fun_data_get(fun);
     143        usb_dev_t *dev = ddf_fun_data_get(fun);
    125144        assert(hcd);
    126         assert(hcd->bus);
    127145        assert(dev);
    128 
    129         const usb_target_t target = {{
    130                 .address = dev->address,
    131                 .endpoint = endpoint_desc->endpoint_no
    132         }};
    133 
     146        const usb_target_t target =
     147            {{.address = dev->address, .endpoint = endpoint}};
    134148        usb_log_debug("Unregister endpoint %d:%d %s.\n",
    135                 dev->address, endpoint_desc->endpoint_no,
    136                 usb_str_direction(endpoint_desc->direction));
    137         return bus_remove_ep(hcd->bus, target, endpoint_desc->direction);
     149            dev->address, endpoint, usb_str_direction(direction));
     150        return hcd_remove_ep(hcd, target, direction);
    138151}
    139152
     
    142155        assert(fun);
    143156        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
    144         device_t *dev = ddf_fun_data_get(fun);
     157        usb_dev_t *dev = ddf_fun_data_get(fun);
    145158        assert(hcd);
    146         assert(hcd->bus);
    147159        assert(dev);
    148160
    149161        usb_log_debug("Device %d requested default address at %s speed\n",
    150162            dev->address, usb_str_speed(speed));
    151         return bus_reserve_default_address(hcd->bus, speed);
     163        return hcd_reserve_default_address(hcd, speed);
    152164}
    153165
     
    156168        assert(fun);
    157169        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
    158         device_t *dev = ddf_fun_data_get(fun);
     170        usb_dev_t *dev = ddf_fun_data_get(fun);
    159171        assert(hcd);
    160         assert(hcd->bus);
    161172        assert(dev);
    162173
    163174        usb_log_debug("Device %d released default address\n", dev->address);
    164         return bus_release_default_address(hcd->bus);
     175        return hcd_release_default_address(hcd);
    165176}
    166177
    167178static int device_enumerate(ddf_fun_t *fun, unsigned port)
    168 {
    169         assert(fun);
    170         ddf_dev_t *hc = ddf_fun_get_dev(fun);
    171         assert(hc);
    172         hcd_t *hcd = dev_to_hcd(hc);
    173         assert(hcd);
    174         device_t *hub = ddf_fun_data_get(fun);
    175         assert(hub);
    176 
    177         usb_log_debug("Hub %d reported a new USB device on port: %u\n",
    178             hub->address, port);
    179         return hcd_ddf_new_device(hcd, hc, hub, port);
    180 }
    181 
    182 static int device_remove(ddf_fun_t *fun, unsigned port)
    183179{
    184180        assert(fun);
    185181        ddf_dev_t *ddf_dev = ddf_fun_get_dev(fun);
    186         device_t *dev = ddf_fun_data_get(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
     190static 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);
    187195        assert(ddf_dev);
    188196        assert(dev);
     
    221229{
    222230        assert(fun);
    223         device_t *dev = ddf_fun_data_get(fun);
    224         assert(dev);
     231        usb_dev_t *usb_dev = ddf_fun_data_get(fun);
     232        assert(usb_dev);
    225233        const usb_target_t target = {{
    226             .address  = dev->address,
     234            .address =  usb_dev->address,
    227235            .endpoint = endpoint,
    228236        }};
     
    247255{
    248256        assert(fun);
    249         device_t *dev = ddf_fun_data_get(fun);
    250         assert(dev);
     257        usb_dev_t *usb_dev = ddf_fun_data_get(fun);
     258        assert(usb_dev);
    251259        const usb_target_t target = {{
    252             .address  = dev->address,
     260            .address =  usb_dev->address,
    253261            .endpoint = endpoint,
    254262        }};
     
    282290
    283291/* 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
     315static 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}
    284370
    285371#define ADD_MATCHID_OR_RETURN(list, sc, str, ...) \
     
    308394        assert(l);
    309395        assert(d);
    310 
     396       
    311397        if (d->vendor_id != 0) {
    312398                /* First, with release number. */
     
    315401                    d->vendor_id, d->product_id, (d->device_version >> 8),
    316402                    (d->device_version & 0xff));
    317 
     403       
    318404                /* Next, without release number. */
    319405                ADD_MATCHID_OR_RETURN(l, 90, "usb&vendor=%#04x&product=%#04x",
     
    329415
    330416        return EOK;
    331 }
    332 
    333 static int hcd_ddf_remove_device(ddf_dev_t *device, device_t *hub,
     417
     418}
     419
     420static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub,
    334421    unsigned port)
    335422{
     
    338425        hcd_t *hcd = dev_to_hcd(device);
    339426        assert(hcd);
    340         assert(hcd->bus);
    341427
    342428        hc_dev_t *hc_dev = dev_to_hc_dev(device);
     
    345431        fibril_mutex_lock(&hub->guard);
    346432
    347         device_t *victim = NULL;
    348 
    349         list_foreach(hub->devices, link, device_t, it) {
     433        usb_dev_t *victim = NULL;
     434
     435        list_foreach(hub->devices, link, usb_dev_t, it) {
    350436                if (it->port == port) {
    351437                        victim = it;
     
    354440        }
    355441        if (victim) {
    356                 assert(victim->fun);
    357442                assert(victim->port == port);
    358                 assert(victim->hub == hub);
    359443                list_remove(&victim->link);
    360444                fibril_mutex_unlock(&hub->guard);
     
    362446                if (ret == EOK) {
    363447                        usb_address_t address = victim->address;
    364                         bus_remove_device(hcd->bus, hcd, victim);
    365448                        ddf_fun_destroy(victim->fun);
    366                         bus_release_address(hcd->bus, address);
     449                        hcd_release_address(hcd, address);
    367450                } else {
    368451                        usb_log_warning("Failed to unbind device `%s': %s\n",
     
    375458}
    376459
    377 device_t *hcd_ddf_device_create(ddf_dev_t *hc, size_t device_size)
    378 {
    379         /* Create DDF function for the new device */
    380         ddf_fun_t *fun = ddf_fun_create(hc, fun_inner, NULL);
    381         if (!fun)
    382                 return NULL;
    383 
    384         ddf_fun_set_ops(fun, &usb_ops);
    385 
    386         /* Create USB device node for the new device */
    387         device_t *dev = ddf_fun_data_alloc(fun, device_size);
    388         if (!dev) {
    389                 ddf_fun_destroy(fun);
    390                 return NULL;
    391         }
    392 
    393         device_init(dev);
    394         dev->fun = fun;
    395         return dev;
    396 }
    397 
    398 void hcd_ddf_device_destroy(device_t *dev)
    399 {
    400         assert(dev);
    401         assert(dev->fun);
    402         ddf_fun_destroy(dev->fun);
    403 }
    404 
    405 int hcd_ddf_device_explore(hcd_t *hcd, device_t *device)
    406 {
    407         int err;
    408         match_id_list_t mids;
     460static 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,
     480                .endpoint = 0,
     481        }};
     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 */
    409513        usb_standard_device_descriptor_t desc = { 0 };
    410 
    411         init_match_ids(&mids);
    412 
    413         usb_target_t control_ep = {{
    414                 .address = device->address,
    415                 .endpoint = 0
    416         }};
     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        }
    417567
    418568        /* Get std device descriptor */
     
    421571
    422572        usb_log_debug("Device(%d): Requesting full device descriptor.",
    423             device->address);
    424         ssize_t got = hcd_send_batch_sync(hcd, control_ep, USB_DIRECTION_IN,
     573            address);
     574        got = hcd_send_batch_sync(hcd, target, USB_DIRECTION_IN,
    425575            &desc, sizeof(desc), *(uint64_t *)&get_device_desc,
    426576            "read device descriptor");
    427         if (got < 0) {
    428                 err = got < 0 ? got : EOVERFLOW;
     577        if (ret != EOK) {
    429578                usb_log_error("Device(%d): Failed to set get dev descriptor: %s",
    430                     device->address, str_error(err));
    431                 goto out;
     579                    address, str_error(ret));
     580                hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
     581                hcd_release_address(hcd, target.address);
     582                return ret;
    432583        }
    433584
    434585        /* Create match ids from the device descriptor */
    435         usb_log_debug("Device(%d): Creating match IDs.", device->address);
    436         if ((err = create_match_ids(&mids, &desc))) {
    437                 usb_log_error("Device(%d): Failed to create match ids: %s", device->address, str_error(err));
    438                 goto out;
    439         }
    440 
    441         list_foreach(mids.ids, link, const match_id_t, mid) {
    442                 ddf_fun_add_match_id(device->fun, mid->id, mid->score);
    443         }
    444 
    445 out:
     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);
    446602        clean_match_ids(&mids);
    447         return err;
    448 }
    449 
    450 static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, device_t *hub, unsigned port)
    451 {
    452         int err;
    453         assert(hcd);
    454         assert(hcd->bus);
    455         assert(hub);
    456         assert(hc);
    457 
    458         device_t *dev = hcd_ddf_device_create(hc, hcd->bus->device_size);
    459         if (!dev) {
    460                 usb_log_error("Failed to create USB device function.");
    461                 return ENOMEM;
    462         }
    463 
    464         dev->hub = hub;
    465         dev->port = port;
    466 
    467         if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) {
    468                 usb_log_error("Failed to initialize USB dev memory structures.");
    469                 return err;
    470         }
    471 
    472         /* If the driver didn't name the dev when enumerating,
    473          * do it in some generic way.
    474          */
    475         if (!ddf_fun_get_name(dev->fun)) {
    476                 device_set_default_name(dev);
    477         }
    478 
    479         if ((err = ddf_fun_bind(dev->fun))) {
    480                 usb_log_error("Device(%d): Failed to register: %s.", dev->address, str_error(err));
    481                 goto err_usb_dev;
    482         }
    483 
    484         fibril_mutex_lock(&hub->guard);
    485         list_append(&dev->link, &hub->devices);
    486         fibril_mutex_unlock(&hub->guard);
    487 
    488         return EOK;
    489 
    490 err_usb_dev:
    491         hcd_ddf_device_destroy(dev);
    492         return err;
     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;
    493611}
    494612
     
    498616 * @return Error code
    499617 */
    500 int hcd_setup_virtual_root_hub(hcd_t *hcd, ddf_dev_t *hc)
    501 {
    502         int err;
    503 
    504         assert(hc);
     618int hcd_ddf_setup_root_hub(ddf_dev_t *device)
     619{
     620        assert(device);
     621        hcd_t *hcd = dev_to_hcd(device);
    505622        assert(hcd);
    506         assert(hcd->bus);
    507 
    508         if ((err = bus_reserve_default_address(hcd->bus, USB_SPEED_MAX))) {
    509                 usb_log_error("Failed to reserve default address for roothub setup: %s", str_error(err));
    510                 return err;
    511         }
    512 
    513         device_t *dev = hcd_ddf_device_create(hc, USB_SPEED_MAX);
    514         if (!dev) {
    515                 usb_log_error("Failed to create function for the root hub.");
    516                 goto err_default_address;
    517         }
    518 
    519         ddf_fun_set_name(dev->fun, "roothub");
    520 
    521         dev->tt = (usb_tt_address_t) {
    522                 .address = -1,
    523                 .port = 0,
    524         };
    525 
    526         /* Assign an address to the device */
    527         if ((err = bus_enumerate_device(hcd->bus, hcd, dev))) {
    528                 usb_log_error("Failed to enumerate roothub device: %s", str_error(err));
    529                 goto err_usb_dev;
    530         }
    531 
    532         if ((err = ddf_fun_bind(dev->fun))) {
    533                 usb_log_error("Failed to register roothub: %s.", str_error(err));
    534                 goto err_usb_dev;
    535         }
    536 
    537         bus_release_default_address(hcd->bus);
    538         return EOK;
    539 
    540 err_usb_dev:
    541         hcd_ddf_device_destroy(dev);
    542 err_default_address:
    543         bus_release_default_address(hcd->bus);
    544         return err;
     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;
    545628}
    546629
     
    555638 * This function does all the ddf work for hc driver.
    556639 */
    557 int hcd_ddf_setup_hc(ddf_dev_t *device)
     640int hcd_ddf_setup_hc(ddf_dev_t *device, usb_speed_t max_speed,
     641    size_t bw, bw_count_func_t bw_count)
    558642{
    559643        assert(device);
     
    564648                return ENOMEM;
    565649        }
    566         hcd_init(&instance->hcd);
     650        instance->root_hub = NULL;
     651        hcd_init(&instance->hcd, max_speed, bw, bw_count);
    567652
    568653        int ret = ENOMEM;
     
    663748    const hw_res_list_parsed_t *hw_res,
    664749    interrupt_handler_t handler,
    665     irq_code_gen_t gen_irq_code)
    666 {
     750    int (*gen_irq_code)(irq_code_t *, const hw_res_list_parsed_t *hw_res))
     751{
     752
    667753        assert(device);
    668 
    669         hcd_t *hcd = dev_to_hcd(device);
    670 
    671754        if (!handler || !gen_irq_code)
    672755                return ENOTSUP;
     
    674757        irq_code_t irq_code = {0};
    675758
    676         const int irq = gen_irq_code(&irq_code, hcd, hw_res);
     759        const int irq = gen_irq_code(&irq_code, hw_res);
    677760        if (irq < 0) {
    678761                usb_log_error("Failed to generate IRQ code: %s.\n",
     
    694777        int ret = hcd_ddf_enable_interrupt(device, irq);
    695778        if (ret != EOK) {
    696                 usb_log_error("Failed to enable interrupts: %s.\n",
     779                usb_log_error("Failed to register interrupt handler: %s.\n",
    697780                    str_error(ret));
    698781                unregister_interrupt_handler(device, irq_cap);
     
    761844{
    762845        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        };
    763852
    764853        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        }
    765860
    766861        hw_res_list_parsed_t hw_res;
     
    773868        }
    774869
    775         ret = hcd_ddf_setup_hc(device);
     870        ret = hcd_ddf_setup_hc(device, speed, bw[speed].bw, bw[speed].bw_count);
    776871        if (ret != EOK) {
    777872                usb_log_error("Failed to setup generic HCD.\n");
    778                 goto err_hw_res;
    779         }
    780 
    781         hcd_t *hcd = dev_to_hcd(device);
    782 
    783         if (driver->init)
    784                 ret = driver->init(hcd, &hw_res);
    785         if (ret != EOK) {
    786                 usb_log_error("Failed to init HCD.\n");
    787                 goto err_hcd;
    788         }
    789 
    790         /* Setup interrupts  */
     873                hw_res_list_parsed_clean(&hw_res);
     874                return ret;
     875        }
     876
    791877        interrupt_handler_t *irq_handler =
    792878            driver->irq_handler ? driver->irq_handler : ddf_hcd_gen_irq_handler;
     
    798884        }
    799885
    800         /* Claim the device from BIOS */
    801886        if (driver->claim)
    802                 ret = driver->claim(hcd, device);
    803         if (ret != EOK) {
    804                 usb_log_error("Failed to claim `%s' for driver `%s': %s",
    805                     ddf_dev_get_name(device), driver->name, str_error(ret));
    806                 goto err_irq;
    807         }
    808 
    809         /* Start hw driver */
    810         if (driver->start)
    811                 ret = driver->start(hcd, irqs_enabled);
    812         if (ret != EOK) {
    813                 usb_log_error("Failed to start HCD: %s.\n", str_error(ret));
    814                 goto err_irq;
     887                ret = driver->claim(device);
     888        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);
     899        if (ret != EOK) {
     900                usb_log_error("Failed to init HCD: %s.\n", str_error(ret));
     901                goto irq_unregister;
    815902        }
    816903
     
    821908                        usb_log_error("Failed to create polling fibril\n");
    822909                        ret = ENOMEM;
    823                         goto err_started;
     910                        goto irq_unregister;
    824911                }
    825912                fibril_add_ready(hcd->polling_fibril);
     
    832919         * needs to be ready at this time.
    833920         */
    834         if (driver->setup_root_hub)
    835                 ret = driver->setup_root_hub(hcd, device);
     921        ret = hcd_ddf_setup_root_hub(device);
    836922        if (ret != EOK) {
    837923                usb_log_error("Failed to setup HC root hub: %s.\n",
    838924                    str_error(ret));
    839                 goto err_polling;
     925                driver->fini(dev_to_hcd(device));
     926irq_unregister:
     927                /* Unregistering non-existent should be ok */
     928                unregister_interrupt_handler(device, irq_cap);
     929                hcd_ddf_clean_hc(device);
     930                return ret;
    840931        }
    841932
     
    843934            driver->name, ddf_dev_get_name(device));
    844935        return EOK;
    845 
    846 err_polling:
    847         // TODO: Stop the polling fibril (refactor the interrupt_polling func)
    848         //
    849 err_started:
    850         if (driver->stop)
    851                 driver->stop(hcd);
    852 err_irq:
    853         unregister_interrupt_handler(device, irq_cap);
    854         if (driver->fini)
    855                 driver->fini(hcd);
    856 err_hcd:
    857         hcd_ddf_clean_hc(device);
    858 err_hw_res:
    859         hw_res_list_parsed_clean(&hw_res);
    860         return ret;
    861 }
    862 
     936}
    863937/**
    864938 * @}
  • uspace/lib/usbhost/src/endpoint.c

    r95c675b ra416d070  
    11/*
    22 * Copyright (c) 2011 Jan Vesely
    3  * Copyright (c) 2017 Ondrej Hlavaty <aearsis@eideo.cz>
    43 * All rights reserved.
    54 *
     
    3635
    3736#include <usb/host/endpoint.h>
    38 #include <usb/host/bus.h>
    3937
    4038#include <assert.h>
     39#include <stdlib.h>
    4140#include <atomic.h>
    42 #include <mem.h>
    43 #include <stdlib.h>
    4441
    45 /** Initialize provided endpoint structure.
     42/** Allocate ad initialize endpoint_t structure.
     43 * @param address USB address.
     44 * @param endpoint USB endpoint number.
     45 * @param direction Communication direction.
     46 * @param type USB transfer type.
     47 * @param speed Communication speed.
     48 * @param max_packet_size Maximum size of data packets.
     49 * @param bw Required bandwidth.
     50 * @return Pointer to initialized endpoint_t structure, NULL on failure.
    4651 */
    47 void endpoint_init(endpoint_t *ep, bus_t *bus)
     52endpoint_t * endpoint_create(usb_address_t address, usb_endpoint_t endpoint,
     53    usb_direction_t direction, usb_transfer_type_t type, usb_speed_t speed,
     54    size_t max_packet_size, unsigned packets, size_t bw,
     55    usb_address_t tt_address, unsigned tt_p)
    4856{
    49         memset(ep, 0, sizeof(endpoint_t));
    50 
    51         ep->bus = bus;
    52         atomic_set(&ep->refcnt, 0);
    53         link_initialize(&ep->link);
    54         fibril_mutex_initialize(&ep->guard);
    55         fibril_condvar_initialize(&ep->avail);
     57        endpoint_t *instance = malloc(sizeof(endpoint_t));
     58        if (instance) {
     59                atomic_set(&instance->refcnt, 0);
     60                instance->address = address;
     61                instance->endpoint = endpoint;
     62                instance->direction = direction;
     63                instance->transfer_type = type;
     64                instance->speed = speed;
     65                instance->max_packet_size = max_packet_size;
     66                instance->packets = packets;
     67                instance->bandwidth = bw;
     68                instance->toggle = 0;
     69                instance->active = false;
     70                instance->tt.address = tt_address;
     71                instance->tt.port = tt_p;
     72                instance->hc_data.data = NULL;
     73                instance->hc_data.toggle_get = NULL;
     74                instance->hc_data.toggle_set = NULL;
     75                link_initialize(&instance->link);
     76                fibril_mutex_initialize(&instance->guard);
     77                fibril_condvar_initialize(&instance->avail);
     78        }
     79        return instance;
    5680}
    5781
    58 void endpoint_add_ref(endpoint_t *ep)
     82/** Properly dispose of endpoint_t structure.
     83 * @param instance endpoint_t structure.
     84 */
     85void endpoint_destroy(endpoint_t *instance)
    5986{
    60         atomic_inc(&ep->refcnt);
     87        assert(instance);
     88        assert(!instance->active);
     89        assert(instance->hc_data.data == NULL);
     90        free(instance);
    6191}
    6292
    63 void endpoint_del_ref(endpoint_t *ep)
     93void endpoint_add_ref(endpoint_t *instance)
    6494{
    65         if (atomic_predec(&ep->refcnt) == 0) {
    66                 if (ep->bus->ops.destroy_endpoint) {
    67                         ep->bus->ops.destroy_endpoint(ep);
    68                 }
    69                 else {
    70                         assert(!ep->active);
     95        atomic_inc(&instance->refcnt);
     96}
    7197
    72                         /* Assume mostly the eps will be allocated by malloc. */
    73                         free(ep);
    74                 }
    75         }
     98void endpoint_del_ref(endpoint_t *instance)
     99{
     100        if (atomic_predec(&instance->refcnt) == 0)
     101                endpoint_destroy(instance);
     102}
     103
     104/** Set device specific data and hooks.
     105 * @param instance endpoint_t structure.
     106 * @param data device specific data.
     107 * @param toggle_get Hook to call when retrieving value of toggle bit.
     108 * @param toggle_set Hook to call when setting the value of toggle bit.
     109 */
     110void endpoint_set_hc_data(endpoint_t *instance,
     111    void *data, int (*toggle_get)(void *), void (*toggle_set)(void *, int))
     112{
     113        assert(instance);
     114        fibril_mutex_lock(&instance->guard);
     115        instance->hc_data.data = data;
     116        instance->hc_data.toggle_get = toggle_get;
     117        instance->hc_data.toggle_set = toggle_set;
     118        fibril_mutex_unlock(&instance->guard);
     119}
     120
     121/** Clear device specific data and hooks.
     122 * @param instance endpoint_t structure.
     123 * @note This function does not free memory pointed to by data pointer.
     124 */
     125void endpoint_clear_hc_data(endpoint_t *instance)
     126{
     127        assert(instance);
     128        endpoint_set_hc_data(instance, NULL, NULL, NULL);
    76129}
    77130
    78131/** Mark the endpoint as active and block access for further fibrils.
    79  * @param ep endpoint_t structure.
     132 * @param instance endpoint_t structure.
    80133 */
    81 void endpoint_use(endpoint_t *ep)
     134void endpoint_use(endpoint_t *instance)
    82135{
    83         assert(ep);
     136        assert(instance);
    84137        /* Add reference for active endpoint. */
    85         endpoint_add_ref(ep);
    86         fibril_mutex_lock(&ep->guard);
    87         while (ep->active)
    88                 fibril_condvar_wait(&ep->avail, &ep->guard);
    89         ep->active = true;
    90         fibril_mutex_unlock(&ep->guard);
     138        endpoint_add_ref(instance);
     139        fibril_mutex_lock(&instance->guard);
     140        while (instance->active)
     141                fibril_condvar_wait(&instance->avail, &instance->guard);
     142        instance->active = true;
     143        fibril_mutex_unlock(&instance->guard);
    91144}
    92145
    93146/** Mark the endpoint as inactive and allow access for further fibrils.
    94  * @param ep endpoint_t structure.
     147 * @param instance endpoint_t structure.
    95148 */
    96 void endpoint_release(endpoint_t *ep)
     149void endpoint_release(endpoint_t *instance)
    97150{
    98         assert(ep);
    99         fibril_mutex_lock(&ep->guard);
    100         ep->active = false;
    101         fibril_mutex_unlock(&ep->guard);
    102         fibril_condvar_signal(&ep->avail);
     151        assert(instance);
     152        fibril_mutex_lock(&instance->guard);
     153        instance->active = false;
     154        fibril_mutex_unlock(&instance->guard);
     155        fibril_condvar_signal(&instance->avail);
    103156        /* Drop reference for active endpoint. */
    104         endpoint_del_ref(ep);
     157        endpoint_del_ref(instance);
    105158}
    106159
    107 /** Get the value of toggle bit. Either uses the toggle_get op, or just returns
    108  * the value of the toggle.
    109  * @param ep endpoint_t structure.
     160/** Get the value of toggle bit.
     161 * @param instance endpoint_t structure.
     162 * @note Will use provided hook.
    110163 */
    111 int endpoint_toggle_get(endpoint_t *ep)
     164int endpoint_toggle_get(endpoint_t *instance)
    112165{
    113         assert(ep);
    114         fibril_mutex_lock(&ep->guard);
    115         const int ret = ep->bus->ops.endpoint_get_toggle
    116             ? ep->bus->ops.endpoint_get_toggle(ep)
    117             : ep->toggle;
    118         fibril_mutex_unlock(&ep->guard);
     166        assert(instance);
     167        fibril_mutex_lock(&instance->guard);
     168        if (instance->hc_data.toggle_get)
     169                instance->toggle =
     170                    instance->hc_data.toggle_get(instance->hc_data.data);
     171        const int ret = instance->toggle;
     172        fibril_mutex_unlock(&instance->guard);
    119173        return ret;
    120174}
    121175
    122 /** Set the value of toggle bit. Either uses the toggle_set op, or just sets
    123  * the toggle inside.
    124  * @param ep endpoint_t structure.
     176/** Set the value of toggle bit.
     177 * @param instance endpoint_t structure.
     178 * @note Will use provided hook.
    125179 */
    126 void endpoint_toggle_set(endpoint_t *ep, unsigned toggle)
     180void endpoint_toggle_set(endpoint_t *instance, int toggle)
    127181{
    128         assert(ep);
     182        assert(instance);
    129183        assert(toggle == 0 || toggle == 1);
    130         fibril_mutex_lock(&ep->guard);
    131         if (ep->bus->ops.endpoint_set_toggle) {
    132                 ep->bus->ops.endpoint_set_toggle(ep, toggle);
    133         }
    134         else {
    135                 ep->toggle = toggle;
    136         }
    137         fibril_mutex_unlock(&ep->guard);
     184        fibril_mutex_lock(&instance->guard);
     185        instance->toggle = toggle;
     186        if (instance->hc_data.toggle_set)
     187                instance->hc_data.toggle_set(instance->hc_data.data, toggle);
     188        fibril_mutex_unlock(&instance->guard);
    138189}
    139 
    140190
    141191/**
  • uspace/lib/usbhost/src/hcd.c

    r95c675b ra416d070  
    4444#include "hcd.h"
    4545
     46/** Calls ep_add_hook upon endpoint registration.
     47 * @param ep Endpoint to be registered.
     48 * @param arg hcd_t in disguise.
     49 * @return Error code.
     50 */
     51static int register_helper(endpoint_t *ep, void *arg)
     52{
     53        hcd_t *hcd = arg;
     54        assert(ep);
     55        assert(hcd);
     56        if (hcd->ops.ep_add_hook)
     57                return hcd->ops.ep_add_hook(hcd, ep);
     58        return EOK;
     59}
     60
     61/** Calls ep_remove_hook upon endpoint removal.
     62 * @param ep Endpoint to be unregistered.
     63 * @param arg hcd_t in disguise.
     64 */
     65static void unregister_helper(endpoint_t *ep, void *arg)
     66{
     67        hcd_t *hcd = arg;
     68        assert(ep);
     69        assert(hcd);
     70        if (hcd->ops.ep_remove_hook)
     71                hcd->ops.ep_remove_hook(hcd, ep);
     72}
     73
     74/** Calls ep_remove_hook upon endpoint removal. Prints warning.
     75 *  * @param ep Endpoint to be unregistered.
     76 *   * @param arg hcd_t in disguise.
     77 *    */
     78static void unregister_helper_warn(endpoint_t *ep, void *arg)
     79{
     80        assert(ep);
     81        usb_log_warning("Endpoint %d:%d %s was left behind, removing.\n",
     82            ep->address, ep->endpoint, usb_str_direction(ep->direction));
     83        unregister_helper(ep, arg);
     84}
     85
    4686
    4787/** Initialize hcd_t structure.
     
    5393 * @param bw_count Bandwidth compute function, passed to endpoint manager.
    5494 */
    55 void hcd_init(hcd_t *hcd) {
    56         assert(hcd);
    57 
    58         hcd_set_implementation(hcd, NULL, NULL, NULL);
     95void hcd_init(hcd_t *hcd, usb_speed_t max_speed, size_t bandwidth,
     96    bw_count_func_t bw_count)
     97{
     98        assert(hcd);
     99        usb_bus_init(&hcd->bus, bandwidth, bw_count, max_speed);
     100
     101        hcd_set_implementation(hcd, NULL, NULL);
    59102}
    60103
     
    63106        assert(hcd);
    64107        usb_address_t address = 0;
    65         const int ret = bus_request_address(hcd->bus, &address, false, speed);
     108        const int ret = usb_bus_request_address(
     109            &hcd->bus, &address, false, speed);
    66110        if (ret != EOK)
    67111                return ret;
    68112        return address;
    69113}
     114
     115int hcd_release_address(hcd_t *hcd, usb_address_t address)
     116{
     117        assert(hcd);
     118        return usb_bus_remove_address(&hcd->bus, address,
     119            unregister_helper_warn, hcd);
     120}
     121
     122int hcd_reserve_default_address(hcd_t *hcd, usb_speed_t speed)
     123{
     124        assert(hcd);
     125        usb_address_t address = 0;
     126        return usb_bus_request_address(&hcd->bus, &address, true, speed);
     127}
     128
     129int hcd_add_ep(hcd_t *hcd, usb_target_t target, usb_direction_t dir,
     130    usb_transfer_type_t type, size_t max_packet_size, unsigned packets,
     131    size_t size, usb_address_t tt_address, unsigned tt_port)
     132{
     133        assert(hcd);
     134        return usb_bus_add_ep(&hcd->bus, target.address,
     135            target.endpoint, dir, type, max_packet_size, packets, size,
     136            register_helper, hcd, tt_address, tt_port);
     137}
     138
     139int hcd_remove_ep(hcd_t *hcd, usb_target_t target, usb_direction_t dir)
     140{
     141        assert(hcd);
     142        return usb_bus_remove_ep(&hcd->bus, target.address,
     143            target.endpoint, dir, unregister_helper, hcd);
     144}
     145
    70146
    71147typedef struct {
     
    83159                usb_log_debug2("Reseting toggle on %d:%d.\n",
    84160                    toggle->target.address, toggle->target.endpoint);
    85                 bus_reset_toggle(toggle->hcd->bus,
     161                usb_bus_reset_toggle(&toggle->hcd->bus,
    86162                    toggle->target, toggle->target.endpoint == 0);
    87163        }
     
    109185        assert(hcd);
    110186
    111         endpoint_t *ep = bus_find_endpoint(hcd->bus, target, direction);
     187        endpoint_t *ep = usb_bus_find_ep(&hcd->bus,
     188            target.address, target.endpoint, direction);
    112189        if (ep == NULL) {
    113190                usb_log_error("Endpoint(%d:%d) not registered for %s.\n",
     
    119196            name, target.address, target.endpoint, size, ep->max_packet_size);
    120197
    121         const size_t bw = bus_count_bw(ep, size);
     198        const size_t bw = bandwidth_count_usb11(
     199            ep->speed, ep->transfer_type, size, ep->max_packet_size);
    122200        /* Check if we have enough bandwidth reserved */
    123201        if (ep->bandwidth < bw) {
    124202                usb_log_error("Endpoint(%d:%d) %s needs %zu bw "
    125203                    "but only %zu is reserved.\n",
    126                     ep->target.address, ep->target.endpoint, name, bw, ep->bandwidth);
     204                    ep->address, ep->endpoint, name, bw, ep->bandwidth);
    127205                return ENOSPC;
    128206        }
     
    170248
    171249typedef struct {
    172         fibril_mutex_t done_mtx;
    173         fibril_condvar_t done_cv;
    174         unsigned done;
     250        volatile unsigned done;
    175251        int ret;
    176252        size_t size;
     
    182258        assert(d);
    183259        d->ret = ret;
     260        d->done = 1;
    184261        d->size = size;
    185         fibril_mutex_lock(&d->done_mtx);
    186         d->done = 1;
    187         fibril_condvar_broadcast(&d->done_cv);
    188         fibril_mutex_unlock(&d->done_mtx);
    189262}
    190263
     
    194267        assert(data);
    195268        d->ret = ret;
    196         fibril_mutex_lock(&d->done_mtx);
    197269        d->done = 1;
    198         fibril_condvar_broadcast(&d->done_cv);
    199         fibril_mutex_unlock(&d->done_mtx);
    200270}
    201271
     
    207277        assert(hcd);
    208278        sync_data_t sd = { .done = 0, .ret = EBUSY, .size = size };
    209         fibril_mutex_initialize(&sd.done_mtx);
    210         fibril_condvar_initialize(&sd.done_cv);
    211279
    212280        const int ret = hcd_send_batch(hcd, target, dir, data, size, setup_data,
     
    216284                return ret;
    217285
    218         fibril_mutex_lock(&sd.done_mtx);
    219         while (!sd.done)
    220                 fibril_condvar_wait(&sd.done_cv, &sd.done_mtx);
    221         fibril_mutex_unlock(&sd.done_mtx);
     286        while (!sd.done) {
     287                async_usleep(1000);
     288        }
    222289
    223290        if (sd.ret == EOK)
Note: See TracChangeset for help on using the changeset viewer.