Ignore:
File:
1 edited

Legend:

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

    r56fd7cf r7de1988c  
    143143int device_setup_ohci(ddf_dev_t *device)
    144144{
     145        bool ih_registered = false;
     146        bool hc_inited = false;
     147        int rc;
     148
    145149        if (device == NULL)
    146150                return EBADMEM;
     
    152156        }
    153157
    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 
    166158        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));
     159        if (instance->hc_fun == NULL) {
     160                usb_log_error("Failed to create OHCI HC function: %s.\n",
     161                    str_error(ENOMEM));
     162                rc = ENOMEM;
     163                goto error;
     164        }
     165
    170166        ddf_fun_set_ops(instance->hc_fun, &hc_ops);
    171167        ddf_fun_data_implant(instance->hc_fun, &instance->hc);
    172168
    173169        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));
     170        if (instance->rh_fun == NULL) {
     171                usb_log_error("Failed to create OHCI RH function: %s.\n",
     172                    str_error(ENOMEM));
     173                rc = ENOMEM;
     174                goto error;
     175        }
     176
    177177        ddf_fun_set_ops(instance->rh_fun, &rh_ops);
    178178
    179         uintptr_t reg_base = 0;
    180         size_t reg_size = 0;
     179        addr_range_t regs;
    181180        int irq = 0;
    182181
    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));
     182        rc = get_my_registers(device, &regs, &irq);
     183        if (rc != EOK) {
     184                usb_log_error("Failed to get register memory addresses "
     185                    "for %" PRIun ": %s.\n", ddf_dev_get_handle(device),
     186                    str_error(rc));
     187                goto error;
     188        }
     189
    187190        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));
     191            RNGABSPTR(regs), RNGSZ(regs), irq);
     192
     193        rc = hc_register_irq_handler(device, &regs, irq, irq_handler);
     194        if (rc != EOK) {
     195                usb_log_error("Failed to register interrupt handler: %s.\n",
     196                    str_error(rc));
     197                goto error;
     198        }
     199
     200        ih_registered = true;
    211201
    212202        /* Try to enable interrupts */
    213203        bool interrupts = false;
    214         ret = enable_interrupts(device);
    215         if (ret != EOK) {
     204        rc = enable_interrupts(device);
     205        if (rc != EOK) {
    216206                usb_log_warning("Failed to enable interrupts: %s."
    217                     " Falling back to polling\n", str_error(ret));
     207                    " Falling back to polling\n", str_error(rc));
    218208                /* We don't need that handler */
    219209                unregister_interrupt_handler(device, irq);
     210                ih_registered = false;
    220211        } else {
    221212                usb_log_debug("Hw interrupts enabled.\n");
     
    223214        }
    224215
    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
     216        rc = hc_init(&instance->hc, &regs, interrupts);
     217        if (rc != EOK) {
     218                usb_log_error("Failed to init ohci_hcd: %s.\n", str_error(rc));
     219                goto error;
     220        }
     221
     222        hc_inited = true;
     223
     224        rc = ddf_fun_bind(instance->hc_fun);
     225        if (rc != EOK) {
     226                usb_log_error("Failed to bind OHCI device function: %s.\n",
     227                    str_error(rc));
     228                goto error;
     229        }
     230
     231        rc = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
     232        if (rc != EOK) {
     233                usb_log_error("Failed to add OHCI to HC category: %s.\n",
     234                    str_error(rc));
     235                goto error;
     236        }
     237
     238        rc = hc_register_hub(&instance->hc, instance->rh_fun);
     239        if (rc != EOK) {
     240                usb_log_error("Failed to register OHCI root hub: %s.\n",
     241                    str_error(rc));
     242                goto error;
     243        }
     244
     245        return EOK;
     246
     247error:
     248        if (hc_inited)
     249                hc_fini(&instance->hc);
     250        if (ih_registered)
     251                unregister_interrupt_handler(device, irq);
     252        if (instance->hc_fun != NULL)
     253                ddf_fun_destroy(instance->hc_fun);
     254        if (instance->rh_fun != NULL)
     255                ddf_fun_destroy(instance->rh_fun);
     256        return rc;
    251257}
    252258/**
Note: See TracChangeset for help on using the changeset viewer.