Ignore:
File:
1 edited

Legend:

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

    r17ceb72 ra7e2f0d  
    2626 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    2727 */
    28 /** @addtogroup drvusbuhcihc
     28/** @addtogroup usb
    2929 * @{
    3030 */
    3131/** @file
    32  * @brief UHCI driver initialization
     32 * @brief UHCI driver
    3333 */
    3434#include <ddf/driver.h>
     35#include <ddf/interrupt.h>
     36#include <device/hw_res.h>
    3537#include <errno.h>
    3638#include <str_error.h>
    3739
     40#include <usb_iface.h>
    3841#include <usb/ddfiface.h>
    3942#include <usb/debug.h>
    4043
    4144#include "iface.h"
     45#include "pci.h"
     46#include "root_hub.h"
    4247#include "uhci.h"
    4348
     
    5560};
    5661/*----------------------------------------------------------------------------*/
    57 /** Initialize a new ddf driver instance for uhci hc and hub.
     62/** IRQ handling callback, identifies devic
     63 *
     64 * @param[in] dev DDF instance of the device to use.
     65 * @param[in] iid (Unused).
     66 * @param[in] call Pointer to the call that represents interrupt.
     67 */
     68static void irq_handler(ddf_dev_t *dev, ipc_callid_t iid, ipc_call_t *call)
     69{
     70        assert(dev);
     71        uhci_t *hc = dev_to_uhci(dev);
     72        uint16_t status = IPC_GET_ARG1(*call);
     73        assert(hc);
     74        uhci_interrupt(hc, status);
     75}
     76/*----------------------------------------------------------------------------*/
     77/** Initializes a new ddf driver instance of UHCI hcd.
    5878 *
    5979 * @param[in] device DDF instance of the device to initialize.
    6080 * @return Error code.
     81 *
     82 * Gets and initialies hardware resources, disables any legacy support,
     83 * and reports root hub device.
    6184 */
    6285int uhci_add_device(ddf_dev_t *device)
    6386{
     87        assert(device);
     88        uhci_t *hcd = NULL;
     89#define CHECK_RET_FREE_HC_RETURN(ret, message...) \
     90if (ret != EOK) { \
     91        usb_log_error(message); \
     92        if (hcd != NULL) \
     93                free(hcd); \
     94        return ret; \
     95}
     96
    6497        usb_log_info("uhci_add_device() called\n");
    65         assert(device);
    66         uhci_t *uhci = malloc(sizeof(uhci_t));
    67         if (uhci == NULL) {
    68                 usb_log_error("Failed to allocate UHCI driver.\n");
    69                 return ENOMEM;
     98
     99        uintptr_t io_reg_base = 0;
     100        size_t io_reg_size = 0;
     101        int irq = 0;
     102
     103        int ret =
     104            pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);
     105        CHECK_RET_FREE_HC_RETURN(ret,
     106            "Failed(%d) to get I/O addresses:.\n", ret, device->handle);
     107        usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n",
     108            io_reg_base, io_reg_size, irq);
     109
     110        ret = pci_disable_legacy(device);
     111        CHECK_RET_FREE_HC_RETURN(ret,
     112            "Failed(%d) to disable legacy USB: %s.\n", ret, str_error(ret));
     113
     114#if 0
     115        ret = pci_enable_interrupts(device);
     116        if (ret != EOK) {
     117                usb_log_warning(
     118                    "Failed(%d) to enable interrupts, fall back to polling.\n",
     119                    ret);
    70120        }
     121#endif
    71122
    72         int ret = uhci_init(uhci, device);
    73         if (ret != EOK) {
    74                 usb_log_error("Failed to initialzie UHCI driver.\n");
    75                 return ret;
    76         }
    77         device->driver_data = uhci;
     123        hcd = malloc(sizeof(uhci_t));
     124        ret = (hcd != NULL) ? EOK : ENOMEM;
     125        CHECK_RET_FREE_HC_RETURN(ret,
     126            "Failed(%d) to allocate memory for uhci hcd.\n", ret);
     127
     128        ret = uhci_init(hcd, device, (void*)io_reg_base, io_reg_size);
     129        CHECK_RET_FREE_HC_RETURN(ret, "Failed(%d) to init uhci-hcd.\n", ret);
     130#undef CHECK_RET_FREE_HC_RETURN
     131
     132        /*
     133         * We might free hcd, but that does not matter since no one
     134         * else would access driver_data anyway.
     135         */
     136        device->driver_data = hcd;
     137
     138        ddf_fun_t *rh = NULL;
     139#define CHECK_RET_FINI_FREE_RETURN(ret, message...) \
     140if (ret != EOK) { \
     141        usb_log_error(message); \
     142        if (hcd != NULL) {\
     143                uhci_fini(hcd); \
     144                free(hcd); \
     145        } \
     146        if (rh != NULL) \
     147                free(rh); \
     148        return ret; \
     149}
     150
     151        /* It does no harm if we register this on polling */
     152        ret = register_interrupt_handler(device, irq, irq_handler,
     153            &hcd->interrupt_code);
     154        CHECK_RET_FINI_FREE_RETURN(ret,
     155            "Failed(%d) to register interrupt handler.\n", ret);
     156
     157        ret = setup_root_hub(&rh, device);
     158        CHECK_RET_FINI_FREE_RETURN(ret,
     159            "Failed(%d) to setup UHCI root hub.\n", ret);
     160        rh->driver_data = hcd->ddf_instance;
     161
     162        ret = ddf_fun_bind(rh);
     163        CHECK_RET_FINI_FREE_RETURN(ret,
     164            "Failed(%d) to register UHCI root hub.\n", ret);
     165
    78166        return EOK;
     167#undef CHECK_RET_FINI_FREE_RETURN
    79168}
    80169/*----------------------------------------------------------------------------*/
    81 /** Initialize global driver structures (NONE).
     170/** Initializes global driver structures (NONE).
    82171 *
    83172 * @param[in] argc Nmber of arguments in argv vector (ignored).
     
    89178int main(int argc, char *argv[])
    90179{
    91         sleep(3); /* TODO: remove in final version */
     180        sleep(3);
    92181        usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
    93182
Note: See TracChangeset for help on using the changeset viewer.