Changeset 32fb6bce in mainline for uspace/drv


Ignore:
Timestamp:
2017-12-18T22:50:21Z (8 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
7f70d1c
Parents:
1ea0bbf
git-author:
Ondřej Hlavatý <aearsis@…> (2017-12-18 22:04:50)
git-committer:
Ondřej Hlavatý <aearsis@…> (2017-12-18 22:50:21)
Message:

usbhost: refactoring

This commit moves interrupt, status and schedule to bus
operations. Then the purpose of hcd_t is better defined, and split into
hc_driver_t and hc_device_t. hc_driver_t is used to wrap driver
implementation by the library (similar to how usb_driver_t is used to
wrap usb device drivers). hc_device_t is used as a parent for hc_t
inside drivers, and is allocated inside the DDF device node.

To support these changes, some local identifiers were renamed, some
functions were moved and/or renamed and their arguments changed. The
most notable one being hcd_send_batch → bus_device_send_batch.

Location:
uspace/drv/bus/usb
Files:
23 edited

Legend:

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

    r1ea0bbf r32fb6bce  
    162162        .parent = &usb2_bus_ops,
    163163
     164        .interrupt = ehci_hc_interrupt,
     165        .status = ehci_hc_status,
    164166        .endpoint_destroy = ehci_endpoint_destroy,
    165167        .endpoint_create = ehci_endpoint_create,
     
    171173        .batch_create = ehci_create_batch,
    172174        .batch_destroy = ehci_destroy_batch,
     175        .batch_schedule = ehci_hc_schedule,
    173176};
    174177
    175 int ehci_bus_init(ehci_bus_t *bus, hcd_t *hcd, hc_t *hc)
     178int ehci_bus_init(ehci_bus_t *bus, hc_t *hc)
    176179{
    177180        assert(hc);
     
    181184        bus_t *bus_base = (bus_t *) bus;
    182185
    183         usb2_bus_init(usb2_bus, hcd, BANDWIDTH_AVAILABLE_USB11);
     186        usb2_bus_init(usb2_bus, BANDWIDTH_AVAILABLE_USB11);
    184187        bus_base->ops = &ehci_bus_ops;
    185188
  • uspace/drv/bus/usb/ehci/ehci_bus.h

    r1ea0bbf r32fb6bce  
    6363void ehci_bus_prepare_ops(void);
    6464
    65 int ehci_bus_init(ehci_bus_t *, hcd_t *, hc_t *);
     65int ehci_bus_init(ehci_bus_t *, hc_t *);
    6666
    6767/** Get and convert assigned ehci_endpoint_t structure
    6868 * @param[in] ep USBD endpoint structure.
    69  * @return Pointer to assigned hcd endpoint structure
     69 * @return Pointer to assigned ehci endpoint structure
    7070 */
    7171static inline ehci_endpoint_t * ehci_endpoint_get(const endpoint_t *ep)
  • uspace/drv/bus/usb/ehci/hc.c

    r1ea0bbf r32fb6bce  
    9797 * @return Error code.
    9898 */
    99 int ehci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)
     99int hc_gen_irq_code(irq_code_t *code, hc_device_t *hcd, const hw_res_list_parsed_t *hw_res)
    100100{
    101101        assert(code);
    102102        assert(hw_res);
    103 
    104         hc_t *instance = hcd_get_driver_data(hcd);
     103        hc_t *instance = hcd_to_hc(hcd);
    105104
    106105        if (hw_res->irqs.count != 1 || hw_res->mem_ranges.count != 1)
     
    149148 * @return Error code
    150149 */
    151 int hc_init(hc_t *instance, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)
    152 {
    153         assert(instance);
     150int hc_add(hc_device_t *hcd, const hw_res_list_parsed_t *hw_res)
     151{
     152        hc_t *instance = hcd_to_hc(hcd);
    154153        assert(hw_res);
    155154        if (hw_res->mem_ranges.count != 1 ||
     
    190189            &instance->rh, instance->caps, instance->registers, "ehci rh");
    191190
    192         ehci_bus_init(&instance->bus, hcd, instance);
     191        ehci_bus_init(&instance->bus, instance);
     192        hc_device_setup(hcd, (bus_t *) &instance->bus);
    193193        return EOK;
    194194}
     
    198198 * @param[in] instance Host controller structure to use.
    199199 */
    200 void hc_fini(hc_t *instance)
     200int hc_gone(hc_device_t *instance)
    201201{
    202202        assert(instance);
     203        return EOK;
    203204        //TODO: stop the hw
    204205#if 0
     
    263264}
    264265
    265 int ehci_hc_status(hcd_t *hcd, uint32_t *status)
    266 {
    267         assert(hcd);
    268         hc_t *instance = hcd_get_driver_data(hcd);
    269         assert(instance);
     266int ehci_hc_status(bus_t *bus_base, uint32_t *status)
     267{
     268        assert(bus_base);
    270269        assert(status);
     270
     271        ehci_bus_t *bus = (ehci_bus_t *) bus_base;
     272        hc_t *hc = bus->hc;
     273        assert(hc);
     274
    271275        *status = 0;
    272         if (instance->registers) {
    273                 *status = EHCI_RD(instance->registers->usbsts);
    274                 EHCI_WR(instance->registers->usbsts, *status);
    275         }
    276         usb_log_debug2("HC(%p): Read status: %x", instance, *status);
     276        if (hc->registers) {
     277                *status = EHCI_RD(hc->registers->usbsts);
     278                EHCI_WR(hc->registers->usbsts, *status);
     279        }
     280        usb_log_debug2("HC(%p): Read status: %x", hc, *status);
    277281        return EOK;
    278282}
     
    284288 * @return Error code.
    285289 */
    286 int ehci_hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
    287 {
    288         assert(hcd);
    289         hc_t *instance = hcd_get_driver_data(hcd);
    290         assert(instance);
     290int ehci_hc_schedule(usb_transfer_batch_t *batch)
     291{
     292        assert(batch);
     293
     294        ehci_bus_t *bus = (ehci_bus_t *) endpoint_get_bus(batch->ep);
     295        hc_t *hc = bus->hc;
     296        assert(hc);
    291297
    292298        /* Check for root hub communication */
    293         if (batch->target.address == ehci_rh_get_address(&instance->rh)) {
     299        if (batch->target.address == ehci_rh_get_address(&hc->rh)) {
    294300                usb_log_debug("HC(%p): Scheduling BATCH(%p) for RH(%p)",
    295                     instance, batch, &instance->rh);
    296                 return ehci_rh_schedule(&instance->rh, batch);
     301                    hc, batch, &hc->rh);
     302                return ehci_rh_schedule(&hc->rh, batch);
    297303        }
    298304
     
    303309                return err;
    304310
    305         fibril_mutex_lock(&instance->guard);
    306         usb_log_debug2("HC(%p): Appending BATCH(%p)", instance, batch);
    307         list_append(&ehci_batch->link, &instance->pending_batches);
    308         usb_log_debug("HC(%p): Committing BATCH(%p)", instance, batch);
     311        fibril_mutex_lock(&hc->guard);
     312        usb_log_debug2("HC(%p): Appending BATCH(%p)", hc, batch);
     313        list_append(&ehci_batch->link, &hc->pending_batches);
     314        usb_log_debug("HC(%p): Committing BATCH(%p)", hc, batch);
    309315        ehci_transfer_batch_commit(ehci_batch);
    310316
    311         fibril_mutex_unlock(&instance->guard);
     317        fibril_mutex_unlock(&hc->guard);
    312318        return EOK;
    313319}
     
    318324 * @param[in] status Value of the status register at the time of interrupt.
    319325 */
    320 void ehci_hc_interrupt(hcd_t *hcd, uint32_t status)
    321 {
    322         assert(hcd);
    323         hc_t *instance = hcd_get_driver_data(hcd);
    324         status = EHCI_RD(status);
    325         assert(instance);
    326 
    327         usb_log_debug2("HC(%p): Interrupt: %"PRIx32, instance, status);
     326void ehci_hc_interrupt(bus_t *bus_base, uint32_t status)
     327{
     328        assert(bus_base);
     329
     330        ehci_bus_t *bus = (ehci_bus_t *) bus_base;
     331        hc_t *hc = bus->hc;
     332        assert(hc);
     333
     334        usb_log_debug2("HC(%p): Interrupt: %"PRIx32, hc, status);
    328335        if (status & USB_STS_PORT_CHANGE_FLAG) {
    329                 ehci_rh_interrupt(&instance->rh);
     336                ehci_rh_interrupt(&hc->rh);
    330337        }
    331338
    332339        if (status & USB_STS_IRQ_ASYNC_ADVANCE_FLAG) {
    333                 fibril_mutex_lock(&instance->guard);
    334                 usb_log_debug2("HC(%p): Signaling doorbell", instance);
    335                 fibril_condvar_broadcast(&instance->async_doorbell);
    336                 fibril_mutex_unlock(&instance->guard);
     340                fibril_mutex_lock(&hc->guard);
     341                usb_log_debug2("HC(%p): Signaling doorbell", hc);
     342                fibril_condvar_broadcast(&hc->async_doorbell);
     343                fibril_mutex_unlock(&hc->guard);
    337344        }
    338345
    339346        if (status & (USB_STS_IRQ_FLAG | USB_STS_ERR_IRQ_FLAG)) {
    340                 fibril_mutex_lock(&instance->guard);
    341 
    342                 usb_log_debug2("HC(%p): Scanning %lu pending batches", instance,
    343                         list_count(&instance->pending_batches));
    344                 list_foreach_safe(instance->pending_batches, current, next) {
     347                fibril_mutex_lock(&hc->guard);
     348
     349                usb_log_debug2("HC(%p): Scanning %lu pending batches", hc,
     350                        list_count(&hc->pending_batches));
     351                list_foreach_safe(hc->pending_batches, current, next) {
    345352                        ehci_transfer_batch_t *batch =
    346353                            ehci_transfer_batch_from_link(current);
     
    351358                        }
    352359                }
    353                 fibril_mutex_unlock(&instance->guard);
     360                fibril_mutex_unlock(&hc->guard);
    354361        }
    355362
    356363        if (status & USB_STS_HOST_ERROR_FLAG) {
    357                 usb_log_fatal("HCD(%p): HOST SYSTEM ERROR!", instance);
     364                usb_log_fatal("HCD(%p): HOST SYSTEM ERROR!", hc);
    358365                //TODO do something here
    359366        }
     
    364371 * @param[in] instance EHCI hc driver structure.
    365372 */
    366 int hc_start(hc_t *instance, bool interrupts)
    367 {
    368         assert(instance);
     373int hc_start(hc_device_t *hcd)
     374{
     375        hc_t *instance = hcd_to_hc(hcd);
    369376        usb_log_debug("HC(%p): Starting HW.", instance);
    370377
  • uspace/drv/bus/usb/ehci/hc.h

    r1ea0bbf r32fb6bce  
    5555/** Main EHCI driver structure */
    5656typedef struct hc {
     57        /* Common device header */
     58        hc_device_t base;
     59
    5760        /** Memory mapped CAPS register area */
    5861        ehci_caps_regs_t *caps;
     
    8588} hc_t;
    8689
    87 int hc_init(hc_t *instance, hcd_t *hcd, const hw_res_list_parsed_t *hw_res);
    88 int hc_start(hc_t *instance, bool interrupts);
    89 void hc_fini(hc_t *instance);
     90static inline hc_t *hcd_to_hc(hc_device_t *hcd)
     91{
     92        assert(hcd);
     93        return (hc_t *) hcd;
     94}
    9095
    91 void hc_enqueue_endpoint(hc_t *instance, const endpoint_t *ep);
    92 void hc_dequeue_endpoint(hc_t *instance, const endpoint_t *ep);
     96void hc_enqueue_endpoint(hc_t *, const endpoint_t *);
     97void hc_dequeue_endpoint(hc_t *, const endpoint_t *);
    9398
    94 int ehci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res);
     99/* Boottime operations */
     100int hc_add(hc_device_t *, const hw_res_list_parsed_t *);
     101int hc_start(hc_device_t *);
     102int hc_gen_irq_code(irq_code_t *, hc_device_t *, const hw_res_list_parsed_t *);
     103int hc_gone(hc_device_t *);
    95104
    96 void ehci_hc_interrupt(hcd_t *hcd, uint32_t status);
    97 int ehci_hc_status(hcd_t *hcd, uint32_t *status);
    98 int ehci_hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
     105/** Runtime operations */
     106void ehci_hc_interrupt(bus_t *, uint32_t);
     107int ehci_hc_status(bus_t *, uint32_t *);
     108int ehci_hc_schedule(usb_transfer_batch_t *);
     109
    99110#endif
    100111/**
  • uspace/drv/bus/usb/ehci/main.c

    r1ea0bbf r32fb6bce  
    3535 */
    3636
    37 #include <ddf/driver.h>
    38 #include <ddf/interrupt.h>
    39 #include <device/hw_res.h>
    40 #include <errno.h>
    41 #include <str_error.h>
    4237#include <io/logctl.h>
    43 
    44 #include <usb_iface.h>
    45 #include <usb/debug.h>
     38#include <usb/host/hcd.h>
    4639#include <usb/host/ddf_helpers.h>
    4740
     
    5144#define NAME "ehci"
    5245
    53 static int ehci_driver_init(hcd_t *, const hw_res_list_parsed_t *, ddf_dev_t *);
    54 static int ehci_driver_claim(hcd_t *, ddf_dev_t *);
    55 static int ehci_driver_start(hcd_t *, bool);
    56 static void ehci_driver_fini(hcd_t *);
     46static const hc_driver_t ehci_driver = {
     47        .name = NAME,
     48        .hc_device_size = sizeof(hc_t),
    5749
    58 static const ddf_hc_driver_t ehci_hc_driver = {
    59         .name = "EHCI-PCI",
    60         .init = ehci_driver_init,
    61         .irq_code_gen = ehci_hc_gen_irq_code,
    62         .claim = ehci_driver_claim,
    63         .start = ehci_driver_start,
     50        .hc_add = hc_add,
     51        .irq_code_gen = hc_gen_irq_code,
     52        .claim = disable_legacy,
     53        .start = hc_start,
    6454        .setup_root_hub = hcd_setup_virtual_root_hub,
    65         .fini = ehci_driver_fini,
    66         .ops = {
    67                 .schedule       = ehci_hc_schedule,
    68                 .irq_hook       = ehci_hc_interrupt,
    69                 .status_hook    = ehci_hc_status,
    70         }
     55        .hc_gone = hc_gone,
    7156};
    72 
    73 
    74 static int ehci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, ddf_dev_t *device)
    75 {
    76         assert(hcd);
    77         assert(hcd_get_driver_data(hcd) == NULL);
    78 
    79         hc_t *instance = malloc(sizeof(hc_t));
    80         if (!instance)
    81                 return ENOMEM;
    82 
    83         const int ret = hc_init(instance, hcd, res);
    84         if (ret == EOK) {
    85                 hcd_set_implementation(hcd, instance, &ehci_hc_driver.ops, &instance->bus.base.base);
    86         } else {
    87                 free(instance);
    88         }
    89         return ret;
    90 }
    91 
    92 static int ehci_driver_claim(hcd_t *hcd, ddf_dev_t *dev)
    93 {
    94         hc_t *instance = hcd_get_driver_data(hcd);
    95         assert(instance);
    96 
    97         return disable_legacy(instance, dev);
    98 }
    99 
    100 static int ehci_driver_start(hcd_t *hcd, bool irq) {
    101         hc_t *instance = hcd_get_driver_data(hcd);
    102         assert(instance);
    103 
    104         return hc_start(instance, irq);
    105 }
    106 
    107 static void ehci_driver_fini(hcd_t *hcd)
    108 {
    109         assert(hcd);
    110         hc_t *hc = hcd_get_driver_data(hcd);
    111         if (hc)
    112                 hc_fini(hc);
    113 
    114         free(hc);
    115         hcd_set_implementation(hcd, NULL, NULL, NULL);
    116 }
    117 
    118 /** Initializes a new ddf driver instance of EHCI hcd.
    119  *
    120  * @param[in] device DDF instance of the device to initialize.
    121  * @return Error code.
    122  */
    123 static int ehci_dev_add(ddf_dev_t *device)
    124 {
    125         usb_log_debug("ehci_dev_add() called\n");
    126         assert(device);
    127 
    128         return hcd_ddf_add_hc(device, &ehci_hc_driver);
    129 
    130 }
    131 
    132 static int ehci_fun_online(ddf_fun_t *fun)
    133 {
    134         return hcd_ddf_device_online(fun);
    135 }
    136 
    137 static int ehci_fun_offline(ddf_fun_t *fun)
    138 {
    139         return hcd_ddf_device_offline(fun);
    140 }
    141 
    142 
    143 static const driver_ops_t ehci_driver_ops = {
    144         .dev_add = ehci_dev_add,
    145         .fun_online = ehci_fun_online,
    146         .fun_offline = ehci_fun_offline
    147 };
    148 
    149 static const driver_t ehci_driver = {
    150         .name = NAME,
    151         .driver_ops = &ehci_driver_ops
    152 };
    153 
    15457
    15558/** Initializes global driver structures (NONE).
     
    16568        log_init(NAME);
    16669        logctl_set_log_level(NAME, LVL_NOTE);
    167         return ddf_driver_main(&ehci_driver);
     70        return hc_driver_main(&ehci_driver);
    16871}
    16972
  • uspace/drv/bus/usb/ehci/res.c

    r1ea0bbf r32fb6bce  
    4545#include <pci_dev_iface.h>
    4646
     47#include "hc.h"
    4748#include "res.h"
    4849#include "ehci_regs.h"
     
    172173}
    173174
    174 int disable_legacy(hc_t *hc, ddf_dev_t *device)
     175int disable_legacy(hc_device_t *hcd)
    175176{
    176         assert(device);
    177 
    178         async_sess_t *parent_sess = ddf_dev_parent_sess_get(device);
     177        hc_t *hc = hcd_to_hc(hcd);
     178
     179        async_sess_t *parent_sess = ddf_dev_parent_sess_get(hcd->ddf_dev);
    179180        if (parent_sess == NULL)
    180181                return ENOMEM;
  • uspace/drv/bus/usb/ehci/res.h

    r1ea0bbf r32fb6bce  
    3636#define DRV_EHCI_PCI_H
    3737
    38 #include <ddf/driver.h>
    39 #include <device/hw_res_parsed.h>
     38typedef struct hc_device hc_device_t;
    4039
    41 #include "hc.h"
    42 
    43 extern int disable_legacy(hc_t *, ddf_dev_t *);
     40extern int disable_legacy(hc_device_t *);
    4441
    4542#endif
  • uspace/drv/bus/usb/ohci/hc.c

    r1ea0bbf r32fb6bce  
    101101 * @return Error code.
    102102 */
    103 int ohci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)
     103int hc_gen_irq_code(irq_code_t *code, hc_device_t *hcd, const hw_res_list_parsed_t *hw_res)
    104104{
    105105        assert(code);
     
    149149 * @return Error code
    150150 */
    151 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res)
    152 {
    153         assert(instance);
     151int hc_add(hc_device_t *hcd, const hw_res_list_parsed_t *hw_res)
     152{
     153        hc_t *instance = hcd_to_hc(hcd);
    154154        assert(hw_res);
    155155        if (hw_res->mem_ranges.count != 1 ||
     
    186186 * @param[in] instance Host controller structure to use.
    187187 */
    188 void hc_fini(hc_t *instance)
     188int hc_gone(hc_device_t *instance)
    189189{
    190190        assert(instance);
    191191        /* TODO: implement*/
    192 };
     192        return ENOTSUP;
     193}
    193194
    194195void hc_enqueue_endpoint(hc_t *instance, const endpoint_t *ep)
     
    260261}
    261262
    262 int ohci_hc_status(hcd_t *hcd, uint32_t *status)
    263 {
    264         assert(hcd);
     263int ohci_hc_status(bus_t *bus_base, uint32_t *status)
     264{
     265        assert(bus_base);
    265266        assert(status);
    266         hc_t *instance = hcd_get_driver_data(hcd);
    267         assert(instance);
    268 
    269         if (instance->registers){
    270                 *status = OHCI_RD(instance->registers->interrupt_status);
    271                 OHCI_WR(instance->registers->interrupt_status, *status);
     267
     268        ohci_bus_t *bus = (ohci_bus_t *) bus_base;
     269        hc_t *hc = bus->hc;
     270        assert(hc);
     271
     272        if (hc->registers){
     273                *status = OHCI_RD(hc->registers->interrupt_status);
     274                OHCI_WR(hc->registers->interrupt_status, *status);
    272275        }
    273276        return EOK;
     
    280283 * @return Error code.
    281284 */
    282 int ohci_hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
    283 {
    284         assert(hcd);
    285         hc_t *instance = hcd_get_driver_data(hcd);
    286         assert(instance);
     285int ohci_hc_schedule(usb_transfer_batch_t *batch)
     286{
     287        assert(batch);
     288
     289        ohci_bus_t *bus = (ohci_bus_t *) endpoint_get_bus(batch->ep);
     290        hc_t *hc = bus->hc;
     291        assert(hc);
    287292
    288293        /* Check for root hub communication */
    289         if (batch->target.address == ohci_rh_get_address(&instance->rh)) {
     294        if (batch->target.address == ohci_rh_get_address(&hc->rh)) {
    290295                usb_log_debug("OHCI root hub request.\n");
    291                 return ohci_rh_schedule(&instance->rh, batch);
     296                return ohci_rh_schedule(&hc->rh, batch);
    292297        }
    293298        ohci_transfer_batch_t *ohci_batch = ohci_transfer_batch_get(batch);
     
    299304                return err;
    300305
    301         fibril_mutex_lock(&instance->guard);
    302         list_append(&ohci_batch->link, &instance->pending_batches);
     306        fibril_mutex_lock(&hc->guard);
     307        list_append(&ohci_batch->link, &hc->pending_batches);
    303308        ohci_transfer_batch_commit(ohci_batch);
    304309
     
    307312        {
    308313        case USB_TRANSFER_CONTROL:
    309                 OHCI_SET(instance->registers->command_status, CS_CLF);
     314                OHCI_SET(hc->registers->command_status, CS_CLF);
    310315                break;
    311316        case USB_TRANSFER_BULK:
    312                 OHCI_SET(instance->registers->command_status, CS_BLF);
     317                OHCI_SET(hc->registers->command_status, CS_BLF);
    313318                break;
    314319        default:
    315320                break;
    316321        }
    317         fibril_mutex_unlock(&instance->guard);
     322        fibril_mutex_unlock(&hc->guard);
    318323        return EOK;
    319324}
     
    324329 * @param[in] status Value of the status register at the time of interrupt.
    325330 */
    326 void ohci_hc_interrupt(hcd_t *hcd, uint32_t status)
    327 {
    328         assert(hcd);
    329         hc_t *instance = hcd_get_driver_data(hcd);
     331void ohci_hc_interrupt(bus_t *bus_base, uint32_t status)
     332{
     333        assert(bus_base);
     334
     335        ohci_bus_t *bus = (ohci_bus_t *) bus_base;
     336        hc_t *hc = bus->hc;
     337        assert(hc);
     338
    330339        status = OHCI_RD(status);
    331         assert(instance);
     340        assert(hc);
    332341        if ((status & ~I_SF) == 0) /* ignore sof status */
    333342                return;
    334         usb_log_debug2("OHCI(%p) interrupt: %x.\n", instance, status);
     343        usb_log_debug2("OHCI(%p) interrupt: %x.\n", hc, status);
    335344        if (status & I_RHSC)
    336                 ohci_rh_interrupt(&instance->rh);
     345                ohci_rh_interrupt(&hc->rh);
    337346
    338347        if (status & I_WDH) {
    339                 fibril_mutex_lock(&instance->guard);
    340                 usb_log_debug2("HCCA: %p-%#" PRIx32 " (%p).\n", instance->hcca,
    341                     OHCI_RD(instance->registers->hcca),
    342                     (void *) addr_to_phys(instance->hcca));
     348                fibril_mutex_lock(&hc->guard);
     349                usb_log_debug2("HCCA: %p-%#" PRIx32 " (%p).\n", hc->hcca,
     350                    OHCI_RD(hc->registers->hcca),
     351                    (void *) addr_to_phys(hc->hcca));
    343352                usb_log_debug2("Periodic current: %#" PRIx32 ".\n",
    344                     OHCI_RD(instance->registers->periodic_current));
    345 
    346                 link_t *current = list_first(&instance->pending_batches);
    347                 while (current && current != &instance->pending_batches.head) {
     353                    OHCI_RD(hc->registers->periodic_current));
     354
     355                link_t *current = list_first(&hc->pending_batches);
     356                while (current && current != &hc->pending_batches.head) {
    348357                        link_t *next = current->next;
    349358                        ohci_transfer_batch_t *batch =
     
    357366                        current = next;
    358367                }
    359                 fibril_mutex_unlock(&instance->guard);
     368                fibril_mutex_unlock(&hc->guard);
    360369        }
    361370
    362371        if (status & I_UE) {
    363372                usb_log_fatal("Error like no other!\n");
    364                 hc_start(instance);
     373                hc_start(&hc->base);
    365374        }
    366375
     
    374383 * @param[in] instance OHCI hc driver structure.
    375384 */
    376 void hc_gain_control(hc_t *instance)
    377 {
    378         assert(instance);
     385int hc_gain_control(hc_device_t *hcd)
     386{
     387        hc_t *instance = hcd_to_hc(hcd);
    379388
    380389        usb_log_debug("Requesting OHCI control.\n");
     
    409418                C_HCFS_SET(instance->registers->control, C_HCFS_RESET);
    410419                async_usleep(50000);
    411                 return;
     420                return EOK;
    412421        }
    413422
     
    418427                if (hc_status == C_HCFS_OPERATIONAL) {
    419428                        usb_log_info("BIOS driver: HC operational.\n");
    420                         return;
     429                        return EOK;
    421430                }
    422431                /* HC is suspended assert resume for 20ms */
     
    424433                async_usleep(20000);
    425434                usb_log_info("BIOS driver: HC resumed.\n");
    426                 return;
     435                return EOK;
    427436        }
    428437
     
    431440        usb_log_debug("Host controller found in reset state.\n");
    432441        async_usleep(50000);
     442        return EOK;
    433443}
    434444
     
    437447 * @param[in] instance OHCI hc driver structure.
    438448 */
    439 void hc_start(hc_t *instance)
    440 {
     449int hc_start(hc_device_t *hcd)
     450{
     451        hc_t *instance = hcd_to_hc(hcd);
    441452        ohci_rh_init(&instance->rh, instance->registers, "ohci rh");
    442453
     
    489500
    490501        /* Enable interrupts */
    491         if (instance->hw_interrupts) {
     502        if (instance->base.irq_cap >= 0) {
    492503                OHCI_WR(instance->registers->interrupt_enable,
    493504                    OHCI_USED_INTERRUPTS);
     
    508519        usb_log_debug("OHCI HC up and running (ctl_reg=0x%x).\n",
    509520            OHCI_RD(instance->registers->control));
     521
     522        return EOK;
    510523}
    511524
     
    555568        memset(&instance->rh, 0, sizeof(instance->rh));
    556569        /* Init queues */
    557         const int ret = hc_init_transfer_lists(instance);
     570        int ret = hc_init_transfer_lists(instance);
    558571        if (ret != EOK) {
    559572                return ret;
     
    574587            instance->lists[USB_TRANSFER_INTERRUPT].list_head_pa);
    575588
     589        if ((ret = ohci_bus_init(&instance->bus, instance))) {
     590                usb_log_error("HC(%p): Failed to setup bus : %s",
     591                    instance, str_error(ret));
     592                return ret;
     593        }
     594
     595        hc_device_setup(&instance->base, (bus_t *) &instance->bus);
     596
    576597        return EOK;
    577598}
  • uspace/drv/bus/usb/ohci/hc.h

    r1ea0bbf r32fb6bce  
    5858/** Main OHCI driver structure */
    5959typedef struct hc {
     60        /** Common hcd header */
     61        hc_device_t base;
     62
    6063        /** Memory mapped I/O registers area */
    6164        ohci_regs_t *registers;
     
    7073        list_t pending_batches;
    7174
    72         /** Fibril for periodic checks if interrupts can't be used */
    73         fid_t interrupt_emulator;
    74 
    7575        /** Guards schedule and endpoint manipulation */
    7676        fibril_mutex_t guard;
    77 
    78         /** interrupts available */
    79         bool hw_interrupts;
    8077
    8178        /** USB hub emulation structure */
     
    8683} hc_t;
    8784
    88 extern int hc_init(hc_t *, const hw_res_list_parsed_t *);
    89 extern void hc_gain_control(hc_t *instance);
    90 extern void hc_start(hc_t *instance);
    91 extern void hc_fini(hc_t *);
     85static inline hc_t * hcd_to_hc(hc_device_t *hcd)
     86{
     87        assert(hcd);
     88        return (hc_t *) hcd;
     89}
     90
     91extern int hc_add(hc_device_t *, const hw_res_list_parsed_t *);
     92extern int hc_gen_irq_code(irq_code_t *, hc_device_t *, const hw_res_list_parsed_t *);
     93extern int hc_gain_control(hc_device_t *);
     94extern int hc_start(hc_device_t *);
     95extern int hc_gone(hc_device_t *);
    9296
    9397extern void hc_enqueue_endpoint(hc_t *, const endpoint_t *);
    9498extern void hc_dequeue_endpoint(hc_t *, const endpoint_t *);
    9599
    96 int ohci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res);
    97 
    98 extern void ohci_hc_interrupt(hcd_t *, uint32_t);
    99 extern int ohci_hc_status(hcd_t *, uint32_t *);
    100 extern int ohci_hc_schedule(hcd_t *, usb_transfer_batch_t *);
     100extern int ohci_hc_schedule(usb_transfer_batch_t *);
     101extern int ohci_hc_status(bus_t *, uint32_t *);
     102extern void ohci_hc_interrupt(bus_t *, uint32_t);
    101103
    102104#endif
  • uspace/drv/bus/usb/ohci/main.c

    r1ea0bbf r32fb6bce  
    4848
    4949#define NAME "ohci"
    50 static int ohci_driver_init(hcd_t *, const hw_res_list_parsed_t *, ddf_dev_t *);
    51 static int ohci_driver_start(hcd_t *, bool);
    52 static int ohci_driver_claim(hcd_t *, ddf_dev_t *);
    53 static void ohci_driver_fini(hcd_t *);
    5450
    55 static const ddf_hc_driver_t ohci_hc_driver = {
    56         .irq_code_gen = ohci_hc_gen_irq_code,
    57         .init = ohci_driver_init,
    58         .claim = ohci_driver_claim,
    59         .start = ohci_driver_start,
     51static const hc_driver_t ohci_driver = {
     52        .name = NAME,
     53        .hc_device_size = sizeof(hc_t),
     54
     55        .hc_add = hc_add,
     56        .irq_code_gen = hc_gen_irq_code,
     57        .claim = hc_gain_control,
     58        .start = hc_start,
    6059        .setup_root_hub = hcd_setup_virtual_root_hub,
    61         .fini = ohci_driver_fini,
    62         .name = "OHCI",
    63         .ops = {
    64                 .schedule       = ohci_hc_schedule,
    65                 .irq_hook       = ohci_hc_interrupt,
    66                 .status_hook    = ohci_hc_status,
    67         },
    68 };
    69 
    70 
    71 static int ohci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, ddf_dev_t *device)
    72 {
    73         int err;
    74 
    75         assert(hcd);
    76         assert(hcd_get_driver_data(hcd) == NULL);
    77 
    78         hc_t *instance = malloc(sizeof(hc_t));
    79         if (!instance)
    80                 return ENOMEM;
    81 
    82         if ((err = hc_init(instance, res)) != EOK)
    83                 goto err;
    84 
    85         if ((err = ohci_bus_init(&instance->bus, hcd, instance)))
    86                 goto err;
    87 
    88         hcd_set_implementation(hcd, instance, &ohci_hc_driver.ops, &instance->bus.base.base);
    89 
    90         return EOK;
    91 
    92 err:
    93         free(instance);
    94         return err;
    95 }
    96 
    97 static int ohci_driver_claim(hcd_t *hcd, ddf_dev_t *dev)
    98 {
    99         hc_t *hc = hcd_get_driver_data(hcd);
    100         assert(hc);
    101 
    102         hc_gain_control(hc);
    103 
    104         return EOK;
    105 }
    106 
    107 static int ohci_driver_start(hcd_t *hcd, bool interrupts)
    108 {
    109         hc_t *hc = hcd_get_driver_data(hcd);
    110         assert(hc);
    111 
    112         hc->hw_interrupts = interrupts;
    113         hc_start(hc);
    114         return EOK;
    115 }
    116 
    117 static void ohci_driver_fini(hcd_t *hcd)
    118 {
    119         assert(hcd);
    120         hc_t *hc = hcd_get_driver_data(hcd);
    121         if (hc)
    122                 hc_fini(hc);
    123 
    124         hcd_set_implementation(hcd, NULL, NULL, NULL);
    125         free(hc);
    126 }
    127 
    128 /** Initializes a new ddf driver instance of OHCI hcd.
    129  *
    130  * @param[in] device DDF instance of the device to initialize.
    131  * @return Error code.
    132  */
    133 static int ohci_dev_add(ddf_dev_t *device)
    134 {
    135         usb_log_debug("ohci_dev_add() called\n");
    136         assert(device);
    137         return hcd_ddf_add_hc(device, &ohci_hc_driver);
    138 }
    139 
    140 static int ohci_fun_online(ddf_fun_t *fun)
    141 {
    142         return hcd_ddf_device_online(fun);
    143 }
    144 
    145 static int ohci_fun_offline(ddf_fun_t *fun)
    146 {
    147         return hcd_ddf_device_offline(fun);
    148 }
    149 
    150 
    151 static const driver_ops_t ohci_driver_ops = {
    152         .dev_add = ohci_dev_add,
    153         .fun_online = ohci_fun_online,
    154         .fun_offline = ohci_fun_offline
    155 };
    156 
    157 static const driver_t ohci_driver = {
    158         .name = NAME,
    159         .driver_ops = &ohci_driver_ops
     60        .hc_gone = hc_gone,
    16061};
    16162
     
    17172{
    17273        log_init(NAME);
    173         return ddf_driver_main(&ohci_driver);
     74        return hc_driver_main(&ohci_driver);
    17475}
    17576
  • uspace/drv/bus/usb/ohci/ohci_bus.c

    r1ea0bbf r32fb6bce  
    158158        .parent = &usb2_bus_ops,
    159159
     160        .interrupt = ohci_hc_interrupt,
     161        .status = ohci_hc_status,
     162
    160163        .endpoint_destroy = ohci_endpoint_destroy,
    161164        .endpoint_create = ohci_endpoint_create,
     
    167170        .batch_create = ohci_create_batch,
    168171        .batch_destroy = ohci_destroy_batch,
     172        .batch_schedule = ohci_hc_schedule,
    169173};
    170174
    171175
    172 int ohci_bus_init(ohci_bus_t *bus, hcd_t *hcd, hc_t *hc)
     176int ohci_bus_init(ohci_bus_t *bus, hc_t *hc)
    173177{
    174178        assert(hc);
    175179        assert(bus);
    176180
    177 
    178181        usb2_bus_t *usb2_bus = (usb2_bus_t *) bus;
    179182        bus_t *bus_base = (bus_t *) bus;
    180183
    181         usb2_bus_init(usb2_bus, hcd, BANDWIDTH_AVAILABLE_USB11);
     184        usb2_bus_init(usb2_bus, BANDWIDTH_AVAILABLE_USB11);
    182185        bus_base->ops = &ohci_bus_ops;
    183186
  • uspace/drv/bus/usb/ohci/ohci_bus.h

    r1ea0bbf r32fb6bce  
    6262} ohci_bus_t;
    6363
    64 int ohci_bus_init(ohci_bus_t *, hcd_t *, hc_t *);
     64int ohci_bus_init(ohci_bus_t *, hc_t *);
    6565
    6666/** Get and convert assigned ohci_endpoint_t structure
  • uspace/drv/bus/usb/uhci/hc.c

    r1ea0bbf r32fb6bce  
    9595
    9696static void hc_init_hw(const hc_t *instance);
    97 static int hc_init_mem_structures(hc_t *instance, hcd_t *);
     97static int hc_init_mem_structures(hc_t *instance, hc_device_t *);
    9898static int hc_init_transfer_lists(hc_t *instance);
    9999
     
    107107 * @return Error code.
    108108 */
    109 int uhci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)
     109int hc_gen_irq_code(irq_code_t *code, hc_device_t *hcd, const hw_res_list_parsed_t *hw_res)
    110110{
    111111        assert(code);
     
    156156 * - resume from suspend state (not implemented)
    157157 */
    158 void uhci_hc_interrupt(hcd_t *hcd, uint32_t status)
    159 {
    160         assert(hcd);
    161         hc_t *instance = hcd_get_driver_data(hcd);
    162         assert(instance);
     158static void hc_interrupt(bus_t *bus, uint32_t status)
     159{
     160        hc_t *instance = bus_to_hc(bus);
     161
    163162        /* Lower 2 bits are transaction error and transaction complete */
    164163        if (status & (UHCI_STATUS_INTERRUPT | UHCI_STATUS_ERROR_INTERRUPT)) {
     
    199198                } else {
    200199                        usb_log_fatal("Too many UHCI hardware failures!.\n");
    201                         hc_fini(instance);
     200                        hc_gone(&instance->base);
    202201                }
    203202        }
     
    215214 * interrupt fibrils.
    216215 */
    217 int hc_init(hc_t *instance, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)
    218 {
    219         assert(instance);
     216int hc_add(hc_device_t *hcd, const hw_res_list_parsed_t *hw_res)
     217{
     218        hc_t *instance = hcd_to_hc(hcd);
    220219        assert(hw_res);
    221220        if (hw_res->io_ranges.count != 1 ||
     
    249248}
    250249
    251 void hc_start(hc_t *instance)
    252 {
     250int hc_start(hc_device_t *hcd)
     251{
     252        hc_t *instance = hcd_to_hc(hcd);
    253253        hc_init_hw(instance);
    254254        (void)hc_debug_checker;
    255255
    256         uhci_rh_init(&instance->rh, instance->registers->ports, "uhci");
     256        return uhci_rh_init(&instance->rh, instance->registers->ports, "uhci");
    257257}
    258258
     
    261261 * @param[in] instance Host controller structure to use.
    262262 */
    263 void hc_fini(hc_t *instance)
     263int hc_gone(hc_device_t *instance)
    264264{
    265265        assert(instance);
    266266        //TODO Implement
     267        return ENOTSUP;
    267268}
    268269
     
    294295        pio_write_32(&registers->flbaseadd, pa);
    295296
    296         if (instance->hw_interrupts) {
     297        if (instance->base.irq_cap >= 0) {
    297298                /* Enable all interrupts, but resume interrupt */
    298299                pio_write_16(&instance->registers->usbintr,
     
    320321}
    321322
     323static int hc_status(bus_t *, uint32_t *);
     324static int hc_schedule(usb_transfer_batch_t *);
     325
    322326static const bus_ops_t uhci_bus_ops = {
    323327        .parent = &usb2_bus_ops,
    324328
     329        .interrupt = hc_interrupt,
     330        .status = hc_status,
     331
    325332        .endpoint_count_bw = bandwidth_count_usb11,
    326333        .batch_create = create_transfer_batch,
     334        .batch_schedule = hc_schedule,
    327335        .batch_destroy = destroy_transfer_batch,
    328336};
     
    338346 *  - frame list page (needs to be one UHCI hw accessible 4K page)
    339347 */
    340 int hc_init_mem_structures(hc_t *instance, hcd_t *hcd)
     348int hc_init_mem_structures(hc_t *instance, hc_device_t *hcd)
    341349{
    342350        int err;
    343351        assert(instance);
    344352
    345         if ((err = usb2_bus_init(&instance->bus, hcd, BANDWIDTH_AVAILABLE_USB11)))
     353        if ((err = usb2_bus_init(&instance->bus, BANDWIDTH_AVAILABLE_USB11)))
    346354                return err;
    347355
    348356        bus_t *bus = (bus_t *) &instance->bus;
    349357        bus->ops = &uhci_bus_ops;
     358
     359        hc_device_setup(&instance->base, bus);
    350360
    351361        /* Init USB frame list page */
     
    438448}
    439449
    440 int uhci_hc_status(hcd_t *hcd, uint32_t *status)
    441 {
    442         assert(hcd);
     450static int hc_status(bus_t *bus, uint32_t *status)
     451{
     452        hc_t *instance = bus_to_hc(bus);
    443453        assert(status);
    444         hc_t *instance = hcd_get_driver_data(hcd);
    445         assert(instance);
    446454
    447455        *status = 0;
     
    462470 * Checks for bandwidth availability and appends the batch to the proper queue.
    463471 */
    464 int uhci_hc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
    465 {
    466         assert(hcd);
    467         hc_t *instance = hcd_get_driver_data(hcd);
    468         assert(instance);
     472static int hc_schedule(usb_transfer_batch_t *batch)
     473{
     474        hc_t *instance = bus_to_hc(endpoint_get_bus(batch->ep));
    469475        assert(batch);
    470476
  • uspace/drv/bus/usb/uhci/hc.h

    r1ea0bbf r32fb6bce  
    100100/** Main UHCI driver structure */
    101101typedef struct hc {
     102        /* Common hc_device header */
     103        hc_device_t base;
     104
    102105        uhci_rh_t rh;
    103106        usb2_bus_t bus;
     
    119122        /** Pointer table to the above lists, helps during scheduling */
    120123        transfer_list_t *transfers[2][4];
    121         /** Indicator of hw interrupts availability */
    122         bool hw_interrupts;
    123124
    124125        /** Number of hw failures detected. */
     
    126127} hc_t;
    127128
    128 extern int hc_init(hc_t *, hcd_t *, const hw_res_list_parsed_t *);
    129 extern void hc_start(hc_t *);
    130 extern void hc_fini(hc_t *);
     129static inline hc_t *hcd_to_hc(hc_device_t *hcd)
     130{
     131        assert(hcd);
     132        return (hc_t *) hcd;
     133}
    131134
    132 extern int uhci_hc_gen_irq_code(irq_code_t *, hcd_t *,const hw_res_list_parsed_t *);
     135static inline hc_t *bus_to_hc(bus_t *bus)
     136{
     137        assert(bus);
     138        return member_to_inst(bus, hc_t, bus);
     139}
    133140
    134 extern void uhci_hc_interrupt(hcd_t *, uint32_t);
    135 extern int uhci_hc_status(hcd_t *, uint32_t *);
    136 extern int uhci_hc_schedule(hcd_t *, usb_transfer_batch_t *);
     141extern int hc_add(hc_device_t *, const hw_res_list_parsed_t *);
     142extern int hc_gen_irq_code(irq_code_t *, hc_device_t *, const hw_res_list_parsed_t *);
     143extern int hc_start(hc_device_t *);
     144extern int hc_gone(hc_device_t *);
    137145
    138146#endif
  • uspace/drv/bus/usb/uhci/main.c

    r1ea0bbf r32fb6bce  
    4949#define NAME "uhci"
    5050
    51 static int uhci_driver_init(hcd_t *, const hw_res_list_parsed_t *, ddf_dev_t *);
    52 static int uhci_driver_start(hcd_t *, bool);
    53 static void uhci_driver_fini(hcd_t *);
    54 static int disable_legacy(hcd_t *, ddf_dev_t *);
     51static int disable_legacy(hc_device_t *);
    5552
    56 static const ddf_hc_driver_t uhci_hc_driver = {
    57         .claim = disable_legacy,
    58         .irq_code_gen = uhci_hc_gen_irq_code,
    59         .init = uhci_driver_init,
    60         .start = uhci_driver_start,
     53static const hc_driver_t uhci_driver = {
     54        .name = NAME,
     55        .hc_device_size = sizeof(hc_t),
     56        .claim = disable_legacy,
     57        .irq_code_gen = hc_gen_irq_code,
     58        .hc_add = hc_add,
     59        .start = hc_start,
    6160        .setup_root_hub = hcd_setup_virtual_root_hub,
    62         .fini = uhci_driver_fini,
    63         .name = "UHCI",
    64         .ops = {
    65                 .schedule    = uhci_hc_schedule,
    66                 .irq_hook    = uhci_hc_interrupt,
    67                 .status_hook = uhci_hc_status,
    68         },
     61        .hc_gone = hc_gone,
    6962};
    70 
    71 static int uhci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, ddf_dev_t *device)
    72 {
    73         int err;
    74 
    75         assert(hcd);
    76         assert(hcd_get_driver_data(hcd) == NULL);
    77 
    78         hc_t *instance = malloc(sizeof(hc_t));
    79         if (!instance)
    80                 return ENOMEM;
    81 
    82         if ((err = hc_init(instance, hcd, res)) != EOK)
    83                 goto err;
    84 
    85         hcd_set_implementation(hcd, instance, &uhci_hc_driver.ops, &instance->bus.base);
    86 
    87         return EOK;
    88 
    89 err:
    90         free(instance);
    91         return err;
    92 }
    93 
    94 static int uhci_driver_start(hcd_t *hcd, bool interrupts)
    95 {
    96         assert(hcd);
    97         hc_t *hc = hcd_get_driver_data(hcd);
    98 
    99         hc->hw_interrupts = interrupts;
    100         hc_start(hc);
    101         return EOK;
    102 }
    103 
    104 static void uhci_driver_fini(hcd_t *hcd)
    105 {
    106         assert(hcd);
    107         hc_t *hc = hcd_get_driver_data(hcd);
    108         if (hc)
    109                 hc_fini(hc);
    110 
    111         hcd_set_implementation(hcd, NULL, NULL, NULL);
    112         free(hc);
    113 }
    11463
    11564/** Call the PCI driver with a request to clear legacy support register
     
    11867 * @return Error code.
    11968 */
    120 static int disable_legacy(hcd_t *hcd, ddf_dev_t *device)
     69static int disable_legacy(hc_device_t *hcd)
    12170{
    122         assert(device);
     71        assert(hcd);
    12372
    124         async_sess_t *parent_sess = ddf_dev_parent_sess_get(device);
     73        async_sess_t *parent_sess = ddf_dev_parent_sess_get(hcd->ddf_dev);
    12574        if (parent_sess == NULL)
    12675                return ENOMEM;
     
    13079        return pci_config_space_write_16(parent_sess, 0xc0, 0xaf00);
    13180}
    132 
    133 /** Initialize a new ddf driver instance for uhci hc and hub.
    134  *
    135  * @param[in] device DDF instance of the device to initialize.
    136  * @return Error code.
    137  */
    138 static int uhci_dev_add(ddf_dev_t *device)
    139 {
    140         usb_log_debug2("uhci_dev_add() called\n");
    141         assert(device);
    142         return hcd_ddf_add_hc(device, &uhci_hc_driver);
    143 }
    144 
    145 static int uhci_fun_online(ddf_fun_t *fun)
    146 {
    147         return hcd_ddf_device_online(fun);
    148 }
    149 
    150 static int uhci_fun_offline(ddf_fun_t *fun)
    151 {
    152         return hcd_ddf_device_offline(fun);
    153 }
    154 
    155 static const driver_ops_t uhci_driver_ops = {
    156         .dev_add = uhci_dev_add,
    157         .fun_online = uhci_fun_online,
    158         .fun_offline = uhci_fun_offline
    159 };
    160 
    161 static const driver_t uhci_driver = {
    162         .name = NAME,
    163         .driver_ops = &uhci_driver_ops
    164 };
    165 
    16681
    16782/** Initialize global driver structures (NONE).
     
    17893        log_init(NAME);
    17994        logctl_set_log_level(NAME, LVL_DEBUG2);
    180         return ddf_driver_main(&uhci_driver);
     95        return hc_driver_main(&uhci_driver);
    18196}
    18297/**
  • uspace/drv/bus/usb/vhc/main.c

    r1ea0bbf r32fb6bce  
    6969                return ret;
    7070        }
    71         vhc_init(vhc, dev_to_hcd(dev));
    7271        return EOK;
    7372}
    7473
    75 hcd_ops_t vhc_hc_ops = {
    76         .schedule = vhc_schedule,
    77 };
    78 
    7974static int vhc_dev_add(ddf_dev_t *dev)
    8075{
     76        /* Initialize generic structures */
     77        int ret = hcd_ddf_setup_hc(dev, sizeof(vhc_data_t));
     78        if (ret != EOK) {
     79                usb_log_error("Failed to init HCD structures: %s.\n",
     80                   str_error(ret));
     81                return ret;
     82        }
     83        vhc_data_t *vhc = ddf_dev_data_get(dev);
     84        vhc_init(vhc);
     85
     86        hc_device_setup(&vhc->base, (bus_t *) &vhc->bus);
     87
    8188        /* Initialize virtual structure */
    8289        ddf_fun_t *ctl_fun = NULL;
    83         int ret = vhc_control_node(dev, &ctl_fun);
     90        ret = vhc_control_node(dev, &ctl_fun);
    8491        if (ret != EOK) {
    8592                usb_log_error("Failed to setup control node.\n");
    8693                return ret;
    8794        }
    88         vhc_data_t *data = ddf_fun_data_get(ctl_fun);
    89 
    90         /* Initialize generic structures */
    91         ret = hcd_ddf_setup_hc(dev);
    92         if (ret != EOK) {
    93                 usb_log_error("Failed to init HCD structures: %s.\n",
    94                    str_error(ret));
    95                 ddf_fun_destroy(ctl_fun);
    96                 return ret;
    97         }
    98 
    99         hcd_set_implementation(dev_to_hcd(dev), data, &vhc_hc_ops, &data->bus.base);
    10095
    10196        /* Add virtual hub device */
    102         ret = vhc_virtdev_plug_hub(data, &data->hub, NULL, 0);
     97        ret = vhc_virtdev_plug_hub(vhc, &vhc->hub, NULL, 0);
    10398        if (ret != EOK) {
    10499                usb_log_error("Failed to plug root hub: %s.\n", str_error(ret));
     
    111106         * needs to be ready at this time.
    112107         */
    113         ret = hcd_setup_virtual_root_hub(dev_to_hcd(dev), dev);
     108        ret = hcd_setup_virtual_root_hub(&vhc->base);
    114109        if (ret != EOK) {
    115110                usb_log_error("Failed to init VHC root hub: %s\n",
  • uspace/drv/bus/usb/vhc/transfer.c

    r1ea0bbf r32fb6bce  
    4040static bool is_set_address_transfer(vhc_transfer_t *transfer)
    4141{
    42         if (transfer->batch->target.endpoint != 0) {
    43                 return false;
    44         }
    45         if (transfer->batch->ep->transfer_type != USB_TRANSFER_CONTROL) {
    46                 return false;
    47         }
    48         if (transfer->batch->dir != USB_DIRECTION_OUT) {
     42        if (transfer->batch.target.endpoint != 0) {
     43                return false;
     44        }
     45        if (transfer->batch.ep->transfer_type != USB_TRANSFER_CONTROL) {
     46                return false;
     47        }
     48        if (transfer->batch.dir != USB_DIRECTION_OUT) {
    4949                return false;
    5050        }
    5151        const usb_device_request_setup_packet_t *setup
    52                 = &transfer->batch->setup.packet;
     52                = &transfer->batch.setup.packet;
    5353        if (setup->request_type != 0) {
    5454                return false;
     
    150150        assert(outcome != ENAK);
    151151        assert(transfer);
    152         assert(transfer->batch);
    153         transfer->batch->error = outcome;
    154         transfer->batch->transfered_size = data_transfer_size;
    155         usb_transfer_batch_finish(transfer->batch);
     152        transfer->batch.error = outcome;
     153        transfer->batch.transfered_size = data_transfer_size;
     154        usb_transfer_batch_finish(&transfer->batch);
    156155        free(transfer);
     156}
     157
     158static usb_transfer_batch_t *batch_create(endpoint_t *ep)
     159{
     160        vhc_transfer_t *transfer = calloc(1, sizeof(vhc_transfer_t));
     161        usb_transfer_batch_init(&transfer->batch, ep);
     162        link_initialize(&transfer->link);
     163        return &transfer->batch;
    157164}
    158165
    159166static const bus_ops_t vhc_bus_ops = {
    160167        .parent = &usb2_bus_ops,
     168
    161169        .endpoint_count_bw = bandwidth_count_usb11,
     170        .batch_create = batch_create,
     171        .batch_schedule = vhc_schedule,
    162172};
    163173
    164 int vhc_init(vhc_data_t *instance, hcd_t *hcd)
     174int vhc_init(vhc_data_t *instance)
    165175{
    166176        assert(instance);
    167177        list_initialize(&instance->devices);
    168178        fibril_mutex_initialize(&instance->guard);
    169         usb2_bus_init(&instance->bus, hcd, BANDWIDTH_AVAILABLE_USB11);
     179        usb2_bus_init(&instance->bus, BANDWIDTH_AVAILABLE_USB11);
    170180        instance->bus.base.ops = &vhc_bus_ops;
    171         instance->magic = 0xDEADBEEF;
    172181        return virthub_init(&instance->hub, "root hub");
    173182}
    174183
    175 int vhc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
    176 {
    177         assert(hcd);
     184int vhc_schedule(usb_transfer_batch_t *batch)
     185{
    178186        assert(batch);
    179         vhc_data_t *vhc = hcd_get_driver_data(hcd);
     187        vhc_transfer_t *transfer = (vhc_transfer_t *) batch;
     188        vhc_data_t *vhc = bus_to_vhc(endpoint_get_bus(batch->ep));
    180189        assert(vhc);
    181 
    182         vhc_transfer_t *transfer = malloc(sizeof(vhc_transfer_t));
    183         if (!transfer)
    184                 return ENOMEM;
    185         link_initialize(&transfer->link);
    186         transfer->batch = batch;
    187190
    188191        fibril_mutex_lock(&vhc->guard);
     
    192195        list_foreach(vhc->devices, link, vhc_virtdev_t, dev) {
    193196                fibril_mutex_lock(&dev->guard);
    194                 if (dev->address == transfer->batch->target.address) {
     197                if (dev->address == transfer->batch.target.address) {
    195198                        if (!targets) {
    196199                                list_append(&transfer->link, &dev->transfer_queue);
     
    227230                size_t data_transfer_size = 0;
    228231                if (dev->dev_sess) {
    229                         rc = process_transfer_remote(transfer->batch,
     232                        rc = process_transfer_remote(&transfer->batch,
    230233                            dev->dev_sess, &data_transfer_size);
    231234                } else if (dev->dev_local != NULL) {
    232                         rc = process_transfer_local(transfer->batch,
     235                        rc = process_transfer_local(&transfer->batch,
    233236                            dev->dev_local, &data_transfer_size);
    234237                } else {
     
    244247                        if (is_set_address_transfer(transfer)) {
    245248                                usb_device_request_setup_packet_t *setup =
    246                                     (void*) transfer->batch->setup.buffer;
     249                                    (void*) transfer->batch.setup.buffer;
    247250                                dev->address = setup->value;
    248251                                usb_log_debug2("Address changed to %d\n",
  • uspace/drv/bus/usb/vhc/vhcd.h

    r1ea0bbf r32fb6bce  
    3939#include <usbvirt/device.h>
    4040#include <async.h>
     41#include <macros.h>
    4142
    4243#include <usb/host/hcd.h>
    4344#include <usb/host/usb2_bus.h>
     45#include <usb/host/usb_transfer_batch.h>
    4446
    4547#define NAME "vhc"
     
    5658
    5759typedef struct {
    58         uint32_t magic;
     60        hc_device_t base;
     61
     62        usb2_bus_t bus;
     63        ddf_fun_t *virtual_fun;
    5964        list_t devices;
    6065        fibril_mutex_t guard;
    6166        usbvirt_device_t hub;
    62         usb2_bus_t bus;
    6367} vhc_data_t;
    6468
    6569typedef struct {
     70        usb_transfer_batch_t batch;
    6671        link_t link;
    67         usb_transfer_batch_t *batch;
    6872} vhc_transfer_t;
     73
     74static inline vhc_data_t *hcd_to_vhc(hc_device_t *hcd)
     75{
     76        assert(hcd);
     77        return (vhc_data_t *) hcd;
     78}
     79
     80static inline vhc_data_t *bus_to_vhc(bus_t *bus)
     81{
     82        assert(bus);
     83        return member_to_inst(bus, vhc_data_t, bus);
     84}
    6985
    7086void on_client_close(ddf_fun_t *fun);
     
    7793void vhc_virtdev_unplug(vhc_data_t *, uintptr_t);
    7894
    79 int vhc_init(vhc_data_t *instance, hcd_t *);
    80 int vhc_schedule(hcd_t *hcd, usb_transfer_batch_t *batch);
     95int vhc_init(vhc_data_t *);
     96int vhc_schedule(usb_transfer_batch_t *);
    8197int vhc_transfer_queue_processor(void *arg);
    8298
  • uspace/drv/bus/usb/xhci/bus.c

    r1ea0bbf r32fb6bce  
    111111
    112112        uint16_t max_packet_size;
    113         if ((err = hcd_get_ep0_max_packet_size(&max_packet_size, hc->hcd, &dev->base)))
     113        if ((err = hcd_get_ep0_max_packet_size(&max_packet_size, (bus_t *) &hc->bus, &dev->base)))
    114114                return err;
    115115
     
    168168
    169169        /* Read the device descriptor, derive the match ids */
    170         if ((err = hcd_ddf_device_explore(dev))) {
     170        if ((err = hcd_device_explore(dev))) {
    171171                usb_log_error("Device(%d): Failed to explore device: %s", dev->address, str_error(err));
    172172                goto err_address;
     
    233233        /* Destroy DDF device. */
    234234        /* XXX: Not a good idea, this method should not destroy devices. */
    235         hcd_ddf_device_destroy(dev);
     235        hcd_ddf_fun_destroy(dev);
    236236
    237237        return EOK;
     
    501501        BIND_OP(batch_destroy)
    502502#undef BIND_OP
     503
     504        .interrupt = hc_interrupt,
     505        .status = hc_status,
     506        .batch_schedule = hc_schedule,
    503507};
    504508
     
    507511        assert(bus);
    508512
    509         bus_init(&bus->base, hc->hcd, sizeof(xhci_device_t));
     513        bus_init(&bus->base, sizeof(xhci_device_t));
    510514
    511515        bus->devices_by_slot = calloc(hc->max_slots, sizeof(xhci_device_t *));
  • uspace/drv/bus/usb/xhci/hc.c

    r1ea0bbf r32fb6bce  
    432432 * Used only when polling. Shall supplement the irq_commands.
    433433 */
    434 int hc_status(xhci_hc_t *hc, uint32_t *status)
    435 {
     434int hc_status(bus_t *bus, uint32_t *status)
     435{
     436        xhci_hc_t *hc = bus_to_hc(bus);
    436437        int ip = XHCI_REG_RD(hc->rt_regs->ir, XHCI_INTR_IP);
    437438        if (ip) {
     
    449450}
    450451
    451 int hc_schedule(xhci_hc_t *hc, usb_transfer_batch_t *batch)
     452int hc_schedule(usb_transfer_batch_t *batch)
    452453{
    453454        assert(batch);
    454         assert(batch->ep);
     455        xhci_hc_t *hc = bus_to_hc(endpoint_get_bus(batch->ep));
    455456
    456457        if (!batch->target.address) {
     
    532533}
    533534
    534 void hc_interrupt(xhci_hc_t *hc, uint32_t status)
    535 {
     535void hc_interrupt(bus_t *bus, uint32_t status)
     536{
     537        xhci_hc_t *hc = bus_to_hc(bus);
    536538        status = xhci2host(32, status);
    537539
  • uspace/drv/bus/usb/xhci/hc.h

    r1ea0bbf r32fb6bce  
    5151
    5252typedef struct xhci_hc {
     53        /** Common HC device header */
     54        hc_device_t base;
     55
    5356        /* MMIO range */
    5457        addr_range_t mmio_range;
     
    8689        xhci_port_speed_t speeds [16];
    8790        uint8_t speed_to_psiv [USB_SPEED_MAX];
     91} xhci_hc_t;
    8892
    89         /* TODO: Hack. Figure out a better way. */
    90         hcd_t *hcd;
    91 } xhci_hc_t;
     93static inline xhci_hc_t *bus_to_hc(bus_t *bus)
     94{
     95        assert(bus);
     96        return member_to_inst(bus, xhci_hc_t, bus);
     97}
    9298
    9399typedef struct xhci_endpoint xhci_endpoint_t;
     
    99105int hc_irq_code_gen(irq_code_t *, xhci_hc_t *, const hw_res_list_parsed_t *);
    100106int hc_start(xhci_hc_t *, bool);
    101 int hc_schedule(xhci_hc_t *hc, usb_transfer_batch_t *batch);
    102 int hc_status(xhci_hc_t *, uint32_t *);
    103 void hc_interrupt(xhci_hc_t *, uint32_t);
    104107void hc_fini(xhci_hc_t *);
    105108int hc_ring_doorbell(xhci_hc_t *, unsigned, unsigned);
     
    113116int hc_update_endpoint(xhci_hc_t *, uint32_t, uint8_t, xhci_ep_ctx_t *);
    114117
     118int hc_schedule(usb_transfer_batch_t *batch);
     119int hc_status(bus_t *, uint32_t *);
     120void hc_interrupt(bus_t *, uint32_t);
     121
    115122#endif
    116123
  • uspace/drv/bus/usb/xhci/main.c

    r1ea0bbf r32fb6bce  
    4747#define NAME "xhci"
    4848
    49 static int hc_driver_init(hcd_t *, const hw_res_list_parsed_t *, ddf_dev_t *);
    50 static int hcd_irq_code_gen(irq_code_t *, hcd_t *, const hw_res_list_parsed_t *);
    51 static int hcd_claim(hcd_t *, ddf_dev_t *);
    52 static int hcd_start(hcd_t *, bool);
    53 static int hcd_status(hcd_t *, uint32_t *);
    54 static void hcd_interrupt(hcd_t *, uint32_t);
    55 static int hcd_schedule(hcd_t *, usb_transfer_batch_t *);
    56 static void hc_driver_fini(hcd_t *);
     49static inline xhci_hc_t *hcd_to_hc(hc_device_t *hcd)
     50{
     51        assert(hcd);
     52        return (xhci_hc_t *) hcd;
     53}
    5754
    58 static const ddf_hc_driver_t xhci_ddf_hc_driver = {
    59         .name = "XHCI-PCI",
    60         .init = hc_driver_init,
     55static int hcd_hc_add(hc_device_t *hcd, const hw_res_list_parsed_t *hw_res)
     56{
     57        int err;
     58        xhci_hc_t *hc = hcd_to_hc(hcd);
     59        hc_device_setup(hcd, (bus_t *) &hc->bus);
     60
     61        if ((err = hc_init_mmio(hc, hw_res)))
     62                return err;
     63
     64        if ((err = hc_init_memory(hc, hcd->ddf_dev)))
     65                return err;
     66
     67        return EOK;
     68}
     69
     70static int hcd_irq_code_gen(irq_code_t *code, hc_device_t *hcd, const hw_res_list_parsed_t *hw_res)
     71{
     72        xhci_hc_t *hc = hcd_to_hc(hcd);
     73        return hc_irq_code_gen(code, hc, hw_res);
     74}
     75
     76static int hcd_claim(hc_device_t *hcd)
     77{
     78        xhci_hc_t *hc = hcd_to_hc(hcd);
     79        return hc_claim(hc, hcd->ddf_dev);
     80}
     81
     82static int hcd_start(hc_device_t *hcd)
     83{
     84        xhci_hc_t *hc = hcd_to_hc(hcd);
     85        return hc_start(hc, hcd->irq_cap >= 0);
     86}
     87
     88static int hcd_hc_gone(hc_device_t *hcd)
     89{
     90        xhci_hc_t *hc = hcd_to_hc(hcd);
     91        hc_fini(hc);
     92        return EOK;
     93}
     94
     95static const hc_driver_t xhci_driver = {
     96        .name = NAME,
     97        .hc_device_size = sizeof(xhci_hc_t),
     98
     99        .hc_add = hcd_hc_add,
    61100        .irq_code_gen = hcd_irq_code_gen,
    62101        .claim = hcd_claim,
    63102        .start = hcd_start,
    64         .setup_root_hub = NULL,
    65         .fini = hc_driver_fini,
    66         .ops = {
    67                 .schedule       = hcd_schedule,
    68                 .irq_hook       = hcd_interrupt,
    69                 .status_hook    = hcd_status,
    70         }
     103        .hc_gone = hcd_hc_gone,
    71104};
    72 
    73 static int hc_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *hw_res, ddf_dev_t *device)
    74 {
    75         int err;
    76 
    77         xhci_hc_t *hc = malloc(sizeof(xhci_hc_t));
    78         if (!hc)
    79                 return ENOMEM;
    80 
    81         if ((err = hc_init_mmio(hc, hw_res)))
    82                 goto err;
    83 
    84         hc->hcd = hcd;
    85 
    86         if ((err = hc_init_memory(hc, device)))
    87                 goto err;
    88 
    89         hcd_set_implementation(hcd, hc, &xhci_ddf_hc_driver.ops, &hc->bus.base);
    90 
    91         return EOK;
    92 err:
    93         free(hc);
    94         return err;
    95 }
    96 
    97 static int hcd_irq_code_gen(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res)
    98 {
    99         xhci_hc_t *hc = hcd_get_driver_data(hcd);
    100         assert(hc);
    101 
    102         return hc_irq_code_gen(code, hc, hw_res);
    103 }
    104 
    105 static int hcd_claim(hcd_t *hcd, ddf_dev_t *dev)
    106 {
    107         xhci_hc_t *hc = hcd_get_driver_data(hcd);
    108         assert(hc);
    109 
    110         return hc_claim(hc, dev);
    111 }
    112 
    113 static int hcd_start(hcd_t *hcd, bool irq)
    114 {
    115         xhci_hc_t *hc = hcd_get_driver_data(hcd);
    116         assert(hc);
    117 
    118         return hc_start(hc, irq);
    119 }
    120 
    121 static int hcd_schedule(hcd_t *hcd, usb_transfer_batch_t *batch)
    122 {
    123         xhci_hc_t *hc = hcd_get_driver_data(hcd);
    124         assert(hc);
    125 
    126         return hc_schedule(hc, batch);
    127 }
    128 
    129 static int hcd_status(hcd_t *hcd, uint32_t *status)
    130 {
    131         xhci_hc_t *hc = hcd_get_driver_data(hcd);
    132         assert(hc);
    133         assert(status);
    134 
    135         return hc_status(hc, status);
    136 }
    137 
    138 static void hcd_interrupt(hcd_t *hcd, uint32_t status)
    139 {
    140         xhci_hc_t *hc = hcd_get_driver_data(hcd);
    141         assert(hc);
    142 
    143         hc_interrupt(hc, status);
    144 }
    145 
    146 static void hc_driver_fini(hcd_t *hcd)
    147 {
    148         xhci_hc_t *hc = hcd_get_driver_data(hcd);
    149         assert(hc);
    150 
    151         hc_fini(hc);
    152 
    153         free(hc);
    154 }
    155 
    156 /** Initializes a new ddf driver instance of XHCI hcd.
    157  *
    158  * @param[in] device DDF instance of the device to initialize.
    159  * @return Error code.
    160  */
    161 static int xhci_dev_add(ddf_dev_t *device)
    162 {
    163         usb_log_info("Adding device %s", ddf_dev_get_name(device));
    164         return hcd_ddf_add_hc(device, &xhci_ddf_hc_driver);
    165 }
    166 
    167 static int xhci_fun_online(ddf_fun_t *fun)
    168 {
    169         return hcd_ddf_device_online(fun);
    170 }
    171 
    172 static int xhci_fun_offline(ddf_fun_t *fun)
    173 {
    174         return hcd_ddf_device_offline(fun);
    175 }
    176 
    177 
    178 static const driver_ops_t xhci_driver_ops = {
    179         .dev_add = xhci_dev_add,
    180         .fun_online = xhci_fun_online,
    181         .fun_offline = xhci_fun_offline
    182 };
    183 
    184 static const driver_t xhci_driver = {
    185         .name = NAME,
    186         .driver_ops = &xhci_driver_ops
    187 };
    188 
    189105
    190106/** Initializes global driver structures (NONE).
     
    200116        log_init(NAME);
    201117        logctl_set_log_level(NAME, LVL_DEBUG2);
    202         return ddf_driver_main(&xhci_driver);
     118        return hc_driver_main(&xhci_driver);
    203119}
    204120
  • uspace/drv/bus/usb/xhci/rh.c

    r1ea0bbf r32fb6bce  
    9494        xhci_bus_t *bus = &rh->hc->bus;
    9595
    96         device_t *dev = hcd_ddf_device_create(rh->hc_device, &bus->base);
     96        device_t *dev = hcd_ddf_fun_create(&rh->hc->base);
    9797        if (!dev) {
    9898                usb_log_error("Failed to create USB device function.");
     
    132132
    133133err_usb_dev:
    134         hcd_ddf_device_destroy(dev);
     134        hcd_ddf_fun_destroy(dev);
    135135        return err;
    136136}
Note: See TracChangeset for help on using the changeset viewer.