summaryrefslogtreecommitdiff
path: root/firmware/usbstack/core/core.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/usbstack/core/core.c')
-rw-r--r--firmware/usbstack/core/core.c392
1 files changed, 392 insertions, 0 deletions
diff --git a/firmware/usbstack/core/core.c b/firmware/usbstack/core/core.c
new file mode 100644
index 0000000000..61b7f83636
--- /dev/null
+++ b/firmware/usbstack/core/core.c
@@ -0,0 +1,392 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
9 *
10 * Copyright (C) 2007 by Christian Gmeiner
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include <errno.h>
21#include <string.h>
22#include <ctype.h>
23#include "usbstack.h"
24
25#include "config.h"
26
27#include "usbstack/core.h"
28#include "usbstack/config.h"
29#include "usbstack/controller.h"
30#include "usbstack/drivers/device/usb_serial.h"
31#include "usbstack/drivers/device/usb_storage.h"
32
33struct usb_core usbcore;
34
35/* private used functions */
36static void update_driver_names(unsigned char* result);
37static void bind_device_driver(struct usb_device_driver* driver);
38
39/**
40 * Initialize usb stack.
41 */
42void usb_stack_init(void) {
43
44 int i;
45 logf("usb_stack_init");
46
47 /* init datastructures */
48 usbcore.controller[0] = NULL;
49 usbcore.controller[1] = NULL;
50 usbcore.active_controller = NULL;
51 usbcore.device_driver = NULL;
52 usbcore.running = false;
53
54 memset(&device_driver_names, 0, USB_STACK_MAX_SETTINGS_NAME);
55
56 /* init arrays */
57 for (i = 0; i < NUM_DRIVERS; i++) {
58 usbcore.device_drivers[i] = NULL;
59 usbcore.host_drivers[i] = NULL;
60 }
61
62 /* init controllers */
63#if (USBSTACK_CAPS & CONTROLLER_DEVICE)
64 usb_dcd_init();
65#endif
66
67#if (USBSTACK_CAPS & CONTROLLER_HOST)
68 usb_hcd_init();
69#endif
70
71 /* init drivers */
72 usb_serial_driver_init();
73 usb_storage_driver_init();
74}
75
76/**
77 * Start processing of usb stack. This function init
78 * active usb controller.
79 */
80void usb_stack_start(void) {
81
82 /* are we allready running? */
83 if (usbcore.running) {
84 logf("allready running!");
85 return;
86 }
87
88 if (usbcore.active_controller == NULL) {
89 logf("no active controller!");
90 return;
91 }
92
93 /* forward to controller */
94 logf("starting controller");
95 usbcore.active_controller->start();
96 usbcore.running = true;
97
98 /* look if started controller is a device controller
99 * and if it has a device driver bind to it */
100 logf("check for auto bind");
101 if (usbcore.active_controller->type == DEVICE) {
102 if (usbcore.active_controller->device_driver == NULL && usbcore.device_driver != NULL) {
103 /* bind driver */
104 logf("binding...");
105 bind_device_driver(usbcore.device_driver);
106 }
107 }
108}
109
110/**
111 * Stop processing of usb stack. This function shutsdown
112 * active usb controller.
113 */
114void usb_stack_stop(void) {
115
116 /* are we allready stopped? */
117 if (usbcore.running == false) {
118 return;
119 }
120
121 /* forward to controller */
122 usbcore.active_controller->stop();
123 usbcore.running = false;
124}
125
126/**
127 * Gets called by upper layers to indicate that there is
128 * an interrupt waiting for the controller.
129 */
130void usb_stack_irq(void) {
131
132 /* simply notify usb controller */
133 if (usbcore.active_controller != NULL && usbcore.active_controller->irq != NULL) {
134 usbcore.active_controller->irq();
135 }
136}
137
138/**
139 * If a host device controller is loaded, we need to have a function
140 * to call for maintanence. We need to check if a new device has connected,
141 * find suitable drivers for new devices.
142 */
143void usb_stack_work(void) {
144 /* TODO will be used with host device controllers
145 * and needs to be called in a loop (thread) */
146}
147
148/**
149 * Register an usb controller in the stack. The stack can
150 * only have two controllers registered at one time.
151 * One device host controller and one host device controller.
152 *
153 * @param ctrl pointer to controller to register.
154 * @return 0 on success else a defined error code.
155 */
156int usb_controller_register(struct usb_controller* ctrl) {
157
158 if (ctrl == NULL) {
159 return EINVAL;
160 }
161
162 logf("usb_stack: register usb ctrl");
163 logf(" -> name: %s", ctrl->name);
164 logf(" -> type: %d", ctrl->type);
165
166 switch (ctrl->type) {
167 case DEVICE:
168 if (usbcore.controller[0] == NULL) {
169 usbcore.controller[0] = ctrl;
170 return 0;
171 }
172 break;
173 case HOST:
174 if (usbcore.controller[1] == NULL) {
175 usbcore.controller[1] = ctrl;
176 return 0;
177 }
178 break;
179 default:
180 return EINVAL;
181 }
182
183 return ENOFREESLOT;
184}
185
186/**
187 * Unregister an usb controller from the stack.
188 *
189 * @param ctrl pointer to controller to unregister.
190 * @return 0 on success else a defined error code.
191 */
192int usb_controller_unregister(struct usb_controller* ctrl) {
193
194 if (ctrl == NULL) {
195 return EINVAL;
196 }
197
198 switch (ctrl->type) {
199 case DEVICE:
200 if (usbcore.controller[0] == ctrl) {
201 usbcore.controller[0] = NULL;
202 return 0;
203 }
204 break;
205 case HOST:
206 if (usbcore.controller[1] == ctrl) {
207 usbcore.controller[1] = NULL;
208 return 0;
209 }
210 break;
211 default:
212 return EINVAL;
213 }
214
215 return 0; /* never reached */
216}
217
218/**
219 * Select an usb controller and active it.
220 *
221 * @param type of controller to activate.
222 */
223void usb_controller_select(int type) {
224
225 struct usb_controller* new = NULL;
226
227 /* check if a controller of the wanted type is already loaded */
228 if (usbcore.active_controller != NULL && (int)usbcore.active_controller->type == type) {
229 logf("controller already set");
230 return;
231 }
232
233 logf("usb_controller_select");
234 logf(" -> type: %d", type);
235
236 usbcore.mode = type;
237
238 switch (type) {
239 case DEVICE:
240 new = usbcore.controller[0];
241 break;
242 case HOST:
243 new = usbcore.controller[1];
244 break;
245 }
246
247 /* if there is only one controller, stop here */
248 if (new == NULL) {
249 logf("no suitable cntrl found");
250 return;
251 }
252
253 /* shutdown current used controller */
254 if (usbcore.active_controller != NULL) {
255 logf("shuting down old one");
256 usbcore.active_controller->shutdown();
257 }
258
259 /* set and init new controller */
260 usbcore.active_controller = new;
261 logf("init controller");
262 usbcore.active_controller->init();
263}
264
265int usb_stack_get_mode(void) {
266 return usbcore.mode;
267}
268
269/**
270 * Register an usb device driver.
271 *
272 * @param driver pointer to an usb_device_driver struct.
273 * @return 0 on success, else a defined error code.
274 */
275int usb_device_driver_register(struct usb_device_driver* driver) {
276
277 int i;
278
279 if (driver == NULL) {
280 return EINVAL;
281 }
282
283 /* add to linked list */
284 logf("usb_stack: register usb driver");
285 for (i = 0; i < NUM_DRIVERS; i++) {
286 if (usbcore.device_drivers[i] == NULL) {
287 usbcore.device_drivers[i] = driver;
288 update_driver_names(device_driver_names);
289 return 0;
290 }
291 }
292
293 update_driver_names(device_driver_names);
294
295 return 0;
296}
297
298int usb_device_driver_bind(const char* name) {
299
300 int i;
301 struct usb_device_driver *tmp = NULL;
302 struct usb_device_driver *driver = NULL;
303
304 if (name == NULL) {
305 return EINVAL;
306 }
307
308 /* look for driver */
309 logf("looking for driver %s", name);
310 for (i = 0; i < NUM_DRIVERS; i++) {
311 tmp = usbcore.device_drivers[i];
312 if (tmp != NULL && strcmp(name, tmp->name) == 0) {
313 driver = tmp;
314 }
315 }
316
317 if (driver == NULL) {
318 logf("no driver found");
319 return ENODRIVERFOUND;
320 }
321
322 /* look if there is an usb controller loaded */
323 if (usbcore.active_controller == NULL) {
324 /* safe choosen driver and set it when controller starts */
325 usbcore.device_driver = driver;
326
327 } else {
328
329 /* we need to have an active dcd controller */
330 if (usbcore.active_controller->type != DEVICE) {
331 logf("wrong type");
332 return EWRONGCONTROLLERTYPE;
333 }
334
335 /* bind driver to controller */
336 bind_device_driver(driver);
337 }
338
339 return 0;
340}
341
342void usb_device_driver_unbind(void) {
343
344 logf("usb_device_driver_unbind");
345 if (usbcore.active_controller->device_driver != NULL) {
346 usbcore.active_controller->device_driver->unbind();
347 usbcore.active_controller->device_driver = NULL;
348 }
349
350 usbcore.device_driver = NULL;
351}
352
353static void update_driver_names(unsigned char* result) {
354
355 int i;
356 int pos = 0;
357 unsigned char terminator = ',';
358 struct usb_device_driver* dd = NULL;
359
360 /* reset buffer, iterate through drivers and add to char array */
361 memset(result, 0, USB_STACK_MAX_SETTINGS_NAME);
362 for (i = 0; i < NUM_DRIVERS; i++) {
363 int len;
364 dd = usbcore.device_drivers[i];
365
366 if (dd != NULL) {
367 len = strlen(dd->name);
368 if (pos > 0) {
369 memcpy(result + pos, &terminator, 1);
370 pos++;
371 }
372 memcpy(result + pos, dd->name, len);
373 pos += len;
374 }
375 }
376}
377
378static void bind_device_driver(struct usb_device_driver* driver) {
379
380 /* look if there is an old driver */
381 if (usbcore.active_controller->device_driver != NULL) {
382 usbcore.active_controller->device_driver->unbind();
383 }
384
385 /* bind driver to controller */
386 usbcore.active_controller->device_driver = driver;
387
388 /* init dirver */
389 driver->bind(usbcore.active_controller->controller_ops);
390}
391
392