Ignore:
File:
1 edited

Legend:

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

    r44c1a48 r507c6f3  
    3333 * @brief OHCI driver
    3434 */
     35
     36/* XXX Fix this */
     37#define _DDF_DATA_IMPLANT
     38
    3539#include <errno.h>
    3640#include <str_error.h>
     
    5256} ohci_t;
    5357
    54 static inline ohci_t * dev_to_ohci(ddf_dev_t *dev)
    55 {
    56         assert(dev);
    57         return dev->driver_data;
     58static inline ohci_t *dev_to_ohci(ddf_dev_t *dev)
     59{
     60        return ddf_dev_data_get(dev);
    5861}
    5962/** IRQ handling callback, identifies device
     
    7578        hc_interrupt(&ohci->hc, status);
    7679}
    77 /*----------------------------------------------------------------------------*/
     80
    7881/** Get USB address assigned to root hub.
    7982 *
     
    8790
    8891        if (address != NULL) {
    89                 *address = dev_to_ohci(fun->dev)->hc.rh.address;
     92                *address = dev_to_ohci(ddf_fun_get_dev(fun))->hc.rh.address;
    9093        }
    9194
    9295        return EOK;
    9396}
    94 /*----------------------------------------------------------------------------*/
     97
    9598/** Gets handle of the respective hc (this device, hc function).
    9699 *
     
    103106{
    104107        assert(fun);
    105         ddf_fun_t *hc_fun = dev_to_ohci(fun->dev)->hc_fun;
     108        ddf_fun_t *hc_fun = dev_to_ohci(ddf_fun_get_dev(fun))->hc_fun;
    106109        assert(hc_fun);
    107110
    108111        if (handle != NULL)
    109                 *handle = hc_fun->handle;
     112                *handle = ddf_fun_get_handle(hc_fun);
    110113        return EOK;
    111114}
    112 /*----------------------------------------------------------------------------*/
     115
    113116/** Root hub USB interface */
    114117static usb_iface_t usb_iface = {
     
    116119        .get_my_address = rh_get_my_address,
    117120};
    118 /*----------------------------------------------------------------------------*/
     121
    119122/** Standard USB HC options (HC interface) */
    120123static ddf_dev_ops_t hc_ops = {
    121124        .interfaces[USBHC_DEV_IFACE] = &hcd_iface,
    122125};
    123 /*----------------------------------------------------------------------------*/
     126
    124127/** Standard USB RH options (RH interface) */
    125128static ddf_dev_ops_t rh_ops = {
    126129        .interfaces[USB_DEV_IFACE] = &usb_iface,
    127130};
    128 /*----------------------------------------------------------------------------*/
     131
    129132/** Initialize hc and rh ddf structures and their respective drivers.
    130133 *
     
    140143int device_setup_ohci(ddf_dev_t *device)
    141144{
     145        bool ih_registered = false;
     146        bool hc_inited = false;
     147        int rc;
     148
    142149        if (device == NULL)
    143150                return EBADMEM;
     
    149156        }
    150157
    151 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
    152 if (ret != EOK) { \
    153         if (instance->hc_fun) { \
    154                 instance->hc_fun->driver_data = NULL; \
    155                 ddf_fun_destroy(instance->hc_fun); \
    156         } \
    157         if (instance->rh_fun) { \
    158                 instance->rh_fun->driver_data = NULL; \
    159                 ddf_fun_destroy(instance->rh_fun); \
    160         } \
    161         usb_log_error(message); \
    162         return ret; \
    163 } else (void)0
    164 
    165158        instance->hc_fun = ddf_fun_create(device, fun_exposed, "ohci_hc");
    166         int ret = instance->hc_fun ? EOK : ENOMEM;
    167         CHECK_RET_DEST_FREE_RETURN(ret,
    168             "Failed to create OHCI HC function: %s.\n", str_error(ret));
    169         instance->hc_fun->ops = &hc_ops;
    170         instance->hc_fun->driver_data = &instance->hc;
     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
     166        ddf_fun_set_ops(instance->hc_fun, &hc_ops);
     167        ddf_fun_data_implant(instance->hc_fun, &instance->hc);
    171168
    172169        instance->rh_fun = ddf_fun_create(device, fun_inner, "ohci_rh");
    173         ret = instance->rh_fun ? EOK : ENOMEM;
    174         CHECK_RET_DEST_FREE_RETURN(ret,
    175             "Failed to create OHCI RH function: %s.\n", str_error(ret));
    176         instance->rh_fun->ops = &rh_ops;
     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
     177        ddf_fun_set_ops(instance->rh_fun, &rh_ops);
    177178
    178179        uintptr_t reg_base = 0;
     
    180181        int irq = 0;
    181182
    182         ret = get_my_registers(device, &reg_base, &reg_size, &irq);
    183         CHECK_RET_DEST_FREE_RETURN(ret,
    184             "Failed to get register memory addresses for %" PRIun ": %s.\n",
    185             device->handle, str_error(ret));
     183        rc = get_my_registers(device, &reg_base, &reg_size, &irq);
     184        if (rc != EOK) {
     185                usb_log_error("Failed to get register memory addresses "
     186                    "for %" PRIun ": %s.\n", ddf_dev_get_handle(device),
     187                    str_error(rc));
     188                goto error;
     189        }
     190
    186191        usb_log_debug("Memory mapped regs at %p (size %zu), IRQ %d.\n",
    187192            (void *) reg_base, reg_size, irq);
    188193
    189         const size_t ranges_count = hc_irq_pio_range_count();
    190         const size_t cmds_count = hc_irq_cmd_count();
    191         irq_pio_range_t irq_ranges[ranges_count];
    192         irq_cmd_t irq_cmds[cmds_count];
    193         irq_code_t irq_code = {
    194                 .rangecount = ranges_count,
    195                 .ranges = irq_ranges,
    196                 .cmdcount = cmds_count,
    197                 .cmds = irq_cmds
    198         };
    199 
    200         ret = hc_get_irq_code(irq_ranges, sizeof(irq_ranges), irq_cmds,
    201             sizeof(irq_cmds), reg_base, reg_size);
    202         CHECK_RET_DEST_FREE_RETURN(ret,
    203             "Failed to generate IRQ code: %s.\n", str_error(ret));
    204 
    205 
    206         /* Register handler to avoid interrupt lockup */
    207         ret = register_interrupt_handler(device, irq, irq_handler, &irq_code);
    208         CHECK_RET_DEST_FREE_RETURN(ret,
    209             "Failed to register interrupt handler: %s.\n", str_error(ret));
     194        rc = hc_register_irq_handler(device, reg_base, reg_size, irq, irq_handler);
     195        if (rc != EOK) {
     196                usb_log_error("Failed to register interrupt handler: %s.\n",
     197                    str_error(rc));
     198                goto error;
     199        }
     200
     201        ih_registered = true;
    210202
    211203        /* Try to enable interrupts */
    212204        bool interrupts = false;
    213         ret = enable_interrupts(device);
    214         if (ret != EOK) {
     205        rc = enable_interrupts(device);
     206        if (rc != EOK) {
    215207                usb_log_warning("Failed to enable interrupts: %s."
    216                     " Falling back to polling\n", str_error(ret));
     208                    " Falling back to polling\n", str_error(rc));
    217209                /* We don't need that handler */
    218210                unregister_interrupt_handler(device, irq);
     211                ih_registered = false;
    219212        } else {
    220213                usb_log_debug("Hw interrupts enabled.\n");
     
    222215        }
    223216
    224         ret = hc_init(&instance->hc, reg_base, reg_size, interrupts);
    225         CHECK_RET_DEST_FREE_RETURN(ret,
    226             "Failed to init ohci_hcd: %s.\n", str_error(ret));
    227 
    228 #define CHECK_RET_FINI_RETURN(ret, message...) \
    229 if (ret != EOK) { \
    230         hc_fini(&instance->hc); \
    231         unregister_interrupt_handler(device, irq); \
    232         CHECK_RET_DEST_FREE_RETURN(ret, message); \
    233 } else (void)0
    234 
    235 
    236         ret = ddf_fun_bind(instance->hc_fun);
    237         CHECK_RET_FINI_RETURN(ret,
    238             "Failed to bind OHCI device function: %s.\n", str_error(ret));
    239 
    240         ret = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
    241         CHECK_RET_FINI_RETURN(ret,
    242             "Failed to add OHCI to HC class: %s.\n", str_error(ret));
    243 
    244         ret = hc_register_hub(&instance->hc, instance->rh_fun);
    245         CHECK_RET_FINI_RETURN(ret,
    246             "Failed to register OHCI root hub: %s.\n", str_error(ret));
    247         return ret;
    248 
    249 #undef CHECK_RET_FINI_RETURN
     217        rc = hc_init(&instance->hc, reg_base, reg_size, interrupts);
     218        if (rc != EOK) {
     219                usb_log_error("Failed to init ohci_hcd: %s.\n", str_error(rc));
     220                goto error;
     221        }
     222
     223        hc_inited = true;
     224
     225        rc = ddf_fun_bind(instance->hc_fun);
     226        if (rc != EOK) {
     227                usb_log_error("Failed to bind OHCI device function: %s.\n",
     228                    str_error(rc));
     229                goto error;
     230        }
     231
     232        rc = ddf_fun_add_to_category(instance->hc_fun, USB_HC_CATEGORY);
     233        if (rc != EOK) {
     234                usb_log_error("Failed to add OHCI to HC category: %s.\n",
     235                    str_error(rc));
     236                goto error;
     237        }
     238
     239        rc = hc_register_hub(&instance->hc, instance->rh_fun);
     240        if (rc != EOK) {
     241                usb_log_error("Failed to register OHCI root hub: %s.\n",
     242                    str_error(rc));
     243                goto error;
     244        }
     245
     246        return EOK;
     247
     248error:
     249        if (hc_inited)
     250                hc_fini(&instance->hc);
     251        if (ih_registered)
     252                unregister_interrupt_handler(device, irq);
     253        if (instance->hc_fun != NULL)
     254                ddf_fun_destroy(instance->hc_fun);
     255        if (instance->rh_fun != NULL)
     256                ddf_fun_destroy(instance->rh_fun);
     257        return rc;
    250258}
    251259/**
Note: See TracChangeset for help on using the changeset viewer.