Ignore:
File:
1 edited

Legend:

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

    r56fd7cf r8820544  
    3434 */
    3535
    36 /* XXX Fix this */
    37 #define _DDF_DATA_IMPLANT
    38 
    3936#include <errno.h>
    4037#include <str_error.h>
     
    6259/** IRQ handling callback, identifies device
    6360 *
    64  * @param[in] dev DDF instance of the device to use.
    6561 * @param[in] iid (Unused).
    6662 * @param[in] call Pointer to the call that represents interrupt.
    67  */
    68 static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
     63 * @param[in] dev DDF instance of the device to use.
     64 *
     65 */
     66static void irq_handler(ipc_callid_t iid, ipc_call_t *call, ddf_dev_t *dev)
    6967{
    7068        assert(dev);
    71 
     69       
    7270        ohci_t *ohci = dev_to_ohci(dev);
    7371        if (!ohci) {
     
    7573                return;
    7674        }
     75       
    7776        const uint16_t status = IPC_GET_ARG1(*call);
    7877        hc_interrupt(&ohci->hc, status);
     
    143142int device_setup_ohci(ddf_dev_t *device)
    144143{
     144        bool ih_registered = false;
     145        bool hc_inited = false;
     146        int rc;
     147
    145148        if (device == NULL)
    146149                return EBADMEM;
     
    152155        }
    153156
    154 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
    155 if (ret != EOK) { \
    156         if (instance->hc_fun) { \
    157                 ddf_fun_destroy(instance->hc_fun); \
    158         } \
    159         if (instance->rh_fun) { \
    160                 ddf_fun_destroy(instance->rh_fun); \
    161         } \
    162         usb_log_error(message); \
    163         return ret; \
    164 } else (void)0
    165 
    166157        instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc");
    167         int ret = instance->hc_fun ? EOK : ENOMEM;
    168         CHECK_RET_DEST_FREE_RETURN(ret,
    169             "Failed to create OHCI HC function: %s.\n", str_error(ret));
     158        if (instance->hc_fun == NULL) {
     159                usb_log_error("Failed to create OHCI HC function: %s.\n",
     160                    str_error(ENOMEM));
     161                rc = ENOMEM;
     162                goto error;
     163        }
     164
    170165        ddf_fun_set_ops(instance->hc_fun, &hc_ops);
    171         ddf_fun_data_implant(instance->hc_fun, &instance->hc);
    172166
    173167        instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh");
    174         ret = instance->rh_fun ? EOK : ENOMEM;
    175         CHECK_RET_DEST_FREE_RETURN(ret,
    176             "Failed to create OHCI RH function: %s.\n", str_error(ret));
     168        if (instance->rh_fun == NULL) {
     169                usb_log_error("Failed to create OHCI RH function: %s.\n",
     170                    str_error(ENOMEM));
     171                rc = ENOMEM;
     172                goto error;
     173        }
     174
    177175        ddf_fun_set_ops(instance->rh_fun, &rh_ops);
    178176
    179         uintptr_t reg_base = 0;
    180         size_t reg_size = 0;
     177        addr_range_t regs;
    181178        int irq = 0;
    182179
    183         ret = get_my_registers(device, &reg_base, &reg_size, &irq);
    184         CHECK_RET_DEST_FREE_RETURN(ret,
    185             "Failed to get register memory addresses for %" PRIun ": %s.\n",
    186             ddf_dev_get_handle(device), str_error(ret));
     180        rc = get_my_registers(device, &regs, &irq);
     181        if (rc != EOK) {
     182                usb_log_error("Failed to get register memory addresses "
     183                    "for %" PRIun ": %s.\n", ddf_dev_get_handle(device),
     184                    str_error(rc));
     185                goto error;
     186        }
     187
    187188        usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n",
    188             (void *) reg_base, reg_size, irq);
    189 
    190         const size_t ranges_count = hc_irq_pio_range_count();
    191         const size_t cmds_count = hc_irq_cmd_count();
    192         irq_pio_range_t irq_ranges[ranges_count];
    193         irq_cmd_t irq_cmds[cmds_count];
    194         irq_code_t irq_code = {
    195                 .rangecount = ranges_count,
    196                 .ranges = irq_ranges,
    197                 .cmdcount = cmds_count,
    198                 .cmds = irq_cmds
    199         };
    200 
    201         ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
    202             sizeof(irq_cmds), reg_base, reg_size);
    203         CHECK_RET_DEST_FREE_RETURN(ret,
    204             "Failed to generate IRQ code: %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));
     189            RNGABSPTR(regs), RNGSZ(regs), irq);
     190
     191        rc = hc_register_irq_handler(device, &regs, irq, irq_handler);
     192        if (rc != EOK) {
     193                usb_log_error("Failed to register interrupt handler: %s.\n",
     194                    str_error(rc));
     195                goto error;
     196        }
     197
     198        ih_registered = true;
    211199
    212200        /* Try to enable interrupts */
    213201        bool interrupts = false;
    214         ret = enable_interrupts(device);
    215         if (ret != EOK) {
     202        rc = enable_interrupts(device);
     203        if (rc != EOK) {
    216204                usb_log_warning("Failed to enable interrupts: %s."
    217                     " Falling back to polling\n", str_error(ret));
     205                    " Falling back to polling\n", str_error(rc));
    218206                /* We don't need that handler */
    219207                unregister_interrupt_handler(device, irq);
     208                ih_registered = false;
    220209        } else {
    221210                usb_log_debug("Hw interrupts enabled.\n");
     
    223212        }
    224213
    225         ret = hc_init(&instance->hc, reg_base, reg_size, interrupts);
    226         CHECK_RET_DEST_FREE_RETURN(ret,
    227             "Failed to init ohci_hcd: %s.\n", str_error(ret));
    228 
    229 #define CHECK_RET_FINI_RETURN(ret, message...) \
    230 if (ret != EOK) { \
    231         hc_fini(&instance->hc); \
    232         unregister_interrupt_handler(device, irq); \
    233         CHECK_RET_DEST_FREE_RETURN(ret, message); \
    234 } else (void)0
    235 
    236 
    237         ret = ddf_fun_bind(instance->hc_fun);
    238         CHECK_RET_FINI_RETURN(ret,
    239             "Failed to bind OHCI device function: %s.\n", str_error(ret));
    240 
    241         ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
    242         CHECK_RET_FINI_RETURN(ret,
    243             "Failed to add OHCI to HC class: %s.\n", str_error(ret));
    244 
    245         ret = hc_register_hub(&instance->hc, instance->rh_fun);
    246         CHECK_RET_FINI_RETURN(ret,
    247             "Failed to register OHCI root hub: %s.\n", str_error(ret));
    248         return ret;
    249 
    250 #undef CHECK_RET_FINI_RETURN
     214        rc = hc_init(&instance->hc, instance->hc_fun, &regs, interrupts);
     215        if (rc != EOK) {
     216                usb_log_error("Failed to init ohci_hcd: %s.\n", str_error(rc));
     217                goto error;
     218        }
     219
     220        hc_inited = true;
     221
     222        rc = ddf_fun_bind(instance->hc_fun);
     223        if (rc != EOK) {
     224                usb_log_error("Failed to bind OHCI device function: %s.\n",
     225                    str_error(rc));
     226                goto error;
     227        }
     228
     229        rc = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
     230        if (rc != EOK) {
     231                usb_log_error("Failed to add OHCI to HC category: %s.\n",
     232                    str_error(rc));
     233                goto error;
     234        }
     235
     236        rc = hc_register_hub(&instance->hc, instance->rh_fun);
     237        if (rc != EOK) {
     238                usb_log_error("Failed to register OHCI root hub: %s.\n",
     239                    str_error(rc));
     240                goto error;
     241        }
     242
     243        return EOK;
     244
     245error:
     246        if (hc_inited)
     247                hc_fini(&instance->hc);
     248        if (ih_registered)
     249                unregister_interrupt_handler(device, irq);
     250        if (instance->hc_fun != NULL)
     251                ddf_fun_destroy(instance->hc_fun);
     252        if (instance->rh_fun != NULL)
     253                ddf_fun_destroy(instance->rh_fun);
     254        return rc;
    251255}
    252256/**
Note: See TracChangeset for help on using the changeset viewer.