Ignore:
File:
1 edited

Legend:

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

    rb375bb8 r357a302  
    3232 * @brief UHCI driver
    3333 */
    34 #include <ddf/driver.h>
    35 #include <ddf/interrupt.h>
    36 #include <device/hw_res.h>
     34#include <driver.h>
     35#include <usb_iface.h>
     36
    3737#include <errno.h>
    38 #include <str_error.h>
    3938
    40 #include <usb_iface.h>
    41 #include <usb/ddfiface.h>
    4239#include <usb/debug.h>
    4340
     
    4946#define NAME "uhci-hcd"
    5047
    51 static int uhci_add_device(ddf_dev_t *device);
    52 /*----------------------------------------------------------------------------*/
     48static 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);
     52
     53        *handle = dev->handle;
     54        return EOK;
     55}
     56
     57static int usb_iface_get_address(device_t *dev, devman_handle_t handle,
     58    usb_address_t *address)
     59{
     60        assert(dev);
     61        uhci_t *hc = dev_to_uhci(dev);
     62        assert(hc);
     63
     64        usb_address_t addr = usb_address_keeping_find(&hc->address_manager,
     65            handle);
     66        if (addr < 0) {
     67                return addr;
     68        }
     69
     70        if (address != NULL) {
     71                *address = addr;
     72        }
     73
     74        return EOK;
     75}
     76
     77static usb_iface_t hc_usb_iface = {
     78        .get_hc_handle = usb_iface_get_hc_handle,
     79        .get_address = usb_iface_get_address
     80};
     81
     82static device_ops_t uhci_ops = {
     83        .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
     84        .interfaces[USBHC_DEV_IFACE] = &uhci_iface
     85};
     86
     87static 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
    53142static driver_ops_t uhci_driver_ops = {
    54143        .add_device = uhci_add_device,
    55144};
    56 /*----------------------------------------------------------------------------*/
     145
    57146static driver_t uhci_driver = {
    58147        .name = NAME,
    59148        .driver_ops = &uhci_driver_ops
    60149};
    61 /*----------------------------------------------------------------------------*/
    62 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    63 {
    64         assert(dev);
    65         uhci_t *hc = dev_to_uhci(dev);
    66         uint16_t status = IPC_GET_ARG1(*call);
    67         assert(hc);
    68         uhci_interrupt(hc, status);
    69 }
    70 /*----------------------------------------------------------------------------*/
    71 static int uhci_add_device(ddf_dev_t *device)
    72 {
    73         assert(device);
    74         uhci_t *hcd = NULL;
    75 #define CHECK_RET_FREE_HC_RETURN(ret, message...) \
    76 if (ret != EOK) { \
    77         usb_log_error(message); \
    78         if (hcd != NULL) \
    79                 free(hcd); \
    80         return ret; \
    81 }
    82150
    83         usb_log_info("uhci_add_device() called\n");
    84 
    85         uintptr_t io_reg_base = 0;
    86         size_t io_reg_size = 0;
    87         int irq = 0;
    88 
    89         int ret =
    90             pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);
    91         CHECK_RET_FREE_HC_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_disable_legacy(device);
    97         CHECK_RET_FREE_HC_RETURN(ret,
    98             "Failed(%d) disable legacy USB: %s.\n", ret, str_error(ret));
    99 
    100 #if 0
    101         ret = pci_enable_interrupts(device);
    102         if (ret != EOK) {
    103                 usb_log_warning(
    104                     "Failed(%d) to enable interrupts, fall back to polling.\n",
    105                     ret);
    106         }
    107 #endif
    108 
    109         hcd = malloc(sizeof(uhci_t));
    110         ret = (hcd != NULL) ? EOK : ENOMEM;
    111         CHECK_RET_FREE_HC_RETURN(ret,
    112             "Failed(%d) to allocate memory for uhci hcd.\n", ret);
    113 
    114         ret = uhci_init(hcd, device, (void*)io_reg_base, io_reg_size);
    115         CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to init uhci-hcd.\n",
    116             ret);
    117 #undef CHECK_RET_FREE_HC_RETURN
    118 
    119         /*
    120          * We might free hcd, but that does not matter since no one
    121          * else would access driver_data anyway.
    122          */
    123         device->driver_data = hcd;
    124 
    125         ddf_fun_t *rh = NULL;
    126 #define CHECK_RET_FINI_FREE_RETURN(ret, message...) \
    127 if (ret != EOK) { \
    128         usb_log_error(message); \
    129         if (hcd != NULL) {\
    130                 uhci_fini(hcd); \
    131                 free(hcd); \
    132         } \
    133         if (rh != NULL) \
    134                 free(rh); \
    135         return ret; \
    136 }
    137 
    138         /* It does no harm if we register this on polling */
    139         ret = register_interrupt_handler(device, irq, irq_handler,
    140             &hcd->interrupt_code);
    141         CHECK_RET_FINI_FREE_RETURN(ret,
    142             "Failed(%d) to register interrupt handler.\n", ret);
    143 
    144         ret = setup_root_hub(&rh, device);
    145         CHECK_RET_FINI_FREE_RETURN(ret,
    146             "Failed(%d) to setup UHCI root hub.\n", ret);
    147         rh->driver_data = hcd->ddf_instance;
    148 
    149         ret = ddf_fun_bind(rh);
    150         CHECK_RET_FINI_FREE_RETURN(ret,
    151             "Failed(%d) to register UHCI root hub.\n", ret);
    152 
    153         return EOK;
    154 #undef CHECK_RET_FINI_FREE_RETURN
    155 }
    156 /*----------------------------------------------------------------------------*/
    157151int main(int argc, char *argv[])
    158152{
    159         sleep(3);
    160         usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
     153        /*
     154         * Do some global initializations.
     155         */
     156        sleep(5);
     157        usb_log_enable(USB_LOG_LEVEL_INFO, NAME);
    161158
    162         return ddf_driver_main(&uhci_driver);
     159        return driver_main(&uhci_driver);
    163160}
    164161/**
Note: See TracChangeset for help on using the changeset viewer.