1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2007 by Björn Stenberg
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 ****************************************************************************/
28 #define SECTOR_SIZE 512
30 /* bulk-only class specific requests */
31 #define USB_BULK_RESET_REQUEST 0xff
32 #define USB_BULK_GET_MAX_LUN 0xfe
34 #define DIRECT_ACCESS_DEVICE 0x00 /* disks */
35 #define DEVICE_REMOVABLE 0x80
37 #define CBW_SIGNATURE 0x43425355
38 #define CSW_SIGNATURE 0x53425355
40 #define SCSI_TEST_UNIT_READY 0x00
41 #define SCSI_INQUIRY 0x12
42 #define SCSI_MODE_SENSE 0x1a
43 #define SCSI_ALLOW_MEDIUM_REMOVAL 0x1e
44 #define SCSI_READ_CAPACITY 0x25
45 #define SCSI_READ_10 0x28
46 #define SCSI_WRITE_10 0x2a
48 #define SCSI_STATUS_GOOD 0x00
49 #define SCSI_STATUS_CHECK_CONDITION 0x02
53 unsigned char DeviceType
;
54 unsigned char DeviceTypeModifier
;
55 unsigned char Versions
;
57 unsigned char AdditionalLength
;
58 unsigned char Reserved
[2];
59 unsigned char Capability
;
60 unsigned char VendorId
[8];
61 unsigned char ProductId
[16];
62 unsigned char ProductRevisionLevel
[4];
63 } __attribute__ ((packed
));
65 struct command_block_wrapper
{
66 unsigned int signature
;
68 unsigned int data_transfer_length
;
71 unsigned char command_length
;
72 unsigned char command_block
[16];
73 } __attribute__ ((packed
));
75 struct command_status_wrapper
{
76 unsigned int signature
;
78 unsigned int data_residue
;
80 } __attribute__ ((packed
));
83 unsigned int block_count
;
84 unsigned int block_size
;
85 } __attribute__ ((packed
));
87 /* the ARC USB controller can at most buffer 16KB unaligned data */
88 static unsigned char _transfer_buffer
[16384];
89 static unsigned char* transfer_buffer
;
90 static struct inquiry_data _inquiry
;
91 static struct inquiry_data
* inquiry
;
92 static struct capacity _capacity_data
;
93 static struct capacity
* capacity_data
;
95 //static unsigned char partial_sector[SECTOR_SIZE];
99 unsigned int offset
; /* if partial sector */
104 void handle_scsi(struct command_block_wrapper
* cbw
);
105 void send_csw(unsigned int tag
, int status
);
106 static void identify2inquiry(void);
114 /* called by usb_code_init() */
115 void usb_storage_init(void)
117 inquiry
= (void*)UNCACHED_ADDR(&_inquiry
);
118 transfer_buffer
= (void*)UNCACHED_ADDR(&_transfer_buffer
);
119 capacity_data
= (void*)UNCACHED_ADDR(&_capacity_data
);
123 /* called by usb_core_transfer_complete() */
124 void usb_storage_transfer_complete(int endpoint
)
126 struct command_block_wrapper
* cbw
= (void*)transfer_buffer
;
130 //logf("ums: %d bytes in", length);
140 /* re-prime endpoint */
141 usb_drv_recv(EP_RX
, transfer_buffer
, sizeof _transfer_buffer
);
145 //logf("ums: %d bytes out", length);
150 /* called by usb_core_control_request() */
151 bool usb_storage_control_request(struct usb_ctrlrequest
* req
)
153 /* note: interrupt context */
155 bool handled
= false;
157 switch (req
->bRequest
) {
158 case USB_BULK_GET_MAX_LUN
: {
159 static char maxlun
= 0;
160 logf("ums: getmaxlun");
161 usb_drv_send(EP_CONTROL
, UNCACHED_ADDR(&maxlun
), 1);
162 usb_drv_recv(EP_CONTROL
, NULL
, 0); /* ack */
167 case USB_BULK_RESET_REQUEST
:
168 logf("ums: bulk reset");
169 usb_drv_reset_endpoint(EP_RX
, false);
170 usb_drv_reset_endpoint(EP_TX
, true);
171 usb_drv_send(EP_CONTROL
, NULL
, 0); /* ack */
175 case USB_REQ_SET_CONFIGURATION
:
176 logf("ums: set config");
177 /* prime rx endpoint */
178 usb_drv_recv(EP_RX
, transfer_buffer
, sizeof _transfer_buffer
);
186 /****************************************************************************/
188 void handle_scsi(struct command_block_wrapper
* cbw
)
190 /* USB Mass Storage assumes LBA capability.
191 TODO: support 48-bit LBA */
193 unsigned int length
= cbw
->data_transfer_length
;
195 switch (cbw
->command_block
[0]) {
196 case SCSI_TEST_UNIT_READY
:
197 logf("scsi test_unit_ready");
198 send_csw(cbw
->tag
, SCSI_STATUS_GOOD
);
202 logf("scsi inquiry");
203 length
= MIN(length
, cbw
->command_block
[4]);
204 usb_drv_send(EP_TX
, inquiry
, MIN(sizeof _inquiry
, length
));
205 send_csw(cbw
->tag
, SCSI_STATUS_GOOD
);
208 case SCSI_MODE_SENSE
: {
209 static unsigned char sense_data
[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
210 logf("scsi mode_sense");
211 usb_drv_send(EP_TX
, UNCACHED_ADDR(&sense_data
),
212 MIN(sizeof sense_data
, length
));
213 send_csw(cbw
->tag
, SCSI_STATUS_GOOD
);
217 case SCSI_ALLOW_MEDIUM_REMOVAL
:
218 logf("scsi allow_medium_removal");
219 send_csw(cbw
->tag
, SCSI_STATUS_GOOD
);
222 case SCSI_READ_CAPACITY
: {
223 logf("scsi read_capacity");
224 #ifdef HAVE_FLASH_STORAGE
225 tCardInfo
* cinfo
= card_get_info(0);
226 capacity_data
->block_count
= htobe32(cinfo
->numblocks
);
227 capacity_data
->block_size
= htobe32(cinfo
->blocksize
);
229 unsigned short* identify
= ata_get_identify();
230 capacity_data
->block_count
= htobe32(identify
[60] << 16 | identify
[61]);
231 capacity_data
->block_size
= htobe32(SECTOR_SIZE
);
233 usb_drv_send(EP_TX
, capacity_data
,
234 MIN(sizeof _capacity_data
, length
));
235 send_csw(cbw
->tag
, SCSI_STATUS_GOOD
);
241 cbw
->command_block
[2] << 24 |
242 cbw
->command_block
[3] << 16 |
243 cbw
->command_block
[4] << 8 |
244 cbw
->command_block
[5] ;
246 cbw
->command_block
[7] << 16 |
247 cbw
->command_block
[8];
248 current_cmd
.offset
= 0;
249 current_cmd
.tag
= cbw
->tag
;
251 logf("scsi read %d %d", current_cmd
.sector
, current_cmd
.count
);
254 if (current_cmd
.count
> (sizeof _transfer_buffer
/ SECTOR_SIZE
)) {
255 send_csw(current_cmd
.tag
, SCSI_STATUS_CHECK_CONDITION
);
259 ata_read_sectors(IF_MV2(0,) current_cmd
.sector
, current_cmd
.count
,
262 usb_drv_send(EP_TX
, transfer_buffer
,
263 MIN(current_cmd
.count
* SECTOR_SIZE
, length
));
267 logf("scsi write10");
271 logf("scsi unknown cmd %x", cbw
->command_block
[0]);
276 void send_csw(unsigned int tag
, int status
)
278 static struct command_status_wrapper _csw
;
279 struct command_status_wrapper
* csw
= UNCACHED_ADDR(&_csw
);
280 csw
->signature
= CSW_SIGNATURE
;
282 csw
->data_residue
= 0;
283 csw
->status
= status
;
285 //logf("csw %x %x", csw->tag, csw->signature);
286 usb_drv_send(EP_TX
, csw
, sizeof _csw
);
289 /* convert ATA IDENTIFY to SCSI INQUIRY */
290 static void identify2inquiry(void)
293 #ifdef HAVE_FLASH_STORAGE
295 inquiry
->VendorId
[i
] = i
+ 'A';
298 inquiry
->ProductId
[i
] = i
+ 'm';
300 unsigned short* dest
;
302 unsigned short* identify
= ata_get_identify();
303 memset(inquiry
, 0, sizeof _inquiry
);
305 if (identify
[82] & 4)
306 inquiry
->DeviceTypeModifier
= DEVICE_REMOVABLE
;
308 /* ATA only has a 'model' field, so we copy the
309 first 8 bytes to 'vendor' and the rest to 'product' */
310 src
= (unsigned short*)&identify
[27];
311 dest
= (unsigned short*)&inquiry
->VendorId
;
315 src
= (unsigned short*)&identify
[27+8];
316 dest
= (unsigned short*)&inquiry
->ProductId
;
320 src
= (unsigned short*)&identify
[23];
321 dest
= (unsigned short*)&inquiry
->ProductRevisionLevel
;
326 inquiry
->DeviceType
= DIRECT_ACCESS_DEVICE
;
327 inquiry
->AdditionalLength
= 0x1f;
328 inquiry
->Versions
= 3; /* ANSI SCSI level 2 */
329 inquiry
->Format
= 3; /* ANSI SCSI level 2 INQUIRY format */