Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/uhci-hcd/main.c

    r357a302 r8e1eb4d0  
    3232 * @brief UHCI driver
    3333 */
    34 #include <driver.h>
     34#include <ddf/driver.h>
     35#include <ddf/interrupt.h>
    3536#include <usb_iface.h>
     37#include <usb/ddfiface.h>
     38#include <device/hw_res.h>
    3639
    3740#include <errno.h>
     
    4649#define NAME "uhci-hcd"
    4750
    48 static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
    49 {
    50         /* This shall be called only for the UHCI itself. */
    51         assert(dev->parent == NULL);
     51static int uhci_add_device(ddf_dev_t *device);
    5252
    53         *handle = dev->handle;
    54         return EOK;
    55 }
    56 
    57 static int usb_iface_get_address(device_t *dev, devman_handle_t handle,
    58     usb_address_t *address)
     53/*----------------------------------------------------------------------------*/
     54static driver_ops_t uhci_driver_ops = {
     55        .add_device = uhci_add_device,
     56};
     57/*----------------------------------------------------------------------------*/
     58static driver_t uhci_driver = {
     59        .name = NAME,
     60        .driver_ops = &uhci_driver_ops
     61};
     62/*----------------------------------------------------------------------------*/
     63static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    5964{
    6065        assert(dev);
    6166        uhci_t *hc = dev_to_uhci(dev);
     67        uint16_t status = IPC_GET_ARG1(*call);
    6268        assert(hc);
     69        uhci_interrupt(hc, status);
     70}
     71/*----------------------------------------------------------------------------*/
     72#define CHECK_RET_RETURN(ret, message...) \
     73if (ret != EOK) { \
     74        usb_log_error(message); \
     75        return ret; \
     76}
    6377
    64         usb_address_t addr = usb_address_keeping_find(&hc->address_manager,
    65             handle);
    66         if (addr < 0) {
    67                 return addr;
     78static int uhci_add_device(ddf_dev_t *device)
     79{
     80        assert(device);
     81
     82        usb_log_info("uhci_add_device() called\n");
     83
     84        uintptr_t io_reg_base = 0;
     85        size_t io_reg_size = 0;
     86        int irq = 0;
     87
     88        int ret =
     89            pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);
     90
     91        CHECK_RET_RETURN(ret,
     92            "Failed(%d) to get I/O addresses:.\n", ret, device->handle);
     93        usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n",
     94            io_reg_base, io_reg_size, irq);
     95
     96//      ret = pci_enable_interrupts(device);
     97//      CHECK_RET_RETURN(ret, "Failed(%d) to get enable interrupts:\n", ret);
     98
     99        uhci_t *uhci_hc = malloc(sizeof(uhci_t));
     100        ret = (uhci_hc != NULL) ? EOK : ENOMEM;
     101        CHECK_RET_RETURN(ret, "Failed to allocate memory for uhci hcd driver.\n");
     102
     103        ret = uhci_init(uhci_hc, device, (void*)io_reg_base, io_reg_size);
     104        if (ret != EOK) {
     105                usb_log_error("Failed to init uhci-hcd.\n");
     106                free(uhci_hc);
     107                return ret;
    68108        }
    69109
    70         if (address != NULL) {
    71                 *address = addr;
     110        /*
     111         * We might free uhci_hc, but that does not matter since no one
     112         * else would access driver_data anyway.
     113         */
     114        device->driver_data = uhci_hc;
     115        ret = register_interrupt_handler(device, irq, irq_handler,
     116            &uhci_hc->interrupt_code);
     117        if (ret != EOK) {
     118                usb_log_error("Failed to register interrupt handler.\n");
     119                uhci_fini(uhci_hc);
     120                free(uhci_hc);
     121                return ret;
     122        }
     123
     124        ddf_fun_t *rh;
     125        ret = setup_root_hub(&rh, device);
     126        if (ret != EOK) {
     127                usb_log_error("Failed to setup uhci root hub.\n");
     128                uhci_fini(uhci_hc);
     129                free(uhci_hc);
     130                return ret;
     131        }
     132        rh->driver_data = uhci_hc->ddf_instance;
     133
     134        ret = ddf_fun_bind(rh);
     135        if (ret != EOK) {
     136                usb_log_error("Failed to register root hub.\n");
     137                uhci_fini(uhci_hc);
     138                free(uhci_hc);
     139                free(rh);
     140                return ret;
    72141        }
    73142
    74143        return EOK;
    75144}
    76 
    77 static usb_iface_t hc_usb_iface = {
    78         .get_hc_handle = usb_iface_get_hc_handle,
    79         .get_address = usb_iface_get_address
    80 };
    81 
    82 static device_ops_t uhci_ops = {
    83         .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
    84         .interfaces[USBHC_DEV_IFACE] = &uhci_iface
    85 };
    86 
    87 static int uhci_add_device(device_t *device)
    88 {
    89         assert(device);
    90 
    91         usb_log_info("uhci_add_device() called\n");
    92         device->ops = &uhci_ops;
    93 
    94         uintptr_t io_reg_base;
    95         size_t io_reg_size;
    96         int irq;
    97 
    98         int rc = pci_get_my_registers(device,
    99             &io_reg_base, &io_reg_size, &irq);
    100 
    101         if (rc != EOK) {
    102                 usb_log_error("Failed(%d) to get I/O registers addresses for device:.\n",
    103                     rc, device->handle);
    104                 return rc;
    105         }
    106 
    107         usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n",
    108             io_reg_base, io_reg_size, irq);
    109 
    110         uhci_t *uhci_hc = malloc(sizeof(uhci_t));
    111         if (!uhci_hc) {
    112                 usb_log_error("Failed to allocaete memory for uhci hcd driver.\n");
    113                 return ENOMEM;
    114         }
    115 
    116         int ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size);
    117         if (ret != EOK) {
    118                 usb_log_error("Failed to init uhci-hcd.\n");
    119                 return ret;
    120         }
    121         device_t *rh;
    122         ret = setup_root_hub(&rh, device);
    123 
    124         if (ret != EOK) {
    125                 usb_log_error("Failed to setup uhci root hub.\n");
    126                 /* TODO: destroy uhci here */
    127                 return ret;
    128         }
    129 
    130         ret = child_device_register(rh, device);
    131         if (ret != EOK) {
    132                 usb_log_error("Failed to register root hub.\n");
    133                 /* TODO: destroy uhci here */
    134                 return ret;
    135         }
    136 
    137         device->driver_data = uhci_hc;
    138 
    139         return EOK;
    140 }
    141 
    142 static driver_ops_t uhci_driver_ops = {
    143         .add_device = uhci_add_device,
    144 };
    145 
    146 static driver_t uhci_driver = {
    147         .name = NAME,
    148         .driver_ops = &uhci_driver_ops
    149 };
    150 
     145/*----------------------------------------------------------------------------*/
    151146int main(int argc, char *argv[])
    152147{
    153         /*
    154          * Do some global initializations.
    155          */
    156         sleep(5);
    157         usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
     148        sleep(3);
     149        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    158150
    159         return driver_main(&uhci_driver);
     151        return ddf_driver_main(&uhci_driver);
    160152}
    161153/**
Note: See TracChangeset for help on using the changeset viewer.