Changeset 26e7d6d in mainline for uspace/drv/bus/usb/ohci/ohci.c


Ignore:
Timestamp:
2011-09-19T16:31:00Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
a347a11
Parents:
3842a955 (diff), 086290d (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 mainline changes

File:
1 moved

Legend:

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

    r3842a955 r26e7d6d  
    4242
    4343#include "ohci.h"
    44 #include "iface.h"
    4544#include "pci.h"
    4645#include "hc.h"
    47 #include "root_hub.h"
    4846
    4947typedef struct ohci {
     
    5250
    5351        hc_t hc;
    54         rh_t rh;
    5552} ohci_t;
    5653
     
    5855{
    5956        assert(dev);
    60         assert(dev->driver_data);
    6157        return dev->driver_data;
    6258}
    63 
    6459/** IRQ handling callback, identifies device
    6560 *
     
    7065static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    7166{
    72         hc_t *hc = &dev_to_ohci(dev)->hc;
    73         assert(hc);
     67        assert(dev);
     68
     69        ohci_t *ohci = dev_to_ohci(dev);
     70        if (!ohci) {
     71                usb_log_warning("Interrupt on device that is not ready.\n");
     72                return;
     73        }
    7474        const uint16_t status = IPC_GET_ARG1(*call);
    75         hc_interrupt(hc, status);
     75        hc_interrupt(&ohci->hc, status);
    7676}
    7777/*----------------------------------------------------------------------------*/
     
    8686{
    8787        assert(fun);
    88         usb_device_keeper_t *manager = &dev_to_ohci(fun->dev)->hc.manager;
    89 
    90         usb_address_t addr = usb_device_keeper_find(manager, handle);
     88        usb_device_manager_t *manager =
     89            &dev_to_ohci(fun->dev)->hc.generic.dev_manager;
     90
     91        const usb_address_t addr = usb_device_manager_find(manager, handle);
    9192        if (addr < 0) {
    9293                return addr;
     
    126127/** Standard USB HC options (HC interface) */
    127128static ddf_dev_ops_t hc_ops = {
    128         .interfaces[USBHC_DEV_IFACE] = &hc_iface, /* see iface.h/c */
     129        .interfaces[USBHC_DEV_IFACE] = &hcd_iface,
    129130};
    130131/*----------------------------------------------------------------------------*/
     
    147148int device_setup_ohci(ddf_dev_t *device)
    148149{
     150        assert(device);
     151
    149152        ohci_t *instance = malloc(sizeof(ohci_t));
    150153        if (instance == NULL) {
     
    152155                return ENOMEM;
    153156        }
     157        instance->rh_fun = NULL;
     158        instance->hc_fun = NULL;
    154159
    155160#define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
    156161if (ret != EOK) { \
    157162        if (instance->hc_fun) { \
    158                 instance->hc_fun->ops = NULL; \
    159                 instance->hc_fun->driver_data = NULL; \
    160163                ddf_fun_destroy(instance->hc_fun); \
    161164        } \
    162165        if (instance->rh_fun) { \
    163                 instance->rh_fun->ops = NULL; \
    164                 instance->rh_fun->driver_data = NULL; \
    165166                ddf_fun_destroy(instance->rh_fun); \
    166167        } \
     
    170171} else (void)0
    171172
    172         instance->rh_fun = NULL;
    173173        instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc");
    174174        int ret = instance->hc_fun ? EOK : ENOMEM;
    175         CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI HC function.\n");
     175        CHECK_RET_DEST_FREE_RETURN(ret,
     176            "Failed to create OHCI HC function: %s.\n", str_error(ret));
    176177        instance->hc_fun->ops = &hc_ops;
    177178        instance->hc_fun->driver_data = &instance->hc;
     
    179180        instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh");
    180181        ret = instance->rh_fun ? EOK : ENOMEM;
    181         CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI RH function.\n");
     182        CHECK_RET_DEST_FREE_RETURN(ret,
     183            "Failed to create OHCI RH function: %s.\n", str_error(ret));
    182184        instance->rh_fun->ops = &rh_ops;
    183185
     
    188190        ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
    189191        CHECK_RET_DEST_FREE_RETURN(ret,
    190             "Failed to get memory addresses for %" PRIun ": %s.\n",
     192            "Failed to get register memory addresses for %" PRIun ": %s.\n",
    191193            device->handle, str_error(ret));
    192194        usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n",
    193195            (void *) reg_base, reg_size, irq);
    194196
     197        const size_t cmd_count = hc_irq_cmd_count();
     198        irq_cmd_t irq_cmds[cmd_count];
     199        irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = irq_cmds };
     200
     201        ret =
     202            hc_get_irq_commands(irq_cmds, sizeof(irq_cmds), reg_base, reg_size);
     203        CHECK_RET_DEST_FREE_RETURN(ret,
     204            "Failed to generate IRQ commands: %s.\n", str_error(ret));
     205
     206
     207        /* Register handler to avoid interrupt lockup */
     208        ret = register_interrupt_handler(device, irq, irq_handler, &irq_code);
     209        CHECK_RET_DEST_FREE_RETURN(ret,
     210            "Failed to register interrupt handler: %s.\n", str_error(ret));
     211
     212        /* Try to enable interrupts */
    195213        bool interrupts = false;
    196 #ifdef CONFIG_USBHC_NO_INTERRUPTS
    197         usb_log_warning("Interrupts disabled in OS config, "
    198             "falling back to polling.\n");
    199 #else
    200214        ret = pci_enable_interrupts(device);
    201215        if (ret != EOK) {
    202                 usb_log_warning("Failed to enable interrupts: %s.\n",
    203                     str_error(ret));
    204                 usb_log_info("HW interrupts not available, "
    205                     "falling back to polling.\n");
     216                usb_log_warning("Failed to enable interrupts: %s."
     217                    " Falling back to polling\n", str_error(ret));
     218                /* We don't need that handler */
     219                unregister_interrupt_handler(device, irq);
    206220        } else {
    207221                usb_log_debug("Hw interrupts enabled.\n");
    208222                interrupts = true;
    209223        }
    210 #endif
    211224
    212225        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);
     226        CHECK_RET_DEST_FREE_RETURN(ret,
     227            "Failed to init ohci_hcd: %s.\n", str_error(ret));
     228
     229        device->driver_data = instance;
    214230
    215231#define CHECK_RET_FINI_RETURN(ret, message...) \
    216232if (ret != EOK) { \
    217233        hc_fini(&instance->hc); \
     234        unregister_interrupt_handler(device, irq); \
    218235        CHECK_RET_DEST_FREE_RETURN(ret, message); \
    219236} else (void)0
    220237
    221         /* It does no harm if we register this on polling */
    222         ret = register_interrupt_handler(device, irq, irq_handler,
    223             &instance->hc.interrupt_code);
    224         CHECK_RET_FINI_RETURN(ret,
    225             "Failed(%d) to register interrupt handler.\n", ret);
    226238
    227239        ret = ddf_fun_bind(instance->hc_fun);
    228240        CHECK_RET_FINI_RETURN(ret,
    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);
     241            "Failed to bind OHCI device function: %s.\n", str_error(ret));
     242
     243        ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
    233244        CHECK_RET_FINI_RETURN(ret,
    234245            "Failed to add OHCI to HC class: %s.\n", str_error(ret));
    235246
    236         device->driver_data = instance;
    237 
    238         hc_start_hw(&instance->hc);
    239         hc_register_hub(&instance->hc, instance->rh_fun);
    240         return EOK;
    241 
    242 #undef CHECK_RET_DEST_FUN_RETURN
     247        ret = hc_register_hub(&instance->hc, instance->rh_fun);
     248        CHECK_RET_FINI_RETURN(ret,
     249            "Failed to register OHCI root hub: %s.\n", str_error(ret));
     250        return ret;
     251
    243252#undef CHECK_RET_FINI_RETURN
    244253}
Note: See TracChangeset for help on using the changeset viewer.