Changes in uspace/drv/ohci/ohci.c [d2bff2f:561112f] in mainline


Ignore:
File:
1 edited

Legend:

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

    rd2bff2f r561112f  
    4444#include "iface.h"
    4545#include "pci.h"
    46 #include "hc.h"
    47 #include "root_hub.h"
    48 
    49 typedef struct ohci {
    50         ddf_fun_t *hc_fun;
    51         ddf_fun_t *rh_fun;
    52 
    53         hc_t hc;
    54         rh_t rh;
    55 } ohci_t;
    56 
    57 static inline ohci_t * dev_to_ohci(ddf_dev_t *dev)
    58 {
    59         assert(dev);
    60         assert(dev->driver_data);
    61         return dev->driver_data;
    62 }
    6346
    6447/** IRQ handling callback, identifies device
     
    7053static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    7154{
    72         hc_t *hc = &dev_to_ohci(dev)->hc;
     55        assert(dev);
     56        hc_t *hc = &((ohci_t*)dev->driver_data)->hc;
     57        uint16_t status = IPC_GET_ARG1(*call);
    7358        assert(hc);
    74         const uint16_t status = IPC_GET_ARG1(*call);
    7559        hc_interrupt(hc, status);
    7660}
     
    8670{
    8771        assert(fun);
    88         usb_device_keeper_t *manager = &dev_to_ohci(fun->dev)->hc.manager;
     72        usb_device_keeper_t *manager = &((ohci_t*)fun->dev->driver_data)->hc.manager;
    8973
    9074        usb_address_t addr = usb_device_keeper_find(manager, handle);
     
    10993    ddf_fun_t *fun, devman_handle_t *handle)
    11094{
    111         assert(fun);
    112         ddf_fun_t *hc_fun = dev_to_ohci(fun->dev)->hc_fun;
    113         assert(hc_fun);
    114 
    115         if (handle != NULL)
    116                 *handle = hc_fun->handle;
     95        assert(handle);
     96        ddf_fun_t *hc_fun = ((ohci_t*)fun->dev->driver_data)->hc_fun;
     97        assert(hc_fun != NULL);
     98
     99        *handle = hc_fun->handle;
    117100        return EOK;
    118101}
    119102/*----------------------------------------------------------------------------*/
    120 /** Root hub USB interface */
     103/** This iface is generic for both RH and HC. */
    121104static usb_iface_t usb_iface = {
    122105        .get_hc_handle = usb_iface_get_hc_handle,
     
    124107};
    125108/*----------------------------------------------------------------------------*/
    126 /** Standard USB HC options (HC interface) */
    127109static ddf_dev_ops_t hc_ops = {
    128110        .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
    129111};
    130112/*----------------------------------------------------------------------------*/
    131 /** Standard USB RH options (RH interface) */
    132113static ddf_dev_ops_t rh_ops = {
    133114        .interfaces[USB_DEV_IFACE] = &usb_iface,
     
    136117/** Initialize hc and rh ddf structures and their respective drivers.
    137118 *
     119 * @param[in] instance OHCI structure to use.
    138120 * @param[in] device DDF instance of the device to use.
    139  * @param[in] instance OHCI structure to use.
    140121 *
    141122 * This function does all the preparatory work for hc and rh drivers:
     
    145126 *  - registers interrupt handler
    146127 */
    147 int device_setup_ohci(ddf_dev_t *device)
    148 {
    149         ohci_t *instance = malloc(sizeof(ohci_t));
    150         if (instance == NULL) {
    151                 usb_log_error("Failed to allocate OHCI driver.\n");
    152                 return ENOMEM;
    153         }
    154 
    155 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
     128int ohci_init(ohci_t *instance, ddf_dev_t *device)
     129{
     130        assert(instance);
     131        instance->hc_fun = NULL;
     132        instance->rh_fun = NULL;
     133#define CHECK_RET_DEST_FUN_RETURN(ret, message...) \
    156134if (ret != EOK) { \
    157         if (instance->hc_fun) { \
    158                 instance->hc_fun->ops = NULL; \
    159                 instance->hc_fun->driver_data = NULL; \
     135        usb_log_error(message); \
     136        if (instance->hc_fun) \
    160137                ddf_fun_destroy(instance->hc_fun); \
    161         } \
    162         if (instance->rh_fun) { \
    163                 instance->rh_fun->ops = NULL; \
    164                 instance->rh_fun->driver_data = NULL; \
     138        if (instance->rh_fun) \
    165139                ddf_fun_destroy(instance->rh_fun); \
    166         } \
    167         free(instance); \
    168         usb_log_error(message); \
    169140        return ret; \
    170 } else (void)0
    171 
    172         instance->rh_fun = NULL;
    173         instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc");
    174         int ret = instance->hc_fun ? EOK : ENOMEM;
    175         CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI HC function.\n");
    176         instance->hc_fun->ops = &hc_ops;
    177         instance->hc_fun->driver_data = &instance->hc;
    178 
    179         instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci-rh");
    180         ret = instance->rh_fun ? EOK : ENOMEM;
    181         CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI RH function.\n");
    182         instance->rh_fun->ops = &rh_ops;
    183 
    184         uintptr_t reg_base = 0;
    185         size_t reg_size = 0;
     141}
     142
     143        uintptr_t mem_reg_base = 0;
     144        size_t mem_reg_size = 0;
    186145        int irq = 0;
    187146
    188         ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
    189         CHECK_RET_DEST_FREE_RETURN(ret,
     147        int ret =
     148            pci_get_my_registers(device, &mem_reg_base, &mem_reg_size, &irq);
     149        CHECK_RET_DEST_FUN_RETURN(ret,
    190150            "Failed to get memory addresses for %" PRIun ": %s.\n",
    191151            device->handle, str_error(ret));
    192152        usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n",
    193             (void *) reg_base, reg_size, irq);
     153            (void *) mem_reg_base, mem_reg_size, irq);
     154
     155        ret = pci_disable_legacy(device);
     156        CHECK_RET_DEST_FUN_RETURN(ret,
     157            "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret));
    194158
    195159        bool interrupts = false;
    196160#ifdef CONFIG_USBHC_NO_INTERRUPTS
    197         usb_log_warning("Interrupts disabled in OS config, "
     161        usb_log_warning("Interrupts disabled in OS config, " \
    198162            "falling back to polling.\n");
    199163#else
     
    202166                usb_log_warning("Failed to enable interrupts: %s.\n",
    203167                    str_error(ret));
    204                 usb_log_info("HW interrupts not available, "
     168                usb_log_info("HW interrupts not available, " \
    205169                    "falling back to polling.\n");
    206170        } else {
     
    210174#endif
    211175
    212         ret = hc_init(&instance->hc, reg_base, reg_size, interrupts);
    213         CHECK_RET_DEST_FREE_RETURN(ret, "Failed(%d) to init ohci-hcd.\n", ret);
     176        instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc");
     177        ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
     178        CHECK_RET_DEST_FUN_RETURN(ret,
     179            "Failed(%d) to create HC function.\n", ret);
     180
     181        ret = hc_init(&instance->hc, instance->hc_fun, device,
     182            mem_reg_base, mem_reg_size, interrupts);
     183        CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to init ohci-hcd.\n", ret);
     184        instance->hc_fun->ops = &hc_ops;
     185        instance->hc_fun->driver_data = &instance->hc;
     186        ret = ddf_fun_bind(instance->hc_fun);
     187        CHECK_RET_DEST_FUN_RETURN(ret,
     188            "Failed(%d) to bind OHCI device function: %s.\n",
     189            ret, str_error(ret));
     190#undef CHECK_RET_HC_RETURN
    214191
    215192#define CHECK_RET_FINI_RETURN(ret, message...) \
    216193if (ret != EOK) { \
     194        usb_log_error(message); \
     195        if (instance->hc_fun) \
     196                ddf_fun_destroy(instance->hc_fun); \
     197        if (instance->rh_fun) \
     198                ddf_fun_destroy(instance->rh_fun); \
    217199        hc_fini(&instance->hc); \
    218         CHECK_RET_DEST_FREE_RETURN(ret, message); \
    219 } else (void)0
     200        return ret; \
     201}
    220202
    221203        /* It does no harm if we register this on polling */
     
    225207            "Failed(%d) to register interrupt handler.\n", ret);
    226208
    227         ret = ddf_fun_bind(instance->hc_fun);
     209        instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci-rh");
     210        ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
    228211        CHECK_RET_FINI_RETURN(ret,
    229             "Failed(%d) to bind OHCI device function: %s.\n",
    230             ret, str_error(ret));
    231 
    232         device->driver_data = instance;
    233 
    234         hc_start_hw(&instance->hc);
     212            "Failed(%d) to create root hub function.\n", ret);
     213
    235214        hc_register_hub(&instance->hc, instance->rh_fun);
     215
     216        instance->rh_fun->ops = &rh_ops;
     217        instance->rh_fun->driver_data = NULL;
     218        ret = ddf_fun_bind(instance->rh_fun);
     219        CHECK_RET_FINI_RETURN(ret,
     220            "Failed(%d) to register OHCI root hub.\n", ret);
     221
    236222        return EOK;
    237 
    238 #undef CHECK_RET_DEST_FUN_RETURN
    239223#undef CHECK_RET_FINI_RETURN
    240224}
Note: See TracChangeset for help on using the changeset viewer.