source: mainline/uspace/drv/uhci-rhd/port.c@ 27270db

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

Debug code refactoring, redundant code removed

  • Property mode set to 100644
File size: 8.1 KB
Line 
1/*
2 * Copyright (c) 2011 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 <errno.h>
35#include <str_error.h>
36#include <fibril_synch.h>
37
38#include <usb/usb.h> /* usb_address_t */
39#include <usb/usbdevice.h>
40#include <usb/hub.h>
41#include <usb/request.h>
42#include <usb/debug.h>
43#include <usb/recognise.h>
44
45#include "port.h"
46#include "port_status.h"
47
48static int uhci_port_new_device(uhci_port_t *port, uint16_t status);
49static int uhci_port_remove_device(uhci_port_t *port);
50static int uhci_port_set_enabled(uhci_port_t *port, bool enabled);
51static int uhci_port_check(void *port);
52static int new_device_enable_port(int portno, void *arg);
53
54int uhci_port_init(
55 uhci_port_t *port, port_status_t *address, unsigned number,
56 unsigned usec, ddf_dev_t *rh)
57{
58 assert(port);
59 port->address = address;
60 port->number = number;
61 port->wait_period_usec = usec;
62 port->attached_device = 0;
63 port->rh = rh;
64 int rc = usb_hc_connection_initialize_from_device(
65 &port->hc_connection, rh);
66 if (rc != EOK) {
67 usb_log_error("Failed to initialize connection to HC.");
68 return rc;
69 }
70
71 port->checker = fibril_create(uhci_port_check, port);
72 if (port->checker == 0) {
73 usb_log_error("Port(%p - %d): failed to launch root hub fibril.",
74 port->address, port->number);
75 return ENOMEM;
76 }
77 fibril_add_ready(port->checker);
78 usb_log_debug("Port(%p - %d): Added fibril. %x\n",
79 port->address, port->number, port->checker);
80 return EOK;
81}
82/*----------------------------------------------------------------------------*/
83void uhci_port_fini(uhci_port_t *port)
84{
85// TODO: destroy fibril
86// TODO: hangup phone
87// fibril_teardown(port->checker);
88 return;
89}
90/*----------------------------------------------------------------------------*/
91int uhci_port_check(void *port)
92{
93 uhci_port_t *port_instance = port;
94 assert(port_instance);
95// port_status_write(port_instance->address, 0);
96
97 unsigned count = 0;
98
99 while (1) {
100 async_usleep(port_instance->wait_period_usec);
101
102 /* read register value */
103 port_status_t port_status =
104 port_status_read(port_instance->address);
105
106 /* debug print */
107 static fibril_mutex_t dbg_mtx = FIBRIL_MUTEX_INITIALIZER(dbg_mtx);
108 fibril_mutex_lock(&dbg_mtx);
109 usb_log_debug2("Port(%p - %d): Status: %#04x. === %u\n",
110 port_instance->address, port_instance->number, port_status, count++);
111// print_port_status(port_status);
112 fibril_mutex_unlock(&dbg_mtx);
113
114 if ((port_status & STATUS_CONNECTED_CHANGED) != 0) {
115 usb_log_debug("Port(%p - %d): Connected change detected: %x.\n",
116 port_instance->address, port_instance->number, port_status);
117
118
119 int rc = usb_hc_connection_open(
120 &port_instance->hc_connection);
121 if (rc != EOK) {
122 usb_log_error("Port(%p - %d): Failed to connect to HC.",
123 port_instance->address, port_instance->number);
124 continue;
125 }
126
127 /* remove any old device */
128 if (port_instance->attached_device) {
129 usb_log_debug("Port(%p - %d): Removing device.\n",
130 port_instance->address, port_instance->number);
131 uhci_port_remove_device(port_instance);
132 }
133
134 if ((port_status & STATUS_CONNECTED) != 0) {
135 /* new device */
136 uhci_port_new_device(port_instance, port_status);
137 } else {
138 /* ack changes by writing one to WC bits */
139 port_status_write(port_instance->address, port_status);
140 usb_log_debug("Port(%p - %d): Change status ACK.\n",
141 port_instance->address, port_instance->number);
142 }
143
144 rc = usb_hc_connection_close(
145 &port_instance->hc_connection);
146 if (rc != EOK) {
147 usb_log_error("Port(%p - %d): Failed to disconnect from HC.",
148 port_instance->address, port_instance->number);
149 }
150 }
151 }
152 return EOK;
153}
154
155/** Callback for enabling port during adding a new device.
156 *
157 * @param portno Port number (unused).
158 * @param arg Pointer to uhci_port_t of port with the new device.
159 * @return Error code.
160 */
161static int new_device_enable_port(int portno, void *arg)
162{
163 uhci_port_t *port = (uhci_port_t *) arg;
164
165 usb_log_debug2("Port(%p - %d): new_device_enable_port.\n",
166 port->address, port->number);
167
168 /*
169 * The host then waits for at least 100 ms to allow completion of
170 * an insertion process and for power at the device to become stable.
171 */
172 async_usleep(100000);
173
174
175 /* The hub maintains the reset signal to that port for 10 ms
176 * (See Section 11.5.1.5)
177 */
178 {
179 usb_log_debug("Port(%p - %d): Reset Signal start.\n",
180 port->address, port->number);
181 port_status_t port_status =
182 port_status_read(port->address);
183 port_status |= STATUS_IN_RESET;
184 port_status_write(port->address, port_status);
185 async_usleep(10000);
186 port_status =
187 port_status_read(port->address);
188 port_status &= ~STATUS_IN_RESET;
189 port_status_write(port->address, port_status);
190 usb_log_debug("Port(%p - %d): Reset Signal stop.\n",
191 port->address, port->number);
192 }
193
194 /* Enable the port. */
195 uhci_port_set_enabled(port, true);
196
197 return EOK;
198}
199
200/*----------------------------------------------------------------------------*/
201static int uhci_port_new_device(uhci_port_t *port, uint16_t status)
202{
203 assert(port);
204 assert(usb_hc_connection_is_opened(&port->hc_connection));
205
206 usb_log_info("Port(%p-%d): Detected new device.\n",
207 port->address, port->number);
208
209 usb_address_t dev_addr;
210 int rc = usb_hc_new_device_wrapper(port->rh, &port->hc_connection,
211 ((status & STATUS_LOW_SPEED) != 0) ? USB_SPEED_LOW : USB_SPEED_FULL,
212 new_device_enable_port, port->number, port,
213 &dev_addr, &port->attached_device, NULL, NULL, NULL);
214
215 if (rc != EOK) {
216 usb_log_error("Port(%p-%d): Failed(%d) adding new device: %s.\n",
217 port->address, port->number, rc, str_error(rc));
218 uhci_port_set_enabled(port, false);
219 return rc;
220 }
221
222 usb_log_info("Port(%p-%d): New device has address %d (handle %zu).\n",
223 port->address, port->number, dev_addr, port->attached_device);
224
225 return EOK;
226}
227
228/*----------------------------------------------------------------------------*/
229static int uhci_port_remove_device(uhci_port_t *port)
230{
231 usb_log_error("Port(%p-%d): Don't know how to remove device %#x.\n",
232 port->address, port->number, (unsigned int)port->attached_device);
233// uhci_port_set_enabled(port, false);
234 return EOK;
235}
236/*----------------------------------------------------------------------------*/
237static int uhci_port_set_enabled(uhci_port_t *port, bool enabled)
238{
239 assert(port);
240
241 /* read register value */
242 port_status_t port_status
243 = port_status_read(port->address);
244
245 /* enable port: register write */
246 if (enabled) {
247 port_status |= STATUS_ENABLED;
248 } else {
249 port_status &= ~STATUS_ENABLED;
250 }
251 port_status_write(port->address, port_status);
252
253 usb_log_info("Port(%p-%d): %sabled port.\n",
254 port->address, port->number, enabled ? "En" : "Dis");
255 return EOK;
256}
257/*----------------------------------------------------------------------------*/
258/**
259 * @}
260 */
Note: See TracBrowser for help on using the repository browser.