source: mainline/uspace/drv/uhci-hcd/main.c@ 733a9a8

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 733a9a8 was 733a9a8, checked in by Jan Vesely <jano.vesely@…>, 14 years ago

Use hardware interrupts

  • Property mode set to 100644
File size: 5.8 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 <ipc/irc.h>
37#include <ipc/ns.h>
38#include <ipc/services.h>
39#include <sysinfo.h>
40
41#include <errno.h>
42
43#include <usb/debug.h>
44
45#include "iface.h"
46#include "pci.h"
47#include "root_hub.h"
48#include "uhci.h"
49
50#define NAME "uhci-hcd"
51
52static int uhci_add_device(device_t *device);
53static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle);
54/*----------------------------------------------------------------------------*/
55static int usb_iface_get_hc_handle(device_t *dev, devman_handle_t *handle)
56{
57 /* This shall be called only for the UHCI itself. */
58 assert(dev->parent == NULL);
59
60 *handle = dev->handle;
61 return EOK;
62}
63/*----------------------------------------------------------------------------*/
64static usb_iface_t hc_usb_iface = {
65 .get_hc_handle = usb_iface_get_hc_handle
66};
67/*----------------------------------------------------------------------------*/
68static device_ops_t uhci_ops = {
69 .interfaces[USB_DEV_IFACE] = &hc_usb_iface,
70 .interfaces[USBHC_DEV_IFACE] = &uhci_iface
71};
72/*----------------------------------------------------------------------------*/
73static driver_ops_t uhci_driver_ops = {
74 .add_device = uhci_add_device,
75};
76/*----------------------------------------------------------------------------*/
77static driver_t uhci_driver = {
78 .name = NAME,
79 .driver_ops = &uhci_driver_ops
80};
81/*----------------------------------------------------------------------------*/
82static irq_cmd_t uhci_cmds[] = {
83 {
84 .cmd = CMD_PIO_READ_16,
85 .addr = (void*)0xc022,
86 .dstarg = 1
87 },
88 {
89 .cmd = CMD_PIO_WRITE_16,
90 .addr = (void*)0xc022,
91 .value = 0x1f
92 },
93 {
94 .cmd = CMD_ACCEPT
95 }
96};
97/*----------------------------------------------------------------------------*/
98static irq_code_t uhci_code = {
99 sizeof(uhci_cmds) / sizeof(irq_cmd_t),
100 uhci_cmds
101};
102/*----------------------------------------------------------------------------*/
103static void irq_handler(device_t *device, ipc_callid_t iid, ipc_call_t *call)
104{
105 assert(device);
106 uhci_t *hc = dev_to_uhci(device);
107 usb_log_info("LOL HARDWARE INTERRUPT: %p.\n", hc);
108 uint16_t status = IPC_GET_ARG1(*call);
109 assert(hc);
110 uhci_interrupt(hc, status);
111}
112/*----------------------------------------------------------------------------*/
113static int uhci_add_device(device_t *device)
114{
115 assert(device);
116
117 usb_log_info("uhci_add_device() called\n");
118 device->ops = &uhci_ops;
119
120 uintptr_t io_reg_base;
121 size_t io_reg_size;
122 int irq;
123
124 int ret =
125 pci_get_my_registers(device, &io_reg_base, &io_reg_size, &irq);
126
127 if (ret != EOK) {
128 usb_log_error(
129 "Failed(%d) to get I/O registers addresses for device:.\n",
130 ret, device->handle);
131 return ret;
132 }
133
134 usb_log_info("I/O regs at 0x%X (size %zu), IRQ %d.\n",
135 io_reg_base, io_reg_size, irq);
136
137
138 sysarg_t apic;
139 sysarg_t i8259;
140 int irc_phone = -1;
141 int irc_service = 0;
142
143 if ((sysinfo_get_value("apic", &apic) == EOK) && (apic)) {
144 irc_service = SERVICE_APIC;
145 usb_log_debug("SERVICE_APIC\n");
146 } else if ((sysinfo_get_value("i8259", &i8259) == EOK) && (i8259)) {
147 irc_service = SERVICE_I8259;
148 usb_log_debug("SERVICE_I8259\n");
149 }
150
151 if (irc_service) {
152 while (irc_phone < 0)
153 irc_phone = service_connect_blocking(irc_service, 0, 0);
154 }
155 usb_log_debug("Interrupt conttroller phone: %d\n", irc_phone);
156
157 async_msg_1(irc_phone, IRC_ENABLE_INTERRUPT, irq);
158// async_hangup(irc_phone);
159
160 ret = register_interrupt_handler(device, irq, irq_handler, &uhci_code);
161 usb_log_debug("Registered interrupt handler %d.\n", ret);
162
163 uhci_t *uhci_hc = malloc(sizeof(uhci_t));
164 if (!uhci_hc) {
165 usb_log_error("Failed to allocate memory for uhci hcd driver.\n");
166 return ENOMEM;
167 }
168
169 ret = uhci_init(uhci_hc, (void*)io_reg_base, io_reg_size);
170 if (ret != EOK) {
171 usb_log_error("Failed to init uhci-hcd.\n");
172 return ret;
173 }
174 device_t *rh;
175 ret = setup_root_hub(&rh, device);
176 if (ret != EOK) {
177 usb_log_error("Failed to setup uhci root hub.\n");
178 /* TODO: destroy uhci here */
179 return ret;
180 }
181
182 ret = child_device_register(rh, device);
183 if (ret != EOK) {
184 usb_log_error("Failed to register root hub.\n");
185 /* TODO: destroy uhci here */
186 return ret;
187 }
188
189 device->driver_data = uhci_hc;
190
191 return EOK;
192}
193/*----------------------------------------------------------------------------*/
194int main(int argc, char *argv[])
195{
196 sleep(3);
197 usb_log_enable(USB_LOG_LEVEL_DEBUG, NAME);
198
199 return driver_main(&uhci_driver);
200}
201/**
202 * @}
203 */
Note: See TracBrowser for help on using the repository browser.