Changes in uspace/drv/ohci/ohci.c [d2bff2f:5d07f54] in mainline


Ignore:
File:
1 edited

Legend:

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

    rd2bff2f r5d07f54  
    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        assert(dev->driver_data);
     57        hc_t *hc = &((ohci_t*)dev->driver_data)->hc;
     58        uint16_t status = IPC_GET_ARG1(*call);
    7359        assert(hc);
    74         const uint16_t status = IPC_GET_ARG1(*call);
    7560        hc_interrupt(hc, status);
    7661}
     
    8671{
    8772        assert(fun);
    88         usb_device_keeper_t *manager = &dev_to_ohci(fun->dev)->hc.manager;
     73        usb_device_keeper_t *manager = &((ohci_t*)fun->dev->driver_data)->hc.manager;
    8974
    9075        usb_address_t addr = usb_device_keeper_find(manager, handle);
     
    10994    ddf_fun_t *fun, devman_handle_t *handle)
    11095{
    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;
     96        assert(handle);
     97        ddf_fun_t *hc_fun = ((ohci_t*)fun->dev->driver_data)->hc_fun;
     98        assert(hc_fun != NULL);
     99
     100        *handle = hc_fun->handle;
    117101        return EOK;
    118102}
    119103/*----------------------------------------------------------------------------*/
    120 /** Root hub USB interface */
     104/** This iface is generic for both RH and HC. */
    121105static usb_iface_t usb_iface = {
    122106        .get_hc_handle = usb_iface_get_hc_handle,
     
    124108};
    125109/*----------------------------------------------------------------------------*/
    126 /** Standard USB HC options (HC interface) */
    127110static ddf_dev_ops_t hc_ops = {
    128111        .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
    129112};
    130113/*----------------------------------------------------------------------------*/
    131 /** Standard USB RH options (RH interface) */
    132114static ddf_dev_ops_t rh_ops = {
    133115        .interfaces[USB_DEV_IFACE] = &usb_iface,
     
    136118/** Initialize hc and rh ddf structures and their respective drivers.
    137119 *
     120 * @param[in] instance OHCI structure to use.
    138121 * @param[in] device DDF instance of the device to use.
    139  * @param[in] instance OHCI structure to use.
    140122 *
    141123 * This function does all the preparatory work for hc and rh drivers:
     
    145127 *  - registers interrupt handler
    146128 */
    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...) \
     129int ohci_init(ohci_t *instance, ddf_dev_t *device)
     130{
     131        assert(instance);
     132        instance->hc_fun = NULL;
     133        instance->rh_fun = NULL;
     134#define CHECK_RET_DEST_FUN_RETURN(ret, message...) \
    156135if (ret != EOK) { \
    157         if (instance->hc_fun) { \
    158                 instance->hc_fun->ops = NULL; \
    159                 instance->hc_fun->driver_data = NULL; \
     136        usb_log_error(message); \
     137        if (instance->hc_fun) \
    160138                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; \
     139        if (instance->rh_fun) \
    165140                ddf_fun_destroy(instance->rh_fun); \
    166         } \
    167         free(instance); \
    168         usb_log_error(message); \
    169141        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;
     142}
     143
     144        uintptr_t mem_reg_base = 0;
     145        size_t mem_reg_size = 0;
    186146        int irq = 0;
    187147
    188         ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
    189         CHECK_RET_DEST_FREE_RETURN(ret,
     148        int ret =
     149            pci_get_my_registers(device, &mem_reg_base, &mem_reg_size, &irq);
     150        CHECK_RET_DEST_FUN_RETURN(ret,
    190151            "Failed to get memory addresses for %" PRIun ": %s.\n",
    191152            device->handle, str_error(ret));
    192153        usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n",
    193             (void *) reg_base, reg_size, irq);
     154            (void *) mem_reg_base, mem_reg_size, irq);
    194155
    195156        bool interrupts = false;
    196157#ifdef CONFIG_USBHC_NO_INTERRUPTS
    197         usb_log_warning("Interrupts disabled in OS config, "
     158        usb_log_warning("Interrupts disabled in OS config, " \
    198159            "falling back to polling.\n");
    199160#else
     
    202163                usb_log_warning("Failed to enable interrupts: %s.\n",
    203164                    str_error(ret));
    204                 usb_log_info("HW interrupts not available, "
     165                usb_log_info("HW interrupts not available, " \
    205166                    "falling back to polling.\n");
    206167        } else {
     
    210171#endif
    211172
    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);
     173        instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci-hc");
     174        ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
     175        CHECK_RET_DEST_FUN_RETURN(ret,
     176            "Failed(%d) to create HC function.\n", ret);
     177
     178        ret = hc_init(&instance->hc, instance->hc_fun, device,
     179            mem_reg_base, mem_reg_size, interrupts);
     180        CHECK_RET_DEST_FUN_RETURN(ret, "Failed(%d) to init ohci-hcd.\n", ret);
     181        instance->hc_fun->ops = &hc_ops;
     182        instance->hc_fun->driver_data = &instance->hc;
     183        ret = ddf_fun_bind(instance->hc_fun);
     184        CHECK_RET_DEST_FUN_RETURN(ret,
     185            "Failed(%d) to bind OHCI device function: %s.\n",
     186            ret, str_error(ret));
     187#undef CHECK_RET_HC_RETURN
    214188
    215189#define CHECK_RET_FINI_RETURN(ret, message...) \
    216190if (ret != EOK) { \
     191        usb_log_error(message); \
     192        if (instance->hc_fun) \
     193                ddf_fun_destroy(instance->hc_fun); \
     194        if (instance->rh_fun) \
     195                ddf_fun_destroy(instance->rh_fun); \
    217196        hc_fini(&instance->hc); \
    218         CHECK_RET_DEST_FREE_RETURN(ret, message); \
    219 } else (void)0
     197        return ret; \
     198}
    220199
    221200        /* It does no harm if we register this on polling */
     
    225204            "Failed(%d) to register interrupt handler.\n", ret);
    226205
    227         ret = ddf_fun_bind(instance->hc_fun);
     206        instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci-rh");
     207        ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
    228208        CHECK_RET_FINI_RETURN(ret,
    229             "Failed(%d) to bind OHCI device function: %s.\n",
    230             ret, str_error(ret));
    231 
     209            "Failed(%d) to create root hub function.\n", ret);
     210
     211
     212        instance->rh_fun->ops = &rh_ops;
     213        instance->rh_fun->driver_data = NULL;
     214       
    232215        device->driver_data = instance;
    233216
    234217        hc_start_hw(&instance->hc);
    235         hc_register_hub(&instance->hc, instance->rh_fun);
    236218        return EOK;
    237 
    238 #undef CHECK_RET_DEST_FUN_RETURN
    239219#undef CHECK_RET_FINI_RETURN
    240220}
Note: See TracChangeset for help on using the changeset viewer.