Colour targets: Revert an optimisation from almost 18 months ago that actually turned...
[Rockbox.git] / firmware / usbstack / usb_storage.c
blob3ee7acfab5c12b9c45b23961b2c5468554de741d
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2007 by Björn Stenberg
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
21 #include "string.h"
22 #include "system.h"
23 #include "usb_core.h"
24 #include "usb_drv.h"
25 //#define LOGF_ENABLE
26 #include "logf.h"
27 #include "ata.h"
28 #include "hotswap.h"
29 #include "disk.h"
30 /* Needed to get at the audio buffer */
31 #include "audio.h"
32 #include "usb_storage.h"
35 #ifdef USB_STORAGE
37 /* Enable the following define to export only the SD card slot. This
38 * is useful for USBCV MSC tests, as those are destructive.
39 * This won't work right if the device doesn't have a card slot.
41 //#define ONLY_EXPOSE_CARD_SLOT
43 #define SECTOR_SIZE 512
45 /* We can currently use up to 20k buffer size. More than that requires
46 * transfer chaining in the driver. Tests on sansa c200 show that the 16k
47 * limitation causes no more than 2% slowdown.
49 #define BUFFER_SIZE 16384
51 /* bulk-only class specific requests */
52 #define USB_BULK_RESET_REQUEST 0xff
53 #define USB_BULK_GET_MAX_LUN 0xfe
55 #define DIRECT_ACCESS_DEVICE 0x00 /* disks */
56 #define DEVICE_REMOVABLE 0x80
58 #define CBW_SIGNATURE 0x43425355
59 #define CSW_SIGNATURE 0x53425355
61 #define SCSI_TEST_UNIT_READY 0x00
62 #define SCSI_INQUIRY 0x12
63 #define SCSI_MODE_SENSE_6 0x1a
64 #define SCSI_MODE_SENSE_10 0x5a
65 #define SCSI_REQUEST_SENSE 0x03
66 #define SCSI_ALLOW_MEDIUM_REMOVAL 0x1e
67 #define SCSI_READ_CAPACITY 0x25
68 #define SCSI_READ_FORMAT_CAPACITY 0x23
69 #define SCSI_READ_10 0x28
70 #define SCSI_WRITE_10 0x2a
71 #define SCSI_START_STOP_UNIT 0x1b
72 #define SCSI_REPORT_LUNS 0xa0
74 #define UMS_STATUS_GOOD 0x00
75 #define UMS_STATUS_FAIL 0x01
77 #define SENSE_NOT_READY 0x02
78 #define SENSE_MEDIUM_ERROR 0x03
79 #define SENSE_ILLEGAL_REQUEST 0x05
80 #define SENSE_UNIT_ATTENTION 0x06
82 #define ASC_MEDIUM_NOT_PRESENT 0x3a
83 #define ASC_INVALID_FIELD_IN_CBD 0x24
84 #define ASC_LBA_OUT_OF_RANGE 0x21
85 #define ASC_WRITE_ERROR 0x0C
86 #define ASC_READ_ERROR 0x11
87 #define ASC_NOT_READY 0x04
88 #define ASCQ_BECOMING_READY 0x01
90 #define SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA 0x02000000
92 /* storage interface */
94 #define USB_SC_SCSI 0x06 /* Transparent */
95 #define USB_PROT_BULK 0x50 /* bulk only */
97 static struct usb_interface_descriptor __attribute__((aligned(2)))
98 interface_descriptor =
100 .bLength = sizeof(struct usb_interface_descriptor),
101 .bDescriptorType = USB_DT_INTERFACE,
102 .bInterfaceNumber = 0,
103 .bAlternateSetting = 0,
104 .bNumEndpoints = 2,
105 .bInterfaceClass = USB_CLASS_MASS_STORAGE,
106 .bInterfaceSubClass = USB_SC_SCSI,
107 .bInterfaceProtocol = USB_PROT_BULK,
108 .iInterface = 0
111 static struct usb_endpoint_descriptor __attribute__((aligned(2)))
112 endpoint_descriptor =
114 .bLength = sizeof(struct usb_endpoint_descriptor),
115 .bDescriptorType = USB_DT_ENDPOINT,
116 .bEndpointAddress = 0,
117 .bmAttributes = USB_ENDPOINT_XFER_BULK,
118 .wMaxPacketSize = 0,
119 .bInterval = 0
122 struct inquiry_data {
123 unsigned char DeviceType;
124 unsigned char DeviceTypeModifier;
125 unsigned char Versions;
126 unsigned char Format;
127 unsigned char AdditionalLength;
128 unsigned char Reserved[2];
129 unsigned char Capability;
130 unsigned char VendorId[8];
131 unsigned char ProductId[16];
132 unsigned char ProductRevisionLevel[4];
133 } __attribute__ ((packed));
135 struct report_lun_data {
136 unsigned int lun_list_length;
137 unsigned int reserved1;
138 unsigned char lun0[8];
139 #ifdef HAVE_HOTSWAP
140 unsigned char lun1[8];
141 #endif
142 } __attribute__ ((packed));
144 struct sense_data {
145 unsigned char ResponseCode;
146 unsigned char Obsolete;
147 unsigned char fei_sensekey;
148 unsigned int Information;
149 unsigned char AdditionalSenseLength;
150 unsigned int CommandSpecificInformation;
151 unsigned char AdditionalSenseCode;
152 unsigned char AdditionalSenseCodeQualifier;
153 unsigned char FieldReplaceableUnitCode;
154 unsigned char SKSV;
155 unsigned short SenseKeySpecific;
156 } __attribute__ ((packed));
158 struct mode_sense_bdesc_longlba {
159 unsigned char num_blocks[8];
160 unsigned char reserved[4];
161 unsigned char block_size[4];
162 } __attribute__ ((packed));
164 struct mode_sense_bdesc_shortlba {
165 unsigned char density_code;
166 unsigned char num_blocks[3];
167 unsigned char reserved;
168 unsigned char block_size[3];
169 } __attribute__ ((packed));
171 struct mode_sense_data_10 {
172 unsigned short mode_data_length;
173 unsigned char medium_type;
174 unsigned char device_specific;
175 unsigned char longlba;
176 unsigned char reserved;
177 unsigned short block_descriptor_length;
178 struct mode_sense_bdesc_longlba block_descriptor;
179 } __attribute__ ((packed));
181 struct mode_sense_data_6 {
182 unsigned char mode_data_length;
183 unsigned char medium_type;
184 unsigned char device_specific;
185 unsigned char block_descriptor_length;
186 struct mode_sense_bdesc_shortlba block_descriptor;
187 } __attribute__ ((packed));
189 struct command_block_wrapper {
190 unsigned int signature;
191 unsigned int tag;
192 unsigned int data_transfer_length;
193 unsigned char flags;
194 unsigned char lun;
195 unsigned char command_length;
196 unsigned char command_block[16];
197 } __attribute__ ((packed));
199 struct command_status_wrapper {
200 unsigned int signature;
201 unsigned int tag;
202 unsigned int data_residue;
203 unsigned char status;
204 } __attribute__ ((packed));
206 struct capacity {
207 unsigned int block_count;
208 unsigned int block_size;
209 } __attribute__ ((packed));
211 struct format_capacity {
212 unsigned int following_length;
213 unsigned int block_count;
214 unsigned int block_size;
215 } __attribute__ ((packed));
218 static union {
219 unsigned char* transfer_buffer;
220 struct inquiry_data* inquiry;
221 struct capacity* capacity_data;
222 struct format_capacity* format_capacity_data;
223 struct sense_data *sense_data;
224 struct mode_sense_data_6 *ms_data_6;
225 struct mode_sense_data_10 *ms_data_10;
226 struct report_lun_data *lun_data;
227 struct command_status_wrapper* csw;
228 char *max_lun;
229 } tb;
231 static struct {
232 unsigned int sector;
233 unsigned int count;
234 unsigned int tag;
235 unsigned int lun;
236 unsigned char *data[2];
237 unsigned char data_select;
238 unsigned int last_result;
239 } cur_cmd;
241 static struct {
242 unsigned char sense_key;
243 unsigned char information;
244 unsigned char asc;
245 unsigned char ascq;
246 } cur_sense_data;
248 static void handle_scsi(struct command_block_wrapper* cbw);
249 static void send_csw(int status);
250 static void send_command_result(void *data,int size);
251 static void send_command_failed_result(void);
252 static void send_block_data(void *data,int size);
253 static void receive_block_data(void *data,int size);
254 static void identify2inquiry(int lun);
255 static void send_and_read_next(void);
256 static bool ejected[NUM_VOLUMES];
258 static int usb_endpoint;
259 static int usb_interface;
261 static enum {
262 WAITING_FOR_COMMAND,
263 SENDING_BLOCKS,
264 SENDING_RESULT,
265 SENDING_FAILED_RESULT,
266 RECEIVING_BLOCKS,
267 SENDING_CSW
268 } state = WAITING_FOR_COMMAND;
270 static bool check_disk_present(IF_MV_NONVOID(int volume))
272 unsigned char sector[512];
273 return ata_read_sectors(IF_MV2(volume,)0,1,sector) == 0;
276 static void try_release_ata(void)
278 /* Check if there is a connected drive left. If not,
279 release excusive access */
280 bool canrelease=true;
281 int i;
282 for(i=0;i<NUM_VOLUMES;i++) {
283 if(ejected[i]==false){
284 canrelease=false;
285 break;
288 if(canrelease) {
289 logf("scsi release ata");
290 usb_release_exclusive_ata();
294 #ifdef HAVE_HOTSWAP
295 void usb_storage_notify_hotswap(int volume,bool inserted)
297 logf("notify %d",inserted);
298 if(inserted && check_disk_present(IF_MV(volume))) {
299 ejected[volume] = false;
301 else {
302 ejected[volume] = true;
303 try_release_ata();
307 #endif
309 void usb_storage_reconnect(void)
311 int i;
312 if(usb_core_driver_enabled(USB_DRIVER_MASS_STORAGE)
313 && usb_inserted()) {
314 for(i=0;i<NUM_VOLUMES;i++)
315 ejected[i] = !check_disk_present(IF_MV(i));
317 usb_request_exclusive_ata();
321 /* called by usb_code_init() */
322 void usb_storage_init(void)
324 int i;
325 for(i=0;i<NUM_VOLUMES;i++) {
326 ejected[i] = !check_disk_present(IF_MV(i));
328 logf("usb_storage_init done");
332 int usb_storage_set_first_endpoint(int endpoint)
334 usb_endpoint = endpoint;
335 return endpoint + 1;
337 int usb_storage_set_first_interface(int interface)
339 usb_interface = interface;
340 return interface + 1;
343 int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size)
345 endpoint_descriptor.wMaxPacketSize=max_packet_size;
346 interface_descriptor.bInterfaceNumber=usb_interface;
348 memcpy(dest,&interface_descriptor,
349 sizeof(struct usb_interface_descriptor));
350 dest+=sizeof(struct usb_interface_descriptor);
352 endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_IN;
353 memcpy(dest,&endpoint_descriptor,
354 sizeof(struct usb_endpoint_descriptor));
355 dest+=sizeof(struct usb_endpoint_descriptor);
357 endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_OUT;
358 memcpy(dest,&endpoint_descriptor,
359 sizeof(struct usb_endpoint_descriptor));
361 return sizeof(struct usb_interface_descriptor) +
362 2*sizeof(struct usb_endpoint_descriptor);
365 void usb_storage_init_connection(void)
367 logf("ums: set config");
368 /* prime rx endpoint. We only need room for commands */
369 state = WAITING_FOR_COMMAND;
371 #if CONFIG_CPU == IMX31L || CONFIG_USBOTG == USBOTG_ISP1583
372 static unsigned char _transfer_buffer[BUFFER_SIZE*2]
373 USBDEVBSS_ATTR __attribute__((aligned(32)));
374 tb.transfer_buffer = (void *)_transfer_buffer;
375 #else
376 /* TODO : check if bufsize is at least 32K ? */
377 size_t bufsize;
378 unsigned char * audio_buffer;
380 audio_buffer = audio_get_buffer(false,&bufsize);
381 tb.transfer_buffer =
382 (void *)UNCACHED_ADDR((unsigned int)(audio_buffer + 31) & 0xffffffe0);
383 invalidate_icache();
384 #endif
385 usb_drv_recv(usb_endpoint, tb.transfer_buffer, 1024);
388 /* called by usb_core_transfer_complete() */
389 void usb_storage_transfer_complete(int ep,bool in,int status,int length)
391 (void)ep;
392 struct command_block_wrapper* cbw = (void*)tb.transfer_buffer;
394 //logf("transfer result %X %d", status, length);
395 switch(state) {
396 case RECEIVING_BLOCKS:
397 if(in==true) {
398 logf("IN received in RECEIVING");
400 logf("scsi write %d %d", cur_cmd.sector, cur_cmd.count);
401 if(status==0) {
402 if((unsigned int)length!=(SECTOR_SIZE*cur_cmd.count)
403 && (unsigned int)length!=BUFFER_SIZE) {
404 logf("unexpected length :%d",length);
407 unsigned int next_sector = cur_cmd.sector +
408 (BUFFER_SIZE/SECTOR_SIZE);
409 unsigned int next_count = cur_cmd.count -
410 MIN(cur_cmd.count,BUFFER_SIZE/SECTOR_SIZE);
412 if(next_count!=0) {
413 /* Ask the host to send more, to the other buffer */
414 receive_block_data(cur_cmd.data[!cur_cmd.data_select],
415 MIN(BUFFER_SIZE,next_count*SECTOR_SIZE));
418 /* Now write the data that just came in, while the host is
419 sending the next bit */
420 int result = ata_write_sectors(IF_MV2(cur_cmd.lun,)
421 cur_cmd.sector,
422 MIN(BUFFER_SIZE/SECTOR_SIZE,
423 cur_cmd.count),
424 cur_cmd.data[cur_cmd.data_select]);
425 if(result != 0) {
426 send_csw(UMS_STATUS_FAIL);
427 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR;
428 cur_sense_data.asc=ASC_WRITE_ERROR;
429 cur_sense_data.ascq=0;
430 break;
433 if(next_count==0) {
434 send_csw(UMS_STATUS_GOOD);
437 /* Switch buffers for the next one */
438 cur_cmd.data_select=!cur_cmd.data_select;
440 cur_cmd.sector = next_sector;
441 cur_cmd.count = next_count;
444 else {
445 logf("Transfer failed %X",status);
446 send_csw(UMS_STATUS_FAIL);
447 /* TODO fill in cur_sense_data */
448 cur_sense_data.sense_key=0;
449 cur_sense_data.information=0;
450 cur_sense_data.asc=0;
451 cur_sense_data.ascq=0;
453 break;
454 case WAITING_FOR_COMMAND:
455 if(in==true) {
456 logf("IN received in WAITING_FOR_COMMAND");
458 //logf("command received");
459 if(letoh32(cbw->signature) == CBW_SIGNATURE){
460 handle_scsi(cbw);
462 else {
463 usb_drv_stall(usb_endpoint, true,true);
464 usb_drv_stall(usb_endpoint, true,false);
466 break;
467 case SENDING_CSW:
468 if(in==false) {
469 logf("OUT received in SENDING_CSW");
471 //logf("csw sent, now go back to idle");
472 state = WAITING_FOR_COMMAND;
473 usb_drv_recv(usb_endpoint, tb.transfer_buffer, 1024);
474 break;
475 case SENDING_RESULT:
476 if(in==false) {
477 logf("OUT received in SENDING");
479 if(status==0) {
480 //logf("data sent, now send csw");
481 send_csw(UMS_STATUS_GOOD);
483 else {
484 logf("Transfer failed %X",status);
485 send_csw(UMS_STATUS_FAIL);
486 /* TODO fill in cur_sense_data */
487 cur_sense_data.sense_key=0;
488 cur_sense_data.information=0;
489 cur_sense_data.asc=0;
490 cur_sense_data.ascq=0;
492 break;
493 case SENDING_FAILED_RESULT:
494 if(in==false) {
495 logf("OUT received in SENDING");
497 send_csw(UMS_STATUS_FAIL);
498 break;
499 case SENDING_BLOCKS:
500 if(in==false) {
501 logf("OUT received in SENDING");
503 if(status==0) {
504 if(cur_cmd.count==0) {
505 //logf("data sent, now send csw");
506 send_csw(UMS_STATUS_GOOD);
508 else {
509 send_and_read_next();
512 else {
513 logf("Transfer failed %X",status);
514 send_csw(UMS_STATUS_FAIL);
515 /* TODO fill in cur_sense_data */
516 cur_sense_data.sense_key=0;
517 cur_sense_data.information=0;
518 cur_sense_data.asc=0;
519 cur_sense_data.ascq=0;
521 break;
525 /* called by usb_core_control_request() */
526 bool usb_storage_control_request(struct usb_ctrlrequest* req)
528 bool handled = false;
531 switch (req->bRequest) {
532 case USB_BULK_GET_MAX_LUN: {
533 #ifdef ONLY_EXPOSE_CARD_SLOT
534 *tb.max_lun = 0;
535 #else
536 *tb.max_lun = NUM_VOLUMES - 1;
537 #endif
538 logf("ums: getmaxlun");
539 usb_drv_send(EP_CONTROL, tb.max_lun, 1);
540 usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */
541 handled = true;
542 break;
545 case USB_BULK_RESET_REQUEST:
546 logf("ums: bulk reset");
547 state = WAITING_FOR_COMMAND;
548 /* UMS BOT 3.1 says The device shall preserve the value of its bulk
549 data toggle bits and endpoint STALL conditions despite
550 the Bulk-Only Mass Storage Reset. */
551 #if 0
552 usb_drv_reset_endpoint(usb_endpoint, false);
553 usb_drv_reset_endpoint(usb_endpoint, true);
554 #endif
556 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */
557 handled = true;
558 break;
561 return handled;
564 static void send_and_read_next(void)
566 if(cur_cmd.last_result!=0) {
567 /* The last read failed. */
568 send_csw(UMS_STATUS_FAIL);
569 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR;
570 cur_sense_data.asc=ASC_READ_ERROR;
571 cur_sense_data.ascq=0;
572 return;
574 send_block_data(cur_cmd.data[cur_cmd.data_select],
575 MIN(BUFFER_SIZE,cur_cmd.count*SECTOR_SIZE));
577 /* Switch buffers for the next one */
578 cur_cmd.data_select=!cur_cmd.data_select;
580 cur_cmd.sector+=(BUFFER_SIZE/SECTOR_SIZE);
581 cur_cmd.count-=MIN(cur_cmd.count,BUFFER_SIZE/SECTOR_SIZE);
583 if(cur_cmd.count!=0){
584 /* already read the next bit, so we can send it out immediately when the
585 * current transfer completes. */
586 cur_cmd.last_result = ata_read_sectors(IF_MV2(cur_cmd.lun,)
587 cur_cmd.sector,
588 MIN(BUFFER_SIZE/SECTOR_SIZE,
589 cur_cmd.count),
590 cur_cmd.data[cur_cmd.data_select]);
593 /****************************************************************************/
595 static void handle_scsi(struct command_block_wrapper* cbw)
597 /* USB Mass Storage assumes LBA capability.
598 TODO: support 48-bit LBA */
600 unsigned int length = cbw->data_transfer_length;
601 unsigned int block_size = 0;
602 unsigned int block_count = 0;
603 bool lun_present=true;
604 #ifdef ONLY_EXPOSE_CARD_SLOT
605 unsigned char lun = cbw->lun+1;
606 #else
607 unsigned char lun = cbw->lun;
608 #endif
609 unsigned int block_size_mult = 1;
610 #if defined(HAVE_ATA_SD) || defined(HAVE_HOTSWAP)
611 tCardInfo* cinfo = card_get_info(lun);
612 if(cinfo->initialized==1 && cinfo->numblocks > 0) {
613 block_size = cinfo->blocksize;
614 block_count = cinfo->numblocks;
616 else {
617 ejected[lun] = true;
618 try_release_ata();
620 #else
621 unsigned short* identify = ata_get_identify();
622 block_size = SECTOR_SIZE;
623 block_count = (identify[61] << 16 | identify[60]);
624 #endif
626 if(ejected[lun])
627 lun_present = false;
629 #ifdef MAX_LOG_SECTOR_SIZE
630 block_size_mult = disk_sector_multiplier;
631 #endif
633 cur_cmd.tag = cbw->tag;
634 cur_cmd.lun = lun;
636 switch (cbw->command_block[0]) {
637 case SCSI_TEST_UNIT_READY:
638 logf("scsi test_unit_ready %d",lun);
639 if(!usb_exclusive_ata()) {
640 send_csw(UMS_STATUS_FAIL);
641 cur_sense_data.sense_key=SENSE_NOT_READY;
642 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
643 cur_sense_data.ascq=0;
644 break;
646 if(lun_present) {
647 send_csw(UMS_STATUS_GOOD);
649 else {
650 send_csw(UMS_STATUS_FAIL);
651 cur_sense_data.sense_key=SENSE_NOT_READY;
652 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
653 cur_sense_data.ascq=0;
655 break;
657 case SCSI_REPORT_LUNS: {
658 logf("scsi inquiry %d",lun);
659 int allocation_length=0;
660 allocation_length|=(cbw->command_block[6]<<24);
661 allocation_length|=(cbw->command_block[7]<<16);
662 allocation_length|=(cbw->command_block[8]<<8);
663 allocation_length|=(cbw->command_block[9]);
664 memset(tb.lun_data,0,sizeof(struct report_lun_data));
665 #ifdef HAVE_HOTSWAP
666 tb.lun_data->lun_list_length=htobe32(16);
667 tb.lun_data->lun1[1]=1;
668 #else
669 tb.lun_data->lun_list_length=htobe32(8);
670 #endif
671 tb.lun_data->lun0[1]=0;
673 send_command_result(tb.lun_data,
674 MIN(sizeof(struct report_lun_data), length));
675 break;
678 case SCSI_INQUIRY:
679 logf("scsi inquiry %d",lun);
680 identify2inquiry(lun);
681 length = MIN(length, cbw->command_block[4]);
682 send_command_result(tb.inquiry,
683 MIN(sizeof(struct inquiry_data), length));
684 break;
686 case SCSI_REQUEST_SENSE: {
687 tb.sense_data->ResponseCode=0x70;/*current error*/
688 tb.sense_data->Obsolete=0;
689 tb.sense_data->fei_sensekey=cur_sense_data.sense_key&0x0f;
690 tb.sense_data->Information=cur_sense_data.information;
691 tb.sense_data->AdditionalSenseLength=10;
692 tb.sense_data->CommandSpecificInformation=0;
693 tb.sense_data->AdditionalSenseCode=cur_sense_data.asc;
694 tb.sense_data->AdditionalSenseCodeQualifier=cur_sense_data.ascq;
695 tb.sense_data->FieldReplaceableUnitCode=0;
696 tb.sense_data->SKSV=0;
697 tb.sense_data->SenseKeySpecific=0;
698 logf("scsi request_sense %d",lun);
699 send_command_result(tb.sense_data, sizeof(struct sense_data));
700 break;
703 case SCSI_MODE_SENSE_10: {
704 if(! lun_present) {
705 send_command_failed_result();
706 cur_sense_data.sense_key=SENSE_NOT_READY;
707 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
708 cur_sense_data.ascq=0;
709 break;
711 /*unsigned char pc = (cbw->command_block[2] & 0xc0) >>6;*/
712 unsigned char page_code = cbw->command_block[2] & 0x3f;
713 logf("scsi mode_sense_10 %d %X",lun,page_code);
714 switch(page_code) {
715 case 0x3f:
716 tb.ms_data_10->mode_data_length =
717 htobe16(sizeof(struct mode_sense_data_10)-2);
718 tb.ms_data_10->medium_type = 0;
719 tb.ms_data_10->device_specific = 0;
720 tb.ms_data_10->reserved = 0;
721 tb.ms_data_10->longlba = 1;
722 tb.ms_data_10->block_descriptor_length =
723 htobe16(sizeof(struct mode_sense_bdesc_longlba));
725 memset(tb.ms_data_10->block_descriptor.reserved,0,4);
726 memset(tb.ms_data_10->block_descriptor.num_blocks,0,8);
728 tb.ms_data_10->block_descriptor.num_blocks[4] =
729 ((block_count/block_size_mult) & 0xff000000)>>24;
730 tb.ms_data_10->block_descriptor.num_blocks[5] =
731 ((block_count/block_size_mult) & 0x00ff0000)>>16;
732 tb.ms_data_10->block_descriptor.num_blocks[6] =
733 ((block_count/block_size_mult) & 0x0000ff00)>>8;
734 tb.ms_data_10->block_descriptor.num_blocks[7] =
735 ((block_count/block_size_mult) & 0x000000ff);
737 tb.ms_data_10->block_descriptor.block_size[0] =
738 ((block_size*block_size_mult) & 0xff000000)>>24;
739 tb.ms_data_10->block_descriptor.block_size[1] =
740 ((block_size*block_size_mult) & 0x00ff0000)>>16;
741 tb.ms_data_10->block_descriptor.block_size[2] =
742 ((block_size*block_size_mult) & 0x0000ff00)>>8;
743 tb.ms_data_10->block_descriptor.block_size[3] =
744 ((block_size*block_size_mult) & 0x000000ff);
745 send_command_result(tb.ms_data_10,
746 MIN(sizeof(struct mode_sense_data_10), length));
747 break;
748 default:
749 send_command_failed_result();
750 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
751 cur_sense_data.asc=ASC_INVALID_FIELD_IN_CBD;
752 cur_sense_data.ascq=0;
753 break;
755 break;
757 case SCSI_MODE_SENSE_6: {
758 if(! lun_present) {
759 send_command_failed_result();
760 cur_sense_data.sense_key=SENSE_NOT_READY;
761 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
762 cur_sense_data.ascq=0;
763 break;
765 /*unsigned char pc = (cbw->command_block[2] & 0xc0) >>6;*/
766 unsigned char page_code = cbw->command_block[2] & 0x3f;
767 logf("scsi mode_sense_6 %d %X",lun,page_code);
768 switch(page_code) {
769 case 0x3f:
770 /* All supported pages. */
771 tb.ms_data_6->mode_data_length =
772 sizeof(struct mode_sense_data_6)-1;
773 tb.ms_data_6->medium_type = 0;
774 tb.ms_data_6->device_specific = 0;
775 tb.ms_data_6->block_descriptor_length =
776 sizeof(struct mode_sense_bdesc_shortlba);
777 tb.ms_data_6->block_descriptor.density_code = 0;
778 tb.ms_data_6->block_descriptor.reserved = 0;
779 if(block_count/block_size_mult > 0xffffff){
780 tb.ms_data_6->block_descriptor.num_blocks[0] = 0xff;
781 tb.ms_data_6->block_descriptor.num_blocks[1] = 0xff;
782 tb.ms_data_6->block_descriptor.num_blocks[2] = 0xff;
784 else {
785 tb.ms_data_6->block_descriptor.num_blocks[0] =
786 ((block_count/block_size_mult) & 0xff0000)>>16;
787 tb.ms_data_6->block_descriptor.num_blocks[1] =
788 ((block_count/block_size_mult) & 0x00ff00)>>8;
789 tb.ms_data_6->block_descriptor.num_blocks[2] =
790 ((block_count/block_size_mult) & 0x0000ff);
792 tb.ms_data_6->block_descriptor.block_size[0] =
793 ((block_size*block_size_mult) & 0xff0000)>>16;
794 tb.ms_data_6->block_descriptor.block_size[1] =
795 ((block_size*block_size_mult) & 0x00ff00)>>8;
796 tb.ms_data_6->block_descriptor.block_size[2] =
797 ((block_size*block_size_mult) & 0x0000ff);
798 send_command_result(tb.ms_data_6,
799 MIN(sizeof(struct mode_sense_data_6), length));
800 break;
801 default:
802 send_command_failed_result();
803 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
804 cur_sense_data.asc=ASC_INVALID_FIELD_IN_CBD;
805 cur_sense_data.ascq=0;
806 break;
808 break;
811 case SCSI_START_STOP_UNIT:
812 logf("scsi start_stop unit %d",lun);
813 if((cbw->command_block[4] & 0xf0) == 0) /*load/eject bit is valid*/
814 { /* Process start and eject bits */
815 logf("scsi load/eject");
816 if((cbw->command_block[4] & 0x01) == 0) /* Don't start */
818 if((cbw->command_block[4] & 0x02) != 0) /* eject */
820 logf("scsi eject");
821 ejected[lun]=true;
822 try_release_ata();
826 send_csw(UMS_STATUS_GOOD);
827 break;
829 case SCSI_ALLOW_MEDIUM_REMOVAL:
830 logf("scsi allow_medium_removal %d",lun);
831 /* TODO: use this to show the connect screen ? */
832 send_csw(UMS_STATUS_GOOD);
833 break;
834 case SCSI_READ_FORMAT_CAPACITY: {
835 logf("scsi read_format_capacity %d",lun);
836 if(lun_present) {
837 tb.format_capacity_data->following_length=htobe32(8);
838 /* "block count" actually means "number of last block" */
839 tb.format_capacity_data->block_count =
840 htobe32(block_count/block_size_mult - 1);
841 tb.format_capacity_data->block_size =
842 htobe32(block_size*block_size_mult);
843 tb.format_capacity_data->block_size |=
844 htobe32(SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA);
846 send_command_result(tb.format_capacity_data,
847 MIN(sizeof(struct format_capacity), length));
849 else
851 send_command_failed_result();
852 cur_sense_data.sense_key=SENSE_NOT_READY;
853 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
854 cur_sense_data.ascq=0;
856 break;
858 case SCSI_READ_CAPACITY: {
859 logf("scsi read_capacity %d",lun);
861 if(lun_present) {
862 /* "block count" actually means "number of last block" */
863 tb.capacity_data->block_count =
864 htobe32(block_count/block_size_mult - 1);
865 tb.capacity_data->block_size =
866 htobe32(block_size*block_size_mult);
868 send_command_result(tb.capacity_data,
869 MIN(sizeof(struct capacity), length));
871 else
873 send_command_failed_result();
874 cur_sense_data.sense_key=SENSE_NOT_READY;
875 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
876 cur_sense_data.ascq=0;
878 break;
881 case SCSI_READ_10:
882 logf("scsi read10 %d",lun);
883 if(! lun_present) {
884 send_command_failed_result();
885 cur_sense_data.sense_key=SENSE_NOT_READY;
886 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
887 cur_sense_data.ascq=0;
888 break;
890 cur_cmd.data[0] = tb.transfer_buffer;
891 cur_cmd.data[1] = &tb.transfer_buffer[BUFFER_SIZE];
892 cur_cmd.data_select=0;
893 cur_cmd.sector = block_size_mult *
894 (cbw->command_block[2] << 24 |
895 cbw->command_block[3] << 16 |
896 cbw->command_block[4] << 8 |
897 cbw->command_block[5] );
898 cur_cmd.count = block_size_mult *
899 (cbw->command_block[7] << 8 |
900 cbw->command_block[8]);
902 //logf("scsi read %d %d", cur_cmd.sector, cur_cmd.count);
904 if((cur_cmd.sector + cur_cmd.count) > block_count) {
905 send_csw(UMS_STATUS_FAIL);
906 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
907 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
908 cur_sense_data.ascq=0;
910 else {
911 cur_cmd.last_result = ata_read_sectors(IF_MV2(cur_cmd.lun,)
912 cur_cmd.sector,
913 MIN(BUFFER_SIZE/SECTOR_SIZE,
914 cur_cmd.count),
915 cur_cmd.data[cur_cmd.data_select]);
916 send_and_read_next();
918 break;
920 case SCSI_WRITE_10:
921 logf("scsi write10 %d",lun);
922 if(! lun_present) {
923 send_csw(UMS_STATUS_FAIL);
924 cur_sense_data.sense_key=SENSE_NOT_READY;
925 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
926 cur_sense_data.ascq=0;
927 break;
929 cur_cmd.data[0] = tb.transfer_buffer;
930 cur_cmd.data[1] = &tb.transfer_buffer[BUFFER_SIZE];
931 cur_cmd.data_select=0;
932 cur_cmd.sector = block_size_mult *
933 (cbw->command_block[2] << 24 |
934 cbw->command_block[3] << 16 |
935 cbw->command_block[4] << 8 |
936 cbw->command_block[5] );
937 cur_cmd.count = block_size_mult *
938 (cbw->command_block[7] << 8 |
939 cbw->command_block[8]);
940 /* expect data */
941 if((cur_cmd.sector + cur_cmd.count) > block_count) {
942 send_csw(UMS_STATUS_FAIL);
943 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
944 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
945 cur_sense_data.ascq=0;
947 else {
948 receive_block_data(cur_cmd.data[0],
949 MIN(BUFFER_SIZE,
950 cur_cmd.count*SECTOR_SIZE));
953 break;
955 default:
956 logf("scsi unknown cmd %x",cbw->command_block[0x0]);
957 usb_drv_stall(usb_endpoint, true,true);
958 send_csw(UMS_STATUS_FAIL);
959 break;
963 static void send_block_data(void *data,int size)
965 usb_drv_send_nonblocking(usb_endpoint, data,size);
966 state = SENDING_BLOCKS;
969 static void send_command_result(void *data,int size)
971 usb_drv_send_nonblocking(usb_endpoint, data,size);
972 state = SENDING_RESULT;
975 static void send_command_failed_result(void)
977 usb_drv_send_nonblocking(usb_endpoint, NULL, 0);
978 state = SENDING_FAILED_RESULT;
981 static void receive_block_data(void *data,int size)
983 usb_drv_recv(usb_endpoint, data, size);
984 state = RECEIVING_BLOCKS;
987 static void send_csw(int status)
989 tb.csw->signature = htole32(CSW_SIGNATURE);
990 tb.csw->tag = cur_cmd.tag;
991 tb.csw->data_residue = 0;
992 tb.csw->status = status;
994 usb_drv_send_nonblocking(usb_endpoint, tb.csw,
995 sizeof(struct command_status_wrapper));
996 state = SENDING_CSW;
997 //logf("CSW: %X",status);
999 if(status == UMS_STATUS_GOOD) {
1000 cur_sense_data.sense_key=0;
1001 cur_sense_data.information=0;
1002 cur_sense_data.asc=0;
1003 cur_sense_data.ascq=0;
1007 /* convert ATA IDENTIFY to SCSI INQUIRY */
1008 static void identify2inquiry(int lun)
1010 #ifdef HAVE_FLASH_STORAGE
1011 if(lun==0) {
1012 memcpy(&tb.inquiry->VendorId,"Rockbox ",8);
1013 memcpy(&tb.inquiry->ProductId,"Internal Storage",16);
1014 memcpy(&tb.inquiry->ProductRevisionLevel,"0.00",4);
1016 else {
1017 memcpy(&tb.inquiry->VendorId,"Rockbox ",8);
1018 memcpy(&tb.inquiry->ProductId,"SD Card Slot ",16);
1019 memcpy(&tb.inquiry->ProductRevisionLevel,"0.00",4);
1021 #else
1022 unsigned int i;
1023 unsigned short* dest;
1024 unsigned short* src;
1025 unsigned short* identify = ata_get_identify();
1026 (void)lun;
1027 memset(tb.inquiry, 0, sizeof(struct inquiry_data));
1029 #if 0
1030 if (identify[82] & 4)
1031 tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
1032 #endif
1034 /* ATA only has a 'model' field, so we copy the
1035 first 8 bytes to 'vendor' and the rest to 'product' (they are
1036 consecutive in the inquiry struct) */
1037 src = (unsigned short*)&identify[27];
1038 dest = (unsigned short*)&tb.inquiry->VendorId;
1039 for (i=0;i<12;i++)
1040 dest[i] = htobe16(src[i]);
1042 src = (unsigned short*)&identify[23];
1043 dest = (unsigned short*)&tb.inquiry->ProductRevisionLevel;
1044 for (i=0;i<2;i++)
1045 dest[i] = htobe16(src[i]);
1046 #endif
1048 tb.inquiry->DeviceType = DIRECT_ACCESS_DEVICE;
1049 tb.inquiry->AdditionalLength = 0x1f;
1050 memset(tb.inquiry->Reserved, 0, 3);
1051 tb.inquiry->Versions = 4; /* SPC-2 */
1052 tb.inquiry->Format = 2; /* SPC-2/3 inquiry format */
1054 #if 0
1055 #ifdef HAVE_HOTSWAP
1056 if(lun>0)
1057 tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
1058 #endif
1059 #endif
1060 /* Mac OSX 10.5 doesn't like this driver if DEVICE_REMOVABLE is not set.
1061 TODO : this can probably be solved by providing caching mode page */
1062 #ifdef TOSHIBA_GIGABEAT_S
1063 tb.inquiry->DeviceTypeModifier = 0;
1064 #else
1065 tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
1066 #endif
1069 #endif /* USB_STORAGE */