Ignore:
File:
1 edited

Legend:

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

    r58563585 rd930980  
    2727 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2828 */
    29 
    3029/** @addtogroup drvusbehci
    3130 * @{
     
    3938#include <device/hw_res.h>
    4039#include <errno.h>
     40#include <stdbool.h>
    4141#include <str_error.h>
    42 #include <io/logctl.h>
    4342
    4443#include <usb_iface.h>
     44#include <usb/ddfiface.h>
    4545#include <usb/debug.h>
    46 #include <usb/host/ddf_helpers.h>
     46#include <usb/host/hcd.h>
    4747
    4848#include "res.h"
    49 #include "hc.h"
    50 #include "ehci_endpoint.h"
    5149
    5250#define NAME "ehci"
    5351
    54 static int ehci_driver_init(hcd_t *, const hw_res_list_parsed_t *, bool);
    55 static void ehci_driver_fini(hcd_t *);
     52static int ehci_dev_add(ddf_dev_t *device);
    5653
    57 static 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         }
     54static driver_ops_t ehci_driver_ops = {
     55        .dev_add = ehci_dev_add,
    7156};
    7257
     58static driver_t ehci_driver = {
     59        .name = NAME,
     60        .driver_ops = &ehci_driver_ops
     61};
     62static ddf_dev_ops_t hc_ops = {
     63        .interfaces[USBHC_DEV_IFACE] = &hcd_iface,
     64};
    7365
    74 static 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 
    93 static 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 }
    10366
    10467/** Initializes a new ddf driver instance of EHCI hcd.
     
    10972static int ehci_dev_add(ddf_dev_t *device)
    11073{
    111         usb_log_debug("ehci_dev_add() called\n");
     74        ddf_fun_t *hc_fun = NULL;
     75        bool fun_bound = false;
     76
    11277        assert(device);
    11378
    114         return hcd_ddf_add_hc(device, &ehci_hc_driver);
     79        uintptr_t reg_base = 0;
     80        size_t reg_size = 0;
     81        int irq = 0;
    11582
     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        }
     89
     90        usb_log_info("Memory mapped regs at 0x%" PRIxn " (size %zu), IRQ %d.\n",
     91            reg_base, reg_size, irq);
     92
     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        }
     99
     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        }
     106
     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;
     138error:
     139        if (fun_bound)
     140                ddf_fun_unbind(hc_fun);
     141        if (hc_fun != NULL)
     142                ddf_fun_destroy(hc_fun);
     143        return rc;
    116144}
    117 
    118 
    119 static const driver_ops_t ehci_driver_ops = {
    120         .dev_add = ehci_dev_add,
    121 };
    122 
    123 static const driver_t ehci_driver = {
    124         .name = NAME,
    125         .driver_ops = &ehci_driver_ops
    126 };
    127 
    128145
    129146/** Initializes global driver structures (NONE).
     
    138155{
    139156        log_init(NAME);
    140         logctl_set_log_level(NAME, LVL_NOTE);
    141157        return ddf_driver_main(&ehci_driver);
    142158}
    143 
    144159/**
    145160 * @}
Note: See TracChangeset for help on using the changeset viewer.