Changeset 9e195e2c in mainline for uspace/drv/ohci/ohci.c


Ignore:
Timestamp:
2011-05-12T09:03:00Z (13 years ago)
Author:
Lubos Slovak <lubos.slovak@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d59d0bb
Parents:
456aea3 (diff), c372e03 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from development

File:
1 edited

Legend:

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

    r456aea3 r9e195e2c  
    4444#include "iface.h"
    4545#include "pci.h"
     46#include "hc.h"
     47#include "root_hub.h"
     48
     49typedef 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
     57static 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}
    4663
    4764/** IRQ handling callback, identifies device
     
    5370static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    5471{
    55         assert(dev);
    56         hc_t *hc = &((ohci_t*)dev->driver_data)->hc;
    57         uint16_t status = IPC_GET_ARG1(*call);
     72        hc_t *hc = &dev_to_ohci(dev)->hc;
    5873        assert(hc);
     74        const uint16_t status = IPC_GET_ARG1(*call);
    5975        hc_interrupt(hc, status);
    6076}
     
    7086{
    7187        assert(fun);
    72         usb_device_keeper_t *manager = &((ohci_t*)fun->dev->driver_data)->hc.manager;
     88        usb_device_keeper_t *manager = &dev_to_ohci(fun->dev)->hc.manager;
    7389
    7490        usb_address_t addr = usb_device_keeper_find(manager, handle);
     
    93109    ddf_fun_t *fun, devman_handle_t *handle)
    94110{
    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;
     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;
    100117        return EOK;
    101118}
    102119/*----------------------------------------------------------------------------*/
    103 /** This iface is generic for both RH and HC. */
     120/** Root hub USB interface */
    104121static usb_iface_t usb_iface = {
    105122        .get_hc_handle = usb_iface_get_hc_handle,
     
    107124};
    108125/*----------------------------------------------------------------------------*/
     126/** Standard USB HC options (HC interface) */
    109127static ddf_dev_ops_t hc_ops = {
    110128        .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
    111129};
    112130/*----------------------------------------------------------------------------*/
     131/** Standard USB RH options (RH interface) */
    113132static ddf_dev_ops_t rh_ops = {
    114133        .interfaces[USB_DEV_IFACE] = &usb_iface,
     
    117136/** Initialize hc and rh ddf structures and their respective drivers.
    118137 *
     138 * @param[in] device DDF instance of the device to use.
    119139 * @param[in] instance OHCI structure to use.
    120  * @param[in] device DDF instance of the device to use.
    121140 *
    122141 * This function does all the preparatory work for hc and rh drivers:
     
    126145 *  - registers interrupt handler
    127146 */
    128 int ohci_init(ohci_t *instance, ddf_dev_t *device)
    129 {
    130         assert(instance);
    131         instance->hc_fun = NULL;
     147int 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...) \
     156if (ret != EOK) { \
     157        if (instance->hc_fun) { \
     158                instance->hc_fun->ops = NULL; \
     159                instance->hc_fun->driver_data = NULL; \
     160                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; \
     165                ddf_fun_destroy(instance->rh_fun); \
     166        } \
     167        free(instance); \
     168        usb_log_error(message); \
     169        return ret; \
     170} else (void)0
     171
    132172        instance->rh_fun = NULL;
    133 #define CHECK_RET_DEST_FUN_RETURN(ret, message...) \
    134 if (ret != EOK) { \
    135         usb_log_error(message); \
    136         if (instance->hc_fun) \
    137                 ddf_fun_destroy(instance->hc_fun); \
    138         if (instance->rh_fun) \
    139                 ddf_fun_destroy(instance->rh_fun); \
    140         return ret; \
    141 }
    142 
    143         uintptr_t mem_reg_base = 0;
    144         size_t mem_reg_size = 0;
     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;
    145186        int irq = 0;
    146187
    147         int ret =
    148             pci_get_my_registers(device, &mem_reg_base, &mem_reg_size, &irq);
    149         CHECK_RET_DEST_FUN_RETURN(ret,
     188        ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
     189        CHECK_RET_DEST_FREE_RETURN(ret,
    150190            "Failed to get memory addresses for %" PRIun ": %s.\n",
    151191            device->handle, str_error(ret));
    152192        usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n",
    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));
     193            (void *) reg_base, reg_size, irq);
    158194
    159195        bool interrupts = false;
    160196#ifdef CONFIG_USBHC_NO_INTERRUPTS
    161         usb_log_warning("Interrupts disabled in OS config, " \
     197        usb_log_warning("Interrupts disabled in OS config, "
    162198            "falling back to polling.\n");
    163199#else
     
    166202                usb_log_warning("Failed to enable interrupts: %s.\n",
    167203                    str_error(ret));
    168                 usb_log_info("HW interrupts not available, " \
     204                usb_log_info("HW interrupts not available, "
    169205                    "falling back to polling.\n");
    170206        } else {
     
    174210#endif
    175211
    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
     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);
    191214
    192215#define CHECK_RET_FINI_RETURN(ret, message...) \
    193216if (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); \
    199217        hc_fini(&instance->hc); \
    200         return ret; \
    201 }
     218        CHECK_RET_DEST_FREE_RETURN(ret, message); \
     219} else (void)0
    202220
    203221        /* It does no harm if we register this on polling */
     
    207225            "Failed(%d) to register interrupt handler.\n", ret);
    208226
    209         instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci-rh");
    210         ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
     227        ret = ddf_fun_bind(instance->hc_fun);
    211228        CHECK_RET_FINI_RETURN(ret,
    212             "Failed(%d) to create root hub function.\n", ret);
    213 
     229            "Failed(%d) to bind OHCI device function: %s.\n",
     230            ret, str_error(ret));
     231
     232        ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
     233        CHECK_RET_FINI_RETURN(ret,
     234            "Failed to add OHCI to HC class: %s.\n", str_error(ret));
     235
     236        device->driver_data = instance;
     237
     238        hc_start_hw(&instance->hc);
    214239        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 
    222240        return EOK;
     241
     242#undef CHECK_RET_DEST_FUN_RETURN
    223243#undef CHECK_RET_FINI_RETURN
    224244}
Note: See TracChangeset for help on using the changeset viewer.