Changeset e4d7363 in mainline for uspace/drv/bus/usb/ehci


Ignore:
Timestamp:
2017-06-22T21:34:39Z (9 years ago)
Author:
Ondřej Hlavatý <aearsis@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
91ca111
Parents:
cb89430
Message:

usbhost: refactor the initialization

Before that, drivers had to setup MMIO range multiple times, or even parse hw
resources themselves again. The former init method was split in half - init and
start. Init shall allocate and initialize inner structures, start shall start
the HC.

In the XHCI it is demonstrated how to isolate inner HC implementation from the
fact this driver is using libusbhost. It adds some boilerplate code, but
I think it leads to cleaner design.

Location:
uspace/drv/bus/usb/ehci
Files:
5 edited

Legend:

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

    rcb89430 re4d7363  
    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         }
    138 
    139         ehci_regs_t *registers =
    140             (ehci_regs_t *)(RNGABSPTR(regs) + EHCI_RD8(caps->caplength));
    141         code->cmds[0].addr = (void *) &registers->usbsts;
    142         code->cmds[3].addr = (void *) &registers->usbsts;
     131
     132        code->cmds[0].addr = (void *) &instance->registers->usbsts;
     133        code->cmds[3].addr = (void *) &instance->registers->usbsts;
    143134        EHCI_WR(code->cmds[1].value, EHCI_USED_INTERRUPTS);
    144135
     
    156147 * @return Error code
    157148 */
    158 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res, bool interrupts)
     149int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res)
    159150{
    160151        assert(instance);
     
    172163                return ret;
    173164        }
     165
    174166        usb_log_info("HC(%p): Device registers at %"PRIx64" (%zuB) accessible.",
    175167            instance, hw_res->mem_ranges.ranges[0].address.absolute,
     
    195187        ehci_rh_init(
    196188            &instance->rh, instance->caps, instance->registers, "ehci rh");
    197         usb_log_debug("HC(%p): Starting HW.", instance);
    198         hc_start(instance);
    199189
    200190        return EOK;
     
    368358 * @param[in] instance EHCI hc driver structure.
    369359 */
    370 void hc_start(hc_t *instance)
    371 {
    372         assert(instance);
     360int hc_start(hc_t *instance, bool interrupts)
     361{
     362        assert(instance);
     363        usb_log_debug("HC(%p): Starting HW.", instance);
     364
    373365        /* Turn off the HC if it's running, Reseting a running device is
    374366         * undefined */
     
    435427        EHCI_WR(instance->registers->usbsts, EHCI_RD(instance->registers->usbsts));
    436428        EHCI_WR(instance->registers->usbintr, EHCI_USED_INTERRUPTS);
     429
     430        return EOK;
    437431}
    438432
  • uspace/drv/bus/usb/ehci/hc.h

    rcb89430 re4d7363  
    8282} hc_t;
    8383
    84 int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res, bool interrupts);
     84int hc_init(hc_t *instance, const hw_res_list_parsed_t *hw_res);
     85int hc_start(hc_t *instance, bool interrupts);
    8586void hc_fini(hc_t *instance);
    8687
     
    8889void hc_dequeue_endpoint(hc_t *instance, const endpoint_t *ep);
    8990
    90 int ehci_hc_gen_irq_code(irq_code_t *code, const hw_res_list_parsed_t *hw_res);
     91int ehci_hc_gen_irq_code(irq_code_t *code, hcd_t *hcd, const hw_res_list_parsed_t *hw_res);
    9192
    9293void ehci_hc_interrupt(hcd_t *hcd, uint32_t status);
  • uspace/drv/bus/usb/ehci/main.c

    rcb89430 re4d7363  
    5252#define NAME "ehci"
    5353
    54 static int ehci_driver_init(hcd_t *, const hw_res_list_parsed_t *, bool);
     54static int ehci_driver_init(hcd_t *, const hw_res_list_parsed_t *);
     55static int ehci_driver_claim(hcd_t *, ddf_dev_t *);
     56static int ehci_driver_start(hcd_t *, bool);
    5557static void ehci_driver_fini(hcd_t *);
    5658
    5759static const ddf_hc_driver_t ehci_hc_driver = {
    58         .claim = disable_legacy,
    5960        .hc_speed = USB_SPEED_HIGH,
     61        .name = "EHCI-PCI",
     62        .init = ehci_driver_init,
    6063        .irq_code_gen = ehci_hc_gen_irq_code,
    61         .init = ehci_driver_init,
     64        .claim = ehci_driver_claim,
     65        .start = ehci_driver_start,
    6266        .fini = ehci_driver_fini,
    63         .name = "EHCI-PCI",
    6467        .ops = {
    6568                .schedule       = ehci_hc_schedule,
     
    7275
    7376
    74 static int ehci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res,
    75     bool irq)
     77static int ehci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res)
    7678{
    7779        assert(hcd);
     
    8284                return ENOMEM;
    8385
    84         const int ret = hc_init(instance, res, irq);
     86        const int ret = hc_init(instance, res);
    8587        if (ret == EOK) {
    8688                hcd_set_implementation(hcd, instance, &ehci_hc_driver.ops);
     
    8991        }
    9092        return ret;
     93}
     94
     95static int ehci_driver_claim(hcd_t *hcd, ddf_dev_t *dev)
     96{
     97        hc_t *instance = hcd_get_driver_data(hcd);
     98        assert(instance);
     99
     100        return disable_legacy(instance, dev);
     101}
     102
     103static int ehci_driver_start(hcd_t *hcd, bool irq) {
     104        hc_t *instance = hcd_get_driver_data(hcd);
     105        assert(instance);
     106
     107        return hc_start(instance, irq);
    91108}
    92109
  • uspace/drv/bus/usb/ehci/res.c

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

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