fix wrong building block_count from read and write commands
[kugel-rb.git] / firmware / usbstack / usb_storage.c
blob746e275655e1a871ff4d60d27102037a8ab83aff
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id: $
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 ****************************************************************************/
19 #include "string.h"
20 #include "system.h"
21 #include "usb_core.h"
22 #include "usb_drv.h"
23 //#define LOGF_ENABLE
24 #include "logf.h"
25 #include "ata.h"
26 #include "hotswap.h"
27 #include "disk.h"
28 /* Needed to get at the audio buffer */
29 #include "audio.h"
31 #ifdef USB_STORAGE
33 /* Enable the following define to export only the SD card slot. This
34 * is useful for USBCV MSC tests, as those are destructive.
35 * This won't work right if the device doesn't have a card slot.
37 //#define ONLY_EXPOSE_CARD_SLOT
39 #define SECTOR_SIZE 512
41 /* We can currently use up to 20k buffer size. More than that requires
42 * transfer chaining in the driver. Tests on sansa c200 show that the 16k
43 * limitation causes no more than 2% slowdown.
45 #define BUFFER_SIZE 16384
47 /* bulk-only class specific requests */
48 #define USB_BULK_RESET_REQUEST 0xff
49 #define USB_BULK_GET_MAX_LUN 0xfe
51 #define DIRECT_ACCESS_DEVICE 0x00 /* disks */
52 #define DEVICE_REMOVABLE 0x80
54 #define CBW_SIGNATURE 0x43425355
55 #define CSW_SIGNATURE 0x53425355
57 #define SCSI_TEST_UNIT_READY 0x00
58 #define SCSI_INQUIRY 0x12
59 #define SCSI_MODE_SENSE_6 0x1a
60 #define SCSI_MODE_SENSE_10 0x5a
61 #define SCSI_REQUEST_SENSE 0x03
62 #define SCSI_ALLOW_MEDIUM_REMOVAL 0x1e
63 #define SCSI_READ_CAPACITY 0x25
64 #define SCSI_READ_FORMAT_CAPACITY 0x23
65 #define SCSI_READ_10 0x28
66 #define SCSI_WRITE_10 0x2a
67 #define SCSI_START_STOP_UNIT 0x1b
68 #define SCSI_REPORT_LUNS 0xa0
70 #define UMS_STATUS_GOOD 0x00
71 #define UMS_STATUS_FAIL 0x01
73 #define SENSE_NOT_READY 0x02
74 #define SENSE_MEDIUM_ERROR 0x03
75 #define SENSE_ILLEGAL_REQUEST 0x05
76 #define SENSE_UNIT_ATTENTION 0x06
78 #define ASC_MEDIUM_NOT_PRESENT 0x3a
79 #define ASC_INVALID_FIELD_IN_CBD 0x24
80 #define ASC_LBA_OUT_OF_RANGE 0x21
81 #define ASC_WRITE_ERROR 0x0C
82 #define ASC_READ_ERROR 0x11
83 #define ASC_NOT_READY 0x04
84 #define ASCQ_BECOMING_READY 0x01
86 #define SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA 0x02000000
89 struct inquiry_data {
90 unsigned char DeviceType;
91 unsigned char DeviceTypeModifier;
92 unsigned char Versions;
93 unsigned char Format;
94 unsigned char AdditionalLength;
95 unsigned char Reserved[2];
96 unsigned char Capability;
97 unsigned char VendorId[8];
98 unsigned char ProductId[16];
99 unsigned char ProductRevisionLevel[4];
100 } __attribute__ ((packed));
102 struct report_lun_data {
103 unsigned int lun_list_length;
104 unsigned int reserved1;
105 unsigned char lun0[8];
106 #ifdef HAVE_HOTSWAP
107 unsigned char lun1[8];
108 #endif
109 } __attribute__ ((packed));
111 struct sense_data {
112 unsigned char ResponseCode;
113 unsigned char Obsolete;
114 unsigned char filemark_eom_ili_sensekey;
115 unsigned int Information;
116 unsigned char AdditionalSenseLength;
117 unsigned int CommandSpecificInformation;
118 unsigned char AdditionalSenseCode;
119 unsigned char AdditionalSenseCodeQualifier;
120 unsigned char FieldReplaceableUnitCode;
121 unsigned char SKSV;
122 unsigned short SenseKeySpecific;
123 } __attribute__ ((packed));
125 struct mode_sense_block_descriptor_longlba {
126 unsigned char number_of_blocks[8];
127 unsigned char reserved[4];
128 unsigned char block_size[4];
129 } __attribute__ ((packed));
131 struct mode_sense_block_descriptor_shortlba {
132 unsigned char density_code;
133 unsigned char number_of_blocks[3];
134 unsigned char reserved;
135 unsigned char block_size[3];
136 } __attribute__ ((packed));
138 struct mode_sense_data_10 {
139 unsigned short mode_data_length;
140 unsigned char medium_type;
141 unsigned char device_specific;
142 unsigned char longlba;
143 unsigned char reserved;
144 unsigned short block_descriptor_length;
145 struct mode_sense_block_descriptor_longlba block_descriptor;
146 } __attribute__ ((packed));
148 struct mode_sense_data_6 {
149 unsigned char mode_data_length;
150 unsigned char medium_type;
151 unsigned char device_specific;
152 unsigned char block_descriptor_length;
153 struct mode_sense_block_descriptor_shortlba block_descriptor;
154 } __attribute__ ((packed));
156 struct command_block_wrapper {
157 unsigned int signature;
158 unsigned int tag;
159 unsigned int data_transfer_length;
160 unsigned char flags;
161 unsigned char lun;
162 unsigned char command_length;
163 unsigned char command_block[16];
164 } __attribute__ ((packed));
166 struct command_status_wrapper {
167 unsigned int signature;
168 unsigned int tag;
169 unsigned int data_residue;
170 unsigned char status;
171 } __attribute__ ((packed));
173 struct capacity {
174 unsigned int block_count;
175 unsigned int block_size;
176 } __attribute__ ((packed));
178 struct format_capacity {
179 unsigned int following_length;
180 unsigned int block_count;
181 unsigned int block_size;
182 } __attribute__ ((packed));
185 static union {
186 unsigned char* transfer_buffer;
187 struct inquiry_data* inquiry;
188 struct capacity* capacity_data;
189 struct format_capacity* format_capacity_data;
190 struct sense_data *sense_data;
191 struct mode_sense_data_6 *mode_sense_data_6;
192 struct mode_sense_data_10 *mode_sense_data_10;
193 struct report_lun_data *lun_data;
194 struct command_status_wrapper* csw;
195 char *max_lun;
196 } tb;
198 static struct {
199 unsigned int sector;
200 unsigned int count;
201 unsigned int tag;
202 unsigned int lun;
203 unsigned char *data[2];
204 unsigned char data_select;
205 unsigned int last_result;
206 } current_cmd;
208 static struct {
209 unsigned char sense_key;
210 unsigned char information;
211 unsigned char asc;
212 unsigned char ascq;
213 } cur_sense_data;
215 static void handle_scsi(struct command_block_wrapper* cbw);
216 static void send_csw(int status);
217 static void send_command_result(void *data,int size);
218 static void send_block_data(void *data,int size);
219 static void receive_block_data(void *data,int size);
220 static void identify2inquiry(int lun);
221 static void send_and_read_next(void);
223 static enum {
224 WAITING_FOR_COMMAND,
225 SENDING_BLOCKS,
226 SENDING_RESULT,
227 RECEIVING_BLOCKS,
228 SENDING_CSW
229 } state = WAITING_FOR_COMMAND;
231 /* called by usb_code_init() */
232 void usb_storage_init(void)
234 logf("usb_storage_init done");
237 /* called by usb_core_transfer_complete() */
238 void usb_storage_transfer_complete(bool in,int status,int length)
240 struct command_block_wrapper* cbw = (void*)tb.transfer_buffer;
242 //logf("transfer result %X %d", status, length);
243 switch(state) {
244 case RECEIVING_BLOCKS:
245 if(in==true) {
246 logf("IN received in RECEIVING");
248 logf("scsi write %d %d", current_cmd.sector, current_cmd.count);
249 if(status==0) {
250 if((unsigned int)length!=(SECTOR_SIZE*current_cmd.count)
251 && (unsigned int)length!=BUFFER_SIZE) {
252 logf("unexpected length :%d",length);
255 unsigned int next_sector = current_cmd.sector + (BUFFER_SIZE/SECTOR_SIZE);
256 unsigned int next_count = current_cmd.count - MIN(current_cmd.count,BUFFER_SIZE/SECTOR_SIZE);
258 if(next_count!=0) {
259 /* Ask the host to send more, to the other buffer */
260 receive_block_data(current_cmd.data[!current_cmd.data_select],
261 MIN(BUFFER_SIZE,next_count*SECTOR_SIZE));
264 /* Now write the data that just came in, while the host is sending the next bit */
265 int result = ata_write_sectors(IF_MV2(current_cmd.lun,)
266 current_cmd.sector, MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count),
267 current_cmd.data[current_cmd.data_select]);
268 if(result != 0) {
269 send_csw(UMS_STATUS_FAIL);
270 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR;
271 cur_sense_data.asc=ASC_WRITE_ERROR;
272 cur_sense_data.ascq=0;
273 break;
276 if(next_count==0) {
277 send_csw(UMS_STATUS_GOOD);
280 /* Switch buffers for the next one */
281 current_cmd.data_select=!current_cmd.data_select;
283 current_cmd.sector = next_sector;
284 current_cmd.count = next_count;
287 else {
288 logf("Transfer failed %X",status);
289 send_csw(UMS_STATUS_FAIL);
290 /* TODO fill in cur_sense_data */
291 cur_sense_data.sense_key=0;
292 cur_sense_data.information=0;
293 cur_sense_data.asc=0;
294 cur_sense_data.ascq=0;
296 break;
297 case WAITING_FOR_COMMAND:
298 if(in==true) {
299 logf("IN received in WAITING_FOR_COMMAND");
301 //logf("command received");
302 if(letoh32(cbw->signature) == CBW_SIGNATURE){
303 handle_scsi(cbw);
305 else {
306 usb_drv_stall(EP_MASS_STORAGE, true,true);
307 usb_drv_stall(EP_MASS_STORAGE, true,false);
309 break;
310 case SENDING_CSW:
311 if(in==false) {
312 logf("OUT received in SENDING_CSW");
314 //logf("csw sent, now go back to idle");
315 state = WAITING_FOR_COMMAND;
316 usb_drv_recv(EP_MASS_STORAGE, tb.transfer_buffer, 1024);
317 break;
318 case SENDING_RESULT:
319 if(in==false) {
320 logf("OUT received in SENDING");
322 if(status==0) {
323 //logf("data sent, now send csw");
324 send_csw(UMS_STATUS_GOOD);
326 else {
327 logf("Transfer failed %X",status);
328 send_csw(UMS_STATUS_FAIL);
329 /* TODO fill in cur_sense_data */
330 cur_sense_data.sense_key=0;
331 cur_sense_data.information=0;
332 cur_sense_data.asc=0;
333 cur_sense_data.ascq=0;
335 break;
336 case SENDING_BLOCKS:
337 if(in==false) {
338 logf("OUT received in SENDING");
340 if(status==0) {
341 if(current_cmd.count==0) {
342 //logf("data sent, now send csw");
343 send_csw(UMS_STATUS_GOOD);
345 else {
346 send_and_read_next();
349 else {
350 logf("Transfer failed %X",status);
351 send_csw(UMS_STATUS_FAIL);
352 /* TODO fill in cur_sense_data */
353 cur_sense_data.sense_key=0;
354 cur_sense_data.information=0;
355 cur_sense_data.asc=0;
356 cur_sense_data.ascq=0;
358 break;
362 /* called by usb_core_control_request() */
363 bool usb_storage_control_request(struct usb_ctrlrequest* req)
365 bool handled = false;
367 switch (req->bRequest) {
368 case USB_BULK_GET_MAX_LUN: {
369 #ifdef ONLY_EXPOSE_CARD_SLOT
370 *tb.max_lun = 0;
371 #else
372 *tb.max_lun = NUM_VOLUMES - 1;
373 #endif
374 logf("ums: getmaxlun");
375 usb_drv_send(EP_CONTROL, UNCACHED_ADDR(tb.max_lun), 1);
376 usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */
377 handled = true;
378 break;
381 case USB_BULK_RESET_REQUEST:
382 logf("ums: bulk reset");
383 state = WAITING_FOR_COMMAND;
384 /* UMS BOT 3.1 says The device shall preserve the value of its bulk
385 * data toggle bits and endpoint STALL conditions despite the Bulk-Only
386 * Mass Storage Reset. */
387 #if 0
388 usb_drv_reset_endpoint(EP_MASS_STORAGE, false);
389 usb_drv_reset_endpoint(EP_MASS_STORAGE, true);
390 #endif
392 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */
393 handled = true;
394 break;
396 case USB_REQ_SET_CONFIGURATION: {
397 size_t bufsize;
398 unsigned char * audio_buffer;
399 logf("ums: set config");
400 /* prime rx endpoint. We only need room for commands */
401 state = WAITING_FOR_COMMAND;
403 /* TODO : check if bufsize is at least 32K ? */
404 audio_buffer = audio_get_buffer(false,&bufsize);
405 tb.transfer_buffer = (void *)UNCACHED_ADDR((unsigned int)(audio_buffer + 31) & 0xffffffe0);
406 usb_drv_recv(EP_MASS_STORAGE, tb.transfer_buffer, 1024);
407 handled = true;
408 break;
412 return handled;
415 static void send_and_read_next(void)
417 if(current_cmd.last_result!=0) {
418 /* The last read failed. */
419 send_csw(UMS_STATUS_FAIL);
420 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR;
421 cur_sense_data.asc=ASC_READ_ERROR;
422 cur_sense_data.ascq=0;
423 return;
425 send_block_data(current_cmd.data[current_cmd.data_select],
426 MIN(BUFFER_SIZE,current_cmd.count*SECTOR_SIZE));
428 /* Switch buffers for the next one */
429 current_cmd.data_select=!current_cmd.data_select;
431 current_cmd.sector+=(BUFFER_SIZE/SECTOR_SIZE);
432 current_cmd.count-=MIN(current_cmd.count,BUFFER_SIZE/SECTOR_SIZE);
434 if(current_cmd.count!=0){
435 /* already read the next bit, so we can send it out immediately when the
436 * current transfer completes. */
437 current_cmd.last_result = ata_read_sectors(IF_MV2(current_cmd.lun,) current_cmd.sector,
438 MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count),
439 current_cmd.data[current_cmd.data_select]);
442 /****************************************************************************/
444 static void handle_scsi(struct command_block_wrapper* cbw)
446 /* USB Mass Storage assumes LBA capability.
447 TODO: support 48-bit LBA */
449 unsigned int length = cbw->data_transfer_length;
450 unsigned int block_size;
451 unsigned int block_count;
452 bool lun_present=true;
453 #ifdef ONLY_EXPOSE_CARD_SLOT
454 unsigned char lun = cbw->lun+1;
455 #else
456 unsigned char lun = cbw->lun;
457 #endif
458 unsigned int block_size_mult = 1;
459 #ifdef HAVE_HOTSWAP
460 tCardInfo* cinfo = card_get_info(lun);
461 if(cinfo->initialized==1 && cinfo->numblocks > 0) {
462 block_size = cinfo->blocksize;
463 block_count = cinfo->numblocks;
465 else {
466 lun_present=false;
467 block_size = 0;
468 block_count = 0;
470 #else
471 unsigned short* identify = ata_get_identify();
472 block_size = SECTOR_SIZE;
473 block_count = (identify[61] << 16 | identify[60]);
474 #endif
476 #ifdef MAX_LOG_SECTOR_SIZE
477 block_size_mult = disk_sector_multiplier;
478 #endif
480 current_cmd.tag = cbw->tag;
481 current_cmd.lun = lun;
483 switch (cbw->command_block[0]) {
484 case SCSI_TEST_UNIT_READY:
485 logf("scsi test_unit_ready %d",lun);
486 if(!usb_exclusive_ata()) {
487 send_csw(UMS_STATUS_FAIL);
488 cur_sense_data.sense_key=SENSE_NOT_READY;
489 cur_sense_data.asc=ASC_NOT_READY;
490 cur_sense_data.ascq=ASCQ_BECOMING_READY;
491 break;
493 if(lun_present) {
494 send_csw(UMS_STATUS_GOOD);
496 else {
497 send_csw(UMS_STATUS_FAIL);
498 cur_sense_data.sense_key=SENSE_NOT_READY;
499 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
500 cur_sense_data.ascq=0;
502 break;
504 case SCSI_REPORT_LUNS: {
505 logf("scsi inquiry %d",lun);
506 int allocation_length=0;
507 allocation_length|=(cbw->command_block[6]<<24);
508 allocation_length|=(cbw->command_block[7]<<16);
509 allocation_length|=(cbw->command_block[8]<<8);
510 allocation_length|=(cbw->command_block[9]);
511 memset(tb.lun_data,0,sizeof(struct report_lun_data));
512 #ifdef HAVE_HOTSWAP
513 tb.lun_data->lun_list_length=htobe32(16);
514 tb.lun_data->lun1[1]=1;
515 #else
516 tb.lun_data->lun_list_length=htobe32(8);
517 #endif
518 tb.lun_data->lun0[1]=0;
520 send_command_result(tb.lun_data, MIN(sizeof(struct report_lun_data), length));
521 break;
524 case SCSI_INQUIRY:
525 logf("scsi inquiry %d",lun);
526 identify2inquiry(lun);
527 length = MIN(length, cbw->command_block[4]);
528 send_command_result(tb.inquiry, MIN(sizeof(struct inquiry_data), length));
529 break;
531 case SCSI_REQUEST_SENSE: {
532 tb.sense_data->ResponseCode=0x70;/*current error*/
533 tb.sense_data->filemark_eom_ili_sensekey=cur_sense_data.sense_key&0x0f;
534 tb.sense_data->Information=cur_sense_data.information;
535 tb.sense_data->AdditionalSenseLength=10;
536 tb.sense_data->CommandSpecificInformation=0;
537 tb.sense_data->AdditionalSenseCode=cur_sense_data.asc;
538 tb.sense_data->AdditionalSenseCodeQualifier=cur_sense_data.ascq;
539 tb.sense_data->FieldReplaceableUnitCode=0;
540 tb.sense_data->SKSV=0;
541 tb.sense_data->SenseKeySpecific=0;
542 logf("scsi request_sense %d",lun);
543 send_command_result(tb.sense_data, sizeof(struct sense_data));
544 break;
547 case SCSI_MODE_SENSE_10: {
548 if(! lun_present) {
549 send_csw(UMS_STATUS_FAIL);
550 cur_sense_data.sense_key=SENSE_NOT_READY;
551 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
552 cur_sense_data.ascq=0;
553 break;
555 /*unsigned char pc = (cbw->command_block[2] & 0xc0) >>6;*/
556 unsigned char page_code = cbw->command_block[2] & 0x3f;
557 logf("scsi mode_sense_10 %d %X",lun,page_code);
558 switch(page_code) {
559 case 0x3f:
560 tb.mode_sense_data_10->mode_data_length=sizeof(struct mode_sense_data_10);
561 tb.mode_sense_data_10->medium_type=0;
562 tb.mode_sense_data_10->device_specific=0;
563 tb.mode_sense_data_10->reserved=0;
564 tb.mode_sense_data_10->longlba=1;
565 tb.mode_sense_data_10->block_descriptor_length=sizeof(struct mode_sense_block_descriptor_longlba);
566 memset(tb.mode_sense_data_10->block_descriptor.reserved,0,4);
567 memset(tb.mode_sense_data_10->block_descriptor.number_of_blocks,0,8);
568 tb.mode_sense_data_10->block_descriptor.number_of_blocks[4]=((block_count/block_size_mult) & 0xff000000)>>24;
569 tb.mode_sense_data_10->block_descriptor.number_of_blocks[5]=((block_count/block_size_mult) & 0x00ff0000)>>16;
570 tb.mode_sense_data_10->block_descriptor.number_of_blocks[6]=((block_count/block_size_mult) & 0x0000ff00)>>8;
571 tb.mode_sense_data_10->block_descriptor.number_of_blocks[7]=((block_count/block_size_mult) & 0x000000ff);
573 tb.mode_sense_data_10->block_descriptor.block_size[0]=((block_size*block_size_mult) & 0xff000000)>>24;
574 tb.mode_sense_data_10->block_descriptor.block_size[1]=((block_size*block_size_mult) & 0x00ff0000)>>16;
575 tb.mode_sense_data_10->block_descriptor.block_size[2]=((block_size*block_size_mult) & 0x0000ff00)>>8;
576 tb.mode_sense_data_10->block_descriptor.block_size[3]=((block_size*block_size_mult) & 0x000000ff);
577 send_command_result(tb.mode_sense_data_10,
578 MIN(sizeof(struct mode_sense_data_10), length));
579 break;
580 default:
581 send_csw(UMS_STATUS_FAIL);
582 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
583 cur_sense_data.asc=ASC_INVALID_FIELD_IN_CBD;
584 cur_sense_data.ascq=0;
585 break;
587 break;
589 case SCSI_MODE_SENSE_6: {
590 if(! lun_present) {
591 send_csw(UMS_STATUS_FAIL);
592 cur_sense_data.sense_key=SENSE_NOT_READY;
593 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
594 cur_sense_data.ascq=0;
595 break;
597 /*unsigned char pc = (cbw->command_block[2] & 0xc0) >>6;*/
598 unsigned char page_code = cbw->command_block[2] & 0x3f;
599 logf("scsi mode_sense_6 %d %X",lun,page_code);
600 switch(page_code) {
601 case 0x3f:
602 /* All supported pages Since we support only one this is easy*/
603 tb.mode_sense_data_6->mode_data_length=sizeof(struct mode_sense_data_6);
604 tb.mode_sense_data_6->medium_type=0;
605 tb.mode_sense_data_6->device_specific=0;
606 tb.mode_sense_data_6->block_descriptor_length=sizeof(struct mode_sense_block_descriptor_shortlba);
607 tb.mode_sense_data_6->block_descriptor.density_code=0;
608 tb.mode_sense_data_6->block_descriptor.reserved=0;
609 if(block_count/block_size_mult > 0xffffff){
610 tb.mode_sense_data_6->block_descriptor.number_of_blocks[0]=0xff;
611 tb.mode_sense_data_6->block_descriptor.number_of_blocks[1]=0xff;
612 tb.mode_sense_data_6->block_descriptor.number_of_blocks[2]=0xff;
614 else {
615 tb.mode_sense_data_6->block_descriptor.number_of_blocks[0]=((block_count/block_size_mult) & 0xff0000)>>16;
616 tb.mode_sense_data_6->block_descriptor.number_of_blocks[1]=((block_count/block_size_mult) & 0x00ff00)>>8;
617 tb.mode_sense_data_6->block_descriptor.number_of_blocks[2]=((block_count/block_size_mult) & 0x0000ff);
619 tb.mode_sense_data_6->block_descriptor.block_size[0]=((block_size*block_size_mult) & 0xff0000)>>16;
620 tb.mode_sense_data_6->block_descriptor.block_size[1]=((block_size*block_size_mult) & 0x00ff00)>>8;
621 tb.mode_sense_data_6->block_descriptor.block_size[2]=((block_size*block_size_mult) & 0x0000ff);
622 send_command_result(tb.mode_sense_data_6,
623 MIN(sizeof(struct mode_sense_data_6), length));
624 break;
625 default:
626 send_csw(UMS_STATUS_FAIL);
627 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
628 cur_sense_data.asc=ASC_INVALID_FIELD_IN_CBD;
629 cur_sense_data.ascq=0;
630 break;
632 break;
635 case SCSI_START_STOP_UNIT:
636 logf("scsi start_stop unit %d",lun);
637 send_csw(UMS_STATUS_GOOD);
638 break;
640 case SCSI_ALLOW_MEDIUM_REMOVAL:
641 logf("scsi allow_medium_removal %d",lun);
642 /* TODO: use this to show the connect screen ? */
643 send_csw(UMS_STATUS_GOOD);
644 break;
645 case SCSI_READ_FORMAT_CAPACITY: {
646 logf("scsi read_format_capacity %d",lun);
647 if(lun_present) {
648 tb.format_capacity_data->following_length=htobe32(8);
649 /* Careful: "block count" actually means "number of last block" */
650 tb.format_capacity_data->block_count = htobe32(block_count/block_size_mult - 1);
651 tb.format_capacity_data->block_size = htobe32(block_size*block_size_mult);
652 tb.format_capacity_data->block_size |= SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA;
654 send_command_result(tb.format_capacity_data,
655 MIN(sizeof(struct format_capacity), length));
657 else
659 send_csw(UMS_STATUS_FAIL);
660 cur_sense_data.sense_key=SENSE_NOT_READY;
661 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
662 cur_sense_data.ascq=0;
664 break;
666 case SCSI_READ_CAPACITY: {
667 logf("scsi read_capacity %d",lun);
669 if(lun_present) {
670 /* Careful: "block count" actually means "number of last block" */
671 tb.capacity_data->block_count = htobe32(block_count/block_size_mult - 1);
672 tb.capacity_data->block_size = htobe32(block_size*block_size_mult);
674 send_command_result(tb.capacity_data, MIN(sizeof(struct capacity), length));
676 else
678 send_csw(UMS_STATUS_FAIL);
679 cur_sense_data.sense_key=SENSE_NOT_READY;
680 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
681 cur_sense_data.ascq=0;
683 break;
686 case SCSI_READ_10:
687 logf("scsi read10 %d",lun);
688 if(! lun_present) {
689 send_csw(UMS_STATUS_FAIL);
690 cur_sense_data.sense_key=SENSE_NOT_READY;
691 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
692 cur_sense_data.ascq=0;
693 break;
695 current_cmd.data[0] = tb.transfer_buffer;
696 current_cmd.data[1] = &tb.transfer_buffer[BUFFER_SIZE];
697 current_cmd.data_select=0;
698 current_cmd.sector = block_size_mult *
699 (cbw->command_block[2] << 24 |
700 cbw->command_block[3] << 16 |
701 cbw->command_block[4] << 8 |
702 cbw->command_block[5] );
703 current_cmd.count = block_size_mult *
704 (cbw->command_block[7] << 8 |
705 cbw->command_block[8]);
707 //logf("scsi read %d %d", current_cmd.sector, current_cmd.count);
709 if((current_cmd.sector + current_cmd.count) > block_count) {
710 send_csw(UMS_STATUS_FAIL);
711 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
712 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
713 cur_sense_data.ascq=0;
715 else {
716 current_cmd.last_result = ata_read_sectors(IF_MV2(current_cmd.lun,) current_cmd.sector,
717 MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count),
718 current_cmd.data[current_cmd.data_select]);
719 send_and_read_next();
721 break;
723 case SCSI_WRITE_10:
724 logf("scsi write10 %d",lun);
725 if(! lun_present) {
726 send_csw(UMS_STATUS_FAIL);
727 cur_sense_data.sense_key=SENSE_NOT_READY;
728 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
729 cur_sense_data.ascq=0;
730 break;
732 current_cmd.data[0] = tb.transfer_buffer;
733 current_cmd.data[1] = &tb.transfer_buffer[BUFFER_SIZE];
734 current_cmd.data_select=0;
735 current_cmd.sector = block_size_mult *
736 (cbw->command_block[2] << 24 |
737 cbw->command_block[3] << 16 |
738 cbw->command_block[4] << 8 |
739 cbw->command_block[5] );
740 current_cmd.count = block_size_mult *
741 (cbw->command_block[7] << 8 |
742 cbw->command_block[8]);
743 /* expect data */
744 if((current_cmd.sector + current_cmd.count) > block_count) {
745 send_csw(UMS_STATUS_FAIL);
746 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
747 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
748 cur_sense_data.ascq=0;
750 else {
751 receive_block_data(current_cmd.data[0],
752 MIN(BUFFER_SIZE,current_cmd.count*SECTOR_SIZE));
755 break;
757 default:
758 logf("scsi unknown cmd %x",cbw->command_block[0x0]);
759 usb_drv_stall(EP_MASS_STORAGE, true,true);
760 send_csw(UMS_STATUS_FAIL);
761 break;
765 static void send_block_data(void *data,int size)
767 usb_drv_send_nonblocking(EP_MASS_STORAGE, data,size);
768 state = SENDING_BLOCKS;
771 static void send_command_result(void *data,int size)
773 usb_drv_send_nonblocking(EP_MASS_STORAGE, data,size);
774 state = SENDING_RESULT;
777 static void receive_block_data(void *data,int size)
779 usb_drv_recv(EP_MASS_STORAGE, data, size);
780 state = RECEIVING_BLOCKS;
783 static void send_csw(int status)
785 tb.csw->signature = htole32(CSW_SIGNATURE);
786 tb.csw->tag = current_cmd.tag;
787 tb.csw->data_residue = 0;
788 tb.csw->status = status;
790 usb_drv_send_nonblocking(EP_MASS_STORAGE, tb.csw, sizeof(struct command_status_wrapper));
791 state = SENDING_CSW;
792 //logf("CSW: %X",status);
794 if(status == UMS_STATUS_GOOD) {
795 cur_sense_data.sense_key=0;
796 cur_sense_data.information=0;
797 cur_sense_data.asc=0;
798 cur_sense_data.ascq=0;
802 /* convert ATA IDENTIFY to SCSI INQUIRY */
803 static void identify2inquiry(int lun)
805 #ifdef HAVE_FLASH_STORAGE
806 if(lun==0) {
807 memcpy(&tb.inquiry->VendorId,"Rockbox ",8);
808 memcpy(&tb.inquiry->ProductId,"Internal Storage",16);
809 memcpy(&tb.inquiry->ProductRevisionLevel,"0.00",4);
811 else {
812 memcpy(&tb.inquiry->VendorId,"Rockbox ",8);
813 memcpy(&tb.inquiry->ProductId,"SD Card Slot ",16);
814 memcpy(&tb.inquiry->ProductRevisionLevel,"0.00",4);
816 #else
817 unsigned int i;
818 unsigned short* dest;
819 unsigned short* src;
820 unsigned short* identify = ata_get_identify();
821 (void)lun;
822 memset(tb.inquiry, 0, sizeof(struct inquiry_data));
824 if (identify[82] & 4)
825 tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
827 /* ATA only has a 'model' field, so we copy the
828 first 8 bytes to 'vendor' and the rest to 'product' (they are
829 consecutive in the inquiry struct) */
830 src = (unsigned short*)&identify[27];
831 dest = (unsigned short*)&tb.inquiry->VendorId;
832 for (i=0;i<12;i++)
833 dest[i] = htobe16(src[i]);
835 src = (unsigned short*)&identify[23];
836 dest = (unsigned short*)&tb.inquiry->ProductRevisionLevel;
837 for (i=0;i<2;i++)
838 dest[i] = htobe16(src[i]);
839 #endif
841 tb.inquiry->DeviceType = DIRECT_ACCESS_DEVICE;
842 tb.inquiry->AdditionalLength = 0x1f;
843 tb.inquiry->Versions = 4; /* SPC-2 */
844 tb.inquiry->Format = 2; /* SPC-2/3 inquiry format */
846 #ifdef HAVE_HOTSWAP
847 if(lun>0)
848 tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
849 #endif
853 #endif /* USB_STORAGE */