Ignore:
File:
1 edited

Legend:

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

    r1dc4a5e r5203e256  
    5858{
    5959        assert(dev);
     60        assert(dev->driver_data);
    6061        return dev->driver_data;
    6162}
     63
    6264/** IRQ handling callback, identifies device
    6365 *
     
    6870static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
    6971{
    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         }
     72        hc_t *hc = &dev_to_ohci(dev)->hc;
     73        assert(hc);
    7774        const uint16_t status = IPC_GET_ARG1(*call);
    78         hc_interrupt(&ohci->hc, status);
     75        hc_interrupt(hc, status);
    7976}
    8077/*----------------------------------------------------------------------------*/
     
    169166        } \
    170167        free(instance); \
    171         device->driver_data = NULL; \
    172168        usb_log_error(message); \
    173169        return ret; \
     
    177173        instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc");
    178174        int ret = instance->hc_fun ? EOK : ENOMEM;
    179         CHECK_RET_DEST_FREE_RETURN(ret,
    180             "Failed to create OHCI HC function: %s.\n", str_error(ret));
     175        CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI HC function.\n");
    181176        instance->hc_fun->ops = &hc_ops;
    182177        instance->hc_fun->driver_data = &instance->hc;
     
    184179        instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh");
    185180        ret = instance->rh_fun ? EOK : ENOMEM;
    186         CHECK_RET_DEST_FREE_RETURN(ret,
    187             "Failed to create OHCI RH function: %s.\n", str_error(ret));
     181        CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create OHCI RH function.\n");
    188182        instance->rh_fun->ops = &rh_ops;
    189183
     
    199193            (void *) reg_base, reg_size, irq);
    200194
    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 */
    216195        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
    217200        ret = pci_enable_interrupts(device);
    218201        if (ret != EOK) {
    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);
     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");
    223206        } else {
    224207                usb_log_debug("Hw interrupts enabled.\n");
    225208                interrupts = true;
    226209        }
     210#endif
    227211
    228212        ret = hc_init(&instance->hc, reg_base, reg_size, interrupts);
    229         CHECK_RET_DEST_FREE_RETURN(ret,
    230             "Failed to init ohci_hcd: %s.\n", str_error(ret));
    231 
    232         device->driver_data = instance;
     213        CHECK_RET_DEST_FREE_RETURN(ret, "Failed(%d) to init ohci_hcd.\n", ret);
    233214
    234215#define CHECK_RET_FINI_RETURN(ret, message...) \
    235216if (ret != EOK) { \
    236         unregister_interrupt_handler(device, irq); \
    237217        hc_fini(&instance->hc); \
    238218        CHECK_RET_DEST_FREE_RETURN(ret, message); \
    239219} else (void)0
    240220
     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);
    241226
    242227        ret = ddf_fun_bind(instance->hc_fun);
    243228        CHECK_RET_FINI_RETURN(ret,
    244             "Failed to bind OHCI device function: %s.\n", str_error(ret));
    245 
    246         ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
     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);
    247233        CHECK_RET_FINI_RETURN(ret,
    248234            "Failed to add OHCI to HC class: %s.\n", str_error(ret));
    249235
     236        device->driver_data = instance;
     237
     238        hc_start_hw(&instance->hc);
    250239        hc_register_hub(&instance->hc, instance->rh_fun);
    251240        return EOK;
Note: See TracChangeset for help on using the changeset viewer.