Changes in / [04efacc:03936831] in mainline


Ignore:
Files:
37 added
6 deleted
57 edited

Legend:

Unmodified
Added
Removed
  • .bzrignore

    r04efacc r03936831  
    234234uspace/dist/drv/virt/
    235235uspace/dist/drv/xtkbd/
     236uspace/dist/drv/xhci/
    236237uspace/dist/inc/_link.ld
    237238uspace/dist/inc/c/
     
    288289uspace/drv/bus/usb/usbmid/usbmid
    289290uspace/drv/bus/usb/vhc/vhc
     291uspace/drv/bus/usb/xhci/xhci
     292uspace/drv/bus/usb/xhci/test-xhci
    290293uspace/drv/char/atkbd/atkbd
    291294uspace/drv/char/i8042/i8042
  • boot/Makefile.common

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

    r04efacc r03936831  
    5454        bus/usb/usbmast \
    5555        bus/usb/usbmid \
    56         bus/usb/vhc
     56        bus/usb/vhc \
     57        bus/usb/xhci
    5758
    5859RD_DRV_CFG += \
  • tools/ew.py

    r04efacc r03936831  
    160160        return ' -usb'
    161161
     162def qemu_xhci_options():
     163        if is_override('noxhci'):
     164                return ''
     165        return ' -device nec-usb-xhci,id=xhci'
     166
    162167def qemu_audio_options():
    163168        if is_override('nosnd'):
     
    180185        if (not 'usb' in cfg.keys()) or cfg['usb']:
    181186                cmdline += qemu_usb_options()
     187        if (not 'xhci' in cfg.keys()) or cfg['xhci']:
     188                cmdline += qemu_xhci_options()
    182189        if (not 'audio' in cfg.keys()) or cfg['audio']:
    183190                cmdline += qemu_audio_options()
     
    286293def usage():
    287294        print("%s - emulator wrapper for running HelenOS\n" % os.path.basename(sys.argv[0]))
    288         print("%s [-d] [-h] [-net e1k|rtl8139|ne2k] [-nohdd] [-nokvm] [-nonet] [-nosnd] [-nousb]\n" %
     295        print("%s [-d] [-h] [-net e1k|rtl8139|ne2k] [-nohdd] [-nokvm] [-nonet] [-nosnd] [-nousb] [-noxhci]\n" %
    289296            os.path.basename(sys.argv[0]))
    290297        print("-d\tDry run: do not run the emulation, just print the command line.")
     
    295302        print("-nosnd\tDisable sound, if applicable.")
    296303        print("-nousb\tDisable USB support, if applicable.")
     304        print("-noxhci\tDisable XHCI support, if applicable.")
    297305
    298306def fail(platform, machine):
     
    336344                elif sys.argv[i] == '-nousb':
    337345                        overrides['nousb'] = True
     346                elif sys.argv[i] == '-noxhci':
     347                        overrides['noxhci'] = True
    338348                else:
    339349                        usage()
  • uspace/Makefile

    r04efacc r03936831  
    156156        drv/bus/usb/usbmid \
    157157        drv/bus/usb/vhc \
     158        drv/bus/usb/xhci \
    158159        drv/char/i8042 \
    159160        drv/char/ns8250 \
  • uspace/drv/bus/usb/ehci/Makefile

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

    r04efacc r03936831  
    4545
    4646#include "ehci_batch.h"
    47 #include "ehci_endpoint.h"
     47#include "ehci_bus.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

    r04efacc r03936831  
    144144        assert(instance);
    145145        assert(batch);
    146         const usb_target_t target = {{
    147                 .address = batch->ep->address,
    148                 .endpoint = batch->ep->endpoint,
    149         }};
     146        const usb_target_t target = batch->ep->target;
    150147        batch->error = virthub_base_request(&instance->base, target,
    151148            usb_transfer_batch_direction(batch), (void*)batch->setup_buffer,
     
    183180            instance, batch);
    184181        if (batch) {
    185                 const usb_target_t target = {{
    186                         .address = batch->ep->address,
    187                         .endpoint = batch->ep->endpoint,
    188                 }};
     182                const usb_target_t target = batch->ep->target;
    189183                batch->error = virthub_base_request(&instance->base, target,
    190184                    usb_transfer_batch_direction(batch),
  • uspace/drv/bus/usb/ehci/endpoint_list.h

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

    r04efacc r03936831  
    8989};
    9090
    91 static void hc_start(hc_t *instance);
    9291static int hc_init_memory(hc_t *instance);
    9392
     
    9897 * @return Error code.
    9998 */
    100 int ehci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res)
     99int ehci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)
    101100{
    102101        assert(code);
    103102        assert(hw_res);
     103
     104        hc_t *instance = hcd_get_driver_data(hcd);
    104105
    105106        if (hw_res->irqs.count != 1 || hw_res->mem_ranges.count != 1)
     
    128129
    129130        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         }
    138131
    139132        ehci_regs_t *registers =
    140             (ehci_regs_t *)(RNGABSPTR(regs) + EHCI_RD8(caps->caplength));
     133                (ehci_regs_t *)(RNGABSPTR(regs) + EHCI_RD8(instance->caps->caplength));
    141134        code->cmds[0].addr = (void *) &registers->usbsts;
    142135        code->cmds[3].addr = (void *) &registers->usbsts;
     
    156149 * @return Error code
    157150 */
    158 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res, bool interrupts)
     151int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res)
    159152{
    160153        assert(instance);
     
    172165                return ret;
    173166        }
     167
    174168        usb_log_info("HC(%p): Device registers at %"PRIx64" (%zuB) accessible.",
    175169            instance, hw_res->mem_ranges.ranges[0].address.absolute,
     
    195189        ehci_rh_init(
    196190            &instance->rh, instance->caps, instance->registers, "ehci rh");
    197         usb_log_debug("HC(%p): Starting HW.", instance);
    198         hc_start(instance);
    199 
     191
     192        ehci_bus_init(&instance->bus, instance);
    200193        return EOK;
    201194}
     
    222215        ehci_endpoint_t *ehci_ep = ehci_endpoint_get(ep);
    223216        usb_log_debug("HC(%p) enqueue EP(%d:%d:%s:%s)\n", instance,
    224             ep->address, ep->endpoint,
     217            ep->target.address, ep->target.endpoint,
    225218            usb_str_transfer_type_short(ep->transfer_type),
    226219            usb_str_direction(ep->direction));
     
    246239        ehci_endpoint_t *ehci_ep = ehci_endpoint_get(ep);
    247240        usb_log_debug("HC(%p) dequeue EP(%d:%d:%s:%s)\n", instance,
    248             ep->address, ep->endpoint,
     241            ep->target.address, ep->target.endpoint,
    249242            usb_str_transfer_type_short(ep->transfer_type),
    250243            usb_str_direction(ep->direction));
     
    298291
    299292        /* Check for root hub communication */
    300         if (batch->ep->address == ehci_rh_get_address(&instance->rh)) {
     293        if (batch->ep->target.address == ehci_rh_get_address(&instance->rh)) {
    301294                usb_log_debug("HC(%p): Scheduling BATCH(%p) for RH(%p)",
    302295                    instance, batch, &instance->rh);
     
    368361 * @param[in] instance EHCI hc driver structure.
    369362 */
    370 void hc_start(hc_t *instance)
    371 {
    372         assert(instance);
     363int hc_start(hc_t *instance, bool interrupts)
     364{
     365        assert(instance);
     366        usb_log_debug("HC(%p): Starting HW.", instance);
     367
    373368        /* Turn off the HC if it's running, Reseting a running device is
    374369         * undefined */
     
    435430        EHCI_WR(instance->registers->usbsts, EHCI_RD(instance->registers->usbsts));
    436431        EHCI_WR(instance->registers->usbintr, EHCI_USED_INTERRUPTS);
     432
     433        return EOK;
    437434}
    438435
  • uspace/drv/bus/usb/ehci/hc.h

    r04efacc r03936831  
    8080        /** USB hub emulation structure */
    8181        ehci_rh_t rh;
     82
     83        /** USB bookkeeping */
     84        ehci_bus_t bus;
    8285} hc_t;
    8386
    84 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res, bool interrupts);
     87int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res);
     88int hc_start(hc_t *instance, bool interrupts);
    8589void hc_fini(hc_t *instance);
    8690
     
    8892void hc_dequeue_endpoint(hc_t *instance, const endpoint_t *ep);
    8993
    90 int ehci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res);
     94int ehci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res);
    9195
    9296void ehci_hc_interrupt(hcd_t *hcd, uint32_t status);
  • uspace/drv/bus/usb/ehci/hw_struct/queue_head.c

    r04efacc r03936831  
    3737#include <mem.h>
    3838#include <macros.h>
     39#include <usb/host/bus.h>
    3940
    4041#include "mem_access.h"
     
    6566        assert(ep->speed < ARRAY_SIZE(speed));
    6667        EHCI_MEM32_WR(instance->ep_char,
    67             QH_EP_CHAR_ADDR_SET(ep->address) |
    68             QH_EP_CHAR_EP_SET(ep->endpoint) |
     68            QH_EP_CHAR_ADDR_SET(ep->target.address) |
     69            QH_EP_CHAR_EP_SET(ep->target.endpoint) |
    6970            speed[ep->speed] |
    7071            QH_EP_CHAR_MAX_LENGTH_SET(ep->max_packet_size)
     
    8182        if (ep->speed != USB_SPEED_HIGH) {
    8283                ep_cap |=
    83                     QH_EP_CAP_TT_PORT_SET(ep->tt.port) |
    84                     QH_EP_CAP_TT_ADDR_SET(ep->tt.address);
     84                    QH_EP_CAP_TT_PORT_SET(ep->device->tt.port) |
     85                    QH_EP_CAP_TT_ADDR_SET(ep->device->tt.address);
    8586        }
    8687        if (ep->transfer_type == USB_TRANSFER_INTERRUPT) {
  • uspace/drv/bus/usb/ehci/main.c

    r04efacc r03936831  
    4848#include "res.h"
    4949#include "hc.h"
    50 #include "ehci_endpoint.h"
    5150
    5251#define NAME "ehci"
    5352
    54 static int ehci_driver_init(hcd_t *, const hw_res_list_parsed_t *, bool);
     53static int ehci_driver_init(hcd_t *, const hw_res_list_parsed_t *, ddf_dev_t *);
     54static int ehci_driver_claim(hcd_t *, ddf_dev_t *);
     55static int ehci_driver_start(hcd_t *, bool);
    5556static void ehci_driver_fini(hcd_t *);
    5657
    5758static const ddf_hc_driver_t ehci_hc_driver = {
    58         .claim = disable_legacy,
    59         .hc_speed = USB_SPEED_HIGH,
     59        .name = "EHCI-PCI",
     60        .init = ehci_driver_init,
    6061        .irq_code_gen = ehci_hc_gen_irq_code,
    61         .init = ehci_driver_init,
     62        .claim = ehci_driver_claim,
     63        .start = ehci_driver_start,
     64        .setup_root_hub = hcd_setup_virtual_root_hub,
    6265        .fini = ehci_driver_fini,
    63         .name = "EHCI-PCI",
    6466        .ops = {
    6567                .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,
    75     bool irq)
     74static int ehci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, ddf_dev_t *device)
    7675{
    7776        assert(hcd);
     
    8281                return ENOMEM;
    8382
    84         const int ret = hc_init(instance, res, irq);
     83        const int ret = hc_init(instance, res);
    8584        if (ret == EOK) {
    86                 hcd_set_implementation(hcd, instance, &ehci_hc_driver.ops);
     85                hcd_set_implementation(hcd, instance, &ehci_hc_driver.ops, &instance->bus.base.base);
    8786        } else {
    8887                free(instance);
    8988        }
    9089        return ret;
     90}
     91
     92static 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
     100static 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);
    91105}
    92106
     
    99113
    100114        free(hc);
    101         hcd_set_implementation(hcd, NULL, NULL);
     115        hcd_set_implementation(hcd, NULL, NULL, NULL);
    102116}
    103117
  • uspace/drv/bus/usb/ehci/res.c

    r04efacc r03936831  
    172172}
    173173
    174 int disable_legacy(ddf_dev_t *device)
     174int disable_legacy(hc_t *hc, ddf_dev_t *device)
    175175{
    176176        assert(device);
     
    182182        usb_log_debug("Disabling EHCI legacy support.\n");
    183183
    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);
     184
     185        const uint32_t hcc_params = EHCI_RD(hc->caps->hccparams);
    214186        usb_log_debug2("Value of hcc params register: %x.\n", hcc_params);
    215187
     
    220192        usb_log_debug2("Value of EECP: %x.\n", eecp);
    221193
    222         ret = disable_extended_caps(parent_sess, eecp);
     194        int ret = disable_extended_caps(parent_sess, eecp);
    223195        if (ret != EOK) {
    224196                usb_log_error("Failed to disable extended capabilities: %s.\n",
     
    227199        }
    228200clean:
    229         //TODO unmap registers
    230         hw_res_list_parsed_clean(&res);
     201        async_hangup(parent_sess);
    231202        return ret;
    232203}
  • uspace/drv/bus/usb/ehci/res.h

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

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

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

    r04efacc r03936831  
    4747#include <usb/usb.h>
    4848
    49 #include "ohci_endpoint.h"
     49#include "ohci_bus.h"
    5050#include "ohci_batch.h"
    5151
     
    8989};
    9090
    91 static void hc_gain_control(hc_t *instance);
    92 static void hc_start(hc_t *instance);
    9391static int hc_init_transfer_lists(hc_t *instance);
    9492static int hc_init_memory(hc_t *instance);
     
    103101 * @return Error code.
    104102 */
    105 int ohci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res)
     103int ohci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)
    106104{
    107105        assert(code);
     
    151149 * @return Error code
    152150 */
    153 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res, bool interrupts)
     151int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res)
    154152{
    155153        assert(instance);
     
    172170        list_initialize(&instance->pending_batches);
    173171        fibril_mutex_initialize(&instance->guard);
    174         instance->hw_interrupts = interrupts;
    175172
    176173        ret = hc_init_memory(instance);
     
    181178                return ret;
    182179        }
    183 
    184         hc_gain_control(instance);
    185 
    186         ohci_rh_init(&instance->rh, instance->registers, "ohci rh");
    187         hc_start(instance);
    188180
    189181        return EOK;
     
    295287
    296288        /* Check for root hub communication */
    297         if (batch->ep->address == ohci_rh_get_address(&instance->rh)) {
     289        if (batch->ep->target.address == ohci_rh_get_address(&instance->rh)) {
    298290                usb_log_debug("OHCI root hub request.\n");
    299291                return ohci_rh_schedule(&instance->rh, batch);
     
    443435void hc_start(hc_t *instance)
    444436{
     437        ohci_rh_init(&instance->rh, instance->registers, "ohci rh");
     438
    445439        /* OHCI guide page 42 */
    446440        assert(instance);
  • uspace/drv/bus/usb/ohci/hc.h

    r04efacc r03936831  
    5252#include "ohci_regs.h"
    5353#include "ohci_rh.h"
     54#include "ohci_bus.h"
    5455#include "endpoint_list.h"
    5556#include "hw_struct/hcca.h"
     
    5960        /** Memory mapped I/O registers area */
    6061        ohci_regs_t *registers;
     62       
    6163        /** Host controller communication area structure */
    6264        hcca_t *hcca;
     
    6466        /** Transfer schedules */
    6567        endpoint_list_t lists[4];
     68
    6669        /** List of active transfers */
    6770        list_t pending_batches;
     
    7881        /** USB hub emulation structure */
    7982        ohci_rh_t rh;
     83
     84        /** USB bookkeeping */
     85        ohci_bus_t bus;
    8086} hc_t;
    8187
    82 extern int hc_init(hc_t *, const hw_res_list_parsed_t *, bool);
     88extern int hc_init(hc_t *, const hw_res_list_parsed_t *);
     89extern void hc_gain_control(hc_t *instance);
     90extern void hc_start(hc_t *instance);
    8391extern void hc_fini(hc_t *);
    8492
     
    8694extern void hc_dequeue_endpoint(hc_t *, const endpoint_t *);
    8795
    88 int ohci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res);
     96int ohci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res);
    8997
    9098extern void ohci_hc_interrupt(hcd_t *, uint32_t);
  • uspace/drv/bus/usb/ohci/hw_struct/endpoint_descriptor.c

    r04efacc r03936831  
    7979        /* Status: address, endpoint nr, direction mask and max packet size. */
    8080        OHCI_MEM32_WR(instance->status,
    81             ((ep->address & ED_STATUS_FA_MASK) << ED_STATUS_FA_SHIFT)
    82             | ((ep->endpoint & ED_STATUS_EN_MASK) << ED_STATUS_EN_SHIFT)
     81            ((ep->target.address & ED_STATUS_FA_MASK) << ED_STATUS_FA_SHIFT)
     82            | ((ep->target.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

    r04efacc r03936831  
    4545
    4646#include "hc.h"
     47#include "ohci_bus.h"
    4748
    4849#define NAME "ohci"
    49 static int ohci_driver_init(hcd_t *, const hw_res_list_parsed_t *, bool);
     50static int ohci_driver_init(hcd_t *, const hw_res_list_parsed_t *, ddf_dev_t *);
     51static int ohci_driver_start(hcd_t *, bool);
     52static int ohci_driver_claim(hcd_t *, ddf_dev_t *);
    5053static void ohci_driver_fini(hcd_t *);
    5154
    5255static const ddf_hc_driver_t ohci_hc_driver = {
    53         .hc_speed = USB_SPEED_FULL,
    5456        .irq_code_gen = ohci_hc_gen_irq_code,
    5557        .init = ohci_driver_init,
     58        .claim = ohci_driver_claim,
     59        .start = ohci_driver_start,
     60        .setup_root_hub = hcd_setup_virtual_root_hub,
    5661        .fini = ohci_driver_fini,
    5762        .name = "OHCI",
    5863        .ops = {
    5964                .schedule       = ohci_hc_schedule,
    60                 .ep_add_hook    = ohci_endpoint_init,
    61                 .ep_remove_hook = ohci_endpoint_fini,
    6265                .irq_hook       = ohci_hc_interrupt,
    6366                .status_hook    = ohci_hc_status,
     
    6669
    6770
    68 static int ohci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, bool irq)
     71static int ohci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, ddf_dev_t *device)
    6972{
     73        int err;
     74
    7075        assert(hcd);
    7176        assert(hcd_get_driver_data(hcd) == NULL);
     
    7580                return ENOMEM;
    7681
    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;
     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
     92err:
     93        free(instance);
     94        return err;
     95}
     96
     97static 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
     107static 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;
    84115}
    85116
     
    91122                hc_fini(hc);
    92123
    93         hcd_set_implementation(hcd, NULL, NULL);
     124        hcd_set_implementation(hcd, NULL, NULL, NULL);
    94125        free(hc);
    95126}
  • uspace/drv/bus/usb/ohci/ohci_batch.c

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

    r04efacc r03936831  
    178178        assert(instance);
    179179        assert(batch);
    180         const usb_target_t target = {{
    181                 .address = batch->ep->address,
    182                 .endpoint = batch->ep->endpoint,
    183         }};
     180        const usb_target_t target = batch->ep->target;
    184181        batch->error = virthub_base_request(&instance->base, target,
    185182            usb_transfer_batch_direction(batch), (void*)batch->setup_buffer,
     
    211208        instance->unfinished_interrupt_transfer = NULL;
    212209        if (batch) {
    213                 const usb_target_t target = {{
    214                         .address = batch->ep->address,
    215                         .endpoint = batch->ep->endpoint,
    216                 }};
     210                const usb_target_t target = batch->ep->target;
    217211                batch->error = virthub_base_request(&instance->base, target,
    218212                    usb_transfer_batch_direction(batch),
  • uspace/drv/bus/usb/uhci/hc.c

    r04efacc r03936831  
    5050#include <usb/usb.h>
    5151#include <usb/host/utils/malloc32.h>
     52#include <usb/host/bandwidth.h>
    5253
    5354#include "uhci_batch.h"
     
    106107 * @return Error code.
    107108 */
    108 int uhci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res)
     109int uhci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)
    109110{
    110111        assert(code);
     
    214215 * interrupt fibrils.
    215216 */
    216 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res, bool interrupts)
     217int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res)
    217218{
    218219        assert(instance);
     
    222223            return EINVAL;
    223224
    224         instance->hw_interrupts = interrupts;
    225225        instance->hw_failures = 0;
    226226
     
    246246        }
    247247
     248        return EOK;
     249}
     250
     251void hc_start(hc_t *instance)
     252{
    248253        hc_init_hw(instance);
    249254        (void)hc_debug_checker;
    250255
    251256        uhci_rh_init(&instance->rh, instance->registers->ports, "uhci");
    252 
    253         return EOK;
    254257}
    255258
     
    318321int hc_init_mem_structures(hc_t *instance)
    319322{
    320         assert(instance);
     323        int err;
     324        assert(instance);
     325
     326        if ((err = usb2_bus_init(&instance->bus, BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11)))
     327                return err;
    321328
    322329        /* Init USB frame list page */
     
    440447        assert(batch);
    441448
    442         if (batch->ep->address == uhci_rh_get_address(&instance->rh))
     449        if (batch->ep->target.address == uhci_rh_get_address(&instance->rh))
    443450                return uhci_rh_schedule(&instance->rh, batch);
    444451
  • uspace/drv/bus/usb/uhci/hc.h

    r04efacc r03936831  
    4343#include <ddi.h>
    4444#include <usb/host/hcd.h>
     45#include <usb/host/usb2_bus.h>
    4546#include <usb/host/usb_transfer_batch.h>
    4647
     
    100101typedef struct hc {
    101102        uhci_rh_t rh;
     103        usb2_bus_t bus;
    102104        /** Addresses of I/O registers */
    103105        uhci_regs_t *registers;
     
    124126} hc_t;
    125127
    126 extern int hc_init(hc_t *, const hw_res_list_parsed_t *, bool);
     128extern int hc_init(hc_t *, const hw_res_list_parsed_t *);
     129extern void hc_start(hc_t *);
    127130extern void hc_fini(hc_t *);
    128131
    129 extern int uhci_hc_gen_irq_code(irq_code_t *, const hw_res_list_parsed_t *);
     132extern int uhci_hc_gen_irq_code(irq_code_t *, hcd_t *,const hw_res_list_parsed_t *);
    130133
    131134extern void uhci_hc_interrupt(hcd_t *, uint32_t);
  • uspace/drv/bus/usb/uhci/main.c

    r04efacc r03936831  
    4949#define NAME "uhci"
    5050
    51 static int uhci_driver_init(hcd_t *, const hw_res_list_parsed_t *, bool);
     51static int uhci_driver_init(hcd_t *, const hw_res_list_parsed_t *, ddf_dev_t *);
     52static int uhci_driver_start(hcd_t *, bool);
    5253static void uhci_driver_fini(hcd_t *);
    53 static int disable_legacy(ddf_dev_t *);
     54static int disable_legacy(hcd_t *, ddf_dev_t *);
    5455
    5556static const ddf_hc_driver_t uhci_hc_driver = {
    5657        .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,
    6062        .fini = uhci_driver_fini,
    6163        .name = "UHCI",
     
    6769};
    6870
    69 static int uhci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, bool irq)
     71static int uhci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, ddf_dev_t *device)
    7072{
     73        int err;
     74
    7175        assert(hcd);
    7276        assert(hcd_get_driver_data(hcd) == NULL);
     
    7680                return ENOMEM;
    7781
    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;
     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
     89err:
     90        free(instance);
     91        return err;
     92}
     93
     94static 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;
    85102}
    86103
     
    92109                hc_fini(hc);
    93110
    94         hcd_set_implementation(hcd, NULL, NULL);
     111        hcd_set_implementation(hcd, NULL, NULL, NULL);
    95112        free(hc);
    96113}
     
    101118 * @return Error code.
    102119 */
    103 static int disable_legacy(ddf_dev_t *device)
     120static int disable_legacy(hcd_t *hcd, ddf_dev_t *device)
    104121{
    105122        assert(device);
  • uspace/drv/bus/usb/uhci/uhci_batch.c

    r04efacc r03936831  
    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 = {{
    231             uhci_batch->usb_batch->ep->address,
    232             uhci_batch->usb_batch->ep->endpoint }};
     230        const usb_target_t target = uhci_batch->usb_batch->ep->target;
    233231
    234232        int toggle = endpoint_toggle_get(uhci_batch->usb_batch->ep);
     
    293291            uhci_batch->usb_batch->ep->speed == USB_SPEED_LOW;
    294292        const size_t mps = uhci_batch->usb_batch->ep->max_packet_size;
    295         const usb_target_t target = {{
    296             uhci_batch->usb_batch->ep->address,
    297             uhci_batch->usb_batch->ep->endpoint }};
     293        const usb_target_t target = uhci_batch->usb_batch->ep->target;
    298294
    299295        /* setup stage */
  • uspace/drv/bus/usb/uhci/uhci_rh.c

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

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

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

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

    r04efacc r03936831  
    8989
    9090        /* Initialize generic structures */
    91         ret = hcd_ddf_setup_hc(dev, USB_SPEED_FULL,
    92             BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
     91        ret = hcd_ddf_setup_hc(dev);
    9392        if (ret != EOK) {
    9493                usb_log_error("Failed to init HCD structures: %s.\n",
     
    9897        }
    9998
    100         hcd_set_implementation(dev_to_hcd(dev), data, &vhc_hc_ops);
     99        hcd_set_implementation(dev_to_hcd(dev), data, &vhc_hc_ops, &data->bus.base);
    101100
    102101        /* Add virtual hub device */
     
    112111         * needs to be ready at this time.
    113112         */
    114         ret = hcd_ddf_setup_root_hub(dev);
     113        ret = hcd_setup_virtual_root_hub(dev_to_hcd(dev), dev);
    115114        if (ret != EOK) {
    116115                usb_log_error("Failed to init VHC root hub: %s\n",
  • uspace/drv/bus/usb/vhc/transfer.c

    r04efacc r03936831  
    3131#include <usb/debug.h>
    3232#include <usbvirt/device.h>
     33#include <usb/host/bandwidth.h>
    3334#include <usbvirt/ipc.h>
    3435#include "vhcd.h"
     
    3738static bool is_set_address_transfer(vhc_transfer_t *transfer)
    3839{
    39         if (transfer->batch->ep->endpoint != 0) {
     40        if (transfer->batch->ep->target.endpoint != 0) {
    4041                return false;
    4142        }
     
    8081                if (dir == USB_DIRECTION_IN) {
    8182                        rc = usbvirt_data_in(dev, batch->ep->transfer_type,
    82                             batch->ep->endpoint,
     83                            batch->ep->target.endpoint,
    8384                            batch->buffer, batch->buffer_size,
    8485                            actual_data_size);
     
    8687                        assert(dir == USB_DIRECTION_OUT);
    8788                        rc = usbvirt_data_out(dev, batch->ep->transfer_type,
    88                             batch->ep->endpoint,
     89                            batch->ep->target.endpoint,
    8990                            batch->buffer, batch->buffer_size);
    9091                }
     
    115116        } else {
    116117                if (dir == USB_DIRECTION_IN) {
    117                         rc = usbvirt_ipc_send_data_in(sess, batch->ep->endpoint,
     118                        rc = usbvirt_ipc_send_data_in(sess, batch->ep->target.endpoint,
    118119                            batch->ep->transfer_type,
    119120                            batch->buffer, batch->buffer_size,
     
    121122                } else {
    122123                        assert(dir == USB_DIRECTION_OUT);
    123                         rc = usbvirt_ipc_send_data_out(sess, batch->ep->endpoint,
     124                        rc = usbvirt_ipc_send_data_out(sess, batch->ep->target.endpoint,
    124125                            batch->ep->transfer_type,
    125126                            batch->buffer, batch->buffer_size);
     
    159160        list_initialize(&instance->devices);
    160161        fibril_mutex_initialize(&instance->guard);
     162        usb2_bus_init(&instance->bus, BANDWIDTH_AVAILABLE_USB11, bandwidth_count_usb11);
    161163        instance->magic = 0xDEADBEEF;
    162164        return virthub_init(&instance->hub, "root hub");
     
    182184        list_foreach(vhc->devices, link, vhc_virtdev_t, dev) {
    183185                fibril_mutex_lock(&dev->guard);
    184                 if (dev->address == transfer->batch->ep->address) {
     186                if (dev->address == transfer->batch->ep->target.address) {
    185187                        if (!targets) {
    186188                                list_append(&transfer->link, &dev->transfer_queue);
  • uspace/drv/bus/usb/vhc/vhcd.h

    r04efacc r03936831  
    4242
    4343#include <usb/host/hcd.h>
     44#include <usb/host/usb2_bus.h>
    4445
    4546#define NAME "vhc"
     
    6061        fibril_mutex_t guard;
    6162        usbvirt_device_t hub;
     63        usb2_bus_t bus;
    6264} vhc_data_t;
    6365
  • uspace/lib/c/include/bitops.h

    r04efacc r03936831  
    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))
    5660
    5761/** Return position of first non-zero bit from left (i.e. [log_2(arg)]).
  • uspace/lib/c/include/byteorder.h

    r04efacc r03936831  
    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
    8792static inline uint64_t uint64_t_byteorder_swap(uint64_t n)
    8893{
  • uspace/lib/drv/generic/remote_usb.c

    r04efacc r03936831  
    175175} pack8_t;
    176176
    177 int 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 
    194 int 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);
     177int 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
     205int 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;
    201230}
    202231
     
    317346};
    318347
     348typedef struct {
     349        ipc_callid_t caller;
     350        ipc_callid_t data_caller;
     351        void *buffer;
     352} async_transaction_t;
     353
    319354void remote_usb_get_my_interface(ddf_fun_t *fun, void *iface,
    320355    ipc_callid_t callid, ipc_call_t *call)
     
    417452    ipc_callid_t callid, ipc_call_t *call)
    418453{
    419         usb_iface_t *usb_iface = (usb_iface_t *) iface;
     454        assert(fun);
     455        assert(iface);
     456        assert(call);
     457
     458        const usb_iface_t *usb_iface = iface;
    420459
    421460        if (!usb_iface->register_endpoint) {
     
    424463        }
    425464
    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);
     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);
     480        async_answer_0(callid, rc);
    439481}
    440482
     
    442484    ipc_callid_t callid, ipc_call_t *call)
    443485{
    444         usb_iface_t *usb_iface = (usb_iface_t *) iface;
     486        assert(fun);
     487        assert(iface);
     488        assert(call);
     489
     490        const usb_iface_t *usb_iface = iface;
    445491
    446492        if (!usb_iface->unregister_endpoint) {
     
    449495        }
    450496
    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 
    456         async_answer_0(callid, rc);
    457 }
    458 
    459 typedef struct {
    460         ipc_callid_t caller;
    461         ipc_callid_t data_caller;
    462         void *buffer;
    463 } async_transaction_t;
     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}
    464516
    465517static void async_transaction_destroy(async_transaction_t *trans)
  • uspace/lib/drv/include/usb_iface.h

    r04efacc r03936831  
    5757extern int usb_device_remove(async_exch_t *, unsigned port);
    5858
    59 extern int usb_register_endpoint(async_exch_t *, usb_endpoint_t,
    60     usb_transfer_type_t, usb_direction_t, size_t, unsigned, unsigned);
    61 extern int usb_unregister_endpoint(async_exch_t *, usb_endpoint_t,
    62     usb_direction_t);
     59extern int usb_register_endpoint(async_exch_t *, usb_endpoint_desc_t *);
     60extern int usb_unregister_endpoint(async_exch_t *, usb_endpoint_desc_t *);
    6361extern int usb_read(async_exch_t *, usb_endpoint_t, uint64_t, void *, size_t,
    6462    size_t *);
     
    8381        int (*device_remove)(ddf_fun_t *, unsigned);
    8482
    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);
     83        int (*register_endpoint)(ddf_fun_t *, usb_endpoint_desc_t *);
     84        int (*unregister_endpoint)(ddf_fun_t *, usb_endpoint_desc_t *);
    8985
    9086        int (*read)(ddf_fun_t *, usb_endpoint_t, uint64_t, uint8_t *, size_t,
  • uspace/lib/pcm/src/format.c

    r04efacc r03936831  
    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)
    4843
    4944#define int8_t_le2host(x) (x)
  • uspace/lib/usb/include/usb/descriptor.h

    r04efacc r03936831  
    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,
    5157        /* Class specific */
    5258        USB_DESCTYPE_HID = 0x21,
     
    5460        USB_DESCTYPE_HID_PHYSICAL = 0x23,
    5561        USB_DESCTYPE_HUB = 0x29,
     62        USB_DESCTYPE_SSPEED_EP_COMPANION = 0x30
    5663        /* USB_DESCTYPE_ = */
    5764} usb_descriptor_type_t;
     
    217224} __attribute__ ((packed)) usb_standard_endpoint_descriptor_t;
    218225
     226/** Superspeed USB endpoint companion descriptor.
     227 * See USB 3 specification, section 9.6.7.
     228 */
     229typedef 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
    219254/** Part of standard USB HID descriptor specifying one class descriptor.
    220255 *
  • uspace/lib/usb/include/usb/request.h

    r04efacc r03936831  
    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
    114138#endif
    115139/**
  • uspace/lib/usb/include/usb/usb.h

    r04efacc r03936831  
    8181        /** USB 2.0 high speed (480Mbits/s). */
    8282        USB_SPEED_HIGH,
     83        /** USB 3.0 super speed (5Gbits/s). */
     84        USB_SPEED_SUPER,
    8385        /** Psuedo-speed serving as a boundary. */
    8486        USB_SPEED_MAX
     
    113115typedef int16_t usb_address_t;
    114116
     117typedef struct {
     118        usb_address_t address;
     119        unsigned port;
     120} usb_tt_address_t;
     121
    115122/** Default USB address. */
    116123#define USB_ADDRESS_DEFAULT 0
     
    157164
    158165
    159 /** USB complete address type. 
     166/** USB complete address type.
    160167 * Pair address + endpoint is identification of transaction recipient.
    161168 */
     
    167174        uint32_t packed;
    168175} usb_target_t;
     176
     177/** Description of usb endpoint.
     178 */
     179typedef 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;
    169200
    170201/** Check USB target for allowed values (address and endpoint).
  • uspace/lib/usb/src/usb.c

    r04efacc r03936831  
    4444        [USB_SPEED_FULL] = "full",
    4545        [USB_SPEED_HIGH] = "high",
     46        [USB_SPEED_SUPER] = "super",
    4647};
    4748
  • uspace/lib/usbdev/include/usb/dev/pipes.h

    r04efacc r03936831  
    5050 */
    5151typedef struct {
    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 
     52        /** Endpoint description */
     53        usb_endpoint_desc_t desc;
    6854        /** Whether to automatically reset halt on the endpoint.
    6955         * Valid only for control endpoint zero.
    7056         */
    7157        bool auto_reset_halt;
    72 
    7358        /** The connection used for sending the data. */
    7459        usb_dev_session_t *bus_session;
  • uspace/lib/usbdev/src/devdrv.c

    r04efacc r03936831  
    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.endpoint_no == ep)
     334                if (usb_dev->pipes[i].pipe.desc.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

    r04efacc r03936831  
    9696                    (int) mapping->interface->interface_subclass,
    9797                    (int) mapping->interface->interface_protocol,
    98                     data->request_size, pipe->max_packet_size);
     98                    data->request_size, pipe->desc.max_packet_size);
    9999        }
    100100
     
    128128                        usb_request_clear_endpoint_halt(
    129129                            usb_device_get_default_pipe(data->dev),
    130                             pipe->endpoint_no);
     130                            pipe->desc.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.transfer_type != USB_TRANSFER_INTERRUPT) ||
    220             (epm->pipe.direction != USB_DIRECTION_IN))
     218
     219        if (!epm || (epm->pipe.desc.transfer_type != USB_TRANSFER_INTERRUPT) ||
     220            (epm->pipe.desc.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

    r04efacc r03936831  
    5151        assert(pipe != NULL);
    5252
    53         if (!pipe->auto_reset_halt || (pipe->endpoint_no != 0)) {
     53        if (!pipe->auto_reset_halt || (pipe->desc.endpoint_no != 0)) {
    5454                return;
    5555        }
     
    8888        }
    8989
    90         if ((pipe->direction != USB_DIRECTION_BOTH)
    91             || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
     90        if ((pipe->desc.direction != USB_DIRECTION_BOTH)
     91            || (pipe->desc.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->endpoint_no, setup_packet, buffer,
     100        const int rc = usb_read(exch, pipe->desc.endpoint_no, setup_packet, buffer,
    101101            buffer_size, &act_size);
    102102        async_exchange_end(exch);
     
    142142        }
    143143
    144         if ((pipe->direction != USB_DIRECTION_BOTH)
    145             || (pipe->transfer_type != USB_TRANSFER_CONTROL)) {
     144        if ((pipe->desc.direction != USB_DIRECTION_BOTH)
     145            || (pipe->desc.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->endpoint_no, setup_packet, buffer, buffer_size);
     154            pipe->desc.endpoint_no, setup_packet, buffer, buffer_size);
    155155        async_exchange_end(exch);
    156156
     
    183183        }
    184184
    185         if (pipe->direction != USB_DIRECTION_IN) {
    186                 return EBADF;
    187         }
    188 
    189         if (pipe->transfer_type == USB_TRANSFER_CONTROL) {
     185        if (pipe->desc.direction != USB_DIRECTION_IN) {
     186                return EBADF;
     187        }
     188
     189        if (pipe->desc.transfer_type == USB_TRANSFER_CONTROL) {
    190190                return EBADF;
    191191        }
    192192
    193193        /* Isochronous transfer are not supported (yet) */
    194         if (pipe->transfer_type != USB_TRANSFER_INTERRUPT &&
    195             pipe->transfer_type != USB_TRANSFER_BULK)
     194        if (pipe->desc.transfer_type != USB_TRANSFER_INTERRUPT &&
     195            pipe->desc.transfer_type != USB_TRANSFER_BULK)
    196196            return ENOTSUP;
    197197
     
    199199        size_t act_size = 0;
    200200        const int rc =
    201             usb_read(exch, pipe->endpoint_no, 0, buffer, size, &act_size);
     201            usb_read(exch, pipe->desc.endpoint_no, 0, buffer, size, &act_size);
    202202        async_exchange_end(exch);
    203203
     
    224224        }
    225225
    226         if (pipe->direction != USB_DIRECTION_OUT) {
    227                 return EBADF;
    228         }
    229 
    230         if (pipe->transfer_type == USB_TRANSFER_CONTROL) {
     226        if (pipe->desc.direction != USB_DIRECTION_OUT) {
     227                return EBADF;
     228        }
     229
     230        if (pipe->desc.transfer_type == USB_TRANSFER_CONTROL) {
    231231                return EBADF;
    232232        }
    233233
    234234        /* Isochronous transfer are not supported (yet) */
    235         if (pipe->transfer_type != USB_TRANSFER_INTERRUPT &&
    236             pipe->transfer_type != USB_TRANSFER_BULK)
     235        if (pipe->desc.transfer_type != USB_TRANSFER_INTERRUPT &&
     236            pipe->desc.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->endpoint_no, 0, buffer, size);
     240        const int rc = usb_write(exch, pipe->desc.endpoint_no, 0, buffer, size);
    241241        async_exchange_end(exch);
    242242        return rc;
     
    258258        assert(pipe);
    259259
    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;
     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;
    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;
    299301        async_exch_t *exch = async_exchange_begin(pipe->bus_session);
    300302        if (!exch)
    301303                return ENOMEM;
    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);
     304
     305        const int ret = usb_register_endpoint(exch, &pipe->desc);
     306
    305307        async_exchange_end(exch);
    306308        return ret;
     
    319321        if (!exch)
    320322                return ENOMEM;
    321         const int ret = usb_unregister_endpoint(exch, pipe->endpoint_no,
    322             pipe->direction);
     323
     324        const int ret = usb_unregister_endpoint(exch, &pipe->desc);
     325
    323326        async_exchange_end(exch);
    324327        return ret;
  • uspace/lib/usbdev/src/pipesinit.c

    r04efacc r03936831  
    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->direction != USB_DIRECTION_BOTH) ||
    346             (pipe->transfer_type != USB_TRANSFER_CONTROL) ||
    347             (pipe->endpoint_no != 0)) {
     345        if ((pipe->desc.direction != USB_DIRECTION_BOTH) ||
     346            (pipe->desc.transfer_type != USB_TRANSFER_CONTROL) ||
     347            (pipe->desc.endpoint_no != 0)) {
    348348                return EINVAL;
    349349        }
     
    369369        }
    370370
    371         pipe->max_packet_size
     371        pipe->desc.max_packet_size
    372372            = dev_descr_start[DEV_DESCR_MAX_PACKET_SIZE_OFFSET];
    373373
  • uspace/lib/usbdev/src/request.c

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

    r04efacc r03936831  
    3939        src/endpoint.c \
    4040        src/hcd.c \
    41         src/usb_bus.c \
     41        src/bus.c \
     42        src/usb2_bus.c \
     43        src/bandwidth.c \
    4244        src/usb_transfer_batch.c
    4345
  • uspace/lib/usbhost/include/usb/host/ddf_helpers.h

    r04efacc r03936831  
    3838
    3939#include <usb/host/hcd.h>
    40 #include <usb/host/usb_bus.h>
     40#include <usb/host/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 *, bool);
     47typedef int (*driver_init_t)(hcd_t *, const hw_res_list_parsed_t *, ddf_dev_t *);
     48typedef int (*irq_code_gen_t)(irq_code_t *, hcd_t *, const hw_res_list_parsed_t *);
     49typedef int (*claim_t)(hcd_t *, ddf_dev_t *);
     50typedef int (*driver_start_t)(hcd_t *, bool irq);
     51typedef int (*setup_root_hub_t)(hcd_t *, ddf_dev_t *);
     52
     53typedef void (*driver_stop_t)(hcd_t *);
    4854typedef void (*driver_fini_t)(hcd_t *);
    49 typedef int (*claim_t)(ddf_dev_t *);
    50 typedef int (*irq_code_gen_t)(irq_code_t *, const hw_res_list_parsed_t *);
    5155
     56/**
     57 * All callbacks are optional.
     58 */
    5259typedef struct {
    5360        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;
    6061        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) */
    6175} ddf_hc_driver_t;
    6276
    6377int hcd_ddf_add_hc(ddf_dev_t *device, const ddf_hc_driver_t *driver);
    6478
    65 int hcd_ddf_setup_hc(ddf_dev_t *device, usb_speed_t max_speed,
    66     size_t bw, bw_count_func_t bw_count);
     79int hcd_ddf_setup_hc(ddf_dev_t *device);
    6780void hcd_ddf_clean_hc(ddf_dev_t *device);
    68 int hcd_ddf_setup_root_hub(ddf_dev_t *device);
     81
     82int hcd_setup_virtual_root_hub(hcd_t *, ddf_dev_t *);
     83
     84device_t *hcd_ddf_device_create(ddf_dev_t *, size_t);
     85void hcd_ddf_device_destroy(device_t *);
     86int hcd_ddf_device_explore(hcd_t *, device_t *);
    6987
    7088hcd_t *dev_to_hcd(ddf_dev_t *dev);
     
    7593    const hw_res_list_parsed_t *hw_res,
    7694    interrupt_handler_t handler,
    77     int (*gen_irq_code)(irq_code_t *, const hw_res_list_parsed_t *));
     95    irq_code_gen_t gen_irq_code);
    7896void ddf_hcd_gen_irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev);
    7997
  • uspace/lib/usbhost/include/usb/host/endpoint.h

    r04efacc r03936831  
    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 *
    3438 */
    3539#ifndef LIBUSBHOST_HOST_ENDPOINT_H
     
    4246#include <atomic.h>
    4347
     48typedef struct bus bus_t;
     49typedef struct device device_t;
     50
    4451/** Host controller side endpoint structure. */
    4552typedef struct endpoint {
     53        /** Managing bus */
     54        bus_t *bus;
    4655        /** Reference count. */
    47         atomic_t refcnt;       
     56        atomic_t refcnt;
    4857        /** Part of linked list. */
    4958        link_t link;
     59        /** USB device */
     60        device_t *device;
    5061        /** USB address. */
    51         usb_address_t address;
    52         /** USB endpoint number. */
    53         usb_endpoint_t endpoint;
     62        usb_target_t target;
    5463        /** Communication direction. */
    5564        usb_direction_t direction;
     
    6271        /** Additional opportunities per uframe */
    6372        unsigned packets;
    64         /** Necessary bandwidth. */
     73        /** Reserved bandwidth. */
    6574        size_t bandwidth;
    6675        /** Value of the toggle bit. */
    6776        unsigned toggle:1;
    6877        /** True if there is a batch using this scheduled for this endpoint. */
    69         volatile bool active;
     78        bool active;
    7079        /** Protects resources and active status changes. */
    7180        fibril_mutex_t guard;
    7281        /** Signals change of active status. */
    7382        fibril_condvar_t avail;
    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;
     83
     84        /* This structure is meant to be extended by overriding. */
    8885} endpoint_t;
    8986
    90 extern 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);
    93 extern void endpoint_destroy(endpoint_t *);
     87extern void endpoint_init(endpoint_t *, bus_t *);
    9488
    9589extern void endpoint_add_ref(endpoint_t *);
    9690extern void endpoint_del_ref(endpoint_t *);
    97 
    98 extern void endpoint_set_hc_data(endpoint_t *, void *, int (*)(void *),
    99     void (*)(void *, int));
    100 extern void endpoint_clear_hc_data(endpoint_t *);
    10191
    10292extern void endpoint_use(endpoint_t *);
     
    10494
    10595extern int endpoint_toggle_get(endpoint_t *);
    106 extern void endpoint_toggle_set(endpoint_t *, int);
     96extern void endpoint_toggle_set(endpoint_t *, unsigned);
    10797
    10898/** list_get_instance wrapper.
  • uspace/lib/usbhost/include/usb/host/hcd.h

    r04efacc r03936831  
    3838
    3939#include <usb/host/endpoint.h>
    40 #include <usb/host/usb_bus.h>
     40#include <usb/host/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 *);
    52 typedef int (*ep_add_hook_t)(hcd_t *, endpoint_t *);
    53 typedef void (*ep_remove_hook_t)(hcd_t *, endpoint_t *);
    5452typedef void (*interrupt_hook_t)(hcd_t *, uint32_t);
    5553typedef int (*status_hook_t)(hcd_t *, uint32_t *);
     54typedef int (*address_device_hook_t)(hcd_t *, usb_speed_t, usb_tt_address_t, usb_address_t *);
    5655
    5756typedef struct {
    5857        /** Transfer scheduling, implement in device driver. */
    5958        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;
    6459        /** Hook to be called on device interrupt, passes ARG1 */
    6560        interrupt_hook_t irq_hook;
    6661        /** Periodic polling hook */
    6762        status_hook_t status_hook;
     63        /** Hook to setup device address */
     64        address_device_hook_t address_device;
    6865} hcd_ops_t;
    6966
     
    7168struct hcd {
    7269        /** Endpoint manager. */
    73         usb_bus_t bus;
     70        bus_t *bus;
    7471
    7572        /** Interrupt replacement fibril */
     
    7875        /** Driver implementation */
    7976        hcd_ops_t ops;
     77
    8078        /** Device specific driver data. */
    8179        void * driver_data;
    8280};
    8381
    84 extern void hcd_init(hcd_t *, usb_speed_t, size_t, bw_count_func_t);
     82extern void hcd_init(hcd_t *);
    8583
    8684static inline void hcd_set_implementation(hcd_t *hcd, void *data,
    87     const hcd_ops_t *ops)
     85    const hcd_ops_t *ops, bus_t *bus)
    8886{
    8987        assert(hcd);
     
    9189                hcd->driver_data = data;
    9290                hcd->ops = *ops;
     91                hcd->bus = bus;
    9392        } else {
    9493                memset(&hcd->ops, 0, sizeof(hcd->ops));
     
    104103extern usb_address_t hcd_request_address(hcd_t *, usb_speed_t);
    105104
    106 extern int hcd_release_address(hcd_t *, usb_address_t);
    107 
    108 extern int hcd_reserve_default_address(hcd_t *, usb_speed_t);
    109 
    110 static inline int hcd_release_default_address(hcd_t *hcd)
    111 {
    112         return hcd_release_address(hcd, USB_ADDRESS_DEFAULT);
    113 }
    114 
    115105extern int hcd_add_ep(hcd_t *, usb_target_t, usb_direction_t,
    116     usb_transfer_type_t, size_t, unsigned int, size_t, usb_address_t,
    117     unsigned int);
     106    usb_transfer_type_t, size_t, unsigned int, size_t, usb_tt_address_t);
    118107
    119108extern int hcd_remove_ep(hcd_t *, usb_target_t, usb_direction_t);
  • uspace/lib/usbhost/include/usb/host/usb_transfer_batch.h

    r04efacc r03936831  
    8989 */
    9090#define USB_TRANSFER_BATCH_ARGS(batch) \
    91         (batch).ep->address, (batch).ep->endpoint, \
     91        (batch).ep->target.address, (batch).ep->target.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

    r04efacc r03936831  
    3535
    3636#include <usb/classes/classes.h>
     37#include <usb/host/bus.h>
    3738#include <usb/debug.h>
    3839#include <usb/descriptor.h>
     
    4950#include <fibril_synch.h>
    5051#include <macros.h>
    51 #include <stdio.h>
    5252#include <stdlib.h>
    5353#include <str_error.h>
     
    5656#include "ddf_helpers.h"
    5757
    58 #define CTRL_PIPE_MIN_PACKET_SIZE 8
    59 
    60 typedef struct usb_dev {
    61         link_t link;
    62         list_t devices;
    63         fibril_mutex_t guard;
    64         ddf_fun_t *fun;
    65         usb_address_t address;
    66         usb_speed_t speed;
    67         usb_address_t tt_address;
    68         unsigned port;
    69 } usb_dev_t;
    70 
    7158typedef struct hc_dev {
    7259        ddf_fun_t *ctl_fun;
    7360        hcd_t hcd;
    74         usb_dev_t *root_hub;
    7561} hc_dev_t;
    7662
     
    9177
    9278
    93 static int hcd_ddf_new_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port);
    94 static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port);
     79static int hcd_ddf_new_device(hcd_t *hcd, ddf_dev_t *hc, device_t *hub_dev, unsigned port);
     80static int hcd_ddf_remove_device(ddf_dev_t *device, device_t *hub, unsigned port);
    9581
    9682
     
    9985/** Register endpoint interface function.
    10086 * @param fun DDF function.
    101  * @param address USB address of the device.
    102  * @param endpoint USB endpoint number to be registered.
    103  * @param transfer_type Endpoint's transfer type.
    104  * @param direction USB communication direction the endpoint is capable of.
    105  * @param max_packet_size Maximu size of packets the endpoint accepts.
    106  * @param interval Preferred timeout between communication.
     87 * @param endpoint_desc Endpoint description.
    10788 * @return Error code.
    10889 */
    10990static int register_endpoint(
    110     ddf_fun_t *fun, usb_endpoint_t endpoint,
    111     usb_transfer_type_t transfer_type, usb_direction_t direction,
    112     size_t max_packet_size, unsigned packets, unsigned interval)
     91        ddf_fun_t *fun, usb_endpoint_desc_t *endpoint_desc)
    11392{
    11493        assert(fun);
    11594        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
    116         usb_dev_t *dev = ddf_fun_data_get(fun);
     95        device_t *dev = ddf_fun_data_get(fun);
    11796        assert(hcd);
     97        assert(hcd->bus);
    11898        assert(dev);
    119         const size_t size = max_packet_size;
    120         const usb_target_t target =
    121             {{.address = dev->address, .endpoint = endpoint}};
     99
     100        const size_t size = endpoint_desc->max_packet_size;
    122101
    123102        usb_log_debug("Register endpoint %d:%d %s-%s %zuB %ums.\n",
    124             dev->address, endpoint, usb_str_transfer_type(transfer_type),
    125             usb_str_direction(direction), max_packet_size, interval);
    126 
    127         return hcd_add_ep(hcd, target, direction, transfer_type,
    128             max_packet_size, packets, size, dev->tt_address, dev->port);
    129 }
    130 
    131 /** Unregister endpoint interface function.
    132  * @param fun DDF function.
    133  * @param address USB address of the endpoint.
    134  * @param endpoint USB endpoint number.
    135  * @param direction Communication direction of the enpdoint to unregister.
    136  * @return Error code.
    137  */
     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  */
    138119static int unregister_endpoint(
    139     ddf_fun_t *fun, usb_endpoint_t endpoint, usb_direction_t direction)
     120        ddf_fun_t *fun, usb_endpoint_desc_t *endpoint_desc)
    140121{
    141122        assert(fun);
    142123        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
    143         usb_dev_t *dev = ddf_fun_data_get(fun);
     124        device_t *dev = ddf_fun_data_get(fun);
    144125        assert(hcd);
     126        assert(hcd->bus);
    145127        assert(dev);
    146         const usb_target_t target =
    147             {{.address = dev->address, .endpoint = endpoint}};
     128
     129        const usb_target_t target = {{
     130                .address = dev->address,
     131                .endpoint = endpoint_desc->endpoint_no
     132        }};
     133
    148134        usb_log_debug("Unregister endpoint %d:%d %s.\n",
    149             dev->address, endpoint, usb_str_direction(direction));
    150         return hcd_remove_ep(hcd, target, direction);
     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);
    151138}
    152139
     
    155142        assert(fun);
    156143        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
    157         usb_dev_t *dev = ddf_fun_data_get(fun);
     144        device_t *dev = ddf_fun_data_get(fun);
    158145        assert(hcd);
     146        assert(hcd->bus);
    159147        assert(dev);
    160148
    161149        usb_log_debug("Device %d requested default address at %s speed\n",
    162150            dev->address, usb_str_speed(speed));
    163         return hcd_reserve_default_address(hcd, speed);
     151        return bus_reserve_default_address(hcd->bus, speed);
    164152}
    165153
     
    168156        assert(fun);
    169157        hcd_t *hcd = dev_to_hcd(ddf_fun_get_dev(fun));
    170         usb_dev_t *dev = ddf_fun_data_get(fun);
     158        device_t *dev = ddf_fun_data_get(fun);
    171159        assert(hcd);
     160        assert(hcd->bus);
    172161        assert(dev);
    173162
    174163        usb_log_debug("Device %d released default address\n", dev->address);
    175         return hcd_release_default_address(hcd);
     164        return bus_release_default_address(hcd->bus);
    176165}
    177166
    178167static 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
     182static int device_remove(ddf_fun_t *fun, unsigned port)
    179183{
    180184        assert(fun);
    181185        ddf_dev_t *ddf_dev = ddf_fun_get_dev(fun);
    182         usb_dev_t *dev = ddf_fun_data_get(fun);
    183         assert(ddf_dev);
    184         assert(dev);
    185         usb_log_debug("Hub %d reported a new USB device on port: %u\n",
    186             dev->address, port);
    187         return hcd_ddf_new_device(ddf_dev, dev, port);
    188 }
    189 
    190 static int device_remove(ddf_fun_t *fun, unsigned port)
    191 {
    192         assert(fun);
    193         ddf_dev_t *ddf_dev = ddf_fun_get_dev(fun);
    194         usb_dev_t *dev = ddf_fun_data_get(fun);
     186        device_t *dev = ddf_fun_data_get(fun);
    195187        assert(ddf_dev);
    196188        assert(dev);
     
    229221{
    230222        assert(fun);
    231         usb_dev_t *usb_dev = ddf_fun_data_get(fun);
    232         assert(usb_dev);
     223        device_t *dev = ddf_fun_data_get(fun);
     224        assert(dev);
    233225        const usb_target_t target = {{
    234             .address =  usb_dev->address,
     226            .address  = dev->address,
    235227            .endpoint = endpoint,
    236228        }};
     
    255247{
    256248        assert(fun);
    257         usb_dev_t *usb_dev = ddf_fun_data_get(fun);
    258         assert(usb_dev);
     249        device_t *dev = ddf_fun_data_get(fun);
     250        assert(dev);
    259251        const usb_target_t target = {{
    260             .address =  usb_dev->address,
     252            .address  = dev->address,
    261253            .endpoint = endpoint,
    262254        }};
     
    290282
    291283/* DDF HELPERS */
    292 
    293 #define GET_DEVICE_DESC(size) \
    294 { \
    295         .request_type = SETUP_REQUEST_TYPE_DEVICE_TO_HOST \
    296             | (USB_REQUEST_TYPE_STANDARD << 5) \
    297             | USB_REQUEST_RECIPIENT_DEVICE, \
    298         .request = USB_DEVREQ_GET_DESCRIPTOR, \
    299         .value = uint16_host2usb(USB_DESCTYPE_DEVICE << 8), \
    300         .index = uint16_host2usb(0), \
    301         .length = uint16_host2usb(size), \
    302 };
    303 
    304 #define SET_ADDRESS(address) \
    305 { \
    306         .request_type = SETUP_REQUEST_TYPE_HOST_TO_DEVICE \
    307             | (USB_REQUEST_TYPE_STANDARD << 5) \
    308             | USB_REQUEST_RECIPIENT_DEVICE, \
    309         .request = USB_DEVREQ_SET_ADDRESS, \
    310         .value = uint16_host2usb(address), \
    311         .index = uint16_host2usb(0), \
    312         .length = uint16_host2usb(0), \
    313 };
    314 
    315 static int hcd_ddf_add_device(ddf_dev_t *parent, usb_dev_t *hub_dev,
    316     unsigned port, usb_address_t address, usb_speed_t speed, const char *name,
    317     const match_id_list_t *mids)
    318 {
    319         assert(parent);
    320 
    321         char default_name[10] = { 0 }; /* usbxyz-ss */
    322         if (!name) {
    323                 snprintf(default_name, sizeof(default_name) - 1,
    324                     "usb%u-%cs", address, usb_str_speed(speed)[0]);
    325                 name = default_name;
    326         }
    327 
    328         ddf_fun_t *fun = ddf_fun_create(parent, fun_inner, name);
    329         if (!fun)
    330                 return ENOMEM;
    331         usb_dev_t *info = ddf_fun_data_alloc(fun, sizeof(usb_dev_t));
    332         if (!info) {
    333                 ddf_fun_destroy(fun);
    334                 return ENOMEM;
    335         }
    336         info->address = address;
    337         info->speed = speed;
    338         info->fun = fun;
    339         info->port = port;
    340         info->tt_address = hub_dev ? hub_dev->tt_address : -1;
    341         link_initialize(&info->link);
    342         list_initialize(&info->devices);
    343         fibril_mutex_initialize(&info->guard);
    344 
    345         if (hub_dev && hub_dev->speed == USB_SPEED_HIGH && usb_speed_is_11(speed))
    346                 info->tt_address = hub_dev->address;
    347 
    348         ddf_fun_set_ops(fun, &usb_ops);
    349         list_foreach(mids->ids, link, const match_id_t, mid) {
    350                 ddf_fun_add_match_id(fun, mid->id, mid->score);
    351         }
    352 
    353         int ret = ddf_fun_bind(fun);
    354         if (ret != EOK) {
    355                 ddf_fun_destroy(fun);
    356                 return ret;
    357         }
    358 
    359         if (hub_dev) {
    360                 fibril_mutex_lock(&hub_dev->guard);
    361                 list_append(&info->link, &hub_dev->devices);
    362                 fibril_mutex_unlock(&hub_dev->guard);
    363         } else {
    364                 hc_dev_t *hc_dev = dev_to_hc_dev(parent);
    365                 assert(hc_dev->root_hub == NULL);
    366                 hc_dev->root_hub = info;
    367         }
    368         return EOK;
    369 }
    370284
    371285#define ADD_MATCHID_OR_RETURN(list, sc, str, ...) \
     
    394308        assert(l);
    395309        assert(d);
    396        
     310
    397311        if (d->vendor_id != 0) {
    398312                /* First, with release number. */
     
    401315                    d->vendor_id, d->product_id, (d->device_version >> 8),
    402316                    (d->device_version & 0xff));
    403        
     317
    404318                /* Next, without release number. */
    405319                ADD_MATCHID_OR_RETURN(l, 90, "usb&vendor=%#04x&product=%#04x",
     
    415329
    416330        return EOK;
    417 
    418 }
    419 
    420 static int hcd_ddf_remove_device(ddf_dev_t *device, usb_dev_t *hub,
     331}
     332
     333static int hcd_ddf_remove_device(ddf_dev_t *device, device_t *hub,
    421334    unsigned port)
    422335{
     
    425338        hcd_t *hcd = dev_to_hcd(device);
    426339        assert(hcd);
     340        assert(hcd->bus);
    427341
    428342        hc_dev_t *hc_dev = dev_to_hc_dev(device);
     
    431345        fibril_mutex_lock(&hub->guard);
    432346
    433         usb_dev_t *victim = NULL;
    434 
    435         list_foreach(hub->devices, link, usb_dev_t, it) {
     347        device_t *victim = NULL;
     348
     349        list_foreach(hub->devices, link, device_t, it) {
    436350                if (it->port == port) {
    437351                        victim = it;
     
    440354        }
    441355        if (victim) {
     356                assert(victim->fun);
    442357                assert(victim->port == port);
     358                assert(victim->hub == hub);
    443359                list_remove(&victim->link);
    444360                fibril_mutex_unlock(&hub->guard);
     
    446362                if (ret == EOK) {
    447363                        usb_address_t address = victim->address;
     364                        bus_remove_device(hcd->bus, hcd, victim);
    448365                        ddf_fun_destroy(victim->fun);
    449                         hcd_release_address(hcd, address);
     366                        bus_release_address(hcd->bus, address);
    450367                } else {
    451368                        usb_log_warning("Failed to unbind device `%s': %s\n",
     
    458375}
    459376
    460 static int hcd_ddf_new_device(ddf_dev_t *device, usb_dev_t *hub, unsigned port)
    461 {
    462         assert(device);
    463 
    464         hcd_t *hcd = dev_to_hcd(device);
    465         assert(hcd);
    466 
    467         usb_speed_t speed = USB_SPEED_MAX;
    468 
    469         /* This checks whether the default address is reserved and gets speed */
    470         int ret = usb_bus_get_speed(&hcd->bus, USB_ADDRESS_DEFAULT, &speed);
    471         if (ret != EOK) {
    472                 usb_log_error("Failed to verify speed: %s.", str_error(ret));
    473                 return ret;
    474         }
    475 
    476         usb_log_debug("Found new %s speed USB device.", usb_str_speed(speed));
    477 
    478         static const usb_target_t default_target = {{
    479                 .address = USB_ADDRESS_DEFAULT,
    480                 .endpoint = 0,
     377device_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
     398void hcd_ddf_device_destroy(device_t *dev)
     399{
     400        assert(dev);
     401        assert(dev->fun);
     402        ddf_fun_destroy(dev->fun);
     403}
     404
     405int hcd_ddf_device_explore(hcd_t *hcd, device_t *device)
     406{
     407        int err;
     408        match_id_list_t mids;
     409        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
    481416        }};
    482 
    483         const usb_address_t address = hcd_request_address(hcd, speed);
    484         if (address < 0) {
    485                 usb_log_error("Failed to reserve new address: %s.",
    486                     str_error(address));
    487                 return address;
    488         }
    489 
    490         usb_log_debug("Reserved new address: %d\n", address);
    491 
    492         const usb_target_t target = {{
    493                 .address = address,
    494                 .endpoint = 0,
    495         }};
    496 
    497         const usb_address_t tt_address = hub ? hub->tt_address : -1;
    498 
    499         /* Add default pipe on default address */
    500         usb_log_debug("Device(%d): Adding default target(0:0)\n", address);
    501         ret = hcd_add_ep(hcd,
    502             default_target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL,
    503             CTRL_PIPE_MIN_PACKET_SIZE, CTRL_PIPE_MIN_PACKET_SIZE, 1,
    504             tt_address, port);
    505         if (ret != EOK) {
    506                 usb_log_error("Device(%d): Failed to add default target: %s.",
    507                     address, str_error(ret));
    508                 hcd_release_address(hcd, address);
    509                 return ret;
    510         }
    511 
    512         /* Get max packet size for default pipe */
    513         usb_standard_device_descriptor_t desc = { 0 };
    514         const usb_device_request_setup_packet_t get_device_desc_8 =
    515             GET_DEVICE_DESC(CTRL_PIPE_MIN_PACKET_SIZE);
    516 
    517         // TODO CALLBACKS
    518         usb_log_debug("Device(%d): Requesting first 8B of device descriptor.",
    519             address);
    520         ssize_t got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_IN,
    521             &desc, CTRL_PIPE_MIN_PACKET_SIZE, *(uint64_t *)&get_device_desc_8,
    522             "read first 8 bytes of dev descriptor");
    523 
    524         if (got != CTRL_PIPE_MIN_PACKET_SIZE) {
    525                 ret = got < 0 ? got : EOVERFLOW;
    526                 usb_log_error("Device(%d): Failed to get 8B of dev descr: %s.",
    527                     address, str_error(ret));
    528                 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH);
    529                 hcd_release_address(hcd, address);
    530                 return ret;
    531         }
    532 
    533         /* Register EP on the new address */
    534         usb_log_debug("Device(%d): Registering control EP.", address);
    535         ret = hcd_add_ep(hcd, target, USB_DIRECTION_BOTH, USB_TRANSFER_CONTROL,
    536             ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)),
    537             ED_MPS_TRANS_OPPORTUNITIES_GET(uint16_usb2host(desc.max_packet_size)),
    538             ED_MPS_PACKET_SIZE_GET(uint16_usb2host(desc.max_packet_size)),
    539             tt_address, port);
    540         if (ret != EOK) {
    541                 usb_log_error("Device(%d): Failed to register EP0: %s",
    542                     address, str_error(ret));
    543                 hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH);
    544                 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
    545                 hcd_release_address(hcd, address);
    546                 return ret;
    547         }
    548 
    549         /* Set new address */
    550         const usb_device_request_setup_packet_t set_address =
    551             SET_ADDRESS(target.address);
    552 
    553         usb_log_debug("Device(%d): Setting USB address.", address);
    554         got = hcd_send_batch_sync(hcd, default_target, USB_DIRECTION_OUT,
    555             NULL, 0, *(uint64_t *)&set_address, "set address");
    556 
    557         usb_log_debug("Device(%d): Removing default (0:0) EP.", address);
    558         hcd_remove_ep(hcd, default_target, USB_DIRECTION_BOTH);
    559 
    560         if (got != 0) {
    561                 usb_log_error("Device(%d): Failed to set new address: %s.",
    562                     address, str_error(got));
    563                 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
    564                 hcd_release_address(hcd, address);
    565                 return got;
    566         }
    567417
    568418        /* Get std device descriptor */
     
    571421
    572422        usb_log_debug("Device(%d): Requesting full device descriptor.",
    573             address);
    574         got = hcd_send_batch_sync(hcd, target, USB_DIRECTION_IN,
     423            device->address);
     424        ssize_t got = hcd_send_batch_sync(hcd, control_ep, USB_DIRECTION_IN,
    575425            &desc, sizeof(desc), *(uint64_t *)&get_device_desc,
    576426            "read device descriptor");
    577         if (ret != EOK) {
     427        if (got < 0) {
     428                err = got < 0 ? got : EOVERFLOW;
    578429                usb_log_error("Device(%d): Failed to set get dev descriptor: %s",
    579                     address, str_error(ret));
    580                 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
    581                 hcd_release_address(hcd, target.address);
    582                 return ret;
     430                    device->address, str_error(err));
     431                goto out;
    583432        }
    584433
    585434        /* Create match ids from the device descriptor */
    586         match_id_list_t mids;
    587         init_match_ids(&mids);
    588 
    589         usb_log_debug("Device(%d): Creating match IDs.", address);
    590         ret = create_match_ids(&mids, &desc);
    591         if (ret != EOK) {
    592                 usb_log_error("Device(%d): Failed to create match ids: %s",
    593                     address, str_error(ret));
    594                 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
    595                 hcd_release_address(hcd, target.address);
    596                 return ret;
    597         }
    598 
    599         /* Register device */
    600         usb_log_debug("Device(%d): Registering DDF device.", address);
    601         ret = hcd_ddf_add_device(device, hub, port, address, speed, NULL, &mids);
     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
     445out:
    602446        clean_match_ids(&mids);
    603         if (ret != EOK) {
    604                 usb_log_error("Device(%d): Failed to register: %s.",
    605                     address, str_error(ret));
    606                 hcd_remove_ep(hcd, target, USB_DIRECTION_BOTH);
    607                 hcd_release_address(hcd, target.address);
    608         }
    609 
    610         return ret;
     447        return err;
     448}
     449
     450static 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
     490err_usb_dev:
     491        hcd_ddf_device_destroy(dev);
     492        return err;
    611493}
    612494
     
    616498 * @return Error code
    617499 */
    618 int hcd_ddf_setup_root_hub(ddf_dev_t *device)
    619 {
    620         assert(device);
    621         hcd_t *hcd = dev_to_hcd(device);
     500int hcd_setup_virtual_root_hub(hcd_t *hcd, ddf_dev_t *hc)
     501{
     502        int err;
     503
     504        assert(hc);
    622505        assert(hcd);
    623 
    624         hcd_reserve_default_address(hcd, hcd->bus.max_speed);
    625         const int ret = hcd_ddf_new_device(device, NULL, 0);
    626         hcd_release_default_address(hcd);
    627         return ret;
     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
     540err_usb_dev:
     541        hcd_ddf_device_destroy(dev);
     542err_default_address:
     543        bus_release_default_address(hcd->bus);
     544        return err;
    628545}
    629546
     
    638555 * This function does all the ddf work for hc driver.
    639556 */
    640 int hcd_ddf_setup_hc(ddf_dev_t *device, usb_speed_t max_speed,
    641     size_t bw, bw_count_func_t bw_count)
     557int hcd_ddf_setup_hc(ddf_dev_t *device)
    642558{
    643559        assert(device);
     
    648564                return ENOMEM;
    649565        }
    650         instance->root_hub = NULL;
    651         hcd_init(&instance->hcd, max_speed, bw, bw_count);
     566        hcd_init(&instance->hcd);
    652567
    653568        int ret = ENOMEM;
     
    748663    const hw_res_list_parsed_t *hw_res,
    749664    interrupt_handler_t handler,
    750     int (*gen_irq_code)(irq_code_t *, const hw_res_list_parsed_t *hw_res))
    751 {
    752 
     665    irq_code_gen_t gen_irq_code)
     666{
    753667        assert(device);
     668
     669        hcd_t *hcd = dev_to_hcd(device);
     670
    754671        if (!handler || !gen_irq_code)
    755672                return ENOTSUP;
     
    757674        irq_code_t irq_code = {0};
    758675
    759         const int irq = gen_irq_code(&irq_code, hw_res);
     676        const int irq = gen_irq_code(&irq_code, hcd, hw_res);
    760677        if (irq < 0) {
    761678                usb_log_error("Failed to generate IRQ code: %s.\n",
     
    777694        int ret = hcd_ddf_enable_interrupt(device, irq);
    778695        if (ret != EOK) {
    779                 usb_log_error("Failed to register interrupt handler: %s.\n",
     696                usb_log_error("Failed to enable interrupts: %s.\n",
    780697                    str_error(ret));
    781698                unregister_interrupt_handler(device, irq_cap);
     
    844761{
    845762        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         };
    852763
    853764        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         }
    860765
    861766        hw_res_list_parsed_t hw_res;
     
    868773        }
    869774
    870         ret = hcd_ddf_setup_hc(device, speed, bw[speed].bw, bw[speed].bw_count);
     775        ret = hcd_ddf_setup_hc(device);
    871776        if (ret != EOK) {
    872777                usb_log_error("Failed to setup generic HCD.\n");
    873                 hw_res_list_parsed_clean(&hw_res);
    874                 return ret;
    875         }
    876 
     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, device);
     785        if (ret != EOK) {
     786                usb_log_error("Failed to init HCD.\n");
     787                goto err_hcd;
     788        }
     789
     790        /* Setup interrupts  */
    877791        interrupt_handler_t *irq_handler =
    878792            driver->irq_handler ? driver->irq_handler : ddf_hcd_gen_irq_handler;
     
    884798        }
    885799
     800        /* Claim the device from BIOS */
    886801        if (driver->claim)
    887                 ret = driver->claim(device);
     802                ret = driver->claim(hcd, device);
    888803        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);
     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);
    899812        if (ret != EOK) {
    900                 usb_log_error("Failed to init HCD: %s.\n", str_error(ret));
    901                 goto irq_unregister;
     813                usb_log_error("Failed to start HCD: %s.\n", str_error(ret));
     814                goto err_irq;
    902815        }
    903816
     
    908821                        usb_log_error("Failed to create polling fibril\n");
    909822                        ret = ENOMEM;
    910                         goto irq_unregister;
     823                        goto err_started;
    911824                }
    912825                fibril_add_ready(hcd->polling_fibril);
     
    919832         * needs to be ready at this time.
    920833         */
    921         ret = hcd_ddf_setup_root_hub(device);
     834        if (driver->setup_root_hub)
     835                ret = driver->setup_root_hub(hcd, device);
    922836        if (ret != EOK) {
    923837                usb_log_error("Failed to setup HC root hub: %s.\n",
    924838                    str_error(ret));
    925                 driver->fini(dev_to_hcd(device));
    926 irq_unregister:
    927                 /* Unregistering non-existent should be ok */
    928                 unregister_interrupt_handler(device, irq_cap);
    929                 hcd_ddf_clean_hc(device);
    930                 return ret;
     839                goto err_polling;
    931840        }
    932841
     
    934843            driver->name, ddf_dev_get_name(device));
    935844        return EOK;
    936 }
     845
     846err_polling:
     847        // TODO: Stop the polling fibril (refactor the interrupt_polling func)
     848        //
     849err_started:
     850        if (driver->stop)
     851                driver->stop(hcd);
     852err_irq:
     853        unregister_interrupt_handler(device, irq_cap);
     854        if (driver->fini)
     855                driver->fini(hcd);
     856err_hcd:
     857        hcd_ddf_clean_hc(device);
     858err_hw_res:
     859        hw_res_list_parsed_clean(&hw_res);
     860        return ret;
     861}
     862
    937863/**
    938864 * @}
  • uspace/lib/usbhost/src/endpoint.c

    r04efacc r03936831  
    11/*
    22 * Copyright (c) 2011 Jan Vesely
     3 * Copyright (c) 2017 Ondrej Hlavaty <aearsis@eideo.cz>
    34 * All rights reserved.
    45 *
     
    3536
    3637#include <usb/host/endpoint.h>
     38#include <usb/host/bus.h>
    3739
    3840#include <assert.h>
     41#include <atomic.h>
     42#include <mem.h>
    3943#include <stdlib.h>
    40 #include <atomic.h>
    4144
    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.
     45/** Initialize provided endpoint structure.
    5146 */
    52 endpoint_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)
     47void endpoint_init(endpoint_t *ep, bus_t *bus)
    5648{
    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;
     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);
    8056}
    8157
    82 /** Properly dispose of endpoint_t structure.
    83  * @param instance endpoint_t structure.
    84  */
    85 void endpoint_destroy(endpoint_t *instance)
     58void endpoint_add_ref(endpoint_t *ep)
    8659{
    87         assert(instance);
    88         assert(!instance->active);
    89         assert(instance->hc_data.data == NULL);
    90         free(instance);
     60        atomic_inc(&ep->refcnt);
    9161}
    9262
    93 void endpoint_add_ref(endpoint_t *instance)
     63void endpoint_del_ref(endpoint_t *ep)
    9464{
    95         atomic_inc(&instance->refcnt);
    96 }
     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);
    9771
    98 void 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  */
    110 void 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  */
    125 void endpoint_clear_hc_data(endpoint_t *instance)
    126 {
    127         assert(instance);
    128         endpoint_set_hc_data(instance, NULL, NULL, NULL);
     72                        /* Assume mostly the eps will be allocated by malloc. */
     73                        free(ep);
     74                }
     75        }
    12976}
    13077
    13178/** Mark the endpoint as active and block access for further fibrils.
    132  * @param instance endpoint_t structure.
     79 * @param ep endpoint_t structure.
    13380 */
    134 void endpoint_use(endpoint_t *instance)
     81void endpoint_use(endpoint_t *ep)
    13582{
    136         assert(instance);
     83        assert(ep);
    13784        /* Add reference for active endpoint. */
    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);
     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);
    14491}
    14592
    14693/** Mark the endpoint as inactive and allow access for further fibrils.
    147  * @param instance endpoint_t structure.
     94 * @param ep endpoint_t structure.
    14895 */
    149 void endpoint_release(endpoint_t *instance)
     96void endpoint_release(endpoint_t *ep)
    15097{
    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);
     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);
    156103        /* Drop reference for active endpoint. */
    157         endpoint_del_ref(instance);
     104        endpoint_del_ref(ep);
    158105}
    159106
    160 /** Get the value of toggle bit.
    161  * @param instance endpoint_t structure.
    162  * @note Will use provided hook.
     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.
    163110 */
    164 int endpoint_toggle_get(endpoint_t *instance)
     111int endpoint_toggle_get(endpoint_t *ep)
    165112{
    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);
     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);
    173119        return ret;
    174120}
    175121
    176 /** Set the value of toggle bit.
    177  * @param instance endpoint_t structure.
    178  * @note Will use provided hook.
     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.
    179125 */
    180 void endpoint_toggle_set(endpoint_t *instance, int toggle)
     126void endpoint_toggle_set(endpoint_t *ep, unsigned toggle)
    181127{
    182         assert(instance);
     128        assert(ep);
    183129        assert(toggle == 0 || toggle == 1);
    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);
     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);
    189138}
     139
    190140
    191141/**
  • uspace/lib/usbhost/src/hcd.c

    r04efacc r03936831  
    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  */
    51 static 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  */
    65 static 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  *    */
    78 static 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 
    8646
    8747/** Initialize hcd_t structure.
     
    9353 * @param bw_count Bandwidth compute function, passed to endpoint manager.
    9454 */
    95 void 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);
     55void hcd_init(hcd_t *hcd) {
     56        assert(hcd);
     57
     58        hcd_set_implementation(hcd, NULL, NULL, NULL);
    10259}
    10360
     
    10663        assert(hcd);
    10764        usb_address_t address = 0;
    108         const int ret = usb_bus_request_address(
    109             &hcd->bus, &address, false, speed);
     65        const int ret = bus_request_address(hcd->bus, &address, false, speed);
    11066        if (ret != EOK)
    11167                return ret;
    11268        return address;
    11369}
    114 
    115 int 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 
    122 int 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 
    129 int 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 
    139 int 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 
    14670
    14771typedef struct {
     
    15983                usb_log_debug2("Reseting toggle on %d:%d.\n",
    16084                    toggle->target.address, toggle->target.endpoint);
    161                 usb_bus_reset_toggle(&toggle->hcd->bus,
     85                bus_reset_toggle(toggle->hcd->bus,
    16286                    toggle->target, toggle->target.endpoint == 0);
    16387        }
     
    185109        assert(hcd);
    186110
    187         endpoint_t *ep = usb_bus_find_ep(&hcd->bus,
    188             target.address, target.endpoint, direction);
     111        endpoint_t *ep = bus_find_endpoint(hcd->bus, target, direction);
    189112        if (ep == NULL) {
    190113                usb_log_error("Endpoint(%d:%d) not registered for %s.\n",
     
    196119            name, target.address, target.endpoint, size, ep->max_packet_size);
    197120
    198         const size_t bw = bandwidth_count_usb11(
    199             ep->speed, ep->transfer_type, size, ep->max_packet_size);
     121        const size_t bw = bus_count_bw(ep, size);
    200122        /* Check if we have enough bandwidth reserved */
    201123        if (ep->bandwidth < bw) {
    202124                usb_log_error("Endpoint(%d:%d) %s needs %zu bw "
    203125                    "but only %zu is reserved.\n",
    204                     ep->address, ep->endpoint, name, bw, ep->bandwidth);
     126                    ep->target.address, ep->target.endpoint, name, bw, ep->bandwidth);
    205127                return ENOSPC;
    206128        }
     
    248170
    249171typedef struct {
    250         volatile unsigned done;
     172        fibril_mutex_t done_mtx;
     173        fibril_condvar_t done_cv;
     174        unsigned done;
    251175        int ret;
    252176        size_t size;
     
    258182        assert(d);
    259183        d->ret = ret;
     184        d->size = size;
     185        fibril_mutex_lock(&d->done_mtx);
    260186        d->done = 1;
    261         d->size = size;
     187        fibril_condvar_broadcast(&d->done_cv);
     188        fibril_mutex_unlock(&d->done_mtx);
    262189}
    263190
     
    267194        assert(data);
    268195        d->ret = ret;
     196        fibril_mutex_lock(&d->done_mtx);
    269197        d->done = 1;
     198        fibril_condvar_broadcast(&d->done_cv);
     199        fibril_mutex_unlock(&d->done_mtx);
    270200}
    271201
     
    277207        assert(hcd);
    278208        sync_data_t sd = { .done = 0, .ret = EBUSY, .size = size };
     209        fibril_mutex_initialize(&sd.done_mtx);
     210        fibril_condvar_initialize(&sd.done_cv);
    279211
    280212        const int ret = hcd_send_batch(hcd, target, dir, data, size, setup_data,
     
    284216                return ret;
    285217
    286         while (!sd.done) {
    287                 async_usleep(1000);
    288         }
     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);
    289222
    290223        if (sd.ret == EOK)
Note: See TracChangeset for help on using the changeset viewer.