Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 561f41b in mainline for uspace/drv/ohci/ohci.c


Ignore:
Timestamp:
2011-05-07T16:00:10Z (11 years ago)
Author:
Jan Vesely <jano.vesely@…>
Branches:
lfn, master
Children:
60b3bea
Parents:
b23e9cc (diff), 3ae5ca8 (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:

Major refactoring #211 should be fixed

UHCI: all interrupts are either communication driven or fatal
OHCI: control is taken only after we can handle interrupts

File:
1 edited

Legend:

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

    rb23e9cc r561f41b  
    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         assert(dev->driver_data);
    57         hc_t *hc = &((ohci_t*)dev->driver_data)->hc;
    58         uint16_t status = IPC_GET_ARG1(*call);
     72        hc_t *hc = &dev_to_ohci(dev)->hc;
    5973        assert(hc);
     74        const uint16_t status = IPC_GET_ARG1(*call);
    6075        hc_interrupt(hc, status);
    6176}
     
    7186{
    7287        assert(fun);
    73         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;
    7489
    7590        usb_address_t addr = usb_device_keeper_find(manager, handle);
     
    94109    ddf_fun_t *fun, devman_handle_t *handle)
    95110{
    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;
     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;
    101117        return EOK;
    102118}
    103119/*----------------------------------------------------------------------------*/
    104 /** This iface is generic for both RH and HC. */
     120/** Root hub USB interface */
    105121static usb_iface_t usb_iface = {
    106122        .get_hc_handle = usb_iface_get_hc_handle,
     
    108124};
    109125/*----------------------------------------------------------------------------*/
     126/** Standard USB HC options (HC interface) */
    110127static ddf_dev_ops_t hc_ops = {
    111128        .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
    112129};
    113130/*----------------------------------------------------------------------------*/
     131/** Standard USB RH options (RH interface) */
    114132static ddf_dev_ops_t rh_ops = {
    115133        .interfaces[USB_DEV_IFACE] = &usb_iface,
     
    118136/** Initialize hc and rh ddf structures and their respective drivers.
    119137 *
     138 * @param[in] device DDF instance of the device to use.
    120139 * @param[in] instance OHCI structure to use.
    121  * @param[in] device DDF instance of the device to use.
    122140 *
    123141 * This function does all the preparatory work for hc and rh drivers:
     
    127145 *  - registers interrupt handler
    128146 */
    129 int ohci_init(ohci_t *instance, ddf_dev_t *device)
    130 {
    131         assert(instance);
    132         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
    133172        instance->rh_fun = NULL;
    134 #define CHECK_RET_DEST_FUN_RETURN(ret, message...) \
    135 if (ret != EOK) { \
    136         usb_log_error(message); \
    137         if (instance->hc_fun) \
    138                 ddf_fun_destroy(instance->hc_fun); \
    139         if (instance->rh_fun) \
    140                 ddf_fun_destroy(instance->rh_fun); \
    141         return ret; \
    142 }
    143 
    144         uintptr_t mem_reg_base = 0;
    145         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;
    146186        int irq = 0;
    147187
    148         int ret =
    149             pci_get_my_registers(device, &mem_reg_base, &mem_reg_size, &irq);
    150         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,
    151190            "Failed to get memory addresses for %" PRIun ": %s.\n",
    152191            device->handle, str_error(ret));
    153192        usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n",
    154             (void *) mem_reg_base, mem_reg_size, irq);
     193            (void *) reg_base, reg_size, irq);
    155194
    156195        bool interrupts = false;
    157196#ifdef CONFIG_USBHC_NO_INTERRUPTS
    158         usb_log_warning("Interrupts disabled in OS config, " \
     197        usb_log_warning("Interrupts disabled in OS config, "
    159198            "falling back to polling.\n");
    160199#else
     
    163202                usb_log_warning("Failed to enable interrupts: %s.\n",
    164203                    str_error(ret));
    165                 usb_log_info("HW interrupts not available, " \
     204                usb_log_info("HW interrupts not available, "
    166205                    "falling back to polling.\n");
    167206        } else {
     
    171210#endif
    172211
    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         ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
    188         CHECK_RET_DEST_FUN_RETURN(ret,
    189             "Failed to add OHCI to HC class: %s.\n", str_error(ret));
    190 
    191 #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);
    192214
    193215#define CHECK_RET_FINI_RETURN(ret, message...) \
    194216if (ret != EOK) { \
    195         usb_log_error(message); \
    196         if (instance->hc_fun) \
    197                 ddf_fun_destroy(instance->hc_fun); \
    198         if (instance->rh_fun) \
    199                 ddf_fun_destroy(instance->rh_fun); \
    200217        hc_fini(&instance->hc); \
    201         return ret; \
    202 }
     218        CHECK_RET_DEST_FREE_RETURN(ret, message); \
     219} else (void)0
    203220
    204221        /* It does no harm if we register this on polling */
     
    208225            "Failed(%d) to register interrupt handler.\n", ret);
    209226
    210         instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci-rh");
    211         ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
     227        ret = ddf_fun_bind(instance->hc_fun);
    212228        CHECK_RET_FINI_RETURN(ret,
    213             "Failed(%d) to create root hub function.\n", ret);
    214 
    215 
    216         instance->rh_fun->ops = &rh_ops;
    217         instance->rh_fun->driver_data = NULL;
    218        
     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
    219236        device->driver_data = instance;
    220237
    221238        hc_start_hw(&instance->hc);
     239        hc_register_hub(&instance->hc, instance->rh_fun);
    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.