source: mainline/uspace/drv/uhci-hcd/main.c@ 41e645c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 41e645c was 063ead6f, checked in by Vojtech Horky <vojtechhorky@…>, 15 years ago

Merge development/ changes

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*
2 * Copyright (c) 2011 Vojtech Horky, Jan Vesely
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28/** @addtogroup usb
29 * @{
30 */
31/** @file
32 * @brief UHCI driver
33 */
34#include <driver.h>
35#include <usb_iface.h>
36#include <usb/ddfiface.h>
37#include <device/hw_res.h>
38
39#include <errno.h>
40
41#include <usb/debug.h>
42
43#include "iface.h"
44#include "pci.h"
45#include "root_hub.h"
46#include "uhci.h"
47
48#define NAME "uhci-hcd"
49
50static int uhci_add_device(device_t *device);
51
52static int usb_iface_get_address(device_t *dev, devman_handle_t handle,
53 usb_address_t *address)
54{
55 assert(dev);
56 uhci_t *hc = dev_to_uhci(dev);
57 assert(hc);
58
59 usb_address_t addr = usb_address_keeping_find(&hc->address_manager,
60 handle);
61 if (addr < 0) {
62 return addr;
63 }
64
65 if (address != NULL) {
66 *address = addr;
67 }
68
69 return EOK;
70}
71
72
73static usb_iface_t hc_usb_iface = {
74 .get_hc_handle = usb_iface_get_hc_handle_hc_impl,
75 .get_address = usb_iface_get_address
76};
77/*----------------------------------------------------------------------------*/
78static device_ops_t uhci_ops = {
79 .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
80 .interfaces[USBHC_DEV_IFACE] = &uhci_iface
81};
82/*----------------------------------------------------------------------------*/
83static driver_ops_t uhci_driver_ops = {
84 .add_device = uhci_add_device,
85};
86/*----------------------------------------------------------------------------*/
87static driver_t uhci_driver = {
88 .name = NAME,
89 .driver_ops = &uhci_driver_ops
90};
91/*----------------------------------------------------------------------------*/
92static void irq_handler(device_t *device, ipc_callid_t iid, ipc_call_t *call)
93{
94 assert(device);
95 uhci_t *hc = dev_to_uhci(device);
96 uint16_t status = IPC_GET_ARG1(*call);
97 assert(hc);
98 uhci_interrupt(hc, status);
99}
100/*----------------------------------------------------------------------------*/
101#define CHECK_RET_RETURN(ret, message...) \
102if (ret != EOK) { \
103 usb_log_error(message); \
104 return ret; \
105}
106
107static int uhci_add_device(device_t *device)
108{
109 assert(device);
110
111 usb_log_info("uhci_add_device() called\n");
112 device->ops = &uhci_ops;
113
114 uintptr_t io_reg_base;
115 size_t io_reg_size;
116 int irq;
117
118 int ret =
119 pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);
120
121 CHECK_RET_RETURN(ret,
122 "Failed(%d) to get I/O addresses:.\n", ret, device->handle);
123 usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n",
124 io_reg_base, io_reg_size, irq);
125
126 ret = pci_enable_interrupts(device);
127 CHECK_RET_RETURN(ret, "Failed(%d) to get enable interrupts:\n", ret);
128
129 uhci_t *uhci_hc = malloc(sizeof(uhci_t));
130 ret = (uhci_hc != NULL) ? EOK : ENOMEM;
131 CHECK_RET_RETURN(ret, "Failed to allocate memory for uhci hcd driver.\n");
132
133 ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size);
134 if (ret != EOK) {
135 usb_log_error("Failed to init uhci-hcd.\n");
136 free(uhci_hc);
137 return ret;
138 }
139
140 ret = register_interrupt_handler(device, irq, irq_handler,
141 &uhci_hc->interrupt_code);
142 if (ret != EOK) {
143 usb_log_error("Failed to register interrupt handler.\n");
144 uhci_fini(uhci_hc);
145 free(uhci_hc);
146 return ret;
147 }
148
149 device_t *rh;
150 ret = setup_root_hub(&rh, device);
151 if (ret != EOK) {
152 usb_log_error("Failed to setup uhci root hub.\n");
153 uhci_fini(uhci_hc);
154 free(uhci_hc);
155 return ret;
156 }
157
158 ret = child_device_register(rh, device);
159 if (ret != EOK) {
160 usb_log_error("Failed to register root hub.\n");
161 uhci_fini(uhci_hc);
162 free(uhci_hc);
163 free(rh);
164 return ret;
165 }
166
167 device->driver_data = uhci_hc;
168 return EOK;
169}
170/*----------------------------------------------------------------------------*/
171int main(int argc, char *argv[])
172{
173 sleep(3);
174 usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
175
176 return driver_main(&uhci_driver);
177}
178/**
179 * @}
180 */
Note: See TracBrowser for help on using the repository browser.