Ignore:
File:
1 edited

Legend:

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

    rdc44023 r7de1988c  
    3333 * Main routines of EHCI driver.
    3434 */
     35
    3536#include <ddf/driver.h>
    3637#include <ddf/interrupt.h>
    3738#include <device/hw_res.h>
    3839#include <errno.h>
     40#include <stdbool.h>
    3941#include <str_error.h>
    4042
    4143#include <usb_iface.h>
     44#include <usb/ddfiface.h>
    4245#include <usb/debug.h>
    43 #include <usb/host/ddf_helpers.h>
     46#include <usb/host/hcd.h>
    4447
    4548#include "res.h"
    46 #include "hc.h"
    47 #include "ehci_endpoint.h"
    4849
    4950#define NAME "ehci"
    5051
    51 static int ehci_driver_init(hcd_t *hcd, const hw_res_list_parsed_t *res, bool irq)
    52 {
    53         assert(hcd);
    54         assert(hcd->driver.data == NULL);
    55 
    56         hc_t *instance = malloc(sizeof(hc_t));
    57         if (!instance)
    58                 return ENOMEM;
    59 
    60         const int ret = hc_init(instance, res, irq);
    61         if (ret == EOK)
    62                 hcd_set_implementation(hcd, instance, ehci_hc_schedule,
    63                     ehci_endpoint_init, ehci_endpoint_fini, ehci_hc_interrupt,
    64                     ehci_hc_status);
    65         return ret;
    66 }
    67 
    68 static void ehci_driver_fini(hcd_t *hcd)
    69 {
    70         assert(hcd);
    71         if (hcd->driver.data)
    72                 hc_fini(hcd->driver.data);
    73 
    74         free(hcd->driver.data);
    75         hcd_set_implementation(hcd, NULL, NULL, NULL, NULL, NULL, NULL);
    76 }
    77 
    7852static int ehci_dev_add(ddf_dev_t *device);
    7953
    80 static const driver_ops_t ehci_driver_ops = {
     54static driver_ops_t ehci_driver_ops = {
    8155        .dev_add = ehci_dev_add,
    8256};
    8357
    84 static const driver_t ehci_driver = {
     58static driver_t ehci_driver = {
    8559        .name = NAME,
    8660        .driver_ops = &ehci_driver_ops
     61};
     62static ddf_dev_ops_t hc_ops = {
     63        .interfaces[USBHC_DEV_IFACE] = &hcd_iface,
    8764};
    8865
     
    9572static int ehci_dev_add(ddf_dev_t *device)
    9673{
    97         usb_log_debug("ehci_dev_add() called\n");
     74        ddf_fun_t *hc_fun = NULL;
     75        bool fun_bound = false;
     76
    9877        assert(device);
    9978
    100         int ret = disable_legacy(device);
    101         if (ret != EOK) {
    102                 usb_log_error("Failed to disable EHCI legacy support: %s\n",
    103                     str_error(ret));
    104                 return ret;
     79        addr_range_t reg_range;
     80        int irq = 0;
     81
     82        int rc = get_my_registers(device, &reg_range, &irq);
     83        if (rc != EOK) {
     84                usb_log_error("Failed to get memory addresses for %" PRIun
     85                    ": %s.\n", ddf_dev_get_handle(device), str_error(rc));
     86                goto error;
    10587        }
    10688
    107         ret = ddf_hcd_device_setup_all(device, USB_SPEED_HIGH,
    108             BANDWIDTH_AVAILABLE_USB20, bandwidth_count_usb11,
    109             ddf_hcd_gen_irq_handler, ehci_hc_gen_irq_code,
    110             ehci_driver_init, ehci_driver_fini);
    111         if (ret != EOK) {
    112                 usb_log_error("Failed to initialize EHCI driver: %s.\n",
    113                     str_error(ret));
    114                 return ret;
     89        usb_log_info("Memory mapped regs at %p (size %zu), IRQ %d.\n",
     90            RNGABSPTR(reg_range), RNGSZ(reg_range), irq);
     91
     92        rc = disable_legacy(device, &reg_range);
     93        if (rc != EOK) {
     94                usb_log_error("Failed to disable legacy USB: %s.\n",
     95                    str_error(rc));
     96                goto error;
    11597        }
    116         usb_log_info("Controlling new EHCI device '%s'.\n",
    117             ddf_dev_get_name(device));
     98
     99        hc_fun = ddf_fun_create(device, fun_exposed, "ehci_hc");
     100        if (hc_fun == NULL) {
     101                usb_log_error("Failed to create EHCI function.\n");
     102                rc = ENOMEM;
     103                goto error;
     104        }
     105
     106        hcd_t *ehci_hc = ddf_fun_data_alloc(hc_fun, sizeof(hcd_t));
     107        if (ehci_hc == NULL) {
     108                usb_log_error("Failed to alloc generic HC driver.\n");
     109                rc = ENOMEM;
     110                goto error;
     111        }
     112
     113        /* High Speed, no bandwidth */
     114        hcd_init(ehci_hc, USB_SPEED_HIGH, 0, NULL);
     115        ddf_fun_set_ops(hc_fun,  &hc_ops);
     116
     117        rc = ddf_fun_bind(hc_fun);
     118        if (rc != EOK) {
     119                usb_log_error("Failed to bind EHCI function: %s.\n",
     120                    str_error(rc));
     121                goto error;
     122        }
     123
     124        fun_bound = true;
     125
     126        rc = ddf_fun_add_to_category(hc_fun, USB_HC_CATEGORY);
     127        if (rc != EOK) {
     128                usb_log_error("Failed to add EHCI to HC class: %s.\n",
     129                    str_error(rc));
     130                goto error;
     131        }
     132
     133        usb_log_info("Controlling new EHCI device `%s' (handle %" PRIun ").\n",
     134            ddf_dev_get_name(device), ddf_dev_get_handle(device));
    118135
    119136        return EOK;
     137error:
     138        if (fun_bound)
     139                ddf_fun_unbind(hc_fun);
     140        if (hc_fun != NULL)
     141                ddf_fun_destroy(hc_fun);
     142        return rc;
    120143}
    121144
Note: See TracChangeset for help on using the changeset viewer.