Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/drv/uhci-hcd/uhci.c

    rd2bff2f r2c49b81b  
    4444#include "pci.h"
    4545
    46 #include "hc.h"
    47 #include "root_hub.h"
    48 
    49 /** Structure representing both functions of UHCI hc, USB host controller
    50  * and USB root hub */
    51 typedef struct uhci {
    52         /** Pointer to DDF represenation of UHCI host controller */
    53         ddf_fun_t *hc_fun;
    54         /** Pointer to DDF represenation of UHCI root hub */
    55         ddf_fun_t *rh_fun;
    56 
    57         /** Internal driver's represenation of UHCI host controller */
    58         hc_t hc;
    59         /** Internal driver's represenation of UHCI root hub */
    60         rh_t rh;
    61 } uhci_t;
    62 
    63 static inline uhci_t * dev_to_uhci(ddf_dev_t *dev)
    64 {
    65         assert(dev);
    66         assert(dev->driver_data);
    67         return dev->driver_data;
    68 }
    69 /*----------------------------------------------------------------------------*/
    7046/** IRQ handling callback, forward status from call to diver structure.
    7147 *
     
    9369{
    9470        assert(fun);
    95         usb_device_keeper_t *manager = &dev_to_uhci(fun->dev)->hc.manager;
     71        usb_device_keeper_t *manager =
     72            &((uhci_t*)fun->dev->driver_data)->hc.manager;
     73
    9674        usb_address_t addr = usb_device_keeper_find(manager, handle);
    97 
    9875        if (addr < 0) {
    9976                return addr;
     
    11693    ddf_fun_t *fun, devman_handle_t *handle)
    11794{
    118         assert(fun);
    119         ddf_fun_t *hc_fun = dev_to_uhci(fun->dev)->hc_fun;
    120         assert(hc_fun);
    121 
    122         if (handle != NULL)
    123                 *handle = hc_fun->handle;
     95        assert(handle);
     96        ddf_fun_t *hc_fun = ((uhci_t*)fun->dev->driver_data)->hc_fun;
     97        assert(hc_fun != NULL);
     98
     99        *handle = hc_fun->handle;
    124100        return EOK;
    125101}
     
    150126static hw_res_ops_t hw_res_iface = {
    151127        .get_resource_list = get_resource_list,
    152         .enable_interrupt = NULL,
     128        .enable_interrupt = NULL
    153129};
    154130/*----------------------------------------------------------------------------*/
     
    170146 *  - registers interrupt handler
    171147 */
    172 int device_setup_uhci(ddf_dev_t *device)
    173 {
    174         assert(device);
    175         uhci_t *instance = malloc(sizeof(uhci_t));
    176         if (instance == NULL) {
    177                 usb_log_error("Failed to allocate OHCI driver.\n");
    178                 return ENOMEM;
    179         }
    180 
    181 #define CHECK_RET_DEST_FREE_RETURN(ret, message...) \
     148int uhci_init(uhci_t *instance, ddf_dev_t *device)
     149{
     150        assert(instance);
     151        instance->hc_fun = NULL;
     152        instance->rh_fun = NULL;
     153#define CHECK_RET_DEST_FUN_RETURN(ret, message...) \
    182154if (ret != EOK) { \
     155        usb_log_error(message); \
    183156        if (instance->hc_fun) \
    184                 instance->hc_fun->ops = NULL; \
    185                 instance->hc_fun->driver_data = NULL; \
    186157                ddf_fun_destroy(instance->hc_fun); \
    187         if (instance->rh_fun) {\
    188                 instance->rh_fun->ops = NULL; \
    189                 instance->rh_fun->driver_data = NULL; \
     158        if (instance->rh_fun) \
    190159                ddf_fun_destroy(instance->rh_fun); \
    191         } \
    192         free(instance); \
    193         usb_log_error(message); \
    194160        return ret; \
    195 } else (void)0
    196 
    197         instance->rh_fun = NULL;
    198         instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci-hc");
    199         int ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
    200         CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI HC function.\n");
    201         instance->hc_fun->ops = &hc_ops;
    202         instance->hc_fun->driver_data = &instance->hc;
    203 
    204         instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci-rh");
    205         ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
    206         CHECK_RET_DEST_FREE_RETURN(ret, "Failed to create UHCI RH function.\n");
    207         instance->rh_fun->ops = &rh_ops;
    208         instance->rh_fun->driver_data = &instance->rh;
    209 
    210         uintptr_t reg_base = 0;
    211         size_t reg_size = 0;
     161}
     162
     163        uintptr_t io_reg_base = 0;
     164        size_t io_reg_size = 0;
    212165        int irq = 0;
    213166
    214         ret = pci_get_my_registers(device, &reg_base, &reg_size, &irq);
    215         CHECK_RET_DEST_FREE_RETURN(ret,
     167        int ret =
     168            pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);
     169        CHECK_RET_DEST_FUN_RETURN(ret,
    216170            "Failed to get I/O addresses for %" PRIun ": %s.\n",
    217171            device->handle, str_error(ret));
    218172        usb_log_debug("I/O regs at 0x%p (size %zu), IRQ %d.\n",
    219             (void *) reg_base, reg_size, irq);
     173            (void *) io_reg_base, io_reg_size, irq);
    220174
    221175        ret = pci_disable_legacy(device);
    222         CHECK_RET_DEST_FREE_RETURN(ret,
     176        CHECK_RET_DEST_FUN_RETURN(ret,
    223177            "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret));
    224178
     
    240194#endif
    241195
    242 
    243         ret = hc_init(&instance->hc, (void*)reg_base, reg_size, interrupts);
    244         CHECK_RET_DEST_FREE_RETURN(ret,
     196        instance->hc_fun = ddf_fun_create(device, fun_exposed, "uhci-hc");
     197        ret = (instance->hc_fun == NULL) ? ENOMEM : EOK;
     198        CHECK_RET_DEST_FUN_RETURN(ret,
     199            "Failed(%d) to create HC function: %s.\n", ret, str_error(ret));
     200
     201        ret = hc_init(&instance->hc, instance->hc_fun,
     202            (void*)io_reg_base, io_reg_size, interrupts);
     203        CHECK_RET_DEST_FUN_RETURN(ret,
    245204            "Failed(%d) to init uhci-hcd: %s.\n", ret, str_error(ret));
     205
     206        instance->hc_fun->ops = &hc_ops;
     207        instance->hc_fun->driver_data = &instance->hc;
     208        ret = ddf_fun_bind(instance->hc_fun);
     209        CHECK_RET_DEST_FUN_RETURN(ret,
     210            "Failed(%d) to bind UHCI device function: %s.\n",
     211            ret, str_error(ret));
     212        ret = ddf_fun_add_to_class(instance->hc_fun, USB_HC_DDF_CLASS_NAME);
     213        CHECK_RET_DEST_FUN_RETURN(ret,
     214            "Failed to add UHCI to HC class: %s.\n", str_error(ret));
     215
     216#undef CHECK_RET_HC_RETURN
    246217
    247218#define CHECK_RET_FINI_RETURN(ret, message...) \
    248219if (ret != EOK) { \
     220        usb_log_error(message); \
     221        if (instance->hc_fun) \
     222                ddf_fun_destroy(instance->hc_fun); \
     223        if (instance->rh_fun) \
     224                ddf_fun_destroy(instance->rh_fun); \
    249225        hc_fini(&instance->hc); \
    250         CHECK_RET_DEST_FREE_RETURN(ret, message); \
    251226        return ret; \
    252 } else (void)0
     227}
    253228
    254229        /* It does no harm if we register this on polling */
     
    259234            ret, str_error(ret));
    260235
    261         ret = ddf_fun_bind(instance->hc_fun);
    262         CHECK_RET_FINI_RETURN(ret,
    263             "Failed(%d) to bind UHCI device function: %s.\n",
     236        instance->rh_fun = ddf_fun_create(device, fun_inner, "uhci-rh");
     237        ret = (instance->rh_fun == NULL) ? ENOMEM : EOK;
     238        CHECK_RET_FINI_RETURN(ret,
     239            "Failed(%d) to create root hub function: %s.\n",
    264240            ret, str_error(ret));
    265241
     
    269245            "Failed(%d) to setup UHCI root hub: %s.\n", ret, str_error(ret));
    270246
     247        instance->rh_fun->ops = &rh_ops;
     248        instance->rh_fun->driver_data = &instance->rh;
    271249        ret = ddf_fun_bind(instance->rh_fun);
    272250        CHECK_RET_FINI_RETURN(ret,
    273251            "Failed(%d) to register UHCI root hub: %s.\n", ret, str_error(ret));
    274252
    275         device->driver_data = instance;
    276253        return EOK;
    277254#undef CHECK_RET_FINI_RETURN
Note: See TracChangeset for help on using the changeset viewer.