Changeset 159100a in mainline for uspace/drv/bus/usb/ohci/ohci.c


Ignore:
Timestamp:
2011-07-13T22:19:26Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
ef9460b
Parents:
3e5c48c9 (diff), 5d36062 (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 OHCI improvements and fixes.

File:
1 edited

Legend:

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

    r3e5c48c9 r159100a  
    5858{
    5959        assert(dev);
    60         assert(dev->driver_data);
    6160        return dev->driver_data;
    6261}
    63 
    6462/** IRQ handling callback, identifies device
    6563 *
     
    7068static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    7169{
    72         hc_t *hc = &dev_to_ohci(dev)->hc;
    73         assert(hc);
     70        assert(dev);
     71
     72        ohci_t *ohci = dev_to_ohci(dev);
     73        if (!ohci) {
     74                usb_log_warning("Interrupt on device that is not ready.\n");
     75                return;
     76        }
    7477        const uint16_t status = IPC_GET_ARG1(*call);
    75         hc_interrupt(hc, status);
     78        hc_interrupt(&ohci->hc, status);
    7679}
    7780/*----------------------------------------------------------------------------*/
     
    166169        } \
    167170        free(instance); \
     171        device->driver_data = NULL; \
    168172        usb_log_error(message); \
    169173        return ret; \
     
    173177        instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc");
    174178        int ret = instance->hc_fun ? EOK : ENOMEM;
    175         CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI HC function.\n");
     179        CHECK_RET_DEST_FREE_RETURN(ret,
     180            "Failed to create OHCI HC function: %s.\n", str_error(ret));
    176181        instance->hc_fun->ops = &hc_ops;
    177182        instance->hc_fun->driver_data = &instance->hc;
     
    179184        instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh");
    180185        ret = instance->rh_fun ? EOK : ENOMEM;
    181         CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI RH function.\n");
     186        CHECK_RET_DEST_FREE_RETURN(ret,
     187            "Failed to create OHCI RH function: %s.\n", str_error(ret));
    182188        instance->rh_fun->ops = &rh_ops;
    183189
     
    193199            (void *) reg_base, reg_size, irq);
    194200
     201        const size_t cmd_count = hc_irq_cmd_count();
     202        irq_cmd_t irq_cmds[cmd_count];
     203        ret =
     204            hc_get_irq_commands(irq_cmds, sizeof(irq_cmds), reg_base, reg_size);
     205        CHECK_RET_DEST_FREE_RETURN(ret,
     206            "Failed to generate IRQ commands: %s.\n", str_error(ret));
     207
     208        irq_code_t irq_code = { .cmdcount = cmd_count, .cmds = irq_cmds };
     209
     210        /* Register handler to avoid interrupt lockup */
     211        ret = register_interrupt_handler(device, irq, irq_handler, &irq_code);
     212        CHECK_RET_DEST_FREE_RETURN(ret,
     213            "Failed to register interrupt handler: %s.\n", str_error(ret));
     214
     215        /* Try to enable interrupts */
    195216        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
    200217        ret = pci_enable_interrupts(device);
    201218        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");
     219                usb_log_warning("Failed to enable interrupts: %s."
     220                    " Falling back to polling\n", str_error(ret));
     221                /* We don't need that handler */
     222                unregister_interrupt_handler(device, irq);
    206223        } else {
    207224                usb_log_debug("Hw interrupts enabled.\n");
    208225                interrupts = true;
    209226        }
    210 #endif
    211227
    212228        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);
     229        CHECK_RET_DEST_FREE_RETURN(ret,
     230            "Failed to init ohci_hcd: %s.\n", str_error(ret));
     231
     232        device->driver_data = instance;
    214233
    215234#define CHECK_RET_FINI_RETURN(ret, message...) \
    216235if (ret != EOK) { \
     236        unregister_interrupt_handler(device, irq); \
    217237        hc_fini(&instance->hc); \
    218238        CHECK_RET_DEST_FREE_RETURN(ret, message); \
    219239} else (void)0
    220240
    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);
    226241
    227242        ret = ddf_fun_bind(instance->hc_fun);
    228243        CHECK_RET_FINI_RETURN(ret,
    229             "Failed(%d) to bind OHCI device function: %s.\n",
    230             ret, str_error(ret));
     244            "Failed to bind OHCI device function: %s.\n", str_error(ret));
    231245
    232246        ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
     
    234248            "Failed to add OHCI to HC class: %s.\n", str_error(ret));
    235249
    236         device->driver_data = instance;
    237 
    238         hc_start_hw(&instance->hc);
    239250        hc_register_hub(&instance->hc, instance->rh_fun);
    240251        return EOK;
Note: See TracChangeset for help on using the changeset viewer.