1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 by Christian Gmeiner
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.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
21 #include "usb_storage.h"
22 #include "usbstack/utils.h"
24 /*-------------------------------------------------------------------------*/
26 static struct usb_dcd_controller_ops
* ops
;
28 struct usb_device_driver usb_storage_driver
= {
30 .bind
= usb_storage_driver_bind
,
31 .unbind
= usb_storage_driver_unbind
,
32 .request
= usb_storage_driver_request
,
35 .speed
= usb_storage_driver_speed
,
38 /*-------------------------------------------------------------------------*/
40 #define PROTO_BULK 0x50 // Bulk only
41 #define SUBCL_SCSI 0x06 // Transparent SCSI
43 /* Bulk-only class specific requests */
44 #define USB_BULK_RESET_REQUEST 0xff
45 #define USB_BULK_GET_MAX_LUN_REQUEST 0xfe
47 /*-------------------------------------------------------------------------*/
50 #define MANUFACTURER_STR_ID 1
51 #define PRODUCT_STR_ID 2
52 #define SERIAL_STR_ID 3
53 #define CONFIG_STR_ID 4
56 /* static strings, in UTF-8 */
57 static struct usb_string strings
[] = {
58 { MANUFACTURER_STR_ID
, "RockBox" },
59 { PRODUCT_STR_ID
, "RockBox Storage Driver" },
60 { SERIAL_STR_ID
, "0" },
61 { CONFIG_STR_ID
, "Storage Bulk" },
62 { DATA_STR_ID
, "Storage Data" },
65 static struct usb_device_descriptor storage_device_desc
= {
66 .bLength
= USB_DT_DEVICE_SIZE
,
67 .bDescriptorType
= USB_DT_DEVICE
,
74 .iManufacturer
= MANUFACTURER_STR_ID
,
75 .iProduct
= PRODUCT_STR_ID
,
76 .iSerialNumber
= SERIAL_STR_ID
,
77 .bNumConfigurations
= 1,
80 static struct usb_config_descriptor storage_config_desc
= {
81 .bLength
= USB_DT_CONFIG_SIZE
,
82 .bDescriptorType
= USB_DT_CONFIG
,
85 .bConfigurationValue
= 1,
86 .iConfiguration
= CONFIG_STR_ID
,
87 .bmAttributes
= USB_CONFIG_ATT_ONE
| USB_CONFIG_ATT_SELFPOWER
,
88 .bMaxPower
= 250, /* 500mA in 2mA units */
91 static struct usb_interface_descriptor storage_interface_desc
= {
92 .bLength
= USB_DT_INTERFACE_SIZE
,
93 .bDescriptorType
= USB_DT_INTERFACE
,
94 .bInterfaceNumber
= 0,
96 .bInterfaceClass
= USB_CLASS_MASS_STORAGE
,
97 .bInterfaceSubClass
= SUBCL_SCSI
,
98 .bInterfaceProtocol
= PROTO_BULK
,
99 .iInterface
= DATA_STR_ID
,
102 static struct usb_endpoint_descriptor storage_fs_bulk_in_desc
= {
103 .bLength
= USB_DT_ENDPOINT_SIZE
,
104 .bDescriptorType
= USB_DT_ENDPOINT
,
105 .bEndpointAddress
= USB_DIR_IN
,
106 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
107 .wMaxPacketSize
= 64,
110 static struct usb_endpoint_descriptor storage_fs_bulk_out_desc
= {
111 .bLength
= USB_DT_ENDPOINT_SIZE
,
112 .bDescriptorType
= USB_DT_ENDPOINT
,
113 .bEndpointAddress
= USB_DIR_OUT
,
114 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
115 .wMaxPacketSize
= 64,
118 static struct usb_qualifier_descriptor storage_qualifier_desc
= {
119 .bLength
= sizeof(struct usb_qualifier_descriptor
),
120 .bDescriptorType
= USB_DT_DEVICE_QUALIFIER
,
123 .bNumConfigurations
= 1,
126 struct usb_descriptor_header
*storage_fs_function
[] = {
127 (struct usb_descriptor_header
*) &storage_interface_desc
,
128 (struct usb_descriptor_header
*) &storage_fs_bulk_in_desc
,
129 (struct usb_descriptor_header
*) &storage_fs_bulk_out_desc
,
134 static struct usb_endpoint_descriptor storage_hs_bulk_in_desc
= {
135 .bLength
= USB_DT_ENDPOINT_SIZE
,
136 .bDescriptorType
= USB_DT_ENDPOINT
,
137 .bEndpointAddress
= USB_DIR_IN
,
138 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
139 .wMaxPacketSize
= 512,
142 static struct usb_endpoint_descriptor storage_hs_bulk_out_desc
= {
143 .bLength
= USB_DT_ENDPOINT_SIZE
,
144 .bDescriptorType
= USB_DT_ENDPOINT
,
145 .bEndpointAddress
= USB_DIR_OUT
,
146 .bmAttributes
= USB_ENDPOINT_XFER_BULK
,
147 .wMaxPacketSize
= 512,
150 struct usb_descriptor_header
*storage_hs_function
[] = {
151 (struct usb_descriptor_header
*) &storage_interface_desc
,
152 (struct usb_descriptor_header
*) &storage_hs_bulk_in_desc
,
153 (struct usb_descriptor_header
*) &storage_hs_bulk_out_desc
,
157 #define BUFFER_SIZE 100
158 uint8_t buf
[BUFFER_SIZE
];
160 struct usb_response res
;
162 /* helper functions */
163 static int config_buf(uint8_t *buf
, uint8_t type
, unsigned index
);
164 static int set_config(int config
);
165 static int set_interface_alt_setting(int interface_alt_setting
);
171 uint32_t used_config
;
172 uint32_t used_interface_alt_setting
;
173 struct usb_descriptor_header
** descriptors
;
176 static struct device dev
;
178 /*-------------------------------------------------------------------------*/
180 void usb_storage_driver_init(void)
182 logf("usb storage: register");
183 usb_device_driver_register(&usb_storage_driver
);
186 /*-------------------------------------------------------------------------*/
187 /* device driver ops */
189 int usb_storage_driver_bind(void* controler_ops
)
193 /* serach and asign endpoints */
194 usb_ep_autoconfig_reset();
196 dev
.in
= usb_ep_autoconfig(&storage_fs_bulk_in_desc
);
200 dev
.in
->claimed
= true;
201 logf("usb storage: in: %s", dev
.in
->name
);
203 dev
.out
= usb_ep_autoconfig(&storage_fs_bulk_out_desc
);
207 dev
.out
->claimed
= true;
208 logf("usb storage: out: %s", dev
.out
->name
);
210 /* update device decsriptor */
211 storage_device_desc
.bMaxPacketSize0
= ops
->ep0
->maxpacket
;
213 /* update hs descriptors as we asume that endpoints
214 are the same for fs and hs */
215 storage_hs_bulk_in_desc
.bEndpointAddress
=
216 storage_fs_bulk_in_desc
.bEndpointAddress
;
217 storage_hs_bulk_out_desc
.bEndpointAddress
=
218 storage_fs_bulk_out_desc
.bEndpointAddress
;
223 logf("failed to find endpoints");
227 void usb_storage_driver_unbind(void)
230 /* disable endpoints... */
233 int usb_storage_driver_request(struct usb_ctrlrequest
* request
)
235 int ret
= -EOPNOTSUPP
;
236 logf("usb storage: request");
241 switch (request
->bRequestType
& USB_TYPE_MASK
) {
242 case USB_TYPE_STANDARD
:
244 switch (request
->bRequest
) {
245 case USB_REQ_GET_DESCRIPTOR
:
247 switch (request
->wValue
>> 8) {
249 logf("usb storage: sending device desc");
250 ret
= MIN(sizeof(struct usb_device_descriptor
),
252 res
.buf
= &storage_device_desc
;
255 case USB_DT_DEVICE_QUALIFIER
:
256 logf("usb storage: sending qualifier dec");
257 ret
= MIN(sizeof(struct usb_qualifier_descriptor
),
259 res
.buf
= &storage_qualifier_desc
;
262 case USB_DT_OTHER_SPEED_CONFIG
:
264 logf("usb storage: sending config desc");
266 ret
= config_buf(buf
, request
->wValue
>> 8,
267 request
->wValue
& 0xff);
269 logf("%d, vs %d", request
->wLength
, ret
);
270 ret
= MIN(request
->wLength
, (uint16_t)ret
);
276 logf("usb storage: sending string desc");
277 ret
= usb_stack_get_string(strings
, request
->wValue
& 0xff,
279 ret
= MIN(ret
, request
->wLength
);
285 case USB_REQ_SET_CONFIGURATION
:
286 logf("usb storage: set configuration %d", request
->wValue
);
287 ret
= set_config(request
->wValue
);
290 case USB_REQ_GET_CONFIGURATION
:
291 logf("usb storage: get configuration");
293 res
.buf
= &dev
.used_config
;
296 case USB_REQ_GET_INTERFACE
:
297 logf("usb storage: get interface");
299 res
.buf
= &dev
.used_interface_alt_setting
;
302 case USB_REQ_SET_INTERFACE
:
303 logf("usb storage: set interface");
304 ret
= set_interface_alt_setting(request
->wValue
);
310 switch (request
->bRequest
) {
311 case USB_BULK_RESET_REQUEST
:
312 logf("usb storage: bulk reset");
315 case USB_BULK_GET_MAX_LUN_REQUEST
:
316 logf("usb storage: get max lun");
317 /* we support no LUNs (Logical Unit Number) */
327 ret
= ops
->send(NULL
, &res
);
333 void usb_storage_driver_speed(enum usb_device_speed speed
)
337 logf("usb storage: using highspeed");
338 dev
.descriptors
= storage_hs_function
;
341 logf("usb storage: using fullspeed");
342 dev
.descriptors
= storage_fs_function
;
347 /*-------------------------------------------------------------------------*/
348 /* S/GET CONFIGURATION helpers */
350 static int config_buf(uint8_t *buf
, uint8_t type
, unsigned index
)
356 len
= usb_stack_configdesc(&storage_config_desc
, buf
, BUFFER_SIZE
,
358 logf("result %d", len
);
362 ((struct usb_config_descriptor
*)buf
)->bDescriptorType
= type
;
366 static int set_config(int config
)
368 /* enable endpoints */
369 logf("setup %s", dev
.in
->name
);
370 ops
->enable(dev
.in
, (struct usb_endpoint_descriptor
*)dev
.descriptors
[1]);
371 logf("setup %s", dev
.out
->name
);
372 ops
->enable(dev
.out
, (struct usb_endpoint_descriptor
*)dev
.descriptors
[2]);
374 dev
.used_config
= config
;
381 static int set_interface_alt_setting(int interface_alt_setting
)
383 dev
.used_interface_alt_setting
= interface_alt_setting
;