Changeset 32fb6bce in mainline for uspace/drv/bus/usb/ehci


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/ehci
Files:
7 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
Note: See TracChangeset for help on using the changeset viewer.