Ignore:
File:
1 edited

Legend:

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

    rd930980 r58563585  
    2727 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2828 */
     29
    2930/** @addtogroup drvusbehci
    3031 * @{
     
    3839#include <device/hw_res.h>
    3940#include <errno.h>
    40 #include <stdbool.h>
    4141#include <str_error.h>
     42#include <io/logctl.h>
    4243
    4344#include <usb_iface.h>
    44 #include <usb/ddfiface.h>
    4545#include <usb/debug.h>
    46 #include <usb/host/hcd.h>
     46#include <usb/host/ddf_helpers.h>
    4747
    4848#include "res.h"
     49#include "hc.h"
     50#include "ehci_endpoint.h"
    4951
    5052#define NAME "ehci"
    5153
    52 static int ehci_dev_add(ddf_dev_t *device);
     54static int ehci_driver_init(hcd_t *, const hw_res_list_parsed_t *, bool);
     55static void ehci_driver_fini(hcd_t *);
    5356
    54 static driver_ops_t ehci_driver_ops = {
    55         .dev_add = ehci_dev_add,
     57static const ddf_hc_driver_t ehci_hc_driver = {
     58        .claim = disable_legacy,
     59        .hc_speed = USB_SPEED_HIGH,
     60        .irq_code_gen = ehci_hc_gen_irq_code,
     61        .init = ehci_driver_init,
     62        .fini = ehci_driver_fini,
     63        .name = "EHCI-PCI",
     64        .ops = {
     65                .schedule       = ehci_hc_schedule,
     66                .ep_add_hook    = ehci_endpoint_init,
     67                .ep_remove_hook = ehci_endpoint_fini,
     68                .irq_hook       = ehci_hc_interrupt,
     69                .status_hook    = ehci_hc_status,
     70        }
    5671};
    5772
    58 static driver_t ehci_driver = {
    59         .name = NAME,
    60         .driver_ops = &ehci_driver_ops
    61 };
    62 static ddf_dev_ops_t hc_ops = {
    63         .interfaces[USBHC_DEV_IFACE] = &hcd_iface,
    64 };
    6573
     74static int ehci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res,
     75    bool irq)
     76{
     77        assert(hcd);
     78        assert(hcd_get_driver_data(hcd) == NULL);
     79
     80        hc_t *instance = malloc(sizeof(hc_t));
     81        if (!instance)
     82                return ENOMEM;
     83
     84        const int ret = hc_init(instance, res, irq);
     85        if (ret == EOK) {
     86                hcd_set_implementation(hcd, instance, &ehci_hc_driver.ops);
     87        } else {
     88                free(instance);
     89        }
     90        return ret;
     91}
     92
     93static void ehci_driver_fini(hcd_t *hcd)
     94{
     95        assert(hcd);
     96        hc_t *hc = hcd_get_driver_data(hcd);
     97        if (hc)
     98                hc_fini(hc);
     99
     100        free(hc);
     101        hcd_set_implementation(hcd, NULL, NULL);
     102}
    66103
    67104/** Initializes a new ddf driver instance of EHCI hcd.
     
    72109static int ehci_dev_add(ddf_dev_t *device)
    73110{
    74         ddf_fun_t *hc_fun = NULL;
    75         bool fun_bound = false;
    76 
     111        usb_log_debug("ehci_dev_add() called\n");
    77112        assert(device);
    78113
    79         uintptr_t reg_base = 0;
    80         size_t reg_size = 0;
    81         int irq = 0;
     114        return hcd_ddf_add_hc(device, &ehci_hc_driver);
    82115
    83         int rc = get_my_registers(device, &reg_base, &reg_size, &irq);
    84         if (rc != EOK) {
    85                 usb_log_error("Failed to get memory addresses for %" PRIun
    86                     ": %s.\n", ddf_dev_get_handle(device), str_error(rc));
    87                 goto error;
    88         }
     116}
    89117
    90         usb_log_info("Memory mapped regs at 0x%" PRIxn " (size %zu), IRQ %d.\n",
    91             reg_base, reg_size, irq);
    92118
    93         rc = disable_legacy(device, reg_base, reg_size);
    94         if (rc != EOK) {
    95                 usb_log_error("Failed to disable legacy USB: %s.\n",
    96                     str_error(rc));
    97                 goto error;
    98         }
     119static const driver_ops_t ehci_driver_ops = {
     120        .dev_add = ehci_dev_add,
     121};
    99122
    100         hc_fun = ddf_fun_create(device, fun_exposed, "ehci_hc");
    101         if (hc_fun == NULL) {
    102                 usb_log_error("Failed to create EHCI function.\n");
    103                 rc = ENOMEM;
    104                 goto error;
    105         }
     123static const driver_t ehci_driver = {
     124        .name = NAME,
     125        .driver_ops = &ehci_driver_ops
     126};
    106127
    107         hcd_t *ehci_hc = ddf_fun_data_alloc(hc_fun, sizeof(hcd_t));
    108         if (ehci_hc == NULL) {
    109                 usb_log_error("Failed to alloc generic HC driver.\n");
    110                 rc = ENOMEM;
    111                 goto error;
    112         }
    113 
    114         /* High Speed, no bandwidth */
    115         hcd_init(ehci_hc, USB_SPEED_HIGH, 0, NULL);
    116         ddf_fun_set_ops(hc_fun,  &hc_ops);
    117 
    118         rc = ddf_fun_bind(hc_fun);
    119         if (rc != EOK) {
    120                 usb_log_error("Failed to bind EHCI function: %s.\n",
    121                     str_error(rc));
    122                 goto error;
    123         }
    124 
    125         fun_bound = true;
    126 
    127         rc = ddf_fun_add_to_category(hc_fun, USB_HC_CATEGORY);
    128         if (rc != EOK) {
    129                 usb_log_error("Failed to add EHCI to HC class: %s.\n",
    130                     str_error(rc));
    131                 goto error;
    132         }
    133 
    134         usb_log_info("Controlling new EHCI device `%s' (handle %" PRIun ").\n",
    135             ddf_dev_get_name(device), ddf_dev_get_handle(device));
    136 
    137         return EOK;
    138 error:
    139         if (fun_bound)
    140                 ddf_fun_unbind(hc_fun);
    141         if (hc_fun != NULL)
    142                 ddf_fun_destroy(hc_fun);
    143         return rc;
    144 }
    145128
    146129/** Initializes global driver structures (NONE).
     
    155138{
    156139        log_init(NAME);
     140        logctl_set_log_level(NAME, LVL_NOTE);
    157141        return ddf_driver_main(&ehci_driver);
    158142}
     143
    159144/**
    160145 * @}
Note: See TracChangeset for help on using the changeset viewer.