MODE SENSE output data length field has to be the length of the response excluding...
[kugel-rb.git] / firmware / usbstack / usb_storage.c
blobf1029c3c93d75b0a32cb4051d30490b19002a55c
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);
222 static bool ejected[NUM_VOLUMES];
224 static enum {
225 WAITING_FOR_COMMAND,
226 SENDING_BLOCKS,
227 SENDING_RESULT,
228 RECEIVING_BLOCKS,
229 SENDING_CSW
230 } state = WAITING_FOR_COMMAND;
232 /* called by usb_code_init() */
233 void usb_storage_init(void)
235 int i;
236 for(i=0;i<NUM_VOLUMES;i++)
237 ejected[i]=false;
238 logf("usb_storage_init done");
241 /* called by usb_core_transfer_complete() */
242 void usb_storage_transfer_complete(bool in,int status,int length)
244 struct command_block_wrapper* cbw = (void*)tb.transfer_buffer;
246 //logf("transfer result %X %d", status, length);
247 switch(state) {
248 case RECEIVING_BLOCKS:
249 if(in==true) {
250 logf("IN received in RECEIVING");
252 logf("scsi write %d %d", current_cmd.sector, current_cmd.count);
253 if(status==0) {
254 if((unsigned int)length!=(SECTOR_SIZE*current_cmd.count)
255 && (unsigned int)length!=BUFFER_SIZE) {
256 logf("unexpected length :%d",length);
259 unsigned int next_sector = current_cmd.sector + (BUFFER_SIZE/SECTOR_SIZE);
260 unsigned int next_count = current_cmd.count - MIN(current_cmd.count,BUFFER_SIZE/SECTOR_SIZE);
262 if(next_count!=0) {
263 /* Ask the host to send more, to the other buffer */
264 receive_block_data(current_cmd.data[!current_cmd.data_select],
265 MIN(BUFFER_SIZE,next_count*SECTOR_SIZE));
268 /* Now write the data that just came in, while the host is sending the next bit */
269 int result = ata_write_sectors(IF_MV2(current_cmd.lun,)
270 current_cmd.sector, MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count),
271 current_cmd.data[current_cmd.data_select]);
272 if(result != 0) {
273 send_csw(UMS_STATUS_FAIL);
274 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR;
275 cur_sense_data.asc=ASC_WRITE_ERROR;
276 cur_sense_data.ascq=0;
277 break;
280 if(next_count==0) {
281 send_csw(UMS_STATUS_GOOD);
284 /* Switch buffers for the next one */
285 current_cmd.data_select=!current_cmd.data_select;
287 current_cmd.sector = next_sector;
288 current_cmd.count = next_count;
291 else {
292 logf("Transfer failed %X",status);
293 send_csw(UMS_STATUS_FAIL);
294 /* TODO fill in cur_sense_data */
295 cur_sense_data.sense_key=0;
296 cur_sense_data.information=0;
297 cur_sense_data.asc=0;
298 cur_sense_data.ascq=0;
300 break;
301 case WAITING_FOR_COMMAND:
302 if(in==true) {
303 logf("IN received in WAITING_FOR_COMMAND");
305 //logf("command received");
306 if(letoh32(cbw->signature) == CBW_SIGNATURE){
307 handle_scsi(cbw);
309 else {
310 usb_drv_stall(EP_MASS_STORAGE, true,true);
311 usb_drv_stall(EP_MASS_STORAGE, true,false);
313 break;
314 case SENDING_CSW:
315 if(in==false) {
316 logf("OUT received in SENDING_CSW");
318 //logf("csw sent, now go back to idle");
319 state = WAITING_FOR_COMMAND;
320 usb_drv_recv(EP_MASS_STORAGE, tb.transfer_buffer, 1024);
321 break;
322 case SENDING_RESULT:
323 if(in==false) {
324 logf("OUT received in SENDING");
326 if(status==0) {
327 //logf("data sent, now send csw");
328 send_csw(UMS_STATUS_GOOD);
330 else {
331 logf("Transfer failed %X",status);
332 send_csw(UMS_STATUS_FAIL);
333 /* TODO fill in cur_sense_data */
334 cur_sense_data.sense_key=0;
335 cur_sense_data.information=0;
336 cur_sense_data.asc=0;
337 cur_sense_data.ascq=0;
339 break;
340 case SENDING_BLOCKS:
341 if(in==false) {
342 logf("OUT received in SENDING");
344 if(status==0) {
345 if(current_cmd.count==0) {
346 //logf("data sent, now send csw");
347 send_csw(UMS_STATUS_GOOD);
349 else {
350 send_and_read_next();
353 else {
354 logf("Transfer failed %X",status);
355 send_csw(UMS_STATUS_FAIL);
356 /* TODO fill in cur_sense_data */
357 cur_sense_data.sense_key=0;
358 cur_sense_data.information=0;
359 cur_sense_data.asc=0;
360 cur_sense_data.ascq=0;
362 break;
366 /* called by usb_core_control_request() */
367 bool usb_storage_control_request(struct usb_ctrlrequest* req)
369 bool handled = false;
371 switch (req->bRequest) {
372 case USB_BULK_GET_MAX_LUN: {
373 #ifdef ONLY_EXPOSE_CARD_SLOT
374 *tb.max_lun = 0;
375 #else
376 *tb.max_lun = NUM_VOLUMES - 1;
377 #endif
378 logf("ums: getmaxlun");
379 usb_drv_send(EP_CONTROL, UNCACHED_ADDR(tb.max_lun), 1);
380 usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */
381 handled = true;
382 break;
385 case USB_BULK_RESET_REQUEST:
386 logf("ums: bulk reset");
387 state = WAITING_FOR_COMMAND;
388 /* 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
390 * Mass Storage Reset. */
391 #if 0
392 usb_drv_reset_endpoint(EP_MASS_STORAGE, false);
393 usb_drv_reset_endpoint(EP_MASS_STORAGE, true);
394 #endif
396 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */
397 handled = true;
398 break;
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;
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;
416 return handled;
419 static void send_and_read_next(void)
421 if(current_cmd.last_result!=0) {
422 /* The last read failed. */
423 send_csw(UMS_STATUS_FAIL);
424 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR;
425 cur_sense_data.asc=ASC_READ_ERROR;
426 cur_sense_data.ascq=0;
427 return;
429 send_block_data(current_cmd.data[current_cmd.data_select],
430 MIN(BUFFER_SIZE,current_cmd.count*SECTOR_SIZE));
432 /* Switch buffers for the next one */
433 current_cmd.data_select=!current_cmd.data_select;
435 current_cmd.sector+=(BUFFER_SIZE/SECTOR_SIZE);
436 current_cmd.count-=MIN(current_cmd.count,BUFFER_SIZE/SECTOR_SIZE);
438 if(current_cmd.count!=0){
439 /* already read the next bit, so we can send it out immediately when the
440 * current transfer completes. */
441 current_cmd.last_result = ata_read_sectors(IF_MV2(current_cmd.lun,) current_cmd.sector,
442 MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count),
443 current_cmd.data[current_cmd.data_select]);
446 /****************************************************************************/
448 static void handle_scsi(struct command_block_wrapper* cbw)
450 /* USB Mass Storage assumes LBA capability.
451 TODO: support 48-bit LBA */
453 unsigned int length = cbw->data_transfer_length;
454 unsigned int block_size;
455 unsigned int block_count;
456 bool lun_present=true;
457 #ifdef ONLY_EXPOSE_CARD_SLOT
458 unsigned char lun = cbw->lun+1;
459 #else
460 unsigned char lun = cbw->lun;
461 #endif
462 unsigned int block_size_mult = 1;
463 #ifdef HAVE_HOTSWAP
464 tCardInfo* cinfo = card_get_info(lun);
465 if(cinfo->initialized==1 && cinfo->numblocks > 0) {
466 block_size = cinfo->blocksize;
467 block_count = cinfo->numblocks;
469 else {
470 lun_present=false;
471 block_size = 0;
472 block_count = 0;
474 #else
475 unsigned short* identify = ata_get_identify();
476 block_size = SECTOR_SIZE;
477 block_count = (identify[61] << 16 | identify[60]);
478 #endif
480 if(ejected[lun])
481 lun_present = false;
483 #ifdef MAX_LOG_SECTOR_SIZE
484 block_size_mult = disk_sector_multiplier;
485 #endif
487 current_cmd.tag = cbw->tag;
488 current_cmd.lun = lun;
490 switch (cbw->command_block[0]) {
491 case SCSI_TEST_UNIT_READY:
492 logf("scsi test_unit_ready %d",lun);
493 if(!usb_exclusive_ata()) {
494 send_csw(UMS_STATUS_FAIL);
495 cur_sense_data.sense_key=SENSE_NOT_READY;
496 cur_sense_data.asc=ASC_NOT_READY;
497 cur_sense_data.ascq=ASCQ_BECOMING_READY;
498 break;
500 if(lun_present) {
501 send_csw(UMS_STATUS_GOOD);
503 else {
504 send_csw(UMS_STATUS_FAIL);
505 cur_sense_data.sense_key=SENSE_NOT_READY;
506 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
507 cur_sense_data.ascq=0;
509 break;
511 case SCSI_REPORT_LUNS: {
512 logf("scsi inquiry %d",lun);
513 int allocation_length=0;
514 allocation_length|=(cbw->command_block[6]<<24);
515 allocation_length|=(cbw->command_block[7]<<16);
516 allocation_length|=(cbw->command_block[8]<<8);
517 allocation_length|=(cbw->command_block[9]);
518 memset(tb.lun_data,0,sizeof(struct report_lun_data));
519 #ifdef HAVE_HOTSWAP
520 tb.lun_data->lun_list_length=htobe32(16);
521 tb.lun_data->lun1[1]=1;
522 #else
523 tb.lun_data->lun_list_length=htobe32(8);
524 #endif
525 tb.lun_data->lun0[1]=0;
527 send_command_result(tb.lun_data, MIN(sizeof(struct report_lun_data), length));
528 break;
531 case SCSI_INQUIRY:
532 logf("scsi inquiry %d",lun);
533 identify2inquiry(lun);
534 length = MIN(length, cbw->command_block[4]);
535 send_command_result(tb.inquiry, MIN(sizeof(struct inquiry_data), length));
536 break;
538 case SCSI_REQUEST_SENSE: {
539 tb.sense_data->ResponseCode=0x70;/*current error*/
540 tb.sense_data->filemark_eom_ili_sensekey=cur_sense_data.sense_key&0x0f;
541 tb.sense_data->Information=cur_sense_data.information;
542 tb.sense_data->AdditionalSenseLength=10;
543 tb.sense_data->CommandSpecificInformation=0;
544 tb.sense_data->AdditionalSenseCode=cur_sense_data.asc;
545 tb.sense_data->AdditionalSenseCodeQualifier=cur_sense_data.ascq;
546 tb.sense_data->FieldReplaceableUnitCode=0;
547 tb.sense_data->SKSV=0;
548 tb.sense_data->SenseKeySpecific=0;
549 logf("scsi request_sense %d",lun);
550 send_command_result(tb.sense_data, sizeof(struct sense_data));
551 break;
554 case SCSI_MODE_SENSE_10: {
555 if(! lun_present) {
556 send_csw(UMS_STATUS_FAIL);
557 cur_sense_data.sense_key=SENSE_NOT_READY;
558 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
559 cur_sense_data.ascq=0;
560 break;
562 /*unsigned char pc = (cbw->command_block[2] & 0xc0) >>6;*/
563 unsigned char page_code = cbw->command_block[2] & 0x3f;
564 logf("scsi mode_sense_10 %d %X",lun,page_code);
565 switch(page_code) {
566 case 0x3f:
567 tb.mode_sense_data_10->mode_data_length=htobe16(sizeof(struct mode_sense_data_10)-2);
568 tb.mode_sense_data_10->medium_type=0;
569 tb.mode_sense_data_10->device_specific=0;
570 tb.mode_sense_data_10->reserved=0;
571 tb.mode_sense_data_10->longlba=1;
572 tb.mode_sense_data_10->block_descriptor_length=htobe16(sizeof(struct mode_sense_block_descriptor_longlba));
573 memset(tb.mode_sense_data_10->block_descriptor.reserved,0,4);
574 memset(tb.mode_sense_data_10->block_descriptor.number_of_blocks,0,8);
575 tb.mode_sense_data_10->block_descriptor.number_of_blocks[4]=((block_count/block_size_mult) & 0xff000000)>>24;
576 tb.mode_sense_data_10->block_descriptor.number_of_blocks[5]=((block_count/block_size_mult) & 0x00ff0000)>>16;
577 tb.mode_sense_data_10->block_descriptor.number_of_blocks[6]=((block_count/block_size_mult) & 0x0000ff00)>>8;
578 tb.mode_sense_data_10->block_descriptor.number_of_blocks[7]=((block_count/block_size_mult) & 0x000000ff);
580 tb.mode_sense_data_10->block_descriptor.block_size[0]=((block_size*block_size_mult) & 0xff000000)>>24;
581 tb.mode_sense_data_10->block_descriptor.block_size[1]=((block_size*block_size_mult) & 0x00ff0000)>>16;
582 tb.mode_sense_data_10->block_descriptor.block_size[2]=((block_size*block_size_mult) & 0x0000ff00)>>8;
583 tb.mode_sense_data_10->block_descriptor.block_size[3]=((block_size*block_size_mult) & 0x000000ff);
584 send_command_result(tb.mode_sense_data_10,
585 MIN(sizeof(struct mode_sense_data_10), length));
586 break;
587 default:
588 send_csw(UMS_STATUS_FAIL);
589 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
590 cur_sense_data.asc=ASC_INVALID_FIELD_IN_CBD;
591 cur_sense_data.ascq=0;
592 break;
594 break;
596 case SCSI_MODE_SENSE_6: {
597 if(! lun_present) {
598 send_csw(UMS_STATUS_FAIL);
599 cur_sense_data.sense_key=SENSE_NOT_READY;
600 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
601 cur_sense_data.ascq=0;
602 break;
604 /*unsigned char pc = (cbw->command_block[2] & 0xc0) >>6;*/
605 unsigned char page_code = cbw->command_block[2] & 0x3f;
606 logf("scsi mode_sense_6 %d %X",lun,page_code);
607 switch(page_code) {
608 case 0x3f:
609 /* All supported pages Since we support only one this is easy*/
610 tb.mode_sense_data_6->mode_data_length=sizeof(struct mode_sense_data_6)-1;
611 tb.mode_sense_data_6->medium_type=0;
612 tb.mode_sense_data_6->device_specific=0;
613 tb.mode_sense_data_6->block_descriptor_length=sizeof(struct mode_sense_block_descriptor_shortlba);
614 tb.mode_sense_data_6->block_descriptor.density_code=0;
615 tb.mode_sense_data_6->block_descriptor.reserved=0;
616 if(block_count/block_size_mult > 0xffffff){
617 tb.mode_sense_data_6->block_descriptor.number_of_blocks[0]=0xff;
618 tb.mode_sense_data_6->block_descriptor.number_of_blocks[1]=0xff;
619 tb.mode_sense_data_6->block_descriptor.number_of_blocks[2]=0xff;
621 else {
622 tb.mode_sense_data_6->block_descriptor.number_of_blocks[0]=((block_count/block_size_mult) & 0xff0000)>>16;
623 tb.mode_sense_data_6->block_descriptor.number_of_blocks[1]=((block_count/block_size_mult) & 0x00ff00)>>8;
624 tb.mode_sense_data_6->block_descriptor.number_of_blocks[2]=((block_count/block_size_mult) & 0x0000ff);
626 tb.mode_sense_data_6->block_descriptor.block_size[0]=((block_size*block_size_mult) & 0xff0000)>>16;
627 tb.mode_sense_data_6->block_descriptor.block_size[1]=((block_size*block_size_mult) & 0x00ff00)>>8;
628 tb.mode_sense_data_6->block_descriptor.block_size[2]=((block_size*block_size_mult) & 0x0000ff);
629 send_command_result(tb.mode_sense_data_6,
630 MIN(sizeof(struct mode_sense_data_6), length));
631 break;
632 default:
633 send_csw(UMS_STATUS_FAIL);
634 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
635 cur_sense_data.asc=ASC_INVALID_FIELD_IN_CBD;
636 cur_sense_data.ascq=0;
637 break;
639 break;
642 case SCSI_START_STOP_UNIT:
643 logf("scsi start_stop unit %d",lun);
644 if((cbw->command_block[4] & 0xf0) == 0) /* Process start and eject bits */
646 if((cbw->command_block[4] & 0x01) == 0 &&
647 (cbw->command_block[4] & 0x02) != 0) /* Stop and eject */
649 ejected[lun]=true;
652 send_csw(UMS_STATUS_GOOD);
653 break;
655 case SCSI_ALLOW_MEDIUM_REMOVAL:
656 logf("scsi allow_medium_removal %d",lun);
657 /* TODO: use this to show the connect screen ? */
658 send_csw(UMS_STATUS_GOOD);
659 break;
660 case SCSI_READ_FORMAT_CAPACITY: {
661 logf("scsi read_format_capacity %d",lun);
662 if(lun_present) {
663 tb.format_capacity_data->following_length=htobe32(8);
664 /* Careful: "block count" actually means "number of last block" */
665 tb.format_capacity_data->block_count = htobe32(block_count/block_size_mult - 1);
666 tb.format_capacity_data->block_size = htobe32(block_size*block_size_mult);
667 tb.format_capacity_data->block_size |= SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA;
669 send_command_result(tb.format_capacity_data,
670 MIN(sizeof(struct format_capacity), length));
672 else
674 send_csw(UMS_STATUS_FAIL);
675 cur_sense_data.sense_key=SENSE_NOT_READY;
676 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
677 cur_sense_data.ascq=0;
679 break;
681 case SCSI_READ_CAPACITY: {
682 logf("scsi read_capacity %d",lun);
684 if(lun_present) {
685 /* Careful: "block count" actually means "number of last block" */
686 tb.capacity_data->block_count = htobe32(block_count/block_size_mult - 1);
687 tb.capacity_data->block_size = htobe32(block_size*block_size_mult);
689 send_command_result(tb.capacity_data, MIN(sizeof(struct capacity), length));
691 else
693 send_csw(UMS_STATUS_FAIL);
694 cur_sense_data.sense_key=SENSE_NOT_READY;
695 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
696 cur_sense_data.ascq=0;
698 break;
701 case SCSI_READ_10:
702 logf("scsi read10 %d",lun);
703 if(! lun_present) {
704 send_csw(UMS_STATUS_FAIL);
705 cur_sense_data.sense_key=SENSE_NOT_READY;
706 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
707 cur_sense_data.ascq=0;
708 break;
710 current_cmd.data[0] = tb.transfer_buffer;
711 current_cmd.data[1] = &tb.transfer_buffer[BUFFER_SIZE];
712 current_cmd.data_select=0;
713 current_cmd.sector = block_size_mult *
714 (cbw->command_block[2] << 24 |
715 cbw->command_block[3] << 16 |
716 cbw->command_block[4] << 8 |
717 cbw->command_block[5] );
718 current_cmd.count = block_size_mult *
719 (cbw->command_block[7] << 8 |
720 cbw->command_block[8]);
722 //logf("scsi read %d %d", current_cmd.sector, current_cmd.count);
724 if((current_cmd.sector + current_cmd.count) > block_count) {
725 send_csw(UMS_STATUS_FAIL);
726 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
727 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
728 cur_sense_data.ascq=0;
730 else {
731 current_cmd.last_result = ata_read_sectors(IF_MV2(current_cmd.lun,) current_cmd.sector,
732 MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count),
733 current_cmd.data[current_cmd.data_select]);
734 send_and_read_next();
736 break;
738 case SCSI_WRITE_10:
739 logf("scsi write10 %d",lun);
740 if(! lun_present) {
741 send_csw(UMS_STATUS_FAIL);
742 cur_sense_data.sense_key=SENSE_NOT_READY;
743 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
744 cur_sense_data.ascq=0;
745 break;
747 current_cmd.data[0] = tb.transfer_buffer;
748 current_cmd.data[1] = &tb.transfer_buffer[BUFFER_SIZE];
749 current_cmd.data_select=0;
750 current_cmd.sector = block_size_mult *
751 (cbw->command_block[2] << 24 |
752 cbw->command_block[3] << 16 |
753 cbw->command_block[4] << 8 |
754 cbw->command_block[5] );
755 current_cmd.count = block_size_mult *
756 (cbw->command_block[7] << 8 |
757 cbw->command_block[8]);
758 /* expect data */
759 if((current_cmd.sector + current_cmd.count) > block_count) {
760 send_csw(UMS_STATUS_FAIL);
761 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
762 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
763 cur_sense_data.ascq=0;
765 else {
766 receive_block_data(current_cmd.data[0],
767 MIN(BUFFER_SIZE,current_cmd.count*SECTOR_SIZE));
770 break;
772 default:
773 logf("scsi unknown cmd %x",cbw->command_block[0x0]);
774 usb_drv_stall(EP_MASS_STORAGE, true,true);
775 send_csw(UMS_STATUS_FAIL);
776 break;
780 static void send_block_data(void *data,int size)
782 usb_drv_send_nonblocking(EP_MASS_STORAGE, data,size);
783 state = SENDING_BLOCKS;
786 static void send_command_result(void *data,int size)
788 usb_drv_send_nonblocking(EP_MASS_STORAGE, data,size);
789 state = SENDING_RESULT;
792 static void receive_block_data(void *data,int size)
794 usb_drv_recv(EP_MASS_STORAGE, data, size);
795 state = RECEIVING_BLOCKS;
798 static void send_csw(int status)
800 tb.csw->signature = htole32(CSW_SIGNATURE);
801 tb.csw->tag = current_cmd.tag;
802 tb.csw->data_residue = 0;
803 tb.csw->status = status;
805 usb_drv_send_nonblocking(EP_MASS_STORAGE, tb.csw, sizeof(struct command_status_wrapper));
806 state = SENDING_CSW;
807 //logf("CSW: %X",status);
809 if(status == UMS_STATUS_GOOD) {
810 cur_sense_data.sense_key=0;
811 cur_sense_data.information=0;
812 cur_sense_data.asc=0;
813 cur_sense_data.ascq=0;
817 /* convert ATA IDENTIFY to SCSI INQUIRY */
818 static void identify2inquiry(int lun)
820 #ifdef HAVE_FLASH_STORAGE
821 if(lun==0) {
822 memcpy(&tb.inquiry->VendorId,"Rockbox ",8);
823 memcpy(&tb.inquiry->ProductId,"Internal Storage",16);
824 memcpy(&tb.inquiry->ProductRevisionLevel,"0.00",4);
826 else {
827 memcpy(&tb.inquiry->VendorId,"Rockbox ",8);
828 memcpy(&tb.inquiry->ProductId,"SD Card Slot ",16);
829 memcpy(&tb.inquiry->ProductRevisionLevel,"0.00",4);
831 #else
832 unsigned int i;
833 unsigned short* dest;
834 unsigned short* src;
835 unsigned short* identify = ata_get_identify();
836 (void)lun;
837 memset(tb.inquiry, 0, sizeof(struct inquiry_data));
839 #if 0
840 if (identify[82] & 4)
841 tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
842 #endif
844 /* ATA only has a 'model' field, so we copy the
845 first 8 bytes to 'vendor' and the rest to 'product' (they are
846 consecutive in the inquiry struct) */
847 src = (unsigned short*)&identify[27];
848 dest = (unsigned short*)&tb.inquiry->VendorId;
849 for (i=0;i<12;i++)
850 dest[i] = htobe16(src[i]);
852 src = (unsigned short*)&identify[23];
853 dest = (unsigned short*)&tb.inquiry->ProductRevisionLevel;
854 for (i=0;i<2;i++)
855 dest[i] = htobe16(src[i]);
856 #endif
858 tb.inquiry->DeviceType = DIRECT_ACCESS_DEVICE;
859 tb.inquiry->AdditionalLength = 0x1f;
860 tb.inquiry->Versions = 4; /* SPC-2 */
861 tb.inquiry->Format = 2; /* SPC-2/3 inquiry format */
863 #if 0
864 #ifdef HAVE_HOTSWAP
865 if(lun>0)
866 tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
867 #endif
868 #endif
869 /* Mac OSX 10.5 doesn't like this driver if DEVICE_REMOVABLE is not set */
870 tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
873 #endif /* USB_STORAGE */