Changes in uspace/drv/ohci/main.c [53f1c87:05ead5c] in mainline


Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/ohci/main.c

    r53f1c87 r05ead5c  
    3434 */
    3535#include <ddf/driver.h>
     36#include <ddf/interrupt.h>
     37#include <device/hw_res.h>
    3638#include <errno.h>
    3739#include <str_error.h>
    3840
     41#include <usb_iface.h>
     42#include <usb/ddfiface.h>
    3943#include <usb/debug.h>
    4044
    41 #include "ohci.h"
    42 
    43 #define NAME "ohci"
     45#include "pci.h"
     46#include "iface.h"
     47#include "hc.h"
    4448
    4549static int ohci_add_device(ddf_dev_t *device);
     50static int get_hc_handle(ddf_fun_t *fun, devman_handle_t *handle)
     51{
     52        assert(handle);
     53  assert(fun != NULL);
     54
     55  *handle = fun->handle;
     56  return EOK;
     57}
     58/*----------------------------------------------------------------------------*/
     59static int get_address(
     60    ddf_fun_t *fun, devman_handle_t handle, usb_address_t *address)
     61{
     62        assert(fun);
     63        usb_device_keeper_t *manager = &fun_to_hc(fun)->manager;
     64  usb_address_t addr = usb_device_keeper_find(manager, handle);
     65  if (addr < 0) {
     66    return addr;
     67  }
     68
     69  if (address != NULL) {
     70    *address = addr;
     71  }
     72
     73  return EOK;
     74}
     75/*----------------------------------------------------------------------------*/
     76/** IRQ handling callback, identifies device
     77 *
     78 * @param[in] dev DDF instance of the device to use.
     79 * @param[in] iid (Unused).
     80 * @param[in] call Pointer to the call that represents interrupt.
     81 */
     82static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
     83{
     84        assert(dev);
     85        hc_t *hc = (hc_t*)dev->driver_data;
     86        assert(hc);
     87        hc_interrupt(hc, 0);
     88}
    4689/*----------------------------------------------------------------------------*/
    4790static driver_ops_t ohci_driver_ops = {
     
    5497};
    5598/*----------------------------------------------------------------------------*/
     99static usb_iface_t hc_usb_iface = {
     100        .get_address = get_address,
     101        .get_hc_handle = get_hc_handle,
     102};
     103/*----------------------------------------------------------------------------*/
     104static ddf_dev_ops_t hc_ops = {
     105        .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
     106        .interfaces[USBHC_DEV_IFACE] = &hc_iface,
     107};
     108/*----------------------------------------------------------------------------*/
    56109/** Initializes a new ddf driver instance of OHCI hcd.
    57110 *
     
    59112 * @return Error code.
    60113 */
    61 int ohci_add_device(ddf_dev_t *device)
    62 {
    63         usb_log_debug("ohci_add_device() called\n");
     114static int ohci_add_device(ddf_dev_t *device)
     115{
    64116        assert(device);
    65         ohci_t *ohci = malloc(sizeof(ohci_t));
    66         if (ohci == NULL) {
     117#define CHECK_RET_RETURN(ret, message...) \
     118if (ret != EOK) { \
     119        usb_log_error(message); \
     120        return ret; \
     121}
     122
     123        uintptr_t mem_reg_base = 0;
     124        size_t mem_reg_size = 0;
     125        int irq = 0;
     126
     127        int ret =
     128            pci_get_my_registers(device, &mem_reg_base, &mem_reg_size, &irq);
     129        CHECK_RET_RETURN(ret,
     130            "Failed(%d) to get memory addresses:.\n", ret, device->handle);
     131        usb_log_info("Memory mapped regs at 0x%X (size %zu), IRQ %d.\n",
     132            mem_reg_base, mem_reg_size, irq);
     133
     134        ret = pci_disable_legacy(device);
     135        CHECK_RET_RETURN(ret,
     136            "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret));
     137
     138        hc_t *hcd = malloc(sizeof(hc_t));
     139        if (hcd == NULL) {
    67140                usb_log_error("Failed to allocate OHCI driver.\n");
    68141                return ENOMEM;
    69142        }
    70143
    71         int ret = ohci_init(ohci, device);
     144        ddf_fun_t *hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc");
     145        if (hc_fun == NULL) {
     146                usb_log_error("Failed to create OHCI function.\n");
     147                free(hcd);
     148                return ENOMEM;
     149        }
     150
     151
     152        bool interrupts = false;
     153#ifdef CONFIG_USBHC_NO_INTERRUPTS
     154        usb_log_warning("Interrupts disabled in OS config, " \
     155            "falling back to polling.\n");
     156#else
     157        ret = pci_enable_interrupts(device);
    72158        if (ret != EOK) {
    73                 usb_log_error("Failed to initialize OHCI driver: %s.\n",
     159                usb_log_warning("Failed to enable interrupts: %s.\n",
    74160                    str_error(ret));
     161                usb_log_info("HW interrupts not available, " \
     162                    "falling back to polling.\n");
     163        } else {
     164                usb_log_debug("Hw interrupts enabled.\n");
     165                interrupts = true;
     166        }
     167#endif
     168
     169        ret = hc_init(hcd, hc_fun, device, mem_reg_base, mem_reg_size, interrupts);
     170        if (ret != EOK) {
     171                usb_log_error("Failed to initialize OHCI driver.\n");
     172                free(hcd);
    75173                return ret;
    76174        }
    77         device->driver_data = ohci;
    78 
    79         usb_log_info("Controlling new OHCI device `%s'.\n", device->name);
     175
     176        ret = register_interrupt_handler(device, irq, irq_handler, NULL);
     177
     178        hc_fun->ops = &hc_ops;
     179        ret = ddf_fun_bind(hc_fun);
     180        if (ret != EOK) {
     181                usb_log_error("Failed to bind OHCI function.\n");
     182                ddf_fun_destroy(hc_fun);
     183                free(hcd);
     184                return ret;
     185        }
     186        hc_fun->driver_data = hcd;
     187
     188        fid_t later = fibril_create((int(*)(void*))hc_register_hub, hcd);
     189        fibril_add_ready(later);
     190
     191        usb_log_info("Controlling new OHCI device `%s' (handle %llu).\n",
     192            device->name, device->handle);
    80193
    81194        return EOK;
     195#undef CHECK_RET_RETURN
    82196}
    83197/*----------------------------------------------------------------------------*/
Note: See TracChangeset for help on using the changeset viewer.