summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Gevaerts <frank@gevaerts.be>2008-03-06 21:25:09 +0000
committerFrank Gevaerts <frank@gevaerts.be>2008-03-06 21:25:09 +0000
commitf0b4a32d6f983b1bece0b8cb2f2da1fdd23b012e (patch)
tree90f36c9f421c174d0385268ea47f0013b0c8cd8c
parent5f83f0e4d2aaad77bda682cfd81a7ebb111a6024 (diff)
downloadrockbox-f0b4a32d6f983b1bece0b8cb2f2da1fdd23b012e.tar.gz
rockbox-f0b4a32d6f983b1bece0b8cb2f2da1fdd23b012e.zip
reorganise the usb stack to provide a clean separation between core and class drivers
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16541 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/debug_menu.c11
-rw-r--r--firmware/export/usb.h17
-rw-r--r--firmware/export/usb_core.h23
-rw-r--r--firmware/usb.c8
-rw-r--r--firmware/usbstack/usb_class_driver.h59
-rw-r--r--firmware/usbstack/usb_core.c750
-rw-r--r--firmware/usbstack/usb_serial.c124
-rw-r--r--firmware/usbstack/usb_serial.h5
-rw-r--r--firmware/usbstack/usb_storage.c364
-rw-r--r--firmware/usbstack/usb_storage.h3
10 files changed, 787 insertions, 577 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index 3db6026901..3788631c81 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -102,6 +102,10 @@
102#include "as3514.h" 102#include "as3514.h"
103#endif 103#endif
104 104
105#if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF)
106#include "usb_core.h"
107#endif
108
105/*---------------------------------------------------*/ 109/*---------------------------------------------------*/
106/* SPECIAL DEBUG STUFF */ 110/* SPECIAL DEBUG STUFF */
107/*---------------------------------------------------*/ 111/*---------------------------------------------------*/
@@ -2364,13 +2368,12 @@ static bool dbg_scrollwheel(void)
2364#endif 2368#endif
2365 2369
2366#if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF) 2370#if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF)
2367extern bool usb_core_serial_enabled;
2368
2369static bool logf_usb_serial(void) 2371static bool logf_usb_serial(void)
2370{ 2372{
2371 usb_core_serial_enabled = !usb_core_serial_enabled; 2373 bool serial_enabled = !usb_core_driver_enabled(USB_DRIVER_SERIAL);
2374 usb_core_enable_driver(USB_DRIVER_SERIAL,serial_enabled);
2372 gui_syncsplash(HZ, "USB logf %s", 2375 gui_syncsplash(HZ, "USB logf %s",
2373 usb_core_serial_enabled?"enabled":"disabled"); 2376 serial_enabled?"enabled":"disabled");
2374 return false; 2377 return false;
2375} 2378}
2376#endif 2379#endif
diff --git a/firmware/export/usb.h b/firmware/export/usb.h
index 67793729c6..4dae7c2e68 100644
--- a/firmware/export/usb.h
+++ b/firmware/export/usb.h
@@ -24,13 +24,13 @@
24 24
25/* Messages from usb_tick and thread states */ 25/* Messages from usb_tick and thread states */
26enum { 26enum {
27 USB_INSERTED, 27 USB_INSERTED,
28 USB_EXTRACTED, 28 USB_EXTRACTED,
29 USB_REENABLE, 29 USB_REENABLE,
30 USB_POWERED, 30 USB_POWERED,
31 USB_TRANSFER_COMPLETION, 31 USB_TRANSFER_COMPLETION,
32 USB_REQUEST_DISK, 32 USB_REQUEST_DISK,
33 USB_REQUEST_REBOOT 33 USB_REQUEST_REBOOT
34}; 34};
35 35
36 36
@@ -69,7 +69,8 @@ enum {
69enum { 69enum {
70 USB_DRIVER_MASS_STORAGE, 70 USB_DRIVER_MASS_STORAGE,
71 USB_DRIVER_SERIAL, 71 USB_DRIVER_SERIAL,
72 USB_DRIVER_CHARGING_ONLY 72 USB_DRIVER_CHARGING_ONLY,
73 USB_NUM_DRIVERS
73}; 74};
74#endif 75#endif
75#ifdef HAVE_USBSTACK 76#ifdef HAVE_USBSTACK
diff --git a/firmware/export/usb_core.h b/firmware/export/usb_core.h
index bb4ce6cedd..97712bca4d 100644
--- a/firmware/export/usb_core.h
+++ b/firmware/export/usb_core.h
@@ -21,7 +21,7 @@
21 21
22#ifndef BOOTLOADER 22#ifndef BOOTLOADER
23 23
24//#define USB_SERIAL 24#define USB_SERIAL
25#define USB_STORAGE 25#define USB_STORAGE
26#define USB_CHARGING_ONLY 26#define USB_CHARGING_ONLY
27#else /* BOOTLOADER */ 27#else /* BOOTLOADER */
@@ -32,19 +32,8 @@
32#include "usb.h" 32#include "usb.h"
33 33
34/* endpoints */ 34/* endpoints */
35enum { 35#define EP_CONTROL 0
36 EP_CONTROL = 0, 36#define NUM_ENDPOINTS 3
37#ifdef USB_STORAGE
38 EP_MASS_STORAGE,
39#endif
40#ifdef USB_SERIAL
41 EP_SERIAL,
42#endif
43#ifdef USB_CHARGING_ONLY
44 EP_CHARGING_ONLY,
45#endif
46 NUM_ENDPOINTS
47};
48 37
49extern int usb_max_pkt_size; 38extern int usb_max_pkt_size;
50 39
@@ -54,7 +43,9 @@ void usb_core_control_request(struct usb_ctrlrequest* req);
54void usb_core_transfer_complete(int endpoint, bool in, int status, int length); 43void usb_core_transfer_complete(int endpoint, bool in, int status, int length);
55void usb_core_bus_reset(void); 44void usb_core_bus_reset(void);
56bool usb_core_exclusive_connection(void); 45bool usb_core_exclusive_connection(void);
57void usb_core_enable_protocol(int driver,bool enabled); 46void usb_core_enable_driver(int driver,bool enabled);
58void usb_core_handle_transfer_completion(struct usb_transfer_completion_event_data* event); 47bool usb_core_driver_enabled (int driver);
48void usb_core_handle_transfer_completion(
49 struct usb_transfer_completion_event_data* event);
59#endif 50#endif
60 51
diff --git a/firmware/usb.c b/firmware/usb.c
index 529ecb773b..d59cbc3d15 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -191,8 +191,8 @@ static void usb_thread(void)
191 { 191 {
192 usb_state = USB_POWERED; 192 usb_state = USB_POWERED;
193#ifdef HAVE_USBSTACK 193#ifdef HAVE_USBSTACK
194 usb_core_enable_protocol(USB_DRIVER_MASS_STORAGE,false); 194 usb_core_enable_driver(USB_DRIVER_MASS_STORAGE,false);
195 usb_core_enable_protocol(USB_DRIVER_CHARGING_ONLY,true); 195 usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY,true);
196 usb_enable(true); 196 usb_enable(true);
197#endif 197#endif
198 } 198 }
@@ -200,8 +200,8 @@ static void usb_thread(void)
200#endif 200#endif
201 { 201 {
202#ifdef HAVE_USBSTACK 202#ifdef HAVE_USBSTACK
203 usb_core_enable_protocol(USB_DRIVER_MASS_STORAGE,true); 203 usb_core_enable_driver(USB_DRIVER_MASS_STORAGE,true);
204 usb_core_enable_protocol(USB_DRIVER_CHARGING_ONLY,false); 204 usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY,false);
205 usb_enable(true); 205 usb_enable(true);
206#else 206#else
207 /* Tell all threads that they have to back off the ATA. 207 /* Tell all threads that they have to back off the ATA.
diff --git a/firmware/usbstack/usb_class_driver.h b/firmware/usbstack/usb_class_driver.h
new file mode 100644
index 0000000000..631d5a3bc1
--- /dev/null
+++ b/firmware/usbstack/usb_class_driver.h
@@ -0,0 +1,59 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
9 *
10 * Copyright (C) 2008 Frank Gevaerts
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 _USB_CLASS_DRIVER_H_
21#define _USB_CLASS_DRIVER_H_
22
23/* Common api, implemented by all class drivers */
24
25struct usb_class_driver {
26 bool enabled;
27 bool needs_exclusive_ata;
28 int usb_endpoint;
29 int usb_interface;
30
31 /* Asks the driver to put the interface descriptor and all other
32 needed descriptor for this driver at dest, for the given settings.
33 Returns the number of bytes taken by these descriptors. */
34 int (*get_config_descriptor)(unsigned char *dest,
35 int max_packet_size, int interface_number, int endpoint);
36
37 /* Tells the driver that a usb connection has been set up and is now
38 ready to use. */
39 void (*init_connection)(int interface,int endpoint);
40
41 /* Initialises the driver. This can be called multiple times,
42 and should not perform any action that can disturb other threads
43 (like getting the audio buffer) */
44 void (*init)(void);
45
46 /* Tells the driver that the usb connection is no longer active */
47 void (*disconnect)(void);
48
49 /* Tells the driver that a usb transfer has been completed. Note that "in"
50 is relative to the host */
51 void (*transfer_complete)(bool in, int status, int length);
52
53 /* Tells the driver that a control request has come in. If the driver is
54 able to handle it, it should ack the request, and return true. Otherwise
55 it should return false. */
56 bool (*control_request)(struct usb_ctrlrequest* req);
57};
58
59#endif
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c
index 96a5994417..ff54e4269f 100644
--- a/firmware/usbstack/usb_core.c
+++ b/firmware/usbstack/usb_core.c
@@ -27,6 +27,7 @@
27#include "usb_ch9.h" 27#include "usb_ch9.h"
28#include "usb_drv.h" 28#include "usb_drv.h"
29#include "usb_core.h" 29#include "usb_core.h"
30#include "usb_class_driver.h"
30 31
31#if defined(USB_STORAGE) 32#if defined(USB_STORAGE)
32#include "usb_storage.h" 33#include "usb_storage.h"
@@ -36,7 +37,7 @@
36#include "usb_serial.h" 37#include "usb_serial.h"
37#endif 38#endif
38 39
39/* TODO: Move this target-specific stuff somewhere else (serial number reading) */ 40/* TODO: Move target-specific stuff somewhere else (serial number reading) */
40 41
41#ifdef HAVE_AS3514 42#ifdef HAVE_AS3514
42#include "i2c-pp.h" 43#include "i2c-pp.h"
@@ -54,7 +55,9 @@
54#define USB_SC_SCSI 0x06 /* Transparent */ 55#define USB_SC_SCSI 0x06 /* Transparent */
55#define USB_PROT_BULK 0x50 /* bulk only */ 56#define USB_PROT_BULK 0x50 /* bulk only */
56 57
57static const struct usb_device_descriptor __attribute__((aligned(2))) device_descriptor= { 58static const struct usb_device_descriptor __attribute__((aligned(2)))
59 device_descriptor=
60{
58 .bLength = sizeof(struct usb_device_descriptor), 61 .bLength = sizeof(struct usb_device_descriptor),
59 .bDescriptorType = USB_DT_DEVICE, 62 .bDescriptorType = USB_DT_DEVICE,
60#ifdef USE_HIGH_SPEED 63#ifdef USE_HIGH_SPEED
@@ -75,7 +78,8 @@ static const struct usb_device_descriptor __attribute__((aligned(2))) device_des
75 .bNumConfigurations = 1 78 .bNumConfigurations = 1
76} ; 79} ;
77 80
78struct usb_config_descriptor __attribute__((aligned(2))) config_descriptor = 81static struct usb_config_descriptor __attribute__((aligned(2)))
82 config_descriptor =
79{ 83{
80 .bLength = sizeof(struct usb_config_descriptor), 84 .bLength = sizeof(struct usb_config_descriptor),
81 .bDescriptorType = USB_DT_CONFIG, 85 .bDescriptorType = USB_DT_CONFIG,
@@ -89,7 +93,8 @@ struct usb_config_descriptor __attribute__((aligned(2))) config_descriptor =
89 93
90#ifdef USB_CHARGING_ONLY 94#ifdef USB_CHARGING_ONLY
91/* dummy interface for charging-only */ 95/* dummy interface for charging-only */
92struct usb_interface_descriptor __attribute__((aligned(2))) charging_interface_descriptor = 96static struct usb_interface_descriptor __attribute__((aligned(2)))
97 charging_interface_descriptor =
93{ 98{
94 .bLength = sizeof(struct usb_interface_descriptor), 99 .bLength = sizeof(struct usb_interface_descriptor),
95 .bDescriptorType = USB_DT_INTERFACE, 100 .bDescriptorType = USB_DT_INTERFACE,
@@ -103,77 +108,8 @@ struct usb_interface_descriptor __attribute__((aligned(2))) charging_interface_d
103}; 108};
104#endif 109#endif
105 110
106#ifdef USB_STORAGE 111static const struct usb_qualifier_descriptor __attribute__((aligned(2)))
107/* storage interface */ 112 qualifier_descriptor =
108struct usb_interface_descriptor __attribute__((aligned(2))) mass_storage_interface_descriptor =
109{
110 .bLength = sizeof(struct usb_interface_descriptor),
111 .bDescriptorType = USB_DT_INTERFACE,
112 .bInterfaceNumber = 0,
113 .bAlternateSetting = 0,
114 .bNumEndpoints = 2,
115 .bInterfaceClass = USB_CLASS_MASS_STORAGE,
116 .bInterfaceSubClass = USB_SC_SCSI,
117 .bInterfaceProtocol = USB_PROT_BULK,
118 .iInterface = 0
119};
120
121struct usb_endpoint_descriptor __attribute__((aligned(2))) mass_storage_ep_in_descriptor =
122{
123 .bLength = sizeof(struct usb_endpoint_descriptor),
124 .bDescriptorType = USB_DT_ENDPOINT,
125 .bEndpointAddress = EP_MASS_STORAGE | USB_DIR_IN,
126 .bmAttributes = USB_ENDPOINT_XFER_BULK,
127 .wMaxPacketSize = 16,
128 .bInterval = 0
129};
130struct usb_endpoint_descriptor __attribute__((aligned(2))) mass_storage_ep_out_descriptor =
131{
132 .bLength = sizeof(struct usb_endpoint_descriptor),
133 .bDescriptorType = USB_DT_ENDPOINT,
134 .bEndpointAddress = EP_MASS_STORAGE | USB_DIR_OUT,
135 .bmAttributes = USB_ENDPOINT_XFER_BULK,
136 .wMaxPacketSize = 16,
137 .bInterval = 0
138};
139#endif
140
141#ifdef USB_SERIAL
142/* serial interface */
143struct usb_interface_descriptor __attribute__((aligned(2))) serial_interface_descriptor =
144{
145 .bLength = sizeof(struct usb_interface_descriptor),
146 .bDescriptorType = USB_DT_INTERFACE,
147 .bInterfaceNumber = 0,
148 .bAlternateSetting = 0,
149 .bNumEndpoints = 2,
150 .bInterfaceClass = USB_CLASS_CDC_DATA,
151 .bInterfaceSubClass = 0,
152 .bInterfaceProtocol = 0,
153 .iInterface = 0
154};
155
156struct usb_endpoint_descriptor __attribute__((aligned(2))) serial_ep_in_descriptor =
157{
158 .bLength = sizeof(struct usb_endpoint_descriptor),
159 .bDescriptorType = USB_DT_ENDPOINT,
160 .bEndpointAddress = EP_SERIAL | USB_DIR_IN,
161 .bmAttributes = USB_ENDPOINT_XFER_BULK,
162 .wMaxPacketSize = 16,
163 .bInterval = 0
164};
165struct usb_endpoint_descriptor __attribute__((aligned(2))) serial_ep_out_descriptor =
166{
167 .bLength = sizeof(struct usb_endpoint_descriptor),
168 .bDescriptorType = USB_DT_ENDPOINT,
169 .bEndpointAddress = EP_SERIAL | USB_DIR_OUT,
170 .bmAttributes = USB_ENDPOINT_XFER_BULK,
171 .wMaxPacketSize = 16,
172 .bInterval = 0
173};
174#endif
175
176static const struct usb_qualifier_descriptor __attribute__((aligned(2))) qualifier_descriptor =
177{ 113{
178 .bLength = sizeof(struct usb_qualifier_descriptor), 114 .bLength = sizeof(struct usb_qualifier_descriptor),
179 .bDescriptorType = USB_DT_DEVICE_QUALIFIER, 115 .bDescriptorType = USB_DT_DEVICE_QUALIFIER,
@@ -185,21 +121,26 @@ static const struct usb_qualifier_descriptor __attribute__((aligned(2))) qualifi
185 .bNumConfigurations = 1 121 .bNumConfigurations = 1
186}; 122};
187 123
188static struct usb_string_descriptor __attribute__((aligned(2))) usb_string_iManufacturer = 124static struct usb_string_descriptor __attribute__((aligned(2)))
125 usb_string_iManufacturer =
189{ 126{
190 24, 127 24,
191 USB_DT_STRING, 128 USB_DT_STRING,
192 {'R','o','c','k','b','o','x','.','o','r','g'} 129 {'R','o','c','k','b','o','x','.','o','r','g'}
193}; 130};
194 131
195static struct usb_string_descriptor __attribute__((aligned(2))) usb_string_iProduct = 132static struct usb_string_descriptor __attribute__((aligned(2)))
133 usb_string_iProduct =
196{ 134{
197 42, 135 42,
198 USB_DT_STRING, 136 USB_DT_STRING,
199 {'R','o','c','k','b','o','x',' ','m','e','d','i','a',' ','p','l','a','y','e','r'} 137 {'R','o','c','k','b','o','x',' ',
138 'm','e','d','i','a',' ',
139 'p','l','a','y','e','r'}
200}; 140};
201 141
202static struct usb_string_descriptor __attribute__((aligned(2))) usb_string_iSerial = 142static struct usb_string_descriptor __attribute__((aligned(2)))
143 usb_string_iSerial =
203{ 144{
204 84, 145 84,
205 USB_DT_STRING, 146 USB_DT_STRING,
@@ -211,14 +152,16 @@ static struct usb_string_descriptor __attribute__((aligned(2))) usb_string_iSeri
211/* Generic for all targets */ 152/* Generic for all targets */
212 153
213/* this is stringid #0: languages supported */ 154/* this is stringid #0: languages supported */
214static struct usb_string_descriptor __attribute__((aligned(2))) lang_descriptor = 155static struct usb_string_descriptor __attribute__((aligned(2)))
156 lang_descriptor =
215{ 157{
216 4, 158 4,
217 USB_DT_STRING, 159 USB_DT_STRING,
218 {0x0409} /* LANGID US English */ 160 {0x0409} /* LANGID US English */
219}; 161};
220 162
221static struct usb_string_descriptor __attribute__((aligned(2))) usb_string_charging_only = 163static struct usb_string_descriptor __attribute__((aligned(2)))
164 usb_string_charging_only =
222{ 165{
223 28, 166 28,
224 USB_DT_STRING, 167 USB_DT_STRING,
@@ -238,14 +181,56 @@ static int usb_address = 0;
238static bool initialized = false; 181static bool initialized = false;
239static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state; 182static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
240 183
184static int usb_core_num_interfaces;
185
186int usb_charging_get_config_descriptor(unsigned char *dest,int max_packet_size,
187 int interface_number,int endpoint);
188
189struct usb_class_driver drivers[] =
190{
241#ifdef USB_STORAGE 191#ifdef USB_STORAGE
242static bool usb_core_storage_enabled = false; 192 [USB_DRIVER_MASS_STORAGE] = {
193 .enabled = false,
194 .needs_exclusive_ata = true,
195 .usb_endpoint = 0,
196 .usb_interface = 0,
197 .get_config_descriptor = usb_storage_get_config_descriptor,
198 .init_connection = usb_storage_init_connection,
199 .init = usb_storage_init,
200 .disconnect = NULL,
201 .transfer_complete = usb_storage_transfer_complete,
202 .control_request = usb_storage_control_request
203 },
204#endif
205#ifdef USB_SERIAL
206 [USB_DRIVER_SERIAL] = {
207 .enabled = false,
208 .needs_exclusive_ata = false,
209 .usb_endpoint = 0,
210 .usb_interface = 0,
211 .get_config_descriptor = usb_serial_get_config_descriptor,
212 .init_connection = usb_serial_init_connection,
213 .init = usb_serial_init,
214 .disconnect = usb_serial_disconnect,
215 .transfer_complete = usb_serial_transfer_complete,
216 .control_request = usb_serial_control_request
217 },
243#endif 218#endif
244/* Next one is non-static, to enable setting it from the debug menu */
245bool usb_core_serial_enabled = false;
246#ifdef USB_CHARGING_ONLY 219#ifdef USB_CHARGING_ONLY
247static bool usb_core_charging_enabled = false; 220 [USB_DRIVER_CHARGING_ONLY] = {
221 .enabled = false,
222 .needs_exclusive_ata = false,
223 .usb_endpoint = 0,
224 .usb_interface = 0,
225 .get_config_descriptor = usb_charging_get_config_descriptor,
226 .init_connection = NULL,
227 .init = NULL,
228 .disconnect = NULL,
229 .transfer_complete = NULL,
230 .control_request = NULL
231 },
248#endif 232#endif
233};
249 234
250static void usb_core_control_request_handler(struct usb_ctrlrequest* req); 235static void usb_core_control_request_handler(struct usb_ctrlrequest* req);
251static int ack_control(struct usb_ctrlrequest* req); 236static int ack_control(struct usb_ctrlrequest* req);
@@ -272,11 +257,9 @@ static void set_serial_descriptor(void)
272 uint32_t x; 257 uint32_t x;
273 int i,j; 258 int i,j;
274 259
275 for (i = 0; i < 2; i++) 260 for (i = 0; i < 2; i++) {
276 {
277 x = serial[i]; 261 x = serial[i];
278 for (j=0;j<8;j++) 262 for (j=0;j<8;j++) {
279 {
280 *p-- = hex[x & 0xf]; 263 *p-- = hex[x & 0xf];
281 x >>= 4; 264 x >>= 4;
282 } 265 }
@@ -292,8 +275,7 @@ static void set_serial_descriptor(void)
292 int i; 275 int i;
293 276
294 i2c_readbytes(AS3514_I2C_ADDR, 0x30, 0x10, serial); 277 i2c_readbytes(AS3514_I2C_ADDR, 0x30, 0x10, serial);
295 for (i = 0; i < 16; i++) 278 for (i = 0; i < 16; i++) {
296 {
297 *p++ = hex[(serial[i] >> 4) & 0xF]; 279 *p++ = hex[(serial[i] >> 4) & 0xF];
298 *p++ = hex[(serial[i] >> 0) & 0xF]; 280 *p++ = hex[(serial[i] >> 0) & 0xF];
299 } 281 }
@@ -309,8 +291,7 @@ static void set_serial_descriptor(void)
309 unsigned short x; 291 unsigned short x;
310 int i; 292 int i;
311 293
312 for (i = 10; i < 20; i++) 294 for (i = 10; i < 20; i++) {
313 {
314 x = identify[i]; 295 x = identify[i];
315 *p++ = hex[(x >> 12) & 0xF]; 296 *p++ = hex[(x >> 12) & 0xF];
316 *p++ = hex[(x >> 8) & 0xF]; 297 *p++ = hex[(x >> 8) & 0xF];
@@ -323,6 +304,7 @@ static void set_serial_descriptor(void)
323 304
324void usb_core_init(void) 305void usb_core_init(void)
325{ 306{
307 int i;
326 if (initialized) 308 if (initialized)
327 return; 309 return;
328 310
@@ -333,27 +315,34 @@ void usb_core_init(void)
333 /* class driver init functions should be safe to call even if the driver 315 /* class driver init functions should be safe to call even if the driver
334 * won't be used. This simplifies other logic (i.e. we don't need to know 316 * won't be used. This simplifies other logic (i.e. we don't need to know
335 * yet which drivers will be enabled */ 317 * yet which drivers will be enabled */
336#ifdef USB_STORAGE 318 for(i=0;i<USB_NUM_DRIVERS;i++) {
337 if(usb_core_storage_enabled) 319 if(drivers[i].enabled && drivers[i].init != NULL)
338 usb_storage_init(); 320 drivers[i].init();
339#endif 321 }
340
341#ifdef USB_SERIAL
342 if(usb_core_serial_enabled)
343 usb_serial_init();
344#endif
345 322
346 initialized = true; 323 initialized = true;
347 usb_state = DEFAULT; 324 usb_state = DEFAULT;
348 logf("usb_core_init() finished"); 325 logf("usb_core_init() finished");
349} 326}
350 327
328int usb_charging_get_config_descriptor(unsigned char *dest,int max_packet_size,
329 int interface_number,int endpoint)
330{
331 (void) max_packet_size;
332 (void) endpoint;
333 charging_interface_descriptor.bInterfaceNumber=interface_number;
334 memcpy(dest,&charging_interface_descriptor,
335 sizeof(struct usb_interface_descriptor));
336 return sizeof(struct usb_interface_descriptor);
337}
338
351void usb_core_exit(void) 339void usb_core_exit(void)
352{ 340{
353#ifdef USB_SERIAL 341 int i;
354 if(usb_core_serial_enabled) 342 for(i=0;i<USB_NUM_DRIVERS;i++) {
355 usb_serial_exit(); 343 if(drivers[i].enabled && drivers[i].disconnect != NULL)
356#endif 344 drivers[i].disconnect ();
345 }
357 346
358 if (initialized) { 347 if (initialized) {
359 usb_drv_exit(); 348 usb_drv_exit();
@@ -362,321 +351,332 @@ void usb_core_exit(void)
362 logf("usb_core_exit() finished"); 351 logf("usb_core_exit() finished");
363} 352}
364 353
365void usb_core_handle_transfer_completion(struct usb_transfer_completion_event_data* event) 354void usb_core_handle_transfer_completion(
355 struct usb_transfer_completion_event_data* event)
366{ 356{
357 int i;
367 switch(event->endpoint) { 358 switch(event->endpoint) {
368 case EP_CONTROL: 359 case EP_CONTROL:
369 logf("ctrl handled %ld",current_tick); 360 logf("ctrl handled %ld",current_tick);
370 usb_core_control_request_handler((struct usb_ctrlrequest*)event->data); 361 usb_core_control_request_handler(
371 break; 362 (struct usb_ctrlrequest*)event->data);
372#ifdef USB_STORAGE
373 case EP_MASS_STORAGE:
374 usb_storage_transfer_complete(event->in,event->status,event->length);
375 break; 363 break;
376#endif 364 default:
377#ifdef USB_SERIAL 365 for(i=0;i<USB_NUM_DRIVERS;i++) {
378 case EP_SERIAL: 366 if(drivers[i].enabled &&
379 usb_serial_transfer_complete(event->in,event->status,event->length); 367 drivers[i].usb_endpoint == event->endpoint &&
380 break; 368 drivers[i].transfer_complete != NULL)
381#endif 369 {
382#ifdef USB_CHARGING_ONLY 370 drivers[i].transfer_complete(event->in,
383 case EP_CHARGING_ONLY: 371 event->status,event->length);
372 break;
373 }
374 }
384 break; 375 break;
385#endif
386 } 376 }
387} 377}
388 378
389void usb_core_enable_protocol(int driver,bool enabled) 379void usb_core_enable_driver(int driver,bool enabled)
390{ 380{
391 switch(driver) { 381 drivers[driver].enabled = enabled;
392#ifdef USB_STORAGE 382}
393 case USB_DRIVER_MASS_STORAGE: 383
394 usb_core_storage_enabled = enabled; 384bool usb_core_driver_enabled(int driver)
395 break; 385{
396#endif 386 return drivers[driver].enabled;
397#ifdef USB_SERIAL 387}
398 case USB_DRIVER_SERIAL: 388
399 usb_core_serial_enabled = enabled; 389static void usb_core_set_serial_function_id(void)
400 break; 390{
401#endif 391 int id = 0;
402#ifdef USB_CHARGING_ONLY 392 int i;
403 case USB_DRIVER_CHARGING_ONLY: 393 for(i=0;i<USB_NUM_DRIVERS;i++) {
404 usb_core_charging_enabled = enabled; 394 if(drivers[i].enabled)
405 break; 395 id |= 1<<i;
406#endif
407 } 396 }
397 usb_string_iSerial.wString[0] = hex[id];
408} 398}
409 399
410static void usb_core_control_request_handler(struct usb_ctrlrequest* req) 400static void allocate_interfaces_and_endpoints(void)
411{ 401{
412 if(usb_state == DEFAULT) { 402 int i;
413 set_serial_descriptor(); 403 int interface=0;
414 404 int endpoint=1;
415 int serial_function_id = 0; 405 for(i=0;i<USB_NUM_DRIVERS;i++) {
416#ifdef USB_STORAGE 406 if(drivers[i].enabled) {
417 if(usb_core_storage_enabled) { 407 drivers[i].usb_endpoint = endpoint++;
418 usb_request_exclusive_ata(); 408 drivers[i].usb_interface = interface++;
419 serial_function_id |= 1; 409 }
410 if(endpoint>NUM_ENDPOINTS) {
411 drivers[i].enabled = false;
420 } 412 }
421#endif
422#ifdef USB_SERIAL
423 if(usb_core_serial_enabled)
424 serial_function_id |= 2;
425#endif
426 usb_string_iSerial.wString[0] = hex[serial_function_id];
427 } 413 }
414 usb_core_num_interfaces = interface;
415}
428 416
429 switch (req->bRequest) { 417static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
430 case USB_REQ_SET_CONFIGURATION: 418{
431 logf("usb_core: SET_CONFIG"); 419 int i;
432 usb_drv_cancel_all_transfers(); 420 if(usb_state == DEFAULT) {
433 if (req->wValue){ 421 set_serial_descriptor();
434 usb_state = CONFIGURED; 422 usb_core_set_serial_function_id();
435#ifdef USB_STORAGE
436 if(usb_core_storage_enabled)
437 usb_storage_control_request(req);
438#endif
439 423
440#ifdef USB_SERIAL 424 allocate_interfaces_and_endpoints();
441 if(usb_core_serial_enabled)
442 usb_serial_control_request(req);
443#endif
444 }
445 else {
446 usb_state = ADDRESS;
447 }
448 ack_control(req);
449 break;
450 425
451 case USB_REQ_GET_CONFIGURATION: { 426 for(i=0;i<USB_NUM_DRIVERS;i++) {
452 logf("usb_core: GET_CONFIG"); 427 if(drivers[i].enabled &&
453 if (usb_state == ADDRESS) 428 drivers[i].needs_exclusive_ata) {
454 response_data[0] = 0; 429 usb_request_exclusive_ata();
455 else
456 response_data[0] = 1;
457 if(usb_drv_send(EP_CONTROL, response_data, 1)!= 0)
458 break; 430 break;
459 ack_control(req); 431 }
460 break;
461 } 432 }
433 }
462 434
463 case USB_REQ_SET_INTERFACE: 435 switch(req->bRequestType & 0x1f) {
464 logf("usb_core: SET_INTERFACE"); 436 case 0: /* Device */
465 ack_control(req); 437 switch (req->bRequest) {
466 break; 438 case USB_REQ_GET_CONFIGURATION: {
439 logf("usb_core: GET_CONFIG");
440 if (usb_state == ADDRESS)
441 response_data[0] = 0;
442 else
443 response_data[0] = 1;
444 if(usb_drv_send(EP_CONTROL, response_data, 1)!= 0)
445 break;
446 ack_control(req);
447 break;
448 case USB_REQ_SET_CONFIGURATION:
449 logf("usb_core: SET_CONFIG");
450 usb_drv_cancel_all_transfers();
451 if (req->wValue) {
452 usb_state = CONFIGURED;
453 for(i=0;i<USB_NUM_DRIVERS;i++) {
454 if(drivers[i].enabled &&
455 drivers[i].init_connection!=NULL)
456 {
457 drivers[i].init_connection(
458 drivers[i].usb_interface,
459 drivers[i].usb_endpoint);
460 }
461 }
462 }
463 else {
464 usb_state = ADDRESS;
465 }
466 ack_control(req);
467 break;
468 }
469 case USB_REQ_SET_ADDRESS: {
470 unsigned char address = req->wValue;
471 logf("usb_core: SET_ADR %d", address);
472 if(ack_control(req)!=0)
473 break;
474 usb_drv_cancel_all_transfers();
475 usb_address = address;
476 usb_drv_set_address(usb_address);
477 usb_state = ADDRESS;
478 break;
479 }
480 case USB_REQ_GET_DESCRIPTOR: {
481 int index = req->wValue & 0xff;
482 int length = req->wLength;
483 int size;
484 const void* ptr = NULL;
485 logf("usb_core: GET_DESC %d", req->wValue >> 8);
486
487 switch (req->wValue >> 8) { /* type */
488 case USB_DT_DEVICE:
489 ptr = &device_descriptor;
490 size = sizeof(struct usb_device_descriptor);
491 break;
492
493 case USB_DT_OTHER_SPEED_CONFIG:
494 case USB_DT_CONFIG: {
495 int max_packet_size;
496
497 if(req->wValue >> 8 == USB_DT_CONFIG) {
498 if(usb_drv_port_speed())
499 max_packet_size=512;
500 else
501 max_packet_size=64;
502 config_descriptor.bDescriptorType=USB_DT_CONFIG;
503 }
504 else {
505 if(usb_drv_port_speed())
506 max_packet_size=64;
507 else
508 max_packet_size=512;
509 config_descriptor.bDescriptorType =
510 USB_DT_OTHER_SPEED_CONFIG;
511 }
512 size = sizeof(struct usb_config_descriptor);
513
514 for(i=0;i<USB_NUM_DRIVERS;i++) {
515 if(drivers[i].enabled &&
516 drivers[i].get_config_descriptor)
517 {
518 size+=drivers[i].get_config_descriptor(
519 &response_data[size],
520 max_packet_size,
521 drivers[i].usb_interface,
522 drivers[i].usb_endpoint);
523 }
524 }
525 config_descriptor.bNumInterfaces =
526 usb_core_num_interfaces;
527 config_descriptor.wTotalLength = size;
528 memcpy(&response_data[0],&config_descriptor,
529 sizeof(struct usb_config_descriptor));
530
531 ptr = response_data;
532 break;
533 }
467 534
468 case USB_REQ_GET_INTERFACE: 535 case USB_DT_STRING:
469 logf("usb_core: GET_INTERFACE"); 536 logf("STRING %d",index);
470 response_data[0] = 0; 537 if ((unsigned)index < (sizeof(usb_strings)/
471 if(usb_drv_send(EP_CONTROL, response_data, 1)!=0) 538 sizeof(struct usb_string_descriptor*)))
472 break; 539 {
473 ack_control(req); 540 size = usb_strings[index]->bLength;
474 break; 541 memcpy(&response_data[0],usb_strings[index],
475 case USB_REQ_CLEAR_FEATURE: 542 size);
476 logf("usb_core: CLEAR_FEATURE"); 543 ptr = response_data;
477 if (req->wValue) 544 }
478 usb_drv_stall(req->wIndex & 0xf, false,(req->wIndex & 0x80) !=0); 545 else {
479 else 546 logf("bad string id %d", index);
480 usb_drv_stall(req->wIndex & 0xf, false,(req->wIndex & 0x80) !=0); 547 usb_drv_stall(EP_CONTROL, true,true);
481 ack_control(req); 548 }
482 break; 549 break;
550
551 case USB_DT_DEVICE_QUALIFIER:
552 ptr = &qualifier_descriptor;
553 size = sizeof (struct usb_qualifier_descriptor);
554 break;
555
556 default:
557 logf("bad desc %d", req->wValue >> 8);
558 usb_drv_stall(EP_CONTROL, true,true);
559 break;
560 }
483 561
484 case USB_REQ_SET_FEATURE: 562 if (ptr) {
485 logf("usb_core: SET_FEATURE"); 563 unsigned char *uncached = (void*)UNCACHED_ADDR(ptr);
486 switch(req->bRequestType & 0x0f){ 564 length = MIN(size, length);
487 case 0: /* Device */ 565 if(usb_drv_send(EP_CONTROL, uncached, length)!=0)
566 break;
567 }
568 ack_control(req);
569 break;
570 } /* USB_REQ_GET_DESCRIPTOR */
571 case USB_REQ_CLEAR_FEATURE:
572 break;
573 case USB_REQ_SET_FEATURE:
488 if(req->wValue == 2) { /* TEST_MODE */ 574 if(req->wValue == 2) { /* TEST_MODE */
489 int mode=req->wIndex>>8; 575 int mode=req->wIndex>>8;
490 ack_control(req); 576 ack_control(req);
491 usb_drv_set_test_mode(mode); 577 usb_drv_set_test_mode(mode);
492 } 578 }
493 break; 579 break;
494 case 2: /* Endpoint */ 580 case USB_REQ_GET_STATUS:
495 if (req->wValue) 581 response_data[0]= 0;
496 usb_drv_stall(req->wIndex & 0xf, true,(req->wIndex & 0x80) !=0); 582 response_data[1]= 0;
497 else 583 if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
498 usb_drv_stall(req->wIndex & 0xf, false,(req->wIndex & 0x80) !=0); 584 break;
499 ack_control(req); 585 ack_control(req);
500 break; 586 break;
501 default: 587 default:
502 break; 588 break;
503 } 589 }
504 break; 590 break;
505 591 case 1: /* Interface */
506 case USB_REQ_SET_ADDRESS: { 592 switch (req->bRequest) {
507 unsigned char address = req->wValue; 593 case USB_REQ_SET_INTERFACE:
508 logf("usb_core: SET_ADR %d", address); 594 logf("usb_core: SET_INTERFACE");
509 if(ack_control(req)!=0) 595 ack_control(req);
510 break;
511 usb_drv_cancel_all_transfers();
512 usb_address = address;
513 usb_drv_set_address(usb_address);
514 usb_state = ADDRESS;
515 break;
516 }
517
518 case USB_REQ_GET_STATUS: {
519 response_data[0]= 0;
520 response_data[1]= 0;
521 logf("usb_core: GET_STATUS");
522 if(req->wIndex>0) {
523 if(usb_drv_stalled(req->wIndex&0xf,(req->wIndex&0x80)!=0))
524 response_data[0] = 1;
525 }
526 logf("usb_core: %X %X",response_data[0],response_data[1]);
527 if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
528 break;
529 ack_control(req);
530 break;
531 }
532
533 case USB_REQ_GET_DESCRIPTOR: {
534 int index = req->wValue & 0xff;
535 int length = req->wLength;
536 int size;
537 const void* ptr = NULL;
538 logf("usb_core: GET_DESC %d", req->wValue >> 8);
539
540 switch (req->wValue >> 8) { /* type */
541 case USB_DT_DEVICE:
542 ptr = &device_descriptor;
543 size = sizeof(struct usb_device_descriptor);
544 break; 596 break;
545 597
546 case USB_DT_OTHER_SPEED_CONFIG: 598 case USB_REQ_GET_INTERFACE:
547 case USB_DT_CONFIG: { 599 logf("usb_core: GET_INTERFACE");
548 int max_packet_size; 600 response_data[0] = 0;
549 int interface_number=0; 601 if(usb_drv_send(EP_CONTROL, response_data, 1)!=0)
550 602 break;
551 if(req->wValue >> 8 == USB_DT_CONFIG) { 603 ack_control(req);
552 if(usb_drv_port_speed()) {
553 max_packet_size=512;
554 }
555 else {
556 max_packet_size=64;
557 }
558 config_descriptor.bDescriptorType=USB_DT_CONFIG;
559 }
560 else {
561 if(usb_drv_port_speed()) {
562 max_packet_size=64;
563 }
564 else {
565 max_packet_size=512;
566 }
567 config_descriptor.bDescriptorType=USB_DT_OTHER_SPEED_CONFIG;
568 }
569 size = sizeof(struct usb_config_descriptor);
570
571#ifdef USB_STORAGE
572 if(usb_core_storage_enabled){
573 mass_storage_ep_in_descriptor.wMaxPacketSize=max_packet_size;
574 mass_storage_ep_out_descriptor.wMaxPacketSize=max_packet_size;
575 mass_storage_interface_descriptor.bInterfaceNumber=interface_number;
576 interface_number++;
577
578 memcpy(&response_data[size],&mass_storage_interface_descriptor,sizeof(struct usb_interface_descriptor));
579 size += sizeof(struct usb_interface_descriptor);
580 memcpy(&response_data[size],&mass_storage_ep_in_descriptor,sizeof(struct usb_endpoint_descriptor));
581 size += sizeof(struct usb_endpoint_descriptor);
582 memcpy(&response_data[size],&mass_storage_ep_out_descriptor,sizeof(struct usb_endpoint_descriptor));
583 size += sizeof(struct usb_endpoint_descriptor);
584 }
585#endif
586#ifdef USB_SERIAL
587 if(usb_core_serial_enabled){
588 serial_ep_in_descriptor.wMaxPacketSize=max_packet_size;
589 serial_ep_out_descriptor.wMaxPacketSize=max_packet_size;
590 serial_interface_descriptor.bInterfaceNumber=interface_number;
591 interface_number++;
592
593 memcpy(&response_data[size],&serial_interface_descriptor,sizeof(struct usb_interface_descriptor));
594 size += sizeof(struct usb_interface_descriptor);
595 memcpy(&response_data[size],&serial_ep_in_descriptor,sizeof(struct usb_endpoint_descriptor));
596 size += sizeof(struct usb_endpoint_descriptor);
597 memcpy(&response_data[size],&serial_ep_out_descriptor,sizeof(struct usb_endpoint_descriptor));
598 size += sizeof(struct usb_endpoint_descriptor);
599 }
600#endif
601#ifdef USB_CHARGING_ONLY
602 if(usb_core_charging_enabled && interface_number == 0){
603 charging_interface_descriptor.bInterfaceNumber=interface_number;
604 interface_number++;
605 memcpy(&response_data[size],&charging_interface_descriptor,sizeof(struct usb_interface_descriptor));
606 size += sizeof(struct usb_interface_descriptor);
607 }
608#endif
609 config_descriptor.bNumInterfaces=interface_number;
610 config_descriptor.wTotalLength = size;
611 memcpy(&response_data[0],&config_descriptor,sizeof(struct usb_config_descriptor));
612
613 ptr = response_data;
614 break; 604 break;
605 case USB_REQ_CLEAR_FEATURE:
606 break;
607 case USB_REQ_SET_FEATURE:
608 break;
609 case USB_REQ_GET_STATUS:
610 response_data[0]= 0;
611 response_data[1]= 0;
612 if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
613 break;
614 ack_control(req);
615 break;
616 default: {
617 bool handled=false;
618 for(i=0;i<USB_NUM_DRIVERS;i++) {
619 if(drivers[i].enabled &&
620 drivers[i].control_request &&
621 drivers[i].usb_interface == (req->wIndex))
622 {
623 handled = drivers[i].control_request(req);
624 }
615 } 625 }
616 626 if(!handled) {
617 case USB_DT_STRING: 627 /* nope. flag error */
618 logf("STRING %d",index); 628 logf("usb bad req %d", req->bRequest);
619 if ((unsigned)index < (sizeof(usb_strings)/sizeof(struct usb_string_descriptor*))) {
620 size = usb_strings[index]->bLength;
621 memcpy(&response_data[0],usb_strings[index],size);
622 ptr = response_data;
623 }
624 else {
625 logf("bad string id %d", index);
626 usb_drv_stall(EP_CONTROL, true,true); 629 usb_drv_stall(EP_CONTROL, true,true);
630 ack_control(req);
627 } 631 }
628 break; 632 break;
629 633 }
630 case USB_DT_DEVICE_QUALIFIER: 634 }
631 ptr = &qualifier_descriptor; 635 break;
632 size = sizeof (struct usb_qualifier_descriptor); 636 case 2: /* Endpoint */
637 switch (req->bRequest) {
638 case USB_REQ_CLEAR_FEATURE:
639 if (req->wValue == 0 ) /* ENDPOINT_HALT */
640 usb_drv_stall(req->wIndex & 0xf, false,
641 (req->wIndex & 0x80) !=0);
642 ack_control(req);
633 break; 643 break;
634 644 case USB_REQ_SET_FEATURE:
635 default: 645 if (req->wValue == 0 ) /* ENDPOINT_HALT */
636 logf("bad desc %d", req->wValue >> 8); 646 usb_drv_stall(req->wIndex & 0xf, true,
637 usb_drv_stall(EP_CONTROL, true,true); 647 (req->wIndex & 0x80) !=0);
648 ack_control(req);
638 break; 649 break;
639 } 650 case USB_REQ_GET_STATUS:
640 651 response_data[0]= 0;
641 if (ptr) { 652 response_data[1]= 0;
642 length = MIN(size, length); 653 logf("usb_core: GET_STATUS");
643 if(usb_drv_send(EP_CONTROL, (void*)UNCACHED_ADDR(ptr), length)!=0) 654 if(req->wIndex>0)
655 response_data[0] = usb_drv_stalled(req->wIndex&0xf,
656 (req->wIndex&0x80)!=0);
657 if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
658 break;
659 ack_control(req);
660 break;
661 default: {
662 bool handled=false;
663 for(i=0;i<USB_NUM_DRIVERS;i++) {
664 if(drivers[i].enabled &&
665 drivers[i].control_request &&
666 drivers[i].usb_endpoint == (req->wIndex & 0xf))
667 {
668 handled = drivers[i].control_request(req);
669 }
670 }
671 if(!handled) {
672 /* nope. flag error */
673 logf("usb bad req %d", req->bRequest);
674 usb_drv_stall(EP_CONTROL, true,true);
675 ack_control(req);
676 }
644 break; 677 break;
645 }
646 ack_control(req);
647 break;
648 } /* USB_REQ_GET_DESCRIPTOR */
649
650 default: {
651 bool handled=false;
652 if((req->bRequestType & 0x1f) == 1) /* Interface */
653 {
654#ifdef USB_STORAGE
655 /* does usb_storage know this request? */
656 if(req->wIndex == mass_storage_interface_descriptor.bInterfaceNumber)
657 {
658 handled = usb_storage_control_request(req);
659 }
660#endif
661
662#ifdef USB_SERIAL
663 /* does usb_serial know this request? */
664 if(req->wIndex == serial_interface_descriptor.bInterfaceNumber)
665 {
666 handled = usb_serial_control_request(req);
667 } 678 }
668
669#endif
670 }
671 if(!handled)
672 {
673 /* nope. flag error */
674 logf("usb bad req %d", req->bRequest);
675 usb_drv_stall(EP_CONTROL, true,true);
676 ack_control(req);
677 } 679 }
678 break;
679 }
680 } 680 }
681 logf("control handled"); 681 logf("control handled");
682} 682}
@@ -691,10 +691,6 @@ void usb_core_bus_reset(void)
691/* called by usb_drv_transfer_completed() */ 691/* called by usb_drv_transfer_completed() */
692void usb_core_transfer_complete(int endpoint, bool in, int status,int length) 692void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
693{ 693{
694#if defined(USB_CHARGING_ONLY) || defined(USB_STORAGE)
695 (void)in;
696#endif
697
698 switch (endpoint) { 694 switch (endpoint) {
699 case EP_CONTROL: 695 case EP_CONTROL:
700 /* already handled */ 696 /* already handled */
diff --git a/firmware/usbstack/usb_serial.c b/firmware/usbstack/usb_serial.c
index 8c86932a31..55b76adc69 100644
--- a/firmware/usbstack/usb_serial.c
+++ b/firmware/usbstack/usb_serial.c
@@ -27,6 +27,31 @@
27 27
28#ifdef USB_SERIAL 28#ifdef USB_SERIAL
29 29
30/* serial interface */
31struct usb_interface_descriptor __attribute__((aligned(2)))
32 interface_descriptor =
33{
34 .bLength = sizeof(struct usb_interface_descriptor),
35 .bDescriptorType = USB_DT_INTERFACE,
36 .bInterfaceNumber = 0,
37 .bAlternateSetting = 0,
38 .bNumEndpoints = 2,
39 .bInterfaceClass = USB_CLASS_CDC_DATA,
40 .bInterfaceSubClass = 0,
41 .bInterfaceProtocol = 0,
42 .iInterface = 0
43};
44
45struct usb_endpoint_descriptor __attribute__((aligned(2))) endpoint_descriptor =
46{
47 .bLength = sizeof(struct usb_endpoint_descriptor),
48 .bDescriptorType = USB_DT_ENDPOINT,
49 .bEndpointAddress = 0,
50 .bmAttributes = USB_ENDPOINT_XFER_BULK,
51 .wMaxPacketSize = 0,
52 .bInterval = 0
53};
54
30#define BUFFER_SIZE 512 /* Max 16k because of controller limitations */ 55#define BUFFER_SIZE 512 /* Max 16k because of controller limitations */
31static unsigned char _send_buffer[BUFFER_SIZE] __attribute__((aligned(32))); 56static unsigned char _send_buffer[BUFFER_SIZE] __attribute__((aligned(32)));
32static unsigned char* send_buffer; 57static unsigned char* send_buffer;
@@ -38,8 +63,66 @@ static int buffer_start;
38static int buffer_length; 63static int buffer_length;
39static bool active = false; 64static bool active = false;
40 65
66static int usb_endpoint;
67static int usb_interface;
68
41static struct mutex sendlock; 69static struct mutex sendlock;
42 70
71static void sendout(void)
72{
73 if(buffer_start+buffer_length > BUFFER_SIZE)
74 {
75 /* Buffer wraps. Only send the first part */
76 usb_drv_send_nonblocking(usb_endpoint, &send_buffer[buffer_start],
77 (BUFFER_SIZE - buffer_start));
78 }
79 else
80 {
81 /* Send everything */
82 usb_drv_send_nonblocking(usb_endpoint, &send_buffer[buffer_start],
83 buffer_length);
84 }
85 busy_sending=true;
86}
87
88int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size,
89 int interface_number,int endpoint)
90{
91 endpoint_descriptor.wMaxPacketSize=max_packet_size;
92 interface_descriptor.bInterfaceNumber=interface_number;
93
94
95 memcpy(dest,&interface_descriptor,sizeof(struct usb_interface_descriptor));
96 dest+=sizeof(struct usb_interface_descriptor);
97
98 endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_IN,
99 memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
100 dest+=sizeof(struct usb_endpoint_descriptor);
101
102 endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_OUT,
103 memcpy(dest,&endpoint_descriptor,sizeof(struct usb_endpoint_descriptor));
104 return sizeof(struct usb_interface_descriptor) +
105 2 * sizeof(struct usb_endpoint_descriptor);
106}
107
108void usb_serial_init_connection(int interface,int endpoint)
109{
110 usb_interface = interface;
111 usb_endpoint = endpoint;
112
113 /* prime rx endpoint */
114 usb_drv_recv(usb_endpoint, receive_buffer, sizeof _receive_buffer);
115
116 /* we come here too after a bus reset, so reset some data */
117 mutex_lock(&sendlock);
118 busy_sending = false;
119 if(buffer_length>0)
120 {
121 sendout();
122 }
123 mutex_unlock(&sendlock);
124}
125
43/* called by usb_code_init() */ 126/* called by usb_code_init() */
44void usb_serial_init(void) 127void usb_serial_init(void)
45{ 128{
@@ -53,26 +136,11 @@ void usb_serial_init(void)
53 mutex_init(&sendlock); 136 mutex_init(&sendlock);
54} 137}
55 138
56void usb_serial_exit(void) 139void usb_serial_disconnect(void)
57{ 140{
58 active = false; 141 active = false;
59} 142}
60 143
61static void sendout(void)
62{
63 if(buffer_start+buffer_length > BUFFER_SIZE)
64 {
65 /* Buffer wraps. Only send the first part */
66 usb_drv_send_nonblocking(EP_SERIAL, &send_buffer[buffer_start],(BUFFER_SIZE - buffer_start));
67 }
68 else
69 {
70 /* Send everything */
71 usb_drv_send_nonblocking(EP_SERIAL, &send_buffer[buffer_start],buffer_length);
72 }
73 busy_sending=true;
74}
75
76void usb_serial_send(unsigned char *data,int length) 144void usb_serial_send(unsigned char *data,int length)
77{ 145{
78 if(!active) 146 if(!active)
@@ -85,13 +153,14 @@ void usb_serial_send(unsigned char *data,int length)
85 /* current buffer wraps, so new data can't */ 153 /* current buffer wraps, so new data can't */
86 int available_space = BUFFER_SIZE - buffer_length; 154 int available_space = BUFFER_SIZE - buffer_length;
87 length=MIN(length,available_space); 155 length=MIN(length,available_space);
88 memcpy(&send_buffer[(buffer_start+buffer_length)%BUFFER_SIZE],data,length); 156 memcpy(&send_buffer[(buffer_start+buffer_length)%BUFFER_SIZE],
157 data,length);
89 buffer_length+=length; 158 buffer_length+=length;
90 } 159 }
91 else 160 else
92 { 161 {
93 /* current buffer doesn't wrap, so new data might */ 162 /* current buffer doesn't wrap, so new data might */
94 int available_end_space = (BUFFER_SIZE - (buffer_start + buffer_length)); 163 int available_end_space = (BUFFER_SIZE - (buffer_start+buffer_length));
95 int first_chunk = MIN(length,available_end_space); 164 int first_chunk = MIN(length,available_end_space);
96 memcpy(&send_buffer[buffer_start + buffer_length],data,first_chunk); 165 memcpy(&send_buffer[buffer_start + buffer_length],data,first_chunk);
97 length-=first_chunk; 166 length-=first_chunk;
@@ -121,7 +190,7 @@ void usb_serial_transfer_complete(bool in, int status, int length)
121 case false: 190 case false:
122 logf("serial: %s", receive_buffer); 191 logf("serial: %s", receive_buffer);
123 /* Data received. TODO : Do something with it ? */ 192 /* Data received. TODO : Do something with it ? */
124 usb_drv_recv(EP_SERIAL, receive_buffer, sizeof _receive_buffer); 193 usb_drv_recv(usb_endpoint, receive_buffer, sizeof _receive_buffer);
125 break; 194 break;
126 195
127 case true: 196 case true:
@@ -148,26 +217,9 @@ bool usb_serial_control_request(struct usb_ctrlrequest* req)
148{ 217{
149 bool handled = false; 218 bool handled = false;
150 switch (req->bRequest) { 219 switch (req->bRequest) {
151 case USB_REQ_SET_CONFIGURATION:
152 logf("serial: set config");
153 /* prime rx endpoint */
154 usb_drv_recv(EP_SERIAL, receive_buffer, sizeof _receive_buffer);
155 handled = true;
156
157 /* we come here too after a bus reset, so reset some data */
158 mutex_lock(&sendlock);
159 busy_sending = false;
160 if(buffer_length>0)
161 {
162 sendout();
163 }
164 mutex_unlock(&sendlock);
165 break;
166
167 default: 220 default:
168 logf("serial: unhandeld req %d", req->bRequest); 221 logf("serial: unhandeld req %d", req->bRequest);
169 } 222 }
170
171 return handled; 223 return handled;
172} 224}
173 225
diff --git a/firmware/usbstack/usb_serial.h b/firmware/usbstack/usb_serial.h
index bcb0648af5..5d624137c3 100644
--- a/firmware/usbstack/usb_serial.h
+++ b/firmware/usbstack/usb_serial.h
@@ -21,8 +21,11 @@
21 21
22#include "usb_ch9.h" 22#include "usb_ch9.h"
23 23
24int usb_serial_get_config_descriptor(unsigned char *dest,int max_packet_size,
25 int interface_number, int endpoint);
26void usb_serial_init_connection(int interface,int endpoint);
24void usb_serial_init(void); 27void usb_serial_init(void);
25void usb_serial_exit(void); 28void usb_serial_disconnect(void);
26void usb_serial_transfer_complete(bool in, int status, int length); 29void usb_serial_transfer_complete(bool in, int status, int length);
27bool usb_serial_control_request(struct usb_ctrlrequest* req); 30bool usb_serial_control_request(struct usb_ctrlrequest* req);
28 31
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c
index f1029c3c93..58578d958b 100644
--- a/firmware/usbstack/usb_storage.c
+++ b/firmware/usbstack/usb_storage.c
@@ -28,6 +28,7 @@
28/* Needed to get at the audio buffer */ 28/* Needed to get at the audio buffer */
29#include "audio.h" 29#include "audio.h"
30 30
31
31#ifdef USB_STORAGE 32#ifdef USB_STORAGE
32 33
33/* Enable the following define to export only the SD card slot. This 34/* Enable the following define to export only the SD card slot. This
@@ -85,6 +86,35 @@
85 86
86#define SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA 0x02000000 87#define SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA 0x02000000
87 88
89/* storage interface */
90
91#define USB_SC_SCSI 0x06 /* Transparent */
92#define USB_PROT_BULK 0x50 /* bulk only */
93
94static struct usb_interface_descriptor __attribute__((aligned(2)))
95 interface_descriptor =
96{
97 .bLength = sizeof(struct usb_interface_descriptor),
98 .bDescriptorType = USB_DT_INTERFACE,
99 .bInterfaceNumber = 0,
100 .bAlternateSetting = 0,
101 .bNumEndpoints = 2,
102 .bInterfaceClass = USB_CLASS_MASS_STORAGE,
103 .bInterfaceSubClass = USB_SC_SCSI,
104 .bInterfaceProtocol = USB_PROT_BULK,
105 .iInterface = 0
106};
107
108static struct usb_endpoint_descriptor __attribute__((aligned(2)))
109 endpoint_descriptor =
110{
111 .bLength = sizeof(struct usb_endpoint_descriptor),
112 .bDescriptorType = USB_DT_ENDPOINT,
113 .bEndpointAddress = 0,
114 .bmAttributes = USB_ENDPOINT_XFER_BULK,
115 .wMaxPacketSize = 0,
116 .bInterval = 0
117};
88 118
89struct inquiry_data { 119struct inquiry_data {
90 unsigned char DeviceType; 120 unsigned char DeviceType;
@@ -111,7 +141,7 @@ struct report_lun_data {
111struct sense_data { 141struct sense_data {
112 unsigned char ResponseCode; 142 unsigned char ResponseCode;
113 unsigned char Obsolete; 143 unsigned char Obsolete;
114 unsigned char filemark_eom_ili_sensekey; 144 unsigned char fei_sensekey;
115 unsigned int Information; 145 unsigned int Information;
116 unsigned char AdditionalSenseLength; 146 unsigned char AdditionalSenseLength;
117 unsigned int CommandSpecificInformation; 147 unsigned int CommandSpecificInformation;
@@ -122,15 +152,15 @@ struct sense_data {
122 unsigned short SenseKeySpecific; 152 unsigned short SenseKeySpecific;
123} __attribute__ ((packed)); 153} __attribute__ ((packed));
124 154
125struct mode_sense_block_descriptor_longlba { 155struct mode_sense_bdesc_longlba {
126 unsigned char number_of_blocks[8]; 156 unsigned char num_blocks[8];
127 unsigned char reserved[4]; 157 unsigned char reserved[4];
128 unsigned char block_size[4]; 158 unsigned char block_size[4];
129} __attribute__ ((packed)); 159} __attribute__ ((packed));
130 160
131struct mode_sense_block_descriptor_shortlba { 161struct mode_sense_bdesc_shortlba {
132 unsigned char density_code; 162 unsigned char density_code;
133 unsigned char number_of_blocks[3]; 163 unsigned char num_blocks[3];
134 unsigned char reserved; 164 unsigned char reserved;
135 unsigned char block_size[3]; 165 unsigned char block_size[3];
136} __attribute__ ((packed)); 166} __attribute__ ((packed));
@@ -142,7 +172,7 @@ struct mode_sense_data_10 {
142 unsigned char longlba; 172 unsigned char longlba;
143 unsigned char reserved; 173 unsigned char reserved;
144 unsigned short block_descriptor_length; 174 unsigned short block_descriptor_length;
145 struct mode_sense_block_descriptor_longlba block_descriptor; 175 struct mode_sense_bdesc_longlba block_descriptor;
146} __attribute__ ((packed)); 176} __attribute__ ((packed));
147 177
148struct mode_sense_data_6 { 178struct mode_sense_data_6 {
@@ -150,7 +180,7 @@ struct mode_sense_data_6 {
150 unsigned char medium_type; 180 unsigned char medium_type;
151 unsigned char device_specific; 181 unsigned char device_specific;
152 unsigned char block_descriptor_length; 182 unsigned char block_descriptor_length;
153 struct mode_sense_block_descriptor_shortlba block_descriptor; 183 struct mode_sense_bdesc_shortlba block_descriptor;
154} __attribute__ ((packed)); 184} __attribute__ ((packed));
155 185
156struct command_block_wrapper { 186struct command_block_wrapper {
@@ -188,8 +218,8 @@ static union {
188 struct capacity* capacity_data; 218 struct capacity* capacity_data;
189 struct format_capacity* format_capacity_data; 219 struct format_capacity* format_capacity_data;
190 struct sense_data *sense_data; 220 struct sense_data *sense_data;
191 struct mode_sense_data_6 *mode_sense_data_6; 221 struct mode_sense_data_6 *ms_data_6;
192 struct mode_sense_data_10 *mode_sense_data_10; 222 struct mode_sense_data_10 *ms_data_10;
193 struct report_lun_data *lun_data; 223 struct report_lun_data *lun_data;
194 struct command_status_wrapper* csw; 224 struct command_status_wrapper* csw;
195 char *max_lun; 225 char *max_lun;
@@ -203,7 +233,7 @@ static struct {
203 unsigned char *data[2]; 233 unsigned char *data[2];
204 unsigned char data_select; 234 unsigned char data_select;
205 unsigned int last_result; 235 unsigned int last_result;
206} current_cmd; 236} cur_cmd;
207 237
208static struct { 238static struct {
209 unsigned char sense_key; 239 unsigned char sense_key;
@@ -221,6 +251,9 @@ static void identify2inquiry(int lun);
221static void send_and_read_next(void); 251static void send_and_read_next(void);
222static bool ejected[NUM_VOLUMES]; 252static bool ejected[NUM_VOLUMES];
223 253
254static int usb_endpoint;
255static int usb_interface;
256
224static enum { 257static enum {
225 WAITING_FOR_COMMAND, 258 WAITING_FOR_COMMAND,
226 SENDING_BLOCKS, 259 SENDING_BLOCKS,
@@ -238,6 +271,49 @@ void usb_storage_init(void)
238 logf("usb_storage_init done"); 271 logf("usb_storage_init done");
239} 272}
240 273
274int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size,
275 int interface_number,int endpoint)
276{
277 endpoint_descriptor.wMaxPacketSize=max_packet_size;
278 interface_descriptor.bInterfaceNumber=interface_number;
279
280
281 memcpy(dest,&interface_descriptor,
282 sizeof(struct usb_interface_descriptor));
283 dest+=sizeof(struct usb_interface_descriptor);
284
285 endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_IN,
286 memcpy(dest,&endpoint_descriptor,
287 sizeof(struct usb_endpoint_descriptor));
288 dest+=sizeof(struct usb_endpoint_descriptor);
289
290 endpoint_descriptor.bEndpointAddress = endpoint | USB_DIR_OUT,
291 memcpy(dest,&endpoint_descriptor,
292 sizeof(struct usb_endpoint_descriptor));
293
294 return sizeof(struct usb_interface_descriptor) +
295 2*sizeof(struct usb_endpoint_descriptor);
296}
297
298void usb_storage_init_connection(int interface,int endpoint)
299{
300 size_t bufsize;
301 unsigned char * audio_buffer;
302
303 usb_interface = interface;
304 usb_endpoint = endpoint;
305
306 logf("ums: set config");
307 /* prime rx endpoint. We only need room for commands */
308 state = WAITING_FOR_COMMAND;
309
310 /* TODO : check if bufsize is at least 32K ? */
311 audio_buffer = audio_get_buffer(false,&bufsize);
312 tb.transfer_buffer =
313 (void *)UNCACHED_ADDR((unsigned int)(audio_buffer + 31) & 0xffffffe0);
314 usb_drv_recv(usb_endpoint, tb.transfer_buffer, 1024);
315}
316
241/* called by usb_core_transfer_complete() */ 317/* called by usb_core_transfer_complete() */
242void usb_storage_transfer_complete(bool in,int status,int length) 318void usb_storage_transfer_complete(bool in,int status,int length)
243{ 319{
@@ -249,26 +325,31 @@ void usb_storage_transfer_complete(bool in,int status,int length)
249 if(in==true) { 325 if(in==true) {
250 logf("IN received in RECEIVING"); 326 logf("IN received in RECEIVING");
251 } 327 }
252 logf("scsi write %d %d", current_cmd.sector, current_cmd.count); 328 logf("scsi write %d %d", cur_cmd.sector, cur_cmd.count);
253 if(status==0) { 329 if(status==0) {
254 if((unsigned int)length!=(SECTOR_SIZE*current_cmd.count) 330 if((unsigned int)length!=(SECTOR_SIZE*cur_cmd.count)
255 && (unsigned int)length!=BUFFER_SIZE) { 331 && (unsigned int)length!=BUFFER_SIZE) {
256 logf("unexpected length :%d",length); 332 logf("unexpected length :%d",length);
257 } 333 }
258 334
259 unsigned int next_sector = current_cmd.sector + (BUFFER_SIZE/SECTOR_SIZE); 335 unsigned int next_sector = cur_cmd.sector +
260 unsigned int next_count = current_cmd.count - MIN(current_cmd.count,BUFFER_SIZE/SECTOR_SIZE); 336 (BUFFER_SIZE/SECTOR_SIZE);
337 unsigned int next_count = cur_cmd.count -
338 MIN(cur_cmd.count,BUFFER_SIZE/SECTOR_SIZE);
261 339
262 if(next_count!=0) { 340 if(next_count!=0) {
263 /* Ask the host to send more, to the other buffer */ 341 /* Ask the host to send more, to the other buffer */
264 receive_block_data(current_cmd.data[!current_cmd.data_select], 342 receive_block_data(cur_cmd.data[!cur_cmd.data_select],
265 MIN(BUFFER_SIZE,next_count*SECTOR_SIZE)); 343 MIN(BUFFER_SIZE,next_count*SECTOR_SIZE));
266 } 344 }
267 345
268 /* Now write the data that just came in, while the host is sending the next bit */ 346 /* Now write the data that just came in, while the host is
269 int result = ata_write_sectors(IF_MV2(current_cmd.lun,) 347 sending the next bit */
270 current_cmd.sector, MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count), 348 int result = ata_write_sectors(IF_MV2(cur_cmd.lun,)
271 current_cmd.data[current_cmd.data_select]); 349 cur_cmd.sector,
350 MIN(BUFFER_SIZE/SECTOR_SIZE,
351 cur_cmd.count),
352 cur_cmd.data[cur_cmd.data_select]);
272 if(result != 0) { 353 if(result != 0) {
273 send_csw(UMS_STATUS_FAIL); 354 send_csw(UMS_STATUS_FAIL);
274 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR; 355 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR;
@@ -282,10 +363,10 @@ void usb_storage_transfer_complete(bool in,int status,int length)
282 } 363 }
283 364
284 /* Switch buffers for the next one */ 365 /* Switch buffers for the next one */
285 current_cmd.data_select=!current_cmd.data_select; 366 cur_cmd.data_select=!cur_cmd.data_select;
286 367
287 current_cmd.sector = next_sector; 368 cur_cmd.sector = next_sector;
288 current_cmd.count = next_count; 369 cur_cmd.count = next_count;
289 370
290 } 371 }
291 else { 372 else {
@@ -307,8 +388,8 @@ void usb_storage_transfer_complete(bool in,int status,int length)
307 handle_scsi(cbw); 388 handle_scsi(cbw);
308 } 389 }
309 else { 390 else {
310 usb_drv_stall(EP_MASS_STORAGE, true,true); 391 usb_drv_stall(usb_endpoint, true,true);
311 usb_drv_stall(EP_MASS_STORAGE, true,false); 392 usb_drv_stall(usb_endpoint, true,false);
312 } 393 }
313 break; 394 break;
314 case SENDING_CSW: 395 case SENDING_CSW:
@@ -317,7 +398,7 @@ void usb_storage_transfer_complete(bool in,int status,int length)
317 } 398 }
318 //logf("csw sent, now go back to idle"); 399 //logf("csw sent, now go back to idle");
319 state = WAITING_FOR_COMMAND; 400 state = WAITING_FOR_COMMAND;
320 usb_drv_recv(EP_MASS_STORAGE, tb.transfer_buffer, 1024); 401 usb_drv_recv(usb_endpoint, tb.transfer_buffer, 1024);
321 break; 402 break;
322 case SENDING_RESULT: 403 case SENDING_RESULT:
323 if(in==false) { 404 if(in==false) {
@@ -342,7 +423,7 @@ void usb_storage_transfer_complete(bool in,int status,int length)
342 logf("OUT received in SENDING"); 423 logf("OUT received in SENDING");
343 } 424 }
344 if(status==0) { 425 if(status==0) {
345 if(current_cmd.count==0) { 426 if(cur_cmd.count==0) {
346 //logf("data sent, now send csw"); 427 //logf("data sent, now send csw");
347 send_csw(UMS_STATUS_GOOD); 428 send_csw(UMS_STATUS_GOOD);
348 } 429 }
@@ -368,6 +449,7 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req)
368{ 449{
369 bool handled = false; 450 bool handled = false;
370 451
452
371 switch (req->bRequest) { 453 switch (req->bRequest) {
372 case USB_BULK_GET_MAX_LUN: { 454 case USB_BULK_GET_MAX_LUN: {
373#ifdef ONLY_EXPOSE_CARD_SLOT 455#ifdef ONLY_EXPOSE_CARD_SLOT
@@ -386,31 +468,16 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req)
386 logf("ums: bulk reset"); 468 logf("ums: bulk reset");
387 state = WAITING_FOR_COMMAND; 469 state = WAITING_FOR_COMMAND;
388 /* UMS BOT 3.1 says The device shall preserve the value of its bulk 470 /* UMS BOT 3.1 says The device shall preserve the value of its bulk
389 * data toggle bits and endpoint STALL conditions despite the Bulk-Only 471 data toggle bits and endpoint STALL conditions despite
390 * Mass Storage Reset. */ 472 the Bulk-Only Mass Storage Reset. */
391#if 0 473#if 0
392 usb_drv_reset_endpoint(EP_MASS_STORAGE, false); 474 usb_drv_reset_endpoint(usb_endpoint, false);
393 usb_drv_reset_endpoint(EP_MASS_STORAGE, true); 475 usb_drv_reset_endpoint(usb_endpoint, true);
394#endif 476#endif
395 477
396 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */ 478 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */
397 handled = true; 479 handled = true;
398 break; 480 break;
399
400 case USB_REQ_SET_CONFIGURATION: {
401 size_t bufsize;
402 unsigned char * audio_buffer;
403 logf("ums: set config");
404 /* prime rx endpoint. We only need room for commands */
405 state = WAITING_FOR_COMMAND;
406
407 /* TODO : check if bufsize is at least 32K ? */
408 audio_buffer = audio_get_buffer(false,&bufsize);
409 tb.transfer_buffer = (void *)UNCACHED_ADDR((unsigned int)(audio_buffer + 31) & 0xffffffe0);
410 usb_drv_recv(EP_MASS_STORAGE, tb.transfer_buffer, 1024);
411 handled = true;
412 break;
413 }
414 } 481 }
415 482
416 return handled; 483 return handled;
@@ -418,7 +485,7 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req)
418 485
419static void send_and_read_next(void) 486static void send_and_read_next(void)
420{ 487{
421 if(current_cmd.last_result!=0) { 488 if(cur_cmd.last_result!=0) {
422 /* The last read failed. */ 489 /* The last read failed. */
423 send_csw(UMS_STATUS_FAIL); 490 send_csw(UMS_STATUS_FAIL);
424 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR; 491 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR;
@@ -426,21 +493,23 @@ static void send_and_read_next(void)
426 cur_sense_data.ascq=0; 493 cur_sense_data.ascq=0;
427 return; 494 return;
428 } 495 }
429 send_block_data(current_cmd.data[current_cmd.data_select], 496 send_block_data(cur_cmd.data[cur_cmd.data_select],
430 MIN(BUFFER_SIZE,current_cmd.count*SECTOR_SIZE)); 497 MIN(BUFFER_SIZE,cur_cmd.count*SECTOR_SIZE));
431 498
432 /* Switch buffers for the next one */ 499 /* Switch buffers for the next one */
433 current_cmd.data_select=!current_cmd.data_select; 500 cur_cmd.data_select=!cur_cmd.data_select;
434 501
435 current_cmd.sector+=(BUFFER_SIZE/SECTOR_SIZE); 502 cur_cmd.sector+=(BUFFER_SIZE/SECTOR_SIZE);
436 current_cmd.count-=MIN(current_cmd.count,BUFFER_SIZE/SECTOR_SIZE); 503 cur_cmd.count-=MIN(cur_cmd.count,BUFFER_SIZE/SECTOR_SIZE);
437 504
438 if(current_cmd.count!=0){ 505 if(cur_cmd.count!=0){
439 /* already read the next bit, so we can send it out immediately when the 506 /* already read the next bit, so we can send it out immediately when the
440 * current transfer completes. */ 507 * current transfer completes. */
441 current_cmd.last_result = ata_read_sectors(IF_MV2(current_cmd.lun,) current_cmd.sector, 508 cur_cmd.last_result = ata_read_sectors(IF_MV2(cur_cmd.lun,)
442 MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count), 509 cur_cmd.sector,
443 current_cmd.data[current_cmd.data_select]); 510 MIN(BUFFER_SIZE/SECTOR_SIZE,
511 cur_cmd.count),
512 cur_cmd.data[cur_cmd.data_select]);
444 } 513 }
445} 514}
446/****************************************************************************/ 515/****************************************************************************/
@@ -484,8 +553,8 @@ static void handle_scsi(struct command_block_wrapper* cbw)
484 block_size_mult = disk_sector_multiplier; 553 block_size_mult = disk_sector_multiplier;
485#endif 554#endif
486 555
487 current_cmd.tag = cbw->tag; 556 cur_cmd.tag = cbw->tag;
488 current_cmd.lun = lun; 557 cur_cmd.lun = lun;
489 558
490 switch (cbw->command_block[0]) { 559 switch (cbw->command_block[0]) {
491 case SCSI_TEST_UNIT_READY: 560 case SCSI_TEST_UNIT_READY:
@@ -524,7 +593,8 @@ static void handle_scsi(struct command_block_wrapper* cbw)
524#endif 593#endif
525 tb.lun_data->lun0[1]=0; 594 tb.lun_data->lun0[1]=0;
526 595
527 send_command_result(tb.lun_data, MIN(sizeof(struct report_lun_data), length)); 596 send_command_result(tb.lun_data,
597 MIN(sizeof(struct report_lun_data), length));
528 break; 598 break;
529 } 599 }
530 600
@@ -532,12 +602,13 @@ static void handle_scsi(struct command_block_wrapper* cbw)
532 logf("scsi inquiry %d",lun); 602 logf("scsi inquiry %d",lun);
533 identify2inquiry(lun); 603 identify2inquiry(lun);
534 length = MIN(length, cbw->command_block[4]); 604 length = MIN(length, cbw->command_block[4]);
535 send_command_result(tb.inquiry, MIN(sizeof(struct inquiry_data), length)); 605 send_command_result(tb.inquiry,
606 MIN(sizeof(struct inquiry_data), length));
536 break; 607 break;
537 608
538 case SCSI_REQUEST_SENSE: { 609 case SCSI_REQUEST_SENSE: {
539 tb.sense_data->ResponseCode=0x70;/*current error*/ 610 tb.sense_data->ResponseCode=0x70;/*current error*/
540 tb.sense_data->filemark_eom_ili_sensekey=cur_sense_data.sense_key&0x0f; 611 tb.sense_data->fei_sensekey=cur_sense_data.sense_key&0x0f;
541 tb.sense_data->Information=cur_sense_data.information; 612 tb.sense_data->Information=cur_sense_data.information;
542 tb.sense_data->AdditionalSenseLength=10; 613 tb.sense_data->AdditionalSenseLength=10;
543 tb.sense_data->CommandSpecificInformation=0; 614 tb.sense_data->CommandSpecificInformation=0;
@@ -564,24 +635,36 @@ static void handle_scsi(struct command_block_wrapper* cbw)
564 logf("scsi mode_sense_10 %d %X",lun,page_code); 635 logf("scsi mode_sense_10 %d %X",lun,page_code);
565 switch(page_code) { 636 switch(page_code) {
566 case 0x3f: 637 case 0x3f:
567 tb.mode_sense_data_10->mode_data_length=htobe16(sizeof(struct mode_sense_data_10)-2); 638 tb.ms_data_10->mode_data_length =
568 tb.mode_sense_data_10->medium_type=0; 639 htobe16(sizeof(struct mode_sense_data_10)-2);
569 tb.mode_sense_data_10->device_specific=0; 640 tb.ms_data_10->medium_type = 0;
570 tb.mode_sense_data_10->reserved=0; 641 tb.ms_data_10->device_specific = 0;
571 tb.mode_sense_data_10->longlba=1; 642 tb.ms_data_10->reserved = 0;
572 tb.mode_sense_data_10->block_descriptor_length=htobe16(sizeof(struct mode_sense_block_descriptor_longlba)); 643 tb.ms_data_10->longlba = 1;
573 memset(tb.mode_sense_data_10->block_descriptor.reserved,0,4); 644 tb.ms_data_10->block_descriptor_length =
574 memset(tb.mode_sense_data_10->block_descriptor.number_of_blocks,0,8); 645 htobe16(sizeof(struct mode_sense_bdesc_longlba));
575 tb.mode_sense_data_10->block_descriptor.number_of_blocks[4]=((block_count/block_size_mult) & 0xff000000)>>24; 646
576 tb.mode_sense_data_10->block_descriptor.number_of_blocks[5]=((block_count/block_size_mult) & 0x00ff0000)>>16; 647 memset(tb.ms_data_10->block_descriptor.reserved,0,4);
577 tb.mode_sense_data_10->block_descriptor.number_of_blocks[6]=((block_count/block_size_mult) & 0x0000ff00)>>8; 648 memset(tb.ms_data_10->block_descriptor.num_blocks,0,8);
578 tb.mode_sense_data_10->block_descriptor.number_of_blocks[7]=((block_count/block_size_mult) & 0x000000ff); 649
579 650 tb.ms_data_10->block_descriptor.num_blocks[4] =
580 tb.mode_sense_data_10->block_descriptor.block_size[0]=((block_size*block_size_mult) & 0xff000000)>>24; 651 ((block_count/block_size_mult) & 0xff000000)>>24;
581 tb.mode_sense_data_10->block_descriptor.block_size[1]=((block_size*block_size_mult) & 0x00ff0000)>>16; 652 tb.ms_data_10->block_descriptor.num_blocks[5] =
582 tb.mode_sense_data_10->block_descriptor.block_size[2]=((block_size*block_size_mult) & 0x0000ff00)>>8; 653 ((block_count/block_size_mult) & 0x00ff0000)>>16;
583 tb.mode_sense_data_10->block_descriptor.block_size[3]=((block_size*block_size_mult) & 0x000000ff); 654 tb.ms_data_10->block_descriptor.num_blocks[6] =
584 send_command_result(tb.mode_sense_data_10, 655 ((block_count/block_size_mult) & 0x0000ff00)>>8;
656 tb.ms_data_10->block_descriptor.num_blocks[7] =
657 ((block_count/block_size_mult) & 0x000000ff);
658
659 tb.ms_data_10->block_descriptor.block_size[0] =
660 ((block_size*block_size_mult) & 0xff000000)>>24;
661 tb.ms_data_10->block_descriptor.block_size[1] =
662 ((block_size*block_size_mult) & 0x00ff0000)>>16;
663 tb.ms_data_10->block_descriptor.block_size[2] =
664 ((block_size*block_size_mult) & 0x0000ff00)>>8;
665 tb.ms_data_10->block_descriptor.block_size[3] =
666 ((block_size*block_size_mult) & 0x000000ff);
667 send_command_result(tb.ms_data_10,
585 MIN(sizeof(struct mode_sense_data_10), length)); 668 MIN(sizeof(struct mode_sense_data_10), length));
586 break; 669 break;
587 default: 670 default:
@@ -606,27 +689,35 @@ static void handle_scsi(struct command_block_wrapper* cbw)
606 logf("scsi mode_sense_6 %d %X",lun,page_code); 689 logf("scsi mode_sense_6 %d %X",lun,page_code);
607 switch(page_code) { 690 switch(page_code) {
608 case 0x3f: 691 case 0x3f:
609 /* All supported pages Since we support only one this is easy*/ 692 /* All supported pages. */
610 tb.mode_sense_data_6->mode_data_length=sizeof(struct mode_sense_data_6)-1; 693 tb.ms_data_6->mode_data_length =
611 tb.mode_sense_data_6->medium_type=0; 694 sizeof(struct mode_sense_data_6)-1;
612 tb.mode_sense_data_6->device_specific=0; 695 tb.ms_data_6->medium_type = 0;
613 tb.mode_sense_data_6->block_descriptor_length=sizeof(struct mode_sense_block_descriptor_shortlba); 696 tb.ms_data_6->device_specific = 0;
614 tb.mode_sense_data_6->block_descriptor.density_code=0; 697 tb.ms_data_6->block_descriptor_length =
615 tb.mode_sense_data_6->block_descriptor.reserved=0; 698 sizeof(struct mode_sense_bdesc_shortlba);
699 tb.ms_data_6->block_descriptor.density_code = 0;
700 tb.ms_data_6->block_descriptor.reserved = 0;
616 if(block_count/block_size_mult > 0xffffff){ 701 if(block_count/block_size_mult > 0xffffff){
617 tb.mode_sense_data_6->block_descriptor.number_of_blocks[0]=0xff; 702 tb.ms_data_6->block_descriptor.num_blocks[0] = 0xff;
618 tb.mode_sense_data_6->block_descriptor.number_of_blocks[1]=0xff; 703 tb.ms_data_6->block_descriptor.num_blocks[1] = 0xff;
619 tb.mode_sense_data_6->block_descriptor.number_of_blocks[2]=0xff; 704 tb.ms_data_6->block_descriptor.num_blocks[2] = 0xff;
620 } 705 }
621 else { 706 else {
622 tb.mode_sense_data_6->block_descriptor.number_of_blocks[0]=((block_count/block_size_mult) & 0xff0000)>>16; 707 tb.ms_data_6->block_descriptor.num_blocks[0] =
623 tb.mode_sense_data_6->block_descriptor.number_of_blocks[1]=((block_count/block_size_mult) & 0x00ff00)>>8; 708 ((block_count/block_size_mult) & 0xff0000)>>16;
624 tb.mode_sense_data_6->block_descriptor.number_of_blocks[2]=((block_count/block_size_mult) & 0x0000ff); 709 tb.ms_data_6->block_descriptor.num_blocks[1] =
710 ((block_count/block_size_mult) & 0x00ff00)>>8;
711 tb.ms_data_6->block_descriptor.num_blocks[2] =
712 ((block_count/block_size_mult) & 0x0000ff);
625 } 713 }
626 tb.mode_sense_data_6->block_descriptor.block_size[0]=((block_size*block_size_mult) & 0xff0000)>>16; 714 tb.ms_data_6->block_descriptor.block_size[0] =
627 tb.mode_sense_data_6->block_descriptor.block_size[1]=((block_size*block_size_mult) & 0x00ff00)>>8; 715 ((block_size*block_size_mult) & 0xff0000)>>16;
628 tb.mode_sense_data_6->block_descriptor.block_size[2]=((block_size*block_size_mult) & 0x0000ff); 716 tb.ms_data_6->block_descriptor.block_size[1] =
629 send_command_result(tb.mode_sense_data_6, 717 ((block_size*block_size_mult) & 0x00ff00)>>8;
718 tb.ms_data_6->block_descriptor.block_size[2] =
719 ((block_size*block_size_mult) & 0x0000ff);
720 send_command_result(tb.ms_data_6,
630 MIN(sizeof(struct mode_sense_data_6), length)); 721 MIN(sizeof(struct mode_sense_data_6), length));
631 break; 722 break;
632 default: 723 default:
@@ -641,8 +732,8 @@ static void handle_scsi(struct command_block_wrapper* cbw)
641 732
642 case SCSI_START_STOP_UNIT: 733 case SCSI_START_STOP_UNIT:
643 logf("scsi start_stop unit %d",lun); 734 logf("scsi start_stop unit %d",lun);
644 if((cbw->command_block[4] & 0xf0) == 0) /* Process start and eject bits */ 735 if((cbw->command_block[4] & 0xf0) == 0)
645 { 736 { /* Process start and eject bits */
646 if((cbw->command_block[4] & 0x01) == 0 && 737 if((cbw->command_block[4] & 0x01) == 0 &&
647 (cbw->command_block[4] & 0x02) != 0) /* Stop and eject */ 738 (cbw->command_block[4] & 0x02) != 0) /* Stop and eject */
648 { 739 {
@@ -661,10 +752,13 @@ static void handle_scsi(struct command_block_wrapper* cbw)
661 logf("scsi read_format_capacity %d",lun); 752 logf("scsi read_format_capacity %d",lun);
662 if(lun_present) { 753 if(lun_present) {
663 tb.format_capacity_data->following_length=htobe32(8); 754 tb.format_capacity_data->following_length=htobe32(8);
664 /* Careful: "block count" actually means "number of last block" */ 755 /* "block count" actually means "number of last block" */
665 tb.format_capacity_data->block_count = htobe32(block_count/block_size_mult - 1); 756 tb.format_capacity_data->block_count =
666 tb.format_capacity_data->block_size = htobe32(block_size*block_size_mult); 757 htobe32(block_count/block_size_mult - 1);
667 tb.format_capacity_data->block_size |= SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA; 758 tb.format_capacity_data->block_size =
759 htobe32(block_size*block_size_mult);
760 tb.format_capacity_data->block_size |=
761 SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA;
668 762
669 send_command_result(tb.format_capacity_data, 763 send_command_result(tb.format_capacity_data,
670 MIN(sizeof(struct format_capacity), length)); 764 MIN(sizeof(struct format_capacity), length));
@@ -682,11 +776,14 @@ static void handle_scsi(struct command_block_wrapper* cbw)
682 logf("scsi read_capacity %d",lun); 776 logf("scsi read_capacity %d",lun);
683 777
684 if(lun_present) { 778 if(lun_present) {
685 /* Careful: "block count" actually means "number of last block" */ 779 /* "block count" actually means "number of last block" */
686 tb.capacity_data->block_count = htobe32(block_count/block_size_mult - 1); 780 tb.capacity_data->block_count =
687 tb.capacity_data->block_size = htobe32(block_size*block_size_mult); 781 htobe32(block_count/block_size_mult - 1);
688 782 tb.capacity_data->block_size =
689 send_command_result(tb.capacity_data, MIN(sizeof(struct capacity), length)); 783 htobe32(block_size*block_size_mult);
784
785 send_command_result(tb.capacity_data,
786 MIN(sizeof(struct capacity), length));
690 } 787 }
691 else 788 else
692 { 789 {
@@ -707,30 +804,32 @@ static void handle_scsi(struct command_block_wrapper* cbw)
707 cur_sense_data.ascq=0; 804 cur_sense_data.ascq=0;
708 break; 805 break;
709 } 806 }
710 current_cmd.data[0] = tb.transfer_buffer; 807 cur_cmd.data[0] = tb.transfer_buffer;
711 current_cmd.data[1] = &tb.transfer_buffer[BUFFER_SIZE]; 808 cur_cmd.data[1] = &tb.transfer_buffer[BUFFER_SIZE];
712 current_cmd.data_select=0; 809 cur_cmd.data_select=0;
713 current_cmd.sector = block_size_mult * 810 cur_cmd.sector = block_size_mult *
714 (cbw->command_block[2] << 24 | 811 (cbw->command_block[2] << 24 |
715 cbw->command_block[3] << 16 | 812 cbw->command_block[3] << 16 |
716 cbw->command_block[4] << 8 | 813 cbw->command_block[4] << 8 |
717 cbw->command_block[5] ); 814 cbw->command_block[5] );
718 current_cmd.count = block_size_mult * 815 cur_cmd.count = block_size_mult *
719 (cbw->command_block[7] << 8 | 816 (cbw->command_block[7] << 8 |
720 cbw->command_block[8]); 817 cbw->command_block[8]);
721 818
722 //logf("scsi read %d %d", current_cmd.sector, current_cmd.count); 819 //logf("scsi read %d %d", cur_cmd.sector, cur_cmd.count);
723 820
724 if((current_cmd.sector + current_cmd.count) > block_count) { 821 if((cur_cmd.sector + cur_cmd.count) > block_count) {
725 send_csw(UMS_STATUS_FAIL); 822 send_csw(UMS_STATUS_FAIL);
726 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST; 823 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
727 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE; 824 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
728 cur_sense_data.ascq=0; 825 cur_sense_data.ascq=0;
729 } 826 }
730 else { 827 else {
731 current_cmd.last_result = ata_read_sectors(IF_MV2(current_cmd.lun,) current_cmd.sector, 828 cur_cmd.last_result = ata_read_sectors(IF_MV2(cur_cmd.lun,)
732 MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count), 829 cur_cmd.sector,
733 current_cmd.data[current_cmd.data_select]); 830 MIN(BUFFER_SIZE/SECTOR_SIZE,
831 cur_cmd.count),
832 cur_cmd.data[cur_cmd.data_select]);
734 send_and_read_next(); 833 send_and_read_next();
735 } 834 }
736 break; 835 break;
@@ -744,34 +843,35 @@ static void handle_scsi(struct command_block_wrapper* cbw)
744 cur_sense_data.ascq=0; 843 cur_sense_data.ascq=0;
745 break; 844 break;
746 } 845 }
747 current_cmd.data[0] = tb.transfer_buffer; 846 cur_cmd.data[0] = tb.transfer_buffer;
748 current_cmd.data[1] = &tb.transfer_buffer[BUFFER_SIZE]; 847 cur_cmd.data[1] = &tb.transfer_buffer[BUFFER_SIZE];
749 current_cmd.data_select=0; 848 cur_cmd.data_select=0;
750 current_cmd.sector = block_size_mult * 849 cur_cmd.sector = block_size_mult *
751 (cbw->command_block[2] << 24 | 850 (cbw->command_block[2] << 24 |
752 cbw->command_block[3] << 16 | 851 cbw->command_block[3] << 16 |
753 cbw->command_block[4] << 8 | 852 cbw->command_block[4] << 8 |
754 cbw->command_block[5] ); 853 cbw->command_block[5] );
755 current_cmd.count = block_size_mult * 854 cur_cmd.count = block_size_mult *
756 (cbw->command_block[7] << 8 | 855 (cbw->command_block[7] << 8 |
757 cbw->command_block[8]); 856 cbw->command_block[8]);
758 /* expect data */ 857 /* expect data */
759 if((current_cmd.sector + current_cmd.count) > block_count) { 858 if((cur_cmd.sector + cur_cmd.count) > block_count) {
760 send_csw(UMS_STATUS_FAIL); 859 send_csw(UMS_STATUS_FAIL);
761 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST; 860 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
762 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE; 861 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
763 cur_sense_data.ascq=0; 862 cur_sense_data.ascq=0;
764 } 863 }
765 else { 864 else {
766 receive_block_data(current_cmd.data[0], 865 receive_block_data(cur_cmd.data[0],
767 MIN(BUFFER_SIZE,current_cmd.count*SECTOR_SIZE)); 866 MIN(BUFFER_SIZE,
867 cur_cmd.count*SECTOR_SIZE));
768 } 868 }
769 869
770 break; 870 break;
771 871
772 default: 872 default:
773 logf("scsi unknown cmd %x",cbw->command_block[0x0]); 873 logf("scsi unknown cmd %x",cbw->command_block[0x0]);
774 usb_drv_stall(EP_MASS_STORAGE, true,true); 874 usb_drv_stall(usb_endpoint, true,true);
775 send_csw(UMS_STATUS_FAIL); 875 send_csw(UMS_STATUS_FAIL);
776 break; 876 break;
777 } 877 }
@@ -779,30 +879,31 @@ static void handle_scsi(struct command_block_wrapper* cbw)
779 879
780static void send_block_data(void *data,int size) 880static void send_block_data(void *data,int size)
781{ 881{
782 usb_drv_send_nonblocking(EP_MASS_STORAGE, data,size); 882 usb_drv_send_nonblocking(usb_endpoint, data,size);
783 state = SENDING_BLOCKS; 883 state = SENDING_BLOCKS;
784} 884}
785 885
786static void send_command_result(void *data,int size) 886static void send_command_result(void *data,int size)
787{ 887{
788 usb_drv_send_nonblocking(EP_MASS_STORAGE, data,size); 888 usb_drv_send_nonblocking(usb_endpoint, data,size);
789 state = SENDING_RESULT; 889 state = SENDING_RESULT;
790} 890}
791 891
792static void receive_block_data(void *data,int size) 892static void receive_block_data(void *data,int size)
793{ 893{
794 usb_drv_recv(EP_MASS_STORAGE, data, size); 894 usb_drv_recv(usb_endpoint, data, size);
795 state = RECEIVING_BLOCKS; 895 state = RECEIVING_BLOCKS;
796} 896}
797 897
798static void send_csw(int status) 898static void send_csw(int status)
799{ 899{
800 tb.csw->signature = htole32(CSW_SIGNATURE); 900 tb.csw->signature = htole32(CSW_SIGNATURE);
801 tb.csw->tag = current_cmd.tag; 901 tb.csw->tag = cur_cmd.tag;
802 tb.csw->data_residue = 0; 902 tb.csw->data_residue = 0;
803 tb.csw->status = status; 903 tb.csw->status = status;
804 904
805 usb_drv_send_nonblocking(EP_MASS_STORAGE, tb.csw, sizeof(struct command_status_wrapper)); 905 usb_drv_send_nonblocking(usb_endpoint, tb.csw,
906 sizeof(struct command_status_wrapper));
806 state = SENDING_CSW; 907 state = SENDING_CSW;
807 //logf("CSW: %X",status); 908 //logf("CSW: %X",status);
808 909
@@ -866,7 +967,8 @@ static void identify2inquiry(int lun)
866 tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE; 967 tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
867#endif 968#endif
868#endif 969#endif
869 /* Mac OSX 10.5 doesn't like this driver if DEVICE_REMOVABLE is not set */ 970 /* Mac OSX 10.5 doesn't like this driver if DEVICE_REMOVABLE is not set.
971 TODO : this can probably be solved by providing caching mode page */
870 tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE; 972 tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
871} 973}
872 974
diff --git a/firmware/usbstack/usb_storage.h b/firmware/usbstack/usb_storage.h
index 23903a855a..34bc0144dd 100644
--- a/firmware/usbstack/usb_storage.h
+++ b/firmware/usbstack/usb_storage.h
@@ -21,6 +21,9 @@
21 21
22#include "usb_ch9.h" 22#include "usb_ch9.h"
23 23
24int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size,
25 int interface_number,int endpoint);
26void usb_storage_init_connection(int interface,int endpoint);
24void usb_storage_init(void); 27void usb_storage_init(void);
25void usb_storage_transfer_complete(bool in,int state,int length); 28void usb_storage_transfer_complete(bool in,int state,int length);
26bool usb_storage_control_request(struct usb_ctrlrequest* req); 29bool usb_storage_control_request(struct usb_ctrlrequest* req);