diff options
Diffstat (limited to 'firmware/usbstack')
-rw-r--r-- | firmware/usbstack/config.h | 31 | ||||
-rw-r--r-- | firmware/usbstack/controller.h | 68 | ||||
-rw-r--r-- | firmware/usbstack/core.h | 84 | ||||
-rw-r--r-- | firmware/usbstack/core/config.c | 80 | ||||
-rw-r--r-- | firmware/usbstack/core/core.c | 392 | ||||
-rw-r--r-- | firmware/usbstack/core/epsetup.c | 186 | ||||
-rw-r--r-- | firmware/usbstack/core/utils.c | 125 | ||||
-rw-r--r-- | firmware/usbstack/device.h | 48 | ||||
-rw-r--r-- | firmware/usbstack/drivers/device/usb_serial.c | 300 | ||||
-rw-r--r-- | firmware/usbstack/drivers/device/usb_serial.h | 32 | ||||
-rw-r--r-- | firmware/usbstack/drivers/device/usb_storage.c | 269 | ||||
-rw-r--r-- | firmware/usbstack/drivers/device/usb_storage.h | 31 | ||||
-rw-r--r-- | firmware/usbstack/host.h | 31 |
13 files changed, 1677 insertions, 0 deletions
diff --git a/firmware/usbstack/config.h b/firmware/usbstack/config.h new file mode 100644 index 0000000000..95b00da1b3 --- /dev/null +++ b/firmware/usbstack/config.h | |||
@@ -0,0 +1,31 @@ | |||
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 | #ifndef _USBSTACK_CONFIG_H_ | ||
21 | #define _USBSTACK_CONFIG_H_ | ||
22 | |||
23 | /* default: use no controller */ | ||
24 | #ifndef USBSTACK_CAPS | ||
25 | #define USBSTACK_CAPS 0 | ||
26 | #endif | ||
27 | |||
28 | #define CONTROLLER_DEVICE (1 << 0) | ||
29 | #define CONTROLLER_HOST (1 << 1) | ||
30 | |||
31 | #endif /*_USBSTACK_CONFIG_H_*/ | ||
diff --git a/firmware/usbstack/controller.h b/firmware/usbstack/controller.h new file mode 100644 index 0000000000..8e99cf6641 --- /dev/null +++ b/firmware/usbstack/controller.h | |||
@@ -0,0 +1,68 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: arcotg_udc.c 12340 2007-02-16 22:13:21Z barrywardell $ | ||
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 | #ifndef _USBSTACK_CONTROLLER_H_ | ||
21 | #define _USBSTACK_CONTROLLER_H_ | ||
22 | |||
23 | struct usb_controller { | ||
24 | const char* name; | ||
25 | enum usb_controller_type type; | ||
26 | enum usb_device_speed speed; | ||
27 | void (*init)(void); | ||
28 | void (*shutdown)(void); | ||
29 | void (*irq)(void); | ||
30 | void (*start)(void); | ||
31 | void (*stop)(void); | ||
32 | void* controller_ops; | ||
33 | struct usb_device_driver* device_driver; | ||
34 | struct usb_host_driver* host_driver; | ||
35 | struct usb_ep* ep0; | ||
36 | struct usb_ep endpoints; | ||
37 | }; | ||
38 | |||
39 | struct usb_dcd_controller_ops { | ||
40 | /* endpoint management */ | ||
41 | int (*enable)(struct usb_ep* ep); | ||
42 | int (*disable)(struct usb_ep* ep); | ||
43 | int (*set_halt)(struct usb_ep* ep, bool hald); | ||
44 | |||
45 | /* transmitting */ | ||
46 | int (*send)(struct usb_ep* ep, struct usb_response* req); | ||
47 | int (*receive)(struct usb_ep* ep, struct usb_response* res); | ||
48 | |||
49 | /* ep0 */ | ||
50 | struct usb_ep* ep0; | ||
51 | }; | ||
52 | |||
53 | int usb_controller_register(struct usb_controller* ctrl); | ||
54 | int usb_controller_unregister(struct usb_controller* ctrl); | ||
55 | |||
56 | /* | ||
57 | * dcd - device controller driver | ||
58 | */ | ||
59 | void usb_dcd_init(void); | ||
60 | void usb_dcd_shutdown(void); | ||
61 | |||
62 | /* | ||
63 | * hcd - host controller driver | ||
64 | */ | ||
65 | void usb_hcd_init(void); | ||
66 | void usb_hcd_shutdown(void); | ||
67 | |||
68 | #endif /*_USBSTACK_CONTROLLER_H_*/ | ||
diff --git a/firmware/usbstack/core.h b/firmware/usbstack/core.h new file mode 100644 index 0000000000..7bda2934e7 --- /dev/null +++ b/firmware/usbstack/core.h | |||
@@ -0,0 +1,84 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: arcotg_udc.c 12340 2007-02-16 22:13:21Z barrywardell $ | ||
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 | #ifndef _USBSTACK_CORE_H_ | ||
21 | #define _USBSTACK_CORE_H_ | ||
22 | |||
23 | #include "linkedlist.h" | ||
24 | #include "usb_ch9.h" | ||
25 | #include "logf.h" | ||
26 | #include "system.h" | ||
27 | |||
28 | #include "usbstack.h" | ||
29 | |||
30 | /* | ||
31 | * stack datatypes | ||
32 | */ | ||
33 | struct usb_response { | ||
34 | void* buf; | ||
35 | uint32_t length; | ||
36 | }; | ||
37 | |||
38 | struct usb_ep { | ||
39 | const char name[15]; | ||
40 | uint8_t type; | ||
41 | uint32_t ep_num; /* which endpoint? */ | ||
42 | uint32_t pipe_num; /* which pipe? */ | ||
43 | uint32_t maxpacket; | ||
44 | bool claimed; | ||
45 | |||
46 | struct usb_endpoint_descriptor *desc; | ||
47 | struct list_head list; | ||
48 | }; | ||
49 | |||
50 | #include "usbstack/controller.h" | ||
51 | #include "usbstack/device.h" | ||
52 | #include "usbstack/host.h" | ||
53 | |||
54 | #define NUM_DRIVERS 3 | ||
55 | |||
56 | /* | ||
57 | * usb core | ||
58 | */ | ||
59 | struct usb_core { | ||
60 | /* we can have maximum two controllers (one device, one host) */ | ||
61 | struct usb_controller* controller[2]; | ||
62 | struct usb_controller* active_controller; | ||
63 | /* device driver used by stack */ | ||
64 | struct usb_device_driver* device_driver; | ||
65 | /* for each type of driver use own array */ | ||
66 | struct usb_host_driver* host_drivers[NUM_DRIVERS]; | ||
67 | struct usb_device_driver* device_drivers[NUM_DRIVERS]; | ||
68 | enum usb_controller_type mode; | ||
69 | bool running; | ||
70 | }; | ||
71 | |||
72 | void usb_stack_irq(void); | ||
73 | void usb_stack_work(void); | ||
74 | |||
75 | /* endpoint configuration */ | ||
76 | void usb_ep_autoconfig_reset(void); | ||
77 | struct usb_ep* usb_ep_autoconfig(struct usb_endpoint_descriptor* desc); | ||
78 | |||
79 | /* only used for debug */ | ||
80 | void into_usb_ctrlrequest(struct usb_ctrlrequest* request); | ||
81 | |||
82 | extern struct usb_core usbcore; | ||
83 | |||
84 | #endif /*_USBSTACK_CORE_H_*/ | ||
diff --git a/firmware/usbstack/core/config.c b/firmware/usbstack/core/config.c new file mode 100644 index 0000000000..a05a508bf9 --- /dev/null +++ b/firmware/usbstack/core/config.c | |||
@@ -0,0 +1,80 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: $ | ||
9 | * | ||
10 | * Copyright (C) 2007 by Christian Gmeiner | ||
11 | * | ||
12 | * Based on linux/drivers/usb/gadget/config.c | ||
13 | * Copyright (C) 2003 David Brownell | ||
14 | * | ||
15 | * All files in this archive are subject to the GNU General Public License. | ||
16 | * See the file COPYING in the source tree root for full license agreement. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #include <string.h> | ||
24 | #include "usbstack/core.h" | ||
25 | |||
26 | static int usb_descriptor_fillbuf(void* buf, unsigned buflen, struct usb_descriptor_header** src) { | ||
27 | |||
28 | uint8_t* dest = buf; | ||
29 | |||
30 | if (!src) { | ||
31 | return -EINVAL; | ||
32 | } | ||
33 | |||
34 | /* fill buffer from src[] until null descriptor ptr */ | ||
35 | for (; 0 != *src; src++) { | ||
36 | unsigned len = (*src)->bLength; | ||
37 | |||
38 | logf("len: %d", len); | ||
39 | |||
40 | if (len > buflen) | ||
41 | return -EINVAL; | ||
42 | memcpy(dest, *src, len); | ||
43 | buflen -= len; | ||
44 | dest += len; | ||
45 | } | ||
46 | return dest - (uint8_t *)buf; | ||
47 | } | ||
48 | |||
49 | int usb_stack_configdesc(const struct usb_config_descriptor* config, void* buf, unsigned length, struct usb_descriptor_header** desc) { | ||
50 | |||
51 | struct usb_config_descriptor* cp = buf; | ||
52 | int len; | ||
53 | |||
54 | if (length < USB_DT_CONFIG_SIZE || !desc) { | ||
55 | return -EINVAL; | ||
56 | } | ||
57 | |||
58 | /* config descriptor first */ | ||
59 | *cp = *config; | ||
60 | |||
61 | /* then interface/endpoint/class/vendor/... */ | ||
62 | len = usb_descriptor_fillbuf(USB_DT_CONFIG_SIZE + (uint8_t*)buf, length - USB_DT_CONFIG_SIZE, desc); | ||
63 | |||
64 | if (len < 0) { | ||
65 | return len; | ||
66 | } | ||
67 | |||
68 | len += USB_DT_CONFIG_SIZE; | ||
69 | if (len > 0xffff) { | ||
70 | return -EINVAL; | ||
71 | } | ||
72 | |||
73 | /* patch up the config descriptor */ | ||
74 | cp->bLength = USB_DT_CONFIG_SIZE; | ||
75 | cp->bDescriptorType = USB_DT_CONFIG; | ||
76 | cp->wTotalLength = len; | ||
77 | cp->bmAttributes |= USB_CONFIG_ATT_ONE; | ||
78 | |||
79 | return len; | ||
80 | } | ||
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 | |||
33 | struct usb_core usbcore; | ||
34 | |||
35 | /* private used functions */ | ||
36 | static void update_driver_names(unsigned char* result); | ||
37 | static void bind_device_driver(struct usb_device_driver* driver); | ||
38 | |||
39 | /** | ||
40 | * Initialize usb stack. | ||
41 | */ | ||
42 | void 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 | */ | ||
80 | void 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 | */ | ||
114 | void 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 | */ | ||
130 | void 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 | */ | ||
143 | void 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 | */ | ||
156 | int 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 | */ | ||
192 | int 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 | */ | ||
223 | void 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 | |||
265 | int 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 | */ | ||
275 | int 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 | |||
298 | int 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 | |||
342 | void 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 | |||
353 | static 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 | |||
378 | static 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 | |||
diff --git a/firmware/usbstack/core/epsetup.c b/firmware/usbstack/core/epsetup.c new file mode 100644 index 0000000000..6ae54fb9ac --- /dev/null +++ b/firmware/usbstack/core/epsetup.c | |||
@@ -0,0 +1,186 @@ | |||
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 <string.h> | ||
21 | #include <ctype.h> | ||
22 | #include "usbstack/core.h" | ||
23 | |||
24 | /** | ||
25 | * | ||
26 | * Naming Convention for Endpoint Names | ||
27 | * | ||
28 | * - ep1, ep2, ... address is fixed, not direction or type | ||
29 | * - ep1in, ep2out, ... address and direction are fixed, not type | ||
30 | * - ep1-bulk, ep2-bulk, ... address and type are fixed, not direction | ||
31 | * - ep1in-bulk, ep2out-iso, ... all three are fixed | ||
32 | * - ep-* ... no functionality restrictions | ||
33 | * | ||
34 | * Type suffixes are "-bulk", "-iso", or "-int". Numbers are decimal. | ||
35 | * | ||
36 | */ | ||
37 | static int ep_matches(struct usb_ep* ep, struct usb_endpoint_descriptor* desc); | ||
38 | |||
39 | void usb_ep_autoconfig_reset(void) { | ||
40 | |||
41 | struct usb_ep* ep = NULL; | ||
42 | if (usbcore.active_controller == NULL) { | ||
43 | return; | ||
44 | } | ||
45 | |||
46 | logf("resetting endpoints"); | ||
47 | list_for_each_entry(ep, &usbcore.active_controller->endpoints.list, list) { | ||
48 | logf("reset %s", ep->name); | ||
49 | ep->claimed = false; | ||
50 | } | ||
51 | } | ||
52 | |||
53 | /** | ||
54 | * Find a suitable endpoint for the requested endpoint descriptor. | ||
55 | * @param desc usb descritpro to use for seraching. | ||
56 | * @return NULL or a valid endpoint. | ||
57 | */ | ||
58 | struct usb_ep* usb_ep_autoconfig(struct usb_endpoint_descriptor* desc) { | ||
59 | |||
60 | struct usb_ep* ep = NULL; | ||
61 | if (usbcore.active_controller == NULL) { | ||
62 | logf("active controller NULL"); | ||
63 | return NULL; | ||
64 | } | ||
65 | |||
66 | list_for_each_entry(ep, &usbcore.active_controller->endpoints.list, list) { | ||
67 | if (ep_matches (ep, desc)) { | ||
68 | return ep; | ||
69 | } | ||
70 | } | ||
71 | |||
72 | return NULL; | ||
73 | } | ||
74 | |||
75 | static int ep_matches(struct usb_ep* ep, struct usb_endpoint_descriptor* desc) { | ||
76 | |||
77 | uint8_t type; | ||
78 | const char* tmp; | ||
79 | uint16_t max; | ||
80 | |||
81 | /* endpoint already claimed? */ | ||
82 | if (ep->claimed) { | ||
83 | logf("!! claimed !!"); | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | /* only support ep0 for portable CONTROL traffic */ | ||
88 | type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; | ||
89 | if (type == USB_ENDPOINT_XFER_CONTROL) { | ||
90 | logf("type == control"); | ||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | /* some other naming convention */ | ||
95 | if (ep->name[0] != 'e') { | ||
96 | logf("wrong name"); | ||
97 | return 0; | ||
98 | } | ||
99 | |||
100 | /* type-restriction: "-iso", "-bulk", or "-int". | ||
101 | * direction-restriction: "in", "out". | ||
102 | */ | ||
103 | if (ep->name[2] != '-' ) { | ||
104 | tmp = strrchr (ep->name, '-'); | ||
105 | if (tmp) { | ||
106 | switch (type) { | ||
107 | case USB_ENDPOINT_XFER_INT: | ||
108 | /* bulk endpoints handle interrupt transfers, | ||
109 | * except the toggle-quirky iso-synch kind | ||
110 | */ | ||
111 | if (tmp[2] == 's') { // == "-iso" | ||
112 | return 0; | ||
113 | } | ||
114 | break; | ||
115 | case USB_ENDPOINT_XFER_BULK: | ||
116 | if (tmp[1] != 'b') { // != "-bulk" | ||
117 | return 0; | ||
118 | } | ||
119 | break; | ||
120 | case USB_ENDPOINT_XFER_ISOC: | ||
121 | if (tmp[2] != 's') { // != "-iso" | ||
122 | return 0; | ||
123 | } | ||
124 | } | ||
125 | } else { | ||
126 | tmp = ep->name + strlen (ep->name); | ||
127 | } | ||
128 | |||
129 | /* direction-restriction: "..in-..", "out-.." */ | ||
130 | tmp--; | ||
131 | if (!isdigit(*tmp)) { | ||
132 | if (desc->bEndpointAddress & USB_DIR_IN) { | ||
133 | if ('n' != *tmp) { | ||
134 | return 0; | ||
135 | } | ||
136 | } else { | ||
137 | if ('t' != *tmp) { | ||
138 | return 0; | ||
139 | } | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | |||
144 | |||
145 | /* endpoint maxpacket size is an input parameter, except for bulk | ||
146 | * where it's an output parameter representing the full speed limit. | ||
147 | * the usb spec fixes high speed bulk maxpacket at 512 bytes. | ||
148 | */ | ||
149 | max = 0x7ff & desc->wMaxPacketSize; | ||
150 | |||
151 | switch (type) { | ||
152 | case USB_ENDPOINT_XFER_INT: | ||
153 | /* INT: limit 64 bytes full speed, 1024 high speed */ | ||
154 | if ((usbcore.active_controller->speed != USB_SPEED_HIGH) && (max > 64)) { | ||
155 | return 0; | ||
156 | } | ||
157 | /* FALLTHROUGH */ | ||
158 | |||
159 | case USB_ENDPOINT_XFER_ISOC: | ||
160 | if ((usbcore.active_controller->speed != USB_SPEED_HIGH) && (max > 1023)) { | ||
161 | return 0; | ||
162 | } | ||
163 | break; | ||
164 | } | ||
165 | |||
166 | /* MATCH!! */ | ||
167 | |||
168 | /* report address */ | ||
169 | desc->bEndpointAddress |= ep->ep_num; | ||
170 | |||
171 | /* report (variable) full speed bulk maxpacket */ | ||
172 | if (type == USB_ENDPOINT_XFER_BULK) { | ||
173 | int size = max; | ||
174 | |||
175 | /* min() doesn't work on bitfields with gcc-3.5 */ | ||
176 | if (size > 64) { | ||
177 | size = 64; | ||
178 | } | ||
179 | desc->wMaxPacketSize = size; | ||
180 | } | ||
181 | |||
182 | /* save desc in endpoint */ | ||
183 | ep->desc = desc; | ||
184 | |||
185 | return 1; | ||
186 | } | ||
diff --git a/firmware/usbstack/core/utils.c b/firmware/usbstack/core/utils.c new file mode 100644 index 0000000000..2fb2695732 --- /dev/null +++ b/firmware/usbstack/core/utils.c | |||
@@ -0,0 +1,125 @@ | |||
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 <string.h> | ||
21 | #include "usbstack/core.h" | ||
22 | |||
23 | void into_usb_ctrlrequest(struct usb_ctrlrequest* request) { | ||
24 | |||
25 | char* type = ""; | ||
26 | char* req = ""; | ||
27 | char* extra = 0; | ||
28 | |||
29 | logf("-usb request-"); | ||
30 | /* check if packet is okay */ | ||
31 | if (request->bRequestType == 0 && | ||
32 | request->bRequest == 0 && | ||
33 | request->wValue == 0 && | ||
34 | request->wIndex == 0 && | ||
35 | request->wLength == 0) { | ||
36 | logf(" -> INVALID <-"); | ||
37 | return; | ||
38 | } | ||
39 | |||
40 | switch (request->bRequestType & USB_TYPE_MASK) { | ||
41 | case USB_TYPE_STANDARD: | ||
42 | type = "standard"; | ||
43 | |||
44 | switch (request->bRequest) { | ||
45 | case USB_REQ_GET_STATUS: | ||
46 | req = "get status"; | ||
47 | break; | ||
48 | case USB_REQ_CLEAR_FEATURE: | ||
49 | req = "clear feature"; | ||
50 | break; | ||
51 | case USB_REQ_SET_FEATURE: | ||
52 | req = "set feature"; | ||
53 | break; | ||
54 | case USB_REQ_SET_ADDRESS: | ||
55 | req = "set address"; | ||
56 | break; | ||
57 | case USB_REQ_GET_DESCRIPTOR: | ||
58 | req = "get descriptor"; | ||
59 | |||
60 | switch (request->wValue >> 8) { | ||
61 | case USB_DT_DEVICE: | ||
62 | extra = "get device descriptor"; | ||
63 | break; | ||
64 | case USB_DT_DEVICE_QUALIFIER: | ||
65 | extra = "get device qualifier"; | ||
66 | break; | ||
67 | case USB_DT_OTHER_SPEED_CONFIG: | ||
68 | extra = "get other-speed config descriptor"; | ||
69 | case USB_DT_CONFIG: | ||
70 | extra = "get configuration descriptor"; | ||
71 | break; | ||
72 | case USB_DT_STRING: | ||
73 | extra = "get string descriptor"; | ||
74 | break; | ||
75 | case USB_DT_DEBUG: | ||
76 | extra = "debug"; | ||
77 | break; | ||
78 | } | ||
79 | break; | ||
80 | |||
81 | break; | ||
82 | case USB_REQ_SET_DESCRIPTOR: | ||
83 | req = "set descriptor"; | ||
84 | break; | ||
85 | case USB_REQ_GET_CONFIGURATION: | ||
86 | req = "get configuration"; | ||
87 | break; | ||
88 | case USB_REQ_SET_CONFIGURATION: | ||
89 | req = "set configuration"; | ||
90 | break; | ||
91 | case USB_REQ_GET_INTERFACE: | ||
92 | req = "get interface"; | ||
93 | break; | ||
94 | case USB_REQ_SET_INTERFACE: | ||
95 | req = "set interface"; | ||
96 | break; | ||
97 | case USB_REQ_SYNCH_FRAME: | ||
98 | req = "sync frame"; | ||
99 | break; | ||
100 | default: | ||
101 | req = "unkown"; | ||
102 | break; | ||
103 | } | ||
104 | |||
105 | break; | ||
106 | case USB_TYPE_CLASS: | ||
107 | type = "class"; | ||
108 | break; | ||
109 | |||
110 | case USB_TYPE_VENDOR: | ||
111 | type = "vendor"; | ||
112 | break; | ||
113 | } | ||
114 | |||
115 | logf(" -b 0x%x", request->bRequestType); | ||
116 | logf(" -b 0x%x", request->bRequest); | ||
117 | logf(" -b 0x%x", request->wValue); | ||
118 | logf(" -b 0x%x", request->wIndex); | ||
119 | logf(" -b 0x%x", request->wLength); | ||
120 | logf(" -> t: %s", type); | ||
121 | logf(" -> r: %s", req); | ||
122 | if (extra != 0) { | ||
123 | logf(" -> e: %s", extra); | ||
124 | } | ||
125 | } | ||
diff --git a/firmware/usbstack/device.h b/firmware/usbstack/device.h new file mode 100644 index 0000000000..5b385d8129 --- /dev/null +++ b/firmware/usbstack/device.h | |||
@@ -0,0 +1,48 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: arcotg_udc.c 12340 2007-02-16 22:13:21Z barrywardell $ | ||
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 | #ifndef _USBSTACK_DEVICE_H_ | ||
21 | #define _USBSTACK_DEVICE_H_ | ||
22 | |||
23 | /* | ||
24 | * usb device driver | ||
25 | */ | ||
26 | struct usb_device_driver { | ||
27 | const char* name; | ||
28 | void (*bind)(void* controller_ops); | ||
29 | void (*unbind)(void); | ||
30 | int (*request)(struct usb_ctrlrequest* req); | ||
31 | void (*suspend)(void); | ||
32 | void (*resume)(void); | ||
33 | void (*speed)(enum usb_device_speed speed); | ||
34 | struct usb_descriptors* descriptors; | ||
35 | void* data; /* used to store controller specific ops struct */ | ||
36 | }; | ||
37 | |||
38 | int usb_device_driver_register(struct usb_device_driver* driver); | ||
39 | |||
40 | /* forward declaration */ | ||
41 | struct usb_config_descriptor; | ||
42 | struct usb_descriptor_header; | ||
43 | |||
44 | int usb_stack_configdesc(const struct usb_config_descriptor* config, | ||
45 | void* buf, unsigned length, | ||
46 | struct usb_descriptor_header** desc); | ||
47 | |||
48 | #endif /*_USBSTACK_DEVICE_H_*/ | ||
diff --git a/firmware/usbstack/drivers/device/usb_serial.c b/firmware/usbstack/drivers/device/usb_serial.c new file mode 100644 index 0000000000..fe1e52f25a --- /dev/null +++ b/firmware/usbstack/drivers/device/usb_serial.c | |||
@@ -0,0 +1,300 @@ | |||
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 "usb_serial.h" | ||
21 | #include <string.h> | ||
22 | |||
23 | static struct usb_dcd_controller_ops* ops; | ||
24 | |||
25 | struct usb_device_driver usb_serial_driver = { | ||
26 | .name = "serial", | ||
27 | .bind = usb_serial_driver_bind, | ||
28 | .unbind = NULL, | ||
29 | .request = usb_serial_driver_request, | ||
30 | .suspend = NULL, | ||
31 | .resume = NULL, | ||
32 | .speed = usb_serial_driver_speed, | ||
33 | }; | ||
34 | |||
35 | /*-------------------------------------------------------------------------*/ | ||
36 | /* usb descriptors */ | ||
37 | |||
38 | /* TODO: implement strings */ | ||
39 | #define GS_MANUFACTURER_STR_ID 0 | ||
40 | #define GS_PRODUCT_STR_ID 0 | ||
41 | #define GS_SERIAL_STR_ID 0 | ||
42 | #define GS_BULK_CONFIG_STR_ID 0 | ||
43 | #define GS_DATA_STR_ID 0 | ||
44 | |||
45 | #define GS_BULK_CONFIG_ID 1 | ||
46 | |||
47 | static struct usb_device_descriptor serial_device_desc = { | ||
48 | .bLength = USB_DT_DEVICE_SIZE, | ||
49 | .bDescriptorType = USB_DT_DEVICE, | ||
50 | .bcdUSB = 0x0200, | ||
51 | .bDeviceClass = USB_CLASS_COMM, | ||
52 | .bDeviceSubClass = 0, | ||
53 | .bDeviceProtocol = 0, | ||
54 | .idVendor = 0x0525, | ||
55 | .idProduct = 0xa4a6, | ||
56 | .iManufacturer = GS_MANUFACTURER_STR_ID, | ||
57 | .iProduct = GS_PRODUCT_STR_ID, | ||
58 | .iSerialNumber = GS_SERIAL_STR_ID, | ||
59 | .bNumConfigurations = 1, | ||
60 | }; | ||
61 | |||
62 | static struct usb_config_descriptor serial_bulk_config_desc = { | ||
63 | .bLength = USB_DT_CONFIG_SIZE, | ||
64 | .bDescriptorType = USB_DT_CONFIG, | ||
65 | |||
66 | .bNumInterfaces = 1, | ||
67 | .bConfigurationValue = GS_BULK_CONFIG_ID, | ||
68 | .iConfiguration = GS_BULK_CONFIG_STR_ID, | ||
69 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | ||
70 | .bMaxPower = 1, | ||
71 | }; | ||
72 | |||
73 | static struct usb_interface_descriptor serial_bulk_interface_desc = { | ||
74 | .bLength = USB_DT_INTERFACE_SIZE, | ||
75 | .bDescriptorType = USB_DT_INTERFACE, | ||
76 | .bInterfaceNumber = 0, | ||
77 | .bNumEndpoints = 2, | ||
78 | .bInterfaceClass = USB_CLASS_CDC_DATA, | ||
79 | .bInterfaceSubClass = 0, | ||
80 | .bInterfaceProtocol = 0, | ||
81 | .iInterface = GS_DATA_STR_ID, | ||
82 | }; | ||
83 | |||
84 | static struct usb_endpoint_descriptor serial_fullspeed_in_desc = { | ||
85 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
86 | .bDescriptorType = USB_DT_ENDPOINT, | ||
87 | .bEndpointAddress = USB_DIR_IN, | ||
88 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
89 | .wMaxPacketSize = 8, | ||
90 | }; | ||
91 | |||
92 | static struct usb_endpoint_descriptor serial_fullspeed_out_desc = { | ||
93 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
94 | .bDescriptorType = USB_DT_ENDPOINT, | ||
95 | .bEndpointAddress = USB_DIR_OUT, | ||
96 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
97 | .wMaxPacketSize = 8, | ||
98 | }; | ||
99 | |||
100 | static struct usb_debug_descriptor serial_debug_desc = { | ||
101 | .bLength = sizeof(struct usb_debug_descriptor), | ||
102 | .bDescriptorType = USB_DT_DEBUG, | ||
103 | }; | ||
104 | |||
105 | static struct usb_qualifier_descriptor serial_qualifier_desc = { | ||
106 | .bLength = sizeof(struct usb_qualifier_descriptor), | ||
107 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, | ||
108 | .bcdUSB = 0x0200, | ||
109 | .bDeviceClass = USB_CLASS_COMM, | ||
110 | .bNumConfigurations = 1, | ||
111 | }; | ||
112 | |||
113 | struct usb_descriptor_header *serial_bulk_fullspeed_function[] = { | ||
114 | (struct usb_descriptor_header *) &serial_bulk_interface_desc, | ||
115 | (struct usb_descriptor_header *) &serial_fullspeed_in_desc, | ||
116 | (struct usb_descriptor_header *) &serial_fullspeed_out_desc, | ||
117 | NULL, | ||
118 | }; | ||
119 | |||
120 | #define BUFFER_SIZE 100 | ||
121 | uint8_t buf[BUFFER_SIZE]; | ||
122 | |||
123 | struct usb_response res; | ||
124 | |||
125 | /* helper functions */ | ||
126 | static int config_buf(uint8_t *buf, uint8_t type, unsigned index); | ||
127 | static int set_config(int config); | ||
128 | |||
129 | |||
130 | struct device { | ||
131 | struct usb_ep* in; | ||
132 | struct usb_ep* out; | ||
133 | uint32_t used_config; | ||
134 | }; | ||
135 | |||
136 | static struct device dev; | ||
137 | |||
138 | /*-------------------------------------------------------------------------*/ | ||
139 | |||
140 | void usb_serial_driver_init(void) { | ||
141 | |||
142 | logf("usb serial: register"); | ||
143 | usb_device_driver_register(&usb_serial_driver); | ||
144 | } | ||
145 | |||
146 | /*-------------------------------------------------------------------------*/ | ||
147 | |||
148 | void usb_serial_driver_bind(void* controler_ops) { | ||
149 | |||
150 | logf("usb serial: bind"); | ||
151 | ops = controler_ops; | ||
152 | |||
153 | /* serach and asign endpoints */ | ||
154 | usb_ep_autoconfig_reset(); | ||
155 | |||
156 | dev.in = usb_ep_autoconfig(&serial_fullspeed_in_desc); | ||
157 | if (!dev.in) { | ||
158 | goto autoconf_fail; | ||
159 | } | ||
160 | dev.in->claimed = true; | ||
161 | logf("usb serial: in: %s", dev.in->name); | ||
162 | |||
163 | dev.out = usb_ep_autoconfig(&serial_fullspeed_out_desc); | ||
164 | if (!dev.out) { | ||
165 | goto autoconf_fail; | ||
166 | } | ||
167 | dev.out->claimed = true; | ||
168 | logf("usb serial: out: %s", dev.out->name); | ||
169 | |||
170 | /* update device decsriptor */ | ||
171 | serial_device_desc.bMaxPacketSize0 = ops->ep0->maxpacket; | ||
172 | |||
173 | /* update qualifie descriptor */ | ||
174 | serial_qualifier_desc.bMaxPacketSize0 = ops->ep0->maxpacket; | ||
175 | |||
176 | /* update debug descriptor */ | ||
177 | serial_debug_desc.bDebugInEndpoint = dev.in->ep_num; | ||
178 | serial_debug_desc.bDebugOutEndpoint = dev.out->ep_num; | ||
179 | |||
180 | return; | ||
181 | |||
182 | autoconf_fail: | ||
183 | logf("failed to find endpoiunts"); | ||
184 | } | ||
185 | |||
186 | int usb_serial_driver_request(struct usb_ctrlrequest* request) { | ||
187 | |||
188 | int ret = -EOPNOTSUPP; | ||
189 | logf("usb serial: request"); | ||
190 | |||
191 | res.length = 0; | ||
192 | res.buf = NULL; | ||
193 | |||
194 | switch (request->bRequestType & USB_TYPE_MASK) { | ||
195 | case USB_TYPE_STANDARD: | ||
196 | |||
197 | switch (request->bRequest) { | ||
198 | case USB_REQ_GET_DESCRIPTOR: | ||
199 | |||
200 | switch (request->wValue >> 8) { | ||
201 | case USB_DT_DEVICE: | ||
202 | logf("usb serial: sending device desc"); | ||
203 | ret = MIN(sizeof(struct usb_device_descriptor), request->wLength); | ||
204 | res.buf = &serial_device_desc; | ||
205 | break; | ||
206 | |||
207 | case USB_DT_DEVICE_QUALIFIER: | ||
208 | logf("usb serial: sending qualifier dec"); | ||
209 | ret = MIN(sizeof(struct usb_qualifier_descriptor), request->wLength); | ||
210 | res.buf = &serial_qualifier_desc; | ||
211 | |||
212 | case USB_DT_CONFIG: | ||
213 | logf("usb serial: sending config desc"); | ||
214 | |||
215 | ret = config_buf(buf, request->wValue >> 8, request->wValue & 0xff); | ||
216 | if (ret >= 0) { | ||
217 | logf("%d, vs %d", request->wLength, ret); | ||
218 | ret = MIN(request->wLength, (uint16_t)ret); | ||
219 | } | ||
220 | res.buf = buf; | ||
221 | break; | ||
222 | |||
223 | case USB_DT_DEBUG: | ||
224 | logf("usb serial: sending debug desc"); | ||
225 | ret = MIN(sizeof(struct usb_debug_descriptor), request->wLength); | ||
226 | res.buf = &serial_debug_desc; | ||
227 | break; | ||
228 | } | ||
229 | break; | ||
230 | |||
231 | case USB_REQ_SET_CONFIGURATION: | ||
232 | logf("usb serial: set configuration %d", request->wValue); | ||
233 | ret = set_config(request->wValue); | ||
234 | break; | ||
235 | |||
236 | case USB_REQ_GET_CONFIGURATION: | ||
237 | logf("usb serial: get configuration"); | ||
238 | ret = 1; | ||
239 | res.buf = &dev.used_config; | ||
240 | break; | ||
241 | } | ||
242 | } | ||
243 | |||
244 | if (ret >= 0) { | ||
245 | res.length = ret; | ||
246 | ret = ops->send(NULL, &res); | ||
247 | } | ||
248 | |||
249 | return ret; | ||
250 | } | ||
251 | |||
252 | void usb_serial_driver_speed(enum usb_device_speed speed) { | ||
253 | |||
254 | switch (speed) { | ||
255 | case USB_SPEED_LOW: | ||
256 | case USB_SPEED_FULL: | ||
257 | logf("usb serial: using fullspeed"); | ||
258 | break; | ||
259 | case USB_SPEED_HIGH: | ||
260 | logf("usb serial: using highspeed"); | ||
261 | break; | ||
262 | default: | ||
263 | logf("speed: hmm"); | ||
264 | break; | ||
265 | } | ||
266 | } | ||
267 | |||
268 | /*-------------------------------------------------------------------------*/ | ||
269 | /* helper functions */ | ||
270 | |||
271 | static int config_buf(uint8_t *buf, uint8_t type, unsigned index) { | ||
272 | |||
273 | int len; | ||
274 | |||
275 | /* TODO check index*/ | ||
276 | |||
277 | len = usb_stack_configdesc(&serial_bulk_config_desc, buf, BUFFER_SIZE, serial_bulk_fullspeed_function); | ||
278 | if (len < 0) { | ||
279 | return len; | ||
280 | } | ||
281 | ((struct usb_config_descriptor *)buf)->bDescriptorType = type; | ||
282 | return len; | ||
283 | } | ||
284 | |||
285 | static int set_config(int config) { | ||
286 | |||
287 | /* TODO check config*/ | ||
288 | |||
289 | /* enable endpoints */ | ||
290 | logf("setup %s", dev.in->name); | ||
291 | ops->enable(dev.in); | ||
292 | logf("setup %s", dev.out->name); | ||
293 | ops->enable(dev.out); | ||
294 | |||
295 | /* store config */ | ||
296 | logf("using config %d", config); | ||
297 | dev.used_config = config; | ||
298 | |||
299 | return 0; | ||
300 | } | ||
diff --git a/firmware/usbstack/drivers/device/usb_serial.h b/firmware/usbstack/drivers/device/usb_serial.h new file mode 100644 index 0000000000..808eaa16e3 --- /dev/null +++ b/firmware/usbstack/drivers/device/usb_serial.h | |||
@@ -0,0 +1,32 @@ | |||
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 | #ifndef _SERIAL_H_ | ||
21 | #define _SERIAL_H_ | ||
22 | |||
23 | #include "usbstack/core.h" | ||
24 | |||
25 | /* register serial driver in usb stack */ | ||
26 | void usb_serial_driver_init(void); | ||
27 | |||
28 | void usb_serial_driver_bind(void* controller_ops); | ||
29 | int usb_serial_driver_request(struct usb_ctrlrequest* req); | ||
30 | void usb_serial_driver_speed(enum usb_device_speed speed); | ||
31 | |||
32 | #endif /*_SERIAL_H_*/ | ||
diff --git a/firmware/usbstack/drivers/device/usb_storage.c b/firmware/usbstack/drivers/device/usb_storage.c new file mode 100644 index 0000000000..0cb1f108b5 --- /dev/null +++ b/firmware/usbstack/drivers/device/usb_storage.c | |||
@@ -0,0 +1,269 @@ | |||
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 "usb_storage.h" | ||
21 | #include <string.h> | ||
22 | |||
23 | /*-------------------------------------------------------------------------*/ | ||
24 | |||
25 | static struct usb_dcd_controller_ops* ops; | ||
26 | |||
27 | struct usb_device_driver usb_storage_driver = { | ||
28 | .name = "storage", | ||
29 | .bind = usb_storage_driver_bind, | ||
30 | .unbind = NULL, | ||
31 | .request = usb_storage_driver_request, | ||
32 | .suspend = NULL, | ||
33 | .resume = NULL, | ||
34 | .speed = NULL, | ||
35 | }; | ||
36 | |||
37 | struct device { | ||
38 | struct usb_ep* in; | ||
39 | struct usb_ep* out; | ||
40 | struct usb_ep* intr; | ||
41 | }; | ||
42 | |||
43 | static struct device dev; | ||
44 | |||
45 | /*-------------------------------------------------------------------------*/ | ||
46 | |||
47 | #define PROTO_BULK 0x50 // Bulk only | ||
48 | #define SUBCL_SCSI 0x06 // Transparent SCSI | ||
49 | |||
50 | /* Bulk-only class specific requests */ | ||
51 | #define USB_BULK_RESET_REQUEST 0xff | ||
52 | #define USB_BULK_GET_MAX_LUN_REQUEST 0xfe | ||
53 | |||
54 | /*-------------------------------------------------------------------------*/ | ||
55 | /* usb descriptors */ | ||
56 | |||
57 | static struct usb_device_descriptor storage_device_desc = { | ||
58 | .bLength = USB_DT_DEVICE_SIZE, | ||
59 | .bDescriptorType = USB_DT_DEVICE, | ||
60 | .bcdUSB = 0x0200, | ||
61 | .bDeviceClass = 0, | ||
62 | .bDeviceSubClass = 0, | ||
63 | .bDeviceProtocol = 0, | ||
64 | .bMaxPacketSize0 = 64, | ||
65 | .idVendor = 0xffff, | ||
66 | .idProduct = 0x0001, | ||
67 | .iManufacturer = 0, | ||
68 | .iProduct = 0, | ||
69 | .iSerialNumber = 0, | ||
70 | .bNumConfigurations = 1, | ||
71 | }; | ||
72 | |||
73 | static struct usb_config_descriptor storage_config_desc = { | ||
74 | .bLength = USB_DT_CONFIG_SIZE, | ||
75 | .bDescriptorType = USB_DT_CONFIG, | ||
76 | |||
77 | .bNumInterfaces = 1, | ||
78 | .bConfigurationValue = 1, | ||
79 | .iConfiguration = 0, | ||
80 | .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER, | ||
81 | .bMaxPower = 1, | ||
82 | }; | ||
83 | |||
84 | static struct usb_interface_descriptor storage_interface_desc = { | ||
85 | .bLength = USB_DT_INTERFACE_SIZE, | ||
86 | .bDescriptorType = USB_DT_INTERFACE, | ||
87 | .bInterfaceNumber = 0, | ||
88 | .bNumEndpoints = 3, | ||
89 | .bInterfaceClass = USB_CLASS_MASS_STORAGE, | ||
90 | .bInterfaceSubClass = SUBCL_SCSI, | ||
91 | .bInterfaceProtocol = PROTO_BULK, | ||
92 | .iInterface = 0, | ||
93 | }; | ||
94 | |||
95 | /* endpoint I -> bulk in */ | ||
96 | static struct usb_endpoint_descriptor storage_bulk_in_desc = { | ||
97 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
98 | .bDescriptorType = USB_DT_ENDPOINT, | ||
99 | .bEndpointAddress = USB_DIR_IN, | ||
100 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
101 | .wMaxPacketSize = 512, | ||
102 | }; | ||
103 | |||
104 | /* endpoint II -> bulk out */ | ||
105 | static struct usb_endpoint_descriptor storage_bulk_out_desc = { | ||
106 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
107 | .bDescriptorType = USB_DT_ENDPOINT, | ||
108 | .bEndpointAddress = USB_DIR_OUT, | ||
109 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | ||
110 | .wMaxPacketSize = 512, | ||
111 | }; | ||
112 | |||
113 | struct usb_descriptor_header *storage_fullspeed_function[] = { | ||
114 | (struct usb_descriptor_header *) &storage_interface_desc, | ||
115 | (struct usb_descriptor_header *) &storage_bulk_in_desc, | ||
116 | (struct usb_descriptor_header *) &storage_bulk_out_desc, | ||
117 | NULL, | ||
118 | }; | ||
119 | |||
120 | #define BUFFER_SIZE 100 | ||
121 | uint8_t buf[BUFFER_SIZE]; | ||
122 | |||
123 | struct usb_response res; | ||
124 | |||
125 | /* helper functions */ | ||
126 | static int config_buf(uint8_t *buf, uint8_t type, unsigned index); | ||
127 | static int set_config(int config); | ||
128 | |||
129 | /*-------------------------------------------------------------------------*/ | ||
130 | |||
131 | void usb_storage_driver_init(void) { | ||
132 | |||
133 | logf("usb storage: register"); | ||
134 | usb_device_driver_register(&usb_storage_driver); | ||
135 | } | ||
136 | |||
137 | /*-------------------------------------------------------------------------*/ | ||
138 | /* device driver ops */ | ||
139 | |||
140 | void usb_storage_driver_bind(void* controler_ops) { | ||
141 | |||
142 | ops = controler_ops; | ||
143 | |||
144 | /* serach and asign endpoints */ | ||
145 | usb_ep_autoconfig_reset(); | ||
146 | |||
147 | dev.in = usb_ep_autoconfig(&storage_bulk_in_desc); | ||
148 | if (!dev.in) { | ||
149 | goto autoconf_fail; | ||
150 | } | ||
151 | dev.in->claimed = true; | ||
152 | logf("usb storage: in: %s", dev.in->name); | ||
153 | |||
154 | dev.out = usb_ep_autoconfig(&storage_bulk_out_desc); | ||
155 | if (!dev.out) { | ||
156 | goto autoconf_fail; | ||
157 | } | ||
158 | dev.out->claimed = true; | ||
159 | logf("usb storage: out: %s", dev.out->name); | ||
160 | |||
161 | return; | ||
162 | |||
163 | autoconf_fail: | ||
164 | logf("failed to find endpoints"); | ||
165 | } | ||
166 | |||
167 | int usb_storage_driver_request(struct usb_ctrlrequest* request) { | ||
168 | |||
169 | int ret = -EOPNOTSUPP; | ||
170 | logf("usb storage: request"); | ||
171 | |||
172 | res.length = 0; | ||
173 | res.buf = NULL; | ||
174 | |||
175 | switch (request->bRequestType & USB_TYPE_MASK) { | ||
176 | case USB_TYPE_STANDARD: | ||
177 | |||
178 | switch (request->bRequest) { | ||
179 | case USB_REQ_GET_DESCRIPTOR: | ||
180 | |||
181 | switch (request->wValue >> 8) { | ||
182 | case USB_DT_DEVICE: | ||
183 | logf("usb storage: sending device desc"); | ||
184 | ret = MIN(sizeof(struct usb_device_descriptor), request->wLength); | ||
185 | res.buf = &storage_device_desc; | ||
186 | break; | ||
187 | |||
188 | case USB_DT_CONFIG: | ||
189 | logf("usb storage: sending config desc"); | ||
190 | |||
191 | ret = config_buf(buf, request->wValue >> 8, request->wValue & 0xff); | ||
192 | if (ret >= 0) { | ||
193 | logf("%d, vs %d", request->wLength, ret); | ||
194 | ret = MIN(request->wLength, (uint16_t)ret); | ||
195 | } | ||
196 | res.buf = buf; | ||
197 | break; | ||
198 | } | ||
199 | break; | ||
200 | |||
201 | case USB_REQ_SET_CONFIGURATION: | ||
202 | logf("usb storage: set configuration %d", request->wValue); | ||
203 | ret = set_config(request->wValue); | ||
204 | break; | ||
205 | |||
206 | case USB_REQ_SET_INTERFACE: | ||
207 | logf("usb storage: set interface"); | ||
208 | ret = 0; | ||
209 | break; | ||
210 | } | ||
211 | |||
212 | case USB_TYPE_CLASS: | ||
213 | |||
214 | switch (request->bRequest) { | ||
215 | case USB_BULK_RESET_REQUEST: | ||
216 | logf("usb storage: bulk reset"); | ||
217 | break; | ||
218 | |||
219 | case USB_BULK_GET_MAX_LUN_REQUEST: | ||
220 | logf("usb storage: get max lun"); | ||
221 | /* we support no LUNs (Logical Unit Number) */ | ||
222 | buf[0] = 0; | ||
223 | ret = 1; | ||
224 | break; | ||
225 | } | ||
226 | break; | ||
227 | } | ||
228 | |||
229 | if (ret >= 0) { | ||
230 | res.length = ret; | ||
231 | ret = ops->send(NULL, &res); | ||
232 | } | ||
233 | |||
234 | return ret; | ||
235 | } | ||
236 | |||
237 | /*-------------------------------------------------------------------------*/ | ||
238 | /* S/GET CONFIGURATION helpers */ | ||
239 | |||
240 | static int config_buf(uint8_t *buf, uint8_t type, unsigned index) { | ||
241 | |||
242 | int len; | ||
243 | |||
244 | /* only one configuration */ | ||
245 | if (index != 0) { | ||
246 | return -EINVAL; | ||
247 | } | ||
248 | |||
249 | len = usb_stack_configdesc(&storage_config_desc, buf, BUFFER_SIZE, storage_fullspeed_function); | ||
250 | if (len < 0) { | ||
251 | return len; | ||
252 | } | ||
253 | ((struct usb_config_descriptor *)buf)->bDescriptorType = type; | ||
254 | return len; | ||
255 | } | ||
256 | |||
257 | static int set_config(int config) { | ||
258 | |||
259 | /* enable endpoints */ | ||
260 | logf("setup %s", dev.in->name); | ||
261 | ops->enable(dev.in); | ||
262 | logf("setup %s", dev.out->name); | ||
263 | ops->enable(dev.out); | ||
264 | |||
265 | /* setup buffers */ | ||
266 | |||
267 | return 0; | ||
268 | } | ||
269 | |||
diff --git a/firmware/usbstack/drivers/device/usb_storage.h b/firmware/usbstack/drivers/device/usb_storage.h new file mode 100644 index 0000000000..9494aa76ff --- /dev/null +++ b/firmware/usbstack/drivers/device/usb_storage.h | |||
@@ -0,0 +1,31 @@ | |||
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 | #ifndef _STORGAGE_H_ | ||
21 | #define _STORGAGE_H_ | ||
22 | |||
23 | #include "usbstack/core.h" | ||
24 | |||
25 | /* register serial driver in usb stack */ | ||
26 | void usb_storage_driver_init(void); | ||
27 | |||
28 | void usb_storage_driver_bind(void* controller_ops); | ||
29 | int usb_storage_driver_request(struct usb_ctrlrequest* req); | ||
30 | |||
31 | #endif /*_STORGAGE_H_*/ | ||
diff --git a/firmware/usbstack/host.h b/firmware/usbstack/host.h new file mode 100644 index 0000000000..cb2f550e46 --- /dev/null +++ b/firmware/usbstack/host.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: arcotg_udc.c 12340 2007-02-16 22:13:21Z barrywardell $ | ||
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 | #ifndef _USBSTACK_HOST_H_ | ||
21 | #define _USBSTACK_HOST_H_ | ||
22 | |||
23 | /* | ||
24 | * usb host driver | ||
25 | */ | ||
26 | struct usb_host_driver { | ||
27 | const char* name; | ||
28 | void* data; /* used to store controller specific ops struct */ | ||
29 | }; | ||
30 | |||
31 | #endif /*_USBSTACK_HOST_H_*/ | ||