- some SCSI/UMS fixes
[Rockbox.git] / firmware / usbstack / usb_storage.c
blob9d65f3b90860a43a9f2407868d44b1645e9220ad
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
84 #define SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA 0x02000000
87 struct inquiry_data {
88 unsigned char DeviceType;
89 unsigned char DeviceTypeModifier;
90 unsigned char Versions;
91 unsigned char Format;
92 unsigned char AdditionalLength;
93 unsigned char Reserved[2];
94 unsigned char Capability;
95 unsigned char VendorId[8];
96 unsigned char ProductId[16];
97 unsigned char ProductRevisionLevel[4];
98 } __attribute__ ((packed));
100 struct report_lun_data {
101 unsigned int lun_list_length;
102 unsigned int reserved1;
103 unsigned char lun0[8];
104 #ifdef HAVE_HOTSWAP
105 unsigned char lun1[8];
106 #endif
107 } __attribute__ ((packed));
109 struct sense_data {
110 unsigned char ResponseCode;
111 unsigned char Obsolete;
112 unsigned char filemark_eom_ili_sensekey;
113 unsigned int Information;
114 unsigned char AdditionalSenseLength;
115 unsigned int CommandSpecificInformation;
116 unsigned char AdditionalSenseCode;
117 unsigned char AdditionalSenseCodeQualifier;
118 unsigned char FieldReplaceableUnitCode;
119 unsigned char SKSV;
120 unsigned short SenseKeySpecific;
121 } __attribute__ ((packed));
123 struct mode_sense_header_10 {
124 unsigned short mode_data_length;
125 unsigned char medium_type;
126 unsigned char device_specific;
127 unsigned char reserved1[2];
128 unsigned short block_descriptor_length;
129 } __attribute__ ((packed));
131 struct mode_sense_header_6 {
132 unsigned char mode_data_length;
133 unsigned char medium_type;
134 unsigned char device_specific;
135 unsigned char block_descriptor_length;
136 } __attribute__ ((packed));
138 struct command_block_wrapper {
139 unsigned int signature;
140 unsigned int tag;
141 unsigned int data_transfer_length;
142 unsigned char flags;
143 unsigned char lun;
144 unsigned char command_length;
145 unsigned char command_block[16];
146 } __attribute__ ((packed));
148 struct command_status_wrapper {
149 unsigned int signature;
150 unsigned int tag;
151 unsigned int data_residue;
152 unsigned char status;
153 } __attribute__ ((packed));
155 struct capacity {
156 unsigned int block_count;
157 unsigned int block_size;
158 } __attribute__ ((packed));
160 struct format_capacity {
161 unsigned int following_length;
162 unsigned int block_count;
163 unsigned int block_size;
164 } __attribute__ ((packed));
166 static unsigned char* transfer_buffer;
168 static struct inquiry_data* inquiry;
169 static struct capacity* capacity_data;
170 static struct format_capacity* format_capacity_data;
171 static struct sense_data *sense_data;
172 static struct mode_sense_header_6 *mode_sense_data_6;
173 static struct mode_sense_header_10 *mode_sense_data_10;
174 static struct report_lun_data *lun_data;
175 static struct command_status_wrapper* csw;
176 static char *max_lun;
178 static struct {
179 unsigned int sector;
180 unsigned int count;
181 unsigned int tag;
182 unsigned int lun;
183 unsigned char *data[2];
184 unsigned char data_select;
185 unsigned int last_result;
186 } current_cmd;
188 static struct {
189 unsigned char sense_key;
190 unsigned char information;
191 unsigned char asc;
192 } cur_sense_data;
194 static void handle_scsi(struct command_block_wrapper* cbw);
195 static void send_csw(int status);
196 static void send_command_result(void *data,int size);
197 static void send_block_data(void *data,int size);
198 static void receive_block_data(void *data,int size);
199 static void identify2inquiry(int lun);
200 static void send_and_read_next(void);
202 static enum {
203 WAITING_FOR_COMMAND,
204 SENDING_BLOCKS,
205 SENDING_RESULT,
206 RECEIVING_BLOCKS,
207 SENDING_CSW
208 } state = WAITING_FOR_COMMAND;
210 /* called by usb_code_init() */
211 void usb_storage_init(void)
213 size_t bufsize;
214 unsigned char * audio_buffer = audio_get_buffer(false,&bufsize);
215 /* TODO : check if bufsize is at least 32K ? */
216 transfer_buffer = (void *)UNCACHED_ADDR((unsigned int)(audio_buffer + 31) & 0xffffffe0);
217 inquiry = (void*)transfer_buffer;
218 capacity_data = (void*)transfer_buffer;
219 format_capacity_data = (void*)transfer_buffer;
220 sense_data = (void*)transfer_buffer;
221 mode_sense_data_6 = (void*)transfer_buffer;
222 mode_sense_data_10 = (void*)transfer_buffer;
223 lun_data = (void*)transfer_buffer;
224 max_lun = (void*)transfer_buffer;
225 csw = (void*)transfer_buffer;
226 logf("usb_storage_init done");
229 /* called by usb_core_transfer_complete() */
230 void usb_storage_transfer_complete(bool in,int status,int length)
232 struct command_block_wrapper* cbw = (void*)transfer_buffer;
234 //logf("transfer result %X %d", status, length);
235 switch(state) {
236 case RECEIVING_BLOCKS:
237 if(in==true) {
238 logf("IN received in RECEIVING");
240 logf("scsi write %d %d", current_cmd.sector, current_cmd.count);
241 if(status==0) {
242 if((unsigned int)length!=(SECTOR_SIZE*current_cmd.count)
243 && (unsigned int)length!=BUFFER_SIZE) {
244 logf("unexpected length :%d",length);
247 unsigned int next_sector = current_cmd.sector + (BUFFER_SIZE/SECTOR_SIZE);
248 unsigned int next_count = current_cmd.count - MIN(current_cmd.count,BUFFER_SIZE/SECTOR_SIZE);
250 if(next_count!=0) {
251 /* Ask the host to send more, to the other buffer */
252 receive_block_data(current_cmd.data[!current_cmd.data_select],
253 MIN(BUFFER_SIZE,next_count*SECTOR_SIZE));
256 /* Now write the data that just came in, while the host is sending the next bit */
257 int result = ata_write_sectors(IF_MV2(current_cmd.lun,)
258 current_cmd.sector, MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count),
259 current_cmd.data[current_cmd.data_select]);
260 if(result != 0) {
261 send_csw(UMS_STATUS_FAIL);
262 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR;
263 cur_sense_data.asc=ASC_WRITE_ERROR;
264 break;
267 if(next_count==0) {
268 send_csw(UMS_STATUS_GOOD);
271 /* Switch buffers for the next one */
272 current_cmd.data_select=!current_cmd.data_select;
274 current_cmd.sector = next_sector;
275 current_cmd.count = next_count;
278 else {
279 logf("Transfer failed %X",status);
280 send_csw(UMS_STATUS_FAIL);
281 /* TODO fill in cur_sense_data */
282 cur_sense_data.sense_key=0;
283 cur_sense_data.information=0;
284 cur_sense_data.asc=0;
286 break;
287 case WAITING_FOR_COMMAND:
288 if(in==true) {
289 logf("IN received in WAITING_FOR_COMMAND");
291 //logf("command received");
292 if(letoh32(cbw->signature) == CBW_SIGNATURE){
293 handle_scsi(cbw);
295 else {
296 usb_drv_stall(EP_MASS_STORAGE, true,true);
297 usb_drv_stall(EP_MASS_STORAGE, true,false);
299 break;
300 case SENDING_CSW:
301 if(in==false) {
302 logf("OUT received in SENDING_CSW");
304 //logf("csw sent, now go back to idle");
305 state = WAITING_FOR_COMMAND;
306 usb_drv_recv(EP_MASS_STORAGE, transfer_buffer, 1024);
307 break;
308 case SENDING_RESULT:
309 if(in==false) {
310 logf("OUT received in SENDING");
312 if(status==0) {
313 //logf("data sent, now send csw");
314 send_csw(UMS_STATUS_GOOD);
316 else {
317 logf("Transfer failed %X",status);
318 send_csw(UMS_STATUS_FAIL);
319 /* TODO fill in cur_sense_data */
320 cur_sense_data.sense_key=0;
321 cur_sense_data.information=0;
322 cur_sense_data.asc=0;
324 break;
325 case SENDING_BLOCKS:
326 if(in==false) {
327 logf("OUT received in SENDING");
329 if(status==0) {
330 if(current_cmd.count==0) {
331 //logf("data sent, now send csw");
332 send_csw(UMS_STATUS_GOOD);
334 else {
335 send_and_read_next();
338 else {
339 logf("Transfer failed %X",status);
340 send_csw(UMS_STATUS_FAIL);
341 /* TODO fill in cur_sense_data */
342 cur_sense_data.sense_key=0;
343 cur_sense_data.information=0;
344 cur_sense_data.asc=0;
346 break;
350 /* called by usb_core_control_request() */
351 bool usb_storage_control_request(struct usb_ctrlrequest* req)
353 bool handled = false;
355 switch (req->bRequest) {
356 case USB_BULK_GET_MAX_LUN: {
357 #ifdef ONLY_EXPOSE_CARD_SLOT
358 *max_lun = 0;
359 #else
360 *max_lun = NUM_VOLUMES - 1;
361 #endif
362 logf("ums: getmaxlun");
363 usb_drv_send(EP_CONTROL, UNCACHED_ADDR(max_lun), 1);
364 usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */
365 handled = true;
366 break;
369 case USB_BULK_RESET_REQUEST:
370 logf("ums: bulk reset");
371 state = WAITING_FOR_COMMAND;
372 /* UMS BOT 3.1 says The device shall preserve the value of its bulk
373 * data toggle bits and endpoint STALL conditions despite the Bulk-Only
374 * Mass Storage Reset. */
375 #if 0
376 usb_drv_reset_endpoint(EP_MASS_STORAGE, false);
377 usb_drv_reset_endpoint(EP_MASS_STORAGE, true);
378 #endif
380 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */
381 handled = true;
382 break;
384 case USB_REQ_SET_CONFIGURATION:
385 logf("ums: set config");
386 /* prime rx endpoint. We only need room for commands */
387 state = WAITING_FOR_COMMAND;
388 usb_drv_recv(EP_MASS_STORAGE, transfer_buffer, 1024);
389 handled = true;
390 break;
393 return handled;
396 static void send_and_read_next(void)
398 if(current_cmd.last_result!=0) {
399 /* The last read failed. */
400 send_csw(UMS_STATUS_FAIL);
401 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR;
402 cur_sense_data.asc=ASC_READ_ERROR;
403 return;
405 send_block_data(current_cmd.data[current_cmd.data_select],
406 MIN(BUFFER_SIZE,current_cmd.count*SECTOR_SIZE));
408 /* Switch buffers for the next one */
409 current_cmd.data_select=!current_cmd.data_select;
411 current_cmd.sector+=(BUFFER_SIZE/SECTOR_SIZE);
412 current_cmd.count-=MIN(current_cmd.count,BUFFER_SIZE/SECTOR_SIZE);
414 if(current_cmd.count!=0){
415 /* already read the next bit, so we can send it out immediately when the
416 * current transfer completes. */
417 current_cmd.last_result = ata_read_sectors(IF_MV2(current_cmd.lun,) current_cmd.sector,
418 MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count),
419 current_cmd.data[current_cmd.data_select]);
422 /****************************************************************************/
424 static void handle_scsi(struct command_block_wrapper* cbw)
426 /* USB Mass Storage assumes LBA capability.
427 TODO: support 48-bit LBA */
429 unsigned int length = cbw->data_transfer_length;
430 unsigned int block_size;
431 unsigned int block_count;
432 bool lun_present=true;
433 #ifdef ONLY_EXPOSE_CARD_SLOT
434 unsigned char lun = cbw->lun+1;
435 #else
436 unsigned char lun = cbw->lun;
437 #endif
438 unsigned int block_size_mult = 1;
439 #ifdef HAVE_HOTSWAP
440 tCardInfo* cinfo = card_get_info(lun);
441 if(cinfo->initialized==1 && cinfo->numblocks > 0) {
442 block_size = cinfo->blocksize;
443 block_count = cinfo->numblocks;
445 else {
446 lun_present=false;
447 block_size = 0;
448 block_count = 0;
450 #else
451 unsigned short* identify = ata_get_identify();
452 block_size = SECTOR_SIZE;
453 block_count = (identify[61] << 16 | identify[60]);
454 #endif
456 #ifdef MAX_LOG_SECTOR_SIZE
457 block_size_mult = disk_sector_multiplier;
458 #endif
460 current_cmd.tag = cbw->tag;
461 current_cmd.lun = lun;
463 switch (cbw->command_block[0]) {
464 case SCSI_TEST_UNIT_READY:
465 logf("scsi test_unit_ready %d",lun);
466 if(lun_present) {
467 send_csw(UMS_STATUS_GOOD);
469 else {
470 send_csw(UMS_STATUS_FAIL);
471 cur_sense_data.sense_key=SENSE_NOT_READY;
472 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
474 break;
476 case SCSI_REPORT_LUNS: {
477 logf("scsi inquiry %d",lun);
478 int allocation_length=0;
479 allocation_length|=(cbw->command_block[6]<<24);
480 allocation_length|=(cbw->command_block[7]<<16);
481 allocation_length|=(cbw->command_block[8]<<8);
482 allocation_length|=(cbw->command_block[9]);
483 memset(lun_data,0,sizeof(struct report_lun_data));
484 #ifdef HAVE_HOTSWAP
485 lun_data->lun_list_length=htobe32(16);
486 lun_data->lun1[1]=1;
487 #else
488 lun_data->lun_list_length=htobe32(8);
489 #endif
490 lun_data->lun0[1]=0;
492 send_command_result(lun_data, MIN(sizeof(struct report_lun_data), length));
493 break;
496 case SCSI_INQUIRY:
497 logf("scsi inquiry %d",lun);
498 identify2inquiry(lun);
499 length = MIN(length, cbw->command_block[4]);
500 send_command_result(inquiry, MIN(sizeof(struct inquiry_data), length));
501 break;
503 case SCSI_REQUEST_SENSE: {
504 sense_data->ResponseCode=0x70;/*current error*/
505 sense_data->filemark_eom_ili_sensekey=cur_sense_data.sense_key&0x0f;
506 sense_data->Information=cur_sense_data.information;
507 sense_data->AdditionalSenseLength=10;
508 sense_data->CommandSpecificInformation=0;
509 sense_data->AdditionalSenseCode=cur_sense_data.asc;
510 sense_data->AdditionalSenseCodeQualifier=0;
511 sense_data->FieldReplaceableUnitCode=0;
512 sense_data->SKSV=0;
513 sense_data->SenseKeySpecific=0;
514 logf("scsi request_sense %d",lun);
515 send_command_result(sense_data, sizeof(struct sense_data));
516 break;
519 case SCSI_MODE_SENSE_10: {
520 if(! lun_present) {
521 usb_drv_stall(EP_MASS_STORAGE, true,true);
522 send_csw(UMS_STATUS_FAIL);
523 cur_sense_data.sense_key=SENSE_NOT_READY;
524 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
525 break;
527 /*unsigned char pc = (cbw->command_block[2] & 0xc0) >>6;*/
528 unsigned char page_code = cbw->command_block[2] & 0x3f;
529 logf("scsi mode_sense_10 %d %X",lun,page_code);
530 switch(page_code) {
531 case 0x3f:
532 mode_sense_data_10->mode_data_length=0;
533 mode_sense_data_10->medium_type=0;
534 mode_sense_data_10->device_specific=0;
535 mode_sense_data_10->block_descriptor_length=0;
536 send_command_result(mode_sense_data_10,
537 MIN(sizeof(struct mode_sense_header_10), length));
538 break;
539 default:
540 usb_drv_stall(EP_MASS_STORAGE, true,true);
541 send_csw(UMS_STATUS_FAIL);
542 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
543 cur_sense_data.asc=ASC_INVALID_FIELD_IN_CBD;
544 break;
546 break;
548 case SCSI_MODE_SENSE_6: {
549 if(! lun_present) {
550 usb_drv_stall(EP_MASS_STORAGE, true,true);
551 send_csw(UMS_STATUS_FAIL);
552 cur_sense_data.sense_key=SENSE_NOT_READY;
553 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
554 break;
556 /*unsigned char pc = (cbw->command_block[2] & 0xc0) >>6;*/
557 unsigned char page_code = cbw->command_block[2] & 0x3f;
558 logf("scsi mode_sense_6 %d %X",lun,page_code);
559 switch(page_code) {
560 case 0x3f:
561 /* All supported pages Since we support only one this is easy*/
562 mode_sense_data_6->mode_data_length=0;
563 mode_sense_data_6->medium_type=0;
564 mode_sense_data_6->device_specific=0;
565 mode_sense_data_6->block_descriptor_length=0;
566 send_command_result(mode_sense_data_6,
567 MIN(sizeof(struct mode_sense_header_6), length));
568 break;
569 /* TODO : windows does 1A, Power Condition. Do we need that ? */
570 default:
571 usb_drv_stall(EP_MASS_STORAGE, true,true);
572 send_csw(UMS_STATUS_FAIL);
573 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
574 cur_sense_data.asc=ASC_INVALID_FIELD_IN_CBD;
575 break;
577 break;
580 case SCSI_START_STOP_UNIT:
581 logf("scsi start_stop unit %d",lun);
582 send_csw(UMS_STATUS_GOOD);
583 break;
585 case SCSI_ALLOW_MEDIUM_REMOVAL:
586 logf("scsi allow_medium_removal %d",lun);
587 /* TODO: use this to show the connect screen ? */
588 send_csw(UMS_STATUS_GOOD);
589 break;
590 case SCSI_READ_FORMAT_CAPACITY: {
591 logf("scsi read_format_capacity %d",lun);
592 if(lun_present) {
593 format_capacity_data->following_length=htobe32(8);
594 /* Careful: "block count" actually means "number of last block" */
595 format_capacity_data->block_count = htobe32(block_count/block_size_mult - 1);
596 format_capacity_data->block_size = htobe32(block_size*block_size_mult);
597 format_capacity_data->block_size |= SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA;
599 send_command_result(format_capacity_data,
600 MIN(sizeof(struct format_capacity), length));
602 else
604 usb_drv_stall(EP_MASS_STORAGE, true,true);
605 send_csw(UMS_STATUS_FAIL);
606 cur_sense_data.sense_key=SENSE_NOT_READY;
607 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
609 break;
611 case SCSI_READ_CAPACITY: {
612 logf("scsi read_capacity %d",lun);
614 if(lun_present) {
615 /* Careful: "block count" actually means "number of last block" */
616 capacity_data->block_count = htobe32(block_count/block_size_mult - 1);
617 capacity_data->block_size = htobe32(block_size*block_size_mult);
619 send_command_result(capacity_data, MIN(sizeof(struct capacity), length));
621 else
623 usb_drv_stall(EP_MASS_STORAGE, true,true);
624 send_csw(UMS_STATUS_FAIL);
625 cur_sense_data.sense_key=SENSE_NOT_READY;
626 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
628 break;
631 case SCSI_READ_10:
632 logf("scsi read10 %d",lun);
633 if(! lun_present) {
634 usb_drv_stall(EP_MASS_STORAGE, true,true);
635 send_csw(UMS_STATUS_FAIL);
636 cur_sense_data.sense_key=SENSE_NOT_READY;
637 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
638 break;
640 current_cmd.data[0] = transfer_buffer;
641 current_cmd.data[1] = &transfer_buffer[BUFFER_SIZE];
642 current_cmd.data_select=0;
643 current_cmd.sector = block_size_mult *
644 (cbw->command_block[2] << 24 |
645 cbw->command_block[3] << 16 |
646 cbw->command_block[4] << 8 |
647 cbw->command_block[5] );
648 current_cmd.count = block_size_mult *
649 (cbw->command_block[7] << 16 |
650 cbw->command_block[8]);
652 //logf("scsi read %d %d", current_cmd.sector, current_cmd.count);
654 if((current_cmd.sector + current_cmd.count) > block_count) {
655 usb_drv_stall(EP_MASS_STORAGE, true,true);
656 send_csw(UMS_STATUS_FAIL);
657 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
658 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
660 else {
661 current_cmd.last_result = ata_read_sectors(IF_MV2(current_cmd.lun,) current_cmd.sector,
662 MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count),
663 current_cmd.data[current_cmd.data_select]);
664 send_and_read_next();
666 break;
668 case SCSI_WRITE_10:
669 logf("scsi write10 %d",lun);
670 if(! lun_present) {
671 usb_drv_stall(EP_MASS_STORAGE, true,true);
672 send_csw(UMS_STATUS_FAIL);
673 cur_sense_data.sense_key=SENSE_NOT_READY;
674 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
675 break;
677 current_cmd.data[0] = transfer_buffer;
678 current_cmd.data[1] = &transfer_buffer[BUFFER_SIZE];
679 current_cmd.data_select=0;
680 current_cmd.sector = block_size_mult *
681 (cbw->command_block[2] << 24 |
682 cbw->command_block[3] << 16 |
683 cbw->command_block[4] << 8 |
684 cbw->command_block[5] );
685 current_cmd.count = block_size_mult *
686 (cbw->command_block[7] << 16 |
687 cbw->command_block[8]);
688 /* expect data */
689 if((current_cmd.sector + current_cmd.count) > block_count) {
690 usb_drv_stall(EP_MASS_STORAGE, true,true);
691 send_csw(UMS_STATUS_FAIL);
692 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
693 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
695 else {
696 receive_block_data(current_cmd.data[0],
697 MIN(BUFFER_SIZE,current_cmd.count*SECTOR_SIZE));
700 break;
702 default:
703 logf("scsi unknown cmd %x",cbw->command_block[0x0]);
704 usb_drv_stall(EP_MASS_STORAGE, true,true);
705 send_csw(UMS_STATUS_FAIL);
706 break;
710 static void send_block_data(void *data,int size)
712 usb_drv_send_nonblocking(EP_MASS_STORAGE, data,size);
713 state = SENDING_BLOCKS;
716 static void send_command_result(void *data,int size)
718 usb_drv_send_nonblocking(EP_MASS_STORAGE, data,size);
719 state = SENDING_RESULT;
722 static void receive_block_data(void *data,int size)
724 usb_drv_recv(EP_MASS_STORAGE, data, size);
725 state = RECEIVING_BLOCKS;
728 static void send_csw(int status)
730 csw->signature = htole32(CSW_SIGNATURE);
731 csw->tag = current_cmd.tag;
732 csw->data_residue = 0;
733 csw->status = status;
735 usb_drv_send_nonblocking(EP_MASS_STORAGE, csw, sizeof(struct command_status_wrapper));
736 state = SENDING_CSW;
737 //logf("CSW: %X",status);
739 if(status == UMS_STATUS_GOOD) {
740 cur_sense_data.sense_key=0;
741 cur_sense_data.information=0;
742 cur_sense_data.asc=0;
746 /* convert ATA IDENTIFY to SCSI INQUIRY */
747 static void identify2inquiry(int lun)
749 #ifdef HAVE_FLASH_STORAGE
750 if(lun==0) {
751 memcpy(&inquiry->VendorId,"Rockbox ",8);
752 memcpy(&inquiry->ProductId,"Internal Storage",16);
753 memcpy(&inquiry->ProductRevisionLevel,"0.00",4);
755 else {
756 memcpy(&inquiry->VendorId,"Rockbox ",8);
757 memcpy(&inquiry->ProductId,"SD Card Slot ",16);
758 memcpy(&inquiry->ProductRevisionLevel,"0.00",4);
760 #else
761 unsigned int i;
762 unsigned short* dest;
763 unsigned short* src;
764 unsigned short* identify = ata_get_identify();
765 (void)lun;
766 memset(inquiry, 0, sizeof(struct inquiry_data));
768 if (identify[82] & 4)
769 inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
771 /* ATA only has a 'model' field, so we copy the
772 first 8 bytes to 'vendor' and the rest to 'product' (they are
773 consecutive in the inquiry struct) */
774 src = (unsigned short*)&identify[27];
775 dest = (unsigned short*)&inquiry->VendorId;
776 for (i=0;i<12;i++)
777 dest[i] = htobe16(src[i]);
779 src = (unsigned short*)&identify[23];
780 dest = (unsigned short*)&inquiry->ProductRevisionLevel;
781 for (i=0;i<2;i++)
782 dest[i] = htobe16(src[i]);
783 #endif
785 inquiry->DeviceType = DIRECT_ACCESS_DEVICE;
786 inquiry->AdditionalLength = 0x1f;
787 inquiry->Versions = 4; /* SPC-2 */
788 inquiry->Format = 2; /* SPC-2/3 inquiry format */
790 #ifdef HAVE_HOTSWAP
791 if(lun>0)
792 inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
793 #endif
797 #endif /* USB_STORAGE */