summaryrefslogtreecommitdiff
path: root/firmware/usbstack/usb_storage.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/usbstack/usb_storage.c')
-rw-r--r--firmware/usbstack/usb_storage.c604
1 files changed, 436 insertions, 168 deletions
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c
index a1faf3d1c4..0904e17e75 100644
--- a/firmware/usbstack/usb_storage.c
+++ b/firmware/usbstack/usb_storage.c
@@ -26,8 +26,22 @@
26#include "hotswap.h" 26#include "hotswap.h"
27#include "disk.h" 27#include "disk.h"
28 28
29#ifdef USB_STORAGE
30
31/* Enable the following define to export only the SD card slot. This
32 * is useful for USBCV MSC tests, as those are destructive.
33 * This won't work right if the device doesn't have a card slot.
34 */
35//#define ONLY_EXPOSE_CARD_SLOT
36
29#define SECTOR_SIZE 512 37#define SECTOR_SIZE 512
30 38
39/* We can currently use up to 20k buffer size. More than that requires
40 * transfer chaining in the driver. Tests on sansa c200 show that the 16k
41 * limitation causes no more than 2% slowdown.
42 */
43#define BUFFER_SIZE 16384
44
31/* bulk-only class specific requests */ 45/* bulk-only class specific requests */
32#define USB_BULK_RESET_REQUEST 0xff 46#define USB_BULK_RESET_REQUEST 0xff
33#define USB_BULK_GET_MAX_LUN 0xfe 47#define USB_BULK_GET_MAX_LUN 0xfe
@@ -40,7 +54,8 @@
40 54
41#define SCSI_TEST_UNIT_READY 0x00 55#define SCSI_TEST_UNIT_READY 0x00
42#define SCSI_INQUIRY 0x12 56#define SCSI_INQUIRY 0x12
43#define SCSI_MODE_SENSE 0x1a 57#define SCSI_MODE_SENSE_6 0x1a
58#define SCSI_MODE_SENSE_10 0x5a
44#define SCSI_REQUEST_SENSE 0x03 59#define SCSI_REQUEST_SENSE 0x03
45#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1e 60#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1e
46#define SCSI_READ_CAPACITY 0x25 61#define SCSI_READ_CAPACITY 0x25
@@ -48,11 +63,23 @@
48#define SCSI_READ_10 0x28 63#define SCSI_READ_10 0x28
49#define SCSI_WRITE_10 0x2a 64#define SCSI_WRITE_10 0x2a
50#define SCSI_START_STOP_UNIT 0x1b 65#define SCSI_START_STOP_UNIT 0x1b
66#define SCSI_REPORT_LUNS 0xa0
51 67
52#define SCSI_STATUS_GOOD 0x00 68#define SCSI_STATUS_GOOD 0x00
53#define SCSI_STATUS_FAIL 0x01 69#define SCSI_STATUS_FAIL 0x01
54#define SCSI_STATUS_CHECK_CONDITION 0x02 70#define SCSI_STATUS_CHECK_CONDITION 0x02
55 71
72#define SENSE_NOT_READY 0x02
73#define SENSE_MEDIUM_ERROR 0x03
74#define SENSE_ILLEGAL_REQUEST 0x05
75#define SENSE_UNIT_ATTENTION 0x06
76
77#define ASC_MEDIUM_NOT_PRESENT 0x3a
78#define ASC_INVALID_FIELD_IN_CBD 0x24
79#define ASC_LBA_OUT_OF_RANGE 0x21
80#define ASC_WRITE_ERROR 0x0C
81#define ASC_READ_ERROR 0x11
82
56#define SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA 0x02000000 83#define SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA 0x02000000
57 84
58 85
@@ -69,6 +96,15 @@ struct inquiry_data {
69 unsigned char ProductRevisionLevel[4]; 96 unsigned char ProductRevisionLevel[4];
70} __attribute__ ((packed)); 97} __attribute__ ((packed));
71 98
99struct report_lun_data {
100 unsigned int lun_list_length;
101 unsigned int reserved1;
102 unsigned char lun0[8];
103#ifdef HAVE_HOTSWAP
104 unsigned char lun1[8];
105#endif
106} __attribute__ ((packed));
107
72struct sense_data { 108struct sense_data {
73 unsigned char ResponseCode; 109 unsigned char ResponseCode;
74 unsigned char Obsolete; 110 unsigned char Obsolete;
@@ -83,6 +119,21 @@ struct sense_data {
83 unsigned short SenseKeySpecific; 119 unsigned short SenseKeySpecific;
84} __attribute__ ((packed)); 120} __attribute__ ((packed));
85 121
122struct mode_sense_header_10 {
123 unsigned short mode_data_length;
124 unsigned char medium_type;
125 unsigned char device_specific;
126 unsigned char reserved1[2];
127 unsigned short block_descriptor_length;
128} __attribute__ ((packed));
129
130struct mode_sense_header_6 {
131 unsigned char mode_data_length;
132 unsigned char medium_type;
133 unsigned char device_specific;
134 unsigned char block_descriptor_length;
135} __attribute__ ((packed));
136
86struct command_block_wrapper { 137struct command_block_wrapper {
87 unsigned int signature; 138 unsigned int signature;
88 unsigned int tag; 139 unsigned int tag;
@@ -111,93 +162,195 @@ struct format_capacity {
111 unsigned int block_size; 162 unsigned int block_size;
112} __attribute__ ((packed)); 163} __attribute__ ((packed));
113 164
114/* the ARC USB controller can at most buffer 16KB unaligned data */ 165static unsigned char _transfer_buffer[2*BUFFER_SIZE] __attribute((aligned (4096)));
115static unsigned char _transfer_buffer[16384*8] __attribute((aligned (4096)));
116static unsigned char* transfer_buffer; 166static unsigned char* transfer_buffer;
117static struct inquiry_data _inquiry CACHEALIGN_ATTR; 167
118static struct inquiry_data* inquiry; 168static struct inquiry_data* inquiry;
119static struct capacity _capacity_data CACHEALIGN_ATTR; 169static unsigned char __inquiry[CACHEALIGN_UP(sizeof(struct inquiry_data))] CACHEALIGN_ATTR;
170
120static struct capacity* capacity_data; 171static struct capacity* capacity_data;
121static struct format_capacity _format_capacity_data CACHEALIGN_ATTR; 172static unsigned char __capacity_data[CACHEALIGN_UP(sizeof(struct capacity))] CACHEALIGN_ATTR;
173
122static struct format_capacity* format_capacity_data; 174static struct format_capacity* format_capacity_data;
123static struct sense_data _sense_data CACHEALIGN_ATTR; 175static unsigned char __format_capacity_data[CACHEALIGN_UP(sizeof(struct format_capacity))] CACHEALIGN_ATTR;
176
124static struct sense_data *sense_data; 177static struct sense_data *sense_data;
178static unsigned char __sense_data[CACHEALIGN_UP(sizeof(struct sense_data))] CACHEALIGN_ATTR;
179
180static struct mode_sense_header_6 *mode_sense_data_6;
181static unsigned char __mode_sense_data_6[CACHEALIGN_UP(sizeof(struct mode_sense_header_6))] CACHEALIGN_ATTR;
182
183static struct mode_sense_header_10 *mode_sense_data_10;
184static unsigned char __mode_sense_data_10[CACHEALIGN_UP(sizeof(struct mode_sense_header_10))] CACHEALIGN_ATTR;
185
186static struct report_lun_data *lun_data;
187static unsigned char __lun_data[CACHEALIGN_UP(sizeof(struct report_lun_data))] CACHEALIGN_ATTR;
188
189static struct command_status_wrapper* csw;
190static unsigned char __csw[CACHEALIGN_UP(sizeof(struct command_status_wrapper))] CACHEALIGN_ATTR;
191
192static char *max_lun;
193static unsigned char __max_lun[CACHEALIGN_UP(1)] CACHEALIGN_ATTR;
125 194
126static struct { 195static struct {
127 unsigned int sector; 196 unsigned int sector;
128 unsigned int count; 197 unsigned int count;
129 unsigned int tag; 198 unsigned int tag;
130 unsigned int lun; 199 unsigned int lun;
200 unsigned char *data[2];
201 unsigned char data_select;
202 unsigned int last_result;
131} current_cmd; 203} current_cmd;
132 204
205static struct {
206 unsigned char sense_key;
207 unsigned char information;
208 unsigned char asc;
209} cur_sense_data;
210
133static void handle_scsi(struct command_block_wrapper* cbw); 211static void handle_scsi(struct command_block_wrapper* cbw);
134static void send_csw(unsigned int tag, int status); 212static void send_csw(int status);
213static void send_command_result(void *data,int size);
214static void send_block_data(void *data,int size);
215static void receive_block_data(void *data,int size);
135static void identify2inquiry(int lun); 216static void identify2inquiry(int lun);
217static void send_and_read_next(void);
136 218
137static enum { 219static enum {
138 IDLE, 220 WAITING_FOR_COMMAND,
139 SENDING, 221 SENDING_BLOCKS,
140 RECEIVING 222 SENDING_RESULT,
141} state = IDLE; 223 RECEIVING_BLOCKS,
224 SENDING_CSW
225} state = WAITING_FOR_COMMAND;
142 226
143/* called by usb_code_init() */ 227/* called by usb_code_init() */
144void usb_storage_init(void) 228void usb_storage_init(void)
145{ 229{
146 inquiry = (void*)UNCACHED_ADDR(&_inquiry);
147 transfer_buffer = (void*)UNCACHED_ADDR(&_transfer_buffer); 230 transfer_buffer = (void*)UNCACHED_ADDR(&_transfer_buffer);
148 capacity_data = (void*)UNCACHED_ADDR(&_capacity_data); 231 inquiry = (void*)UNCACHED_ADDR(&__inquiry);
149 format_capacity_data = (void*)UNCACHED_ADDR(&_format_capacity_data); 232 capacity_data = (void*)UNCACHED_ADDR(&__capacity_data);
150 sense_data = (void*)UNCACHED_ADDR(&_sense_data); 233 format_capacity_data = (void*)UNCACHED_ADDR(&__format_capacity_data);
151 state = IDLE; 234 sense_data = (void*)UNCACHED_ADDR(&__sense_data);
235 mode_sense_data_6 = (void*)UNCACHED_ADDR(&__mode_sense_data_6);
236 mode_sense_data_10 = (void*)UNCACHED_ADDR(&__mode_sense_data_10);
237 lun_data = (void*)UNCACHED_ADDR(&__lun_data);
238 max_lun = (void*)UNCACHED_ADDR(&__max_lun);
239 csw = (void*)UNCACHED_ADDR(&__csw);
152 logf("usb_storage_init done"); 240 logf("usb_storage_init done");
153} 241}
154 242
155/* called by usb_core_transfer_complete() */ 243/* called by usb_core_transfer_complete() */
156void usb_storage_transfer_complete(int endpoint) 244void usb_storage_transfer_complete(bool in,int status,int length)
157{ 245{
158 struct command_block_wrapper* cbw = (void*)transfer_buffer; 246 struct command_block_wrapper* cbw = (void*)transfer_buffer;
159 247
160 switch (endpoint) { 248 //logf("transfer result %X %d", status, length);
161 case EP_RX: 249 switch(state) {
162 //logf("ums: %d bytes in", length); 250 case RECEIVING_BLOCKS:
163 if(state == RECEIVING) 251 if(in==true) {
164 { 252 logf("IN received in RECEIVING");
165 int receive_count=usb_drv_get_last_transfer_length(); 253 }
166 logf("scsi write %d %d", current_cmd.sector, current_cmd.count); 254 logf("scsi write %d %d", current_cmd.sector, current_cmd.count);
167 if(usb_drv_get_last_transfer_status()==0) 255 if(status==0) {
168 { 256 if((unsigned int)length!=(SECTOR_SIZE*current_cmd.count)
169 if((unsigned int)receive_count!=(SECTOR_SIZE*current_cmd.count)) 257 && (unsigned int)length!=BUFFER_SIZE) {
170 { 258 logf("unexpected length :%d",length);
171 logf("%d >= %d",SECTOR_SIZE*current_cmd.count,receive_count);
172 }
173 ata_write_sectors(IF_MV2(current_cmd.lun,)
174 current_cmd.sector, current_cmd.count,
175 transfer_buffer);
176 send_csw(current_cmd.tag, SCSI_STATUS_GOOD);
177 } 259 }
178 else 260
179 { 261 unsigned int next_sector = current_cmd.sector + (BUFFER_SIZE/SECTOR_SIZE);
180 logf("Transfer failed %X",usb_drv_get_last_transfer_status()); 262 unsigned int next_count = current_cmd.count - MIN(current_cmd.count,BUFFER_SIZE/SECTOR_SIZE);
181 send_csw(current_cmd.tag, SCSI_STATUS_CHECK_CONDITION); 263
264 if(next_count!=0) {
265 /* Ask the host to send more, to the other buffer */
266 receive_block_data(current_cmd.data[!current_cmd.data_select],
267 MIN(BUFFER_SIZE,next_count*SECTOR_SIZE));
182 } 268 }
269
270 /* Now write the data that just came in, while the host is sending the next bit */
271 int result = ata_write_sectors(IF_MV2(current_cmd.lun,)
272 current_cmd.sector, MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count),
273 current_cmd.data[current_cmd.data_select]);
274 if(result != 0) {
275 send_csw(SCSI_STATUS_CHECK_CONDITION);
276 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR;
277 cur_sense_data.asc=ASC_WRITE_ERROR;
278 break;
279 }
280
281 if(next_count==0) {
282 send_csw(SCSI_STATUS_GOOD);
283 }
284
285 /* Switch buffers for the next one */
286 current_cmd.data_select=!current_cmd.data_select;
287
288 current_cmd.sector = next_sector;
289 current_cmd.count = next_count;
290
183 } 291 }
184 else 292 else {
185 { 293 logf("Transfer failed %X",status);
186 state = SENDING; 294 send_csw(SCSI_STATUS_CHECK_CONDITION);
187 handle_scsi(cbw); 295 /* TODO fill in cur_sense_data */
296 cur_sense_data.sense_key=0;
297 cur_sense_data.information=0;
298 cur_sense_data.asc=0;
188 } 299 }
189
190 break; 300 break;
191 301 case WAITING_FOR_COMMAND:
192 case EP_TX: 302 if(in==true) {
193 //logf("ums: out complete"); 303 logf("IN received in WAITING_FOR_COMMAND");
194 if(state != IDLE) 304 }
195 { 305 //logf("command received");
196 /* re-prime endpoint. We only need room for commands */ 306 handle_scsi(cbw);
197 state = IDLE; 307 break;
198 usb_drv_recv(EP_RX, transfer_buffer, 1024); 308 case SENDING_CSW:
309 if(in==false) {
310 logf("OUT received in SENDING_CSW");
311 }
312 //logf("csw sent, now go back to idle");
313 state = WAITING_FOR_COMMAND;
314 usb_drv_recv(EP_MASS_STORAGE, transfer_buffer, 1024);
315 break;
316 case SENDING_RESULT:
317 if(in==false) {
318 logf("OUT received in SENDING");
319 }
320 if(status==0) {
321 //logf("data sent, now send csw");
322 send_csw(SCSI_STATUS_GOOD);
323 }
324 else {
325 logf("Transfer failed %X",status);
326 send_csw(SCSI_STATUS_CHECK_CONDITION);
327 /* TODO fill in cur_sense_data */
328 cur_sense_data.sense_key=0;
329 cur_sense_data.information=0;
330 cur_sense_data.asc=0;
331 }
332 break;
333 case SENDING_BLOCKS:
334 if(in==false) {
335 logf("OUT received in SENDING");
336 }
337 if(status==0) {
338 if(current_cmd.count==0) {
339 //logf("data sent, now send csw");
340 send_csw(SCSI_STATUS_GOOD);
341 }
342 else {
343 send_and_read_next();
344 }
345 }
346 else {
347 logf("Transfer failed %X",status);
348 send_csw(SCSI_STATUS_CHECK_CONDITION);
349 /* TODO fill in cur_sense_data */
350 cur_sense_data.sense_key=0;
351 cur_sense_data.information=0;
352 cur_sense_data.asc=0;
199 } 353 }
200
201 break; 354 break;
202 } 355 }
203} 356}
@@ -205,15 +358,24 @@ void usb_storage_transfer_complete(int endpoint)
205/* called by usb_core_control_request() */ 358/* called by usb_core_control_request() */
206bool usb_storage_control_request(struct usb_ctrlrequest* req) 359bool usb_storage_control_request(struct usb_ctrlrequest* req)
207{ 360{
208 /* note: interrupt context */
209
210 bool handled = false; 361 bool handled = false;
211 362
212 switch (req->bRequest) { 363 switch (req->bRequest) {
213 case USB_BULK_GET_MAX_LUN: { 364 case USB_BULK_GET_MAX_LUN: {
214 static char maxlun = NUM_VOLUMES - 1; 365#ifdef ONLY_EXPOSE_CARD_SLOT
366 *max_lun = 0;
367#else
368 *max_lun = NUM_VOLUMES - 1;
369#endif
370#ifdef HAVE_HOTSWAP
371 /* Workaround until we find out how to do removable devices properly */
372 tCardInfo* cinfo = card_get_info(1);
373 if(cinfo->initialized==0) {
374 *max_lun=0;
375 }
376#endif
215 logf("ums: getmaxlun"); 377 logf("ums: getmaxlun");
216 usb_drv_send(EP_CONTROL, UNCACHED_ADDR(&maxlun), 1); 378 usb_drv_send(EP_CONTROL, UNCACHED_ADDR(max_lun), 1);
217 usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */ 379 usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */
218 handled = true; 380 handled = true;
219 break; 381 break;
@@ -221,8 +383,8 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req)
221 383
222 case USB_BULK_RESET_REQUEST: 384 case USB_BULK_RESET_REQUEST:
223 logf("ums: bulk reset"); 385 logf("ums: bulk reset");
224 usb_drv_reset_endpoint(EP_RX, false); 386 usb_drv_reset_endpoint(EP_MASS_STORAGE, false);
225 usb_drv_reset_endpoint(EP_TX, true); 387 usb_drv_reset_endpoint(EP_MASS_STORAGE, true);
226 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */ 388 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */
227 handled = true; 389 handled = true;
228 break; 390 break;
@@ -230,8 +392,8 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req)
230 case USB_REQ_SET_CONFIGURATION: 392 case USB_REQ_SET_CONFIGURATION:
231 logf("ums: set config"); 393 logf("ums: set config");
232 /* prime rx endpoint. We only need room for commands */ 394 /* prime rx endpoint. We only need room for commands */
233 state = IDLE; 395 state = WAITING_FOR_COMMAND;
234 usb_drv_recv(EP_RX, transfer_buffer, 1024); 396 usb_drv_recv(EP_MASS_STORAGE, transfer_buffer, 1024);
235 handled = true; 397 handled = true;
236 break; 398 break;
237 } 399 }
@@ -239,6 +401,32 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req)
239 return handled; 401 return handled;
240} 402}
241 403
404static void send_and_read_next(void)
405{
406 if(current_cmd.last_result!=0) {
407 /* The last read failed. */
408 send_csw(SCSI_STATUS_CHECK_CONDITION);
409 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR;
410 cur_sense_data.asc=ASC_READ_ERROR;
411 return;
412 }
413 send_block_data(current_cmd.data[current_cmd.data_select],
414 MIN(BUFFER_SIZE,current_cmd.count*SECTOR_SIZE));
415
416 /* Switch buffers for the next one */
417 current_cmd.data_select=!current_cmd.data_select;
418
419 current_cmd.sector+=(BUFFER_SIZE/SECTOR_SIZE);
420 current_cmd.count-=MIN(current_cmd.count,BUFFER_SIZE/SECTOR_SIZE);
421
422 if(current_cmd.count!=0){
423 /* already read the next bit, so we can send it out immediately when the
424 * current transfer completes. */
425 current_cmd.last_result = ata_read_sectors(IF_MV2(current_cmd.lun,) current_cmd.sector,
426 MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count),
427 current_cmd.data[current_cmd.data_select]);
428 }
429}
242/****************************************************************************/ 430/****************************************************************************/
243 431
244static void handle_scsi(struct command_block_wrapper* cbw) 432static void handle_scsi(struct command_block_wrapper* cbw)
@@ -246,141 +434,196 @@ static void handle_scsi(struct command_block_wrapper* cbw)
246 /* USB Mass Storage assumes LBA capability. 434 /* USB Mass Storage assumes LBA capability.
247 TODO: support 48-bit LBA */ 435 TODO: support 48-bit LBA */
248 436
249 unsigned int sectors_per_transfer=0;
250 unsigned int length = cbw->data_transfer_length; 437 unsigned int length = cbw->data_transfer_length;
251 unsigned int block_size; 438 unsigned int block_size;
439 unsigned int block_count;
440 bool lun_present=true;
441#ifdef ONLY_EXPOSE_CARD_SLOT
442 unsigned char lun = cbw->lun+1;
443#else
252 unsigned char lun = cbw->lun; 444 unsigned char lun = cbw->lun;
445#endif
253 unsigned int block_size_mult = 1; 446 unsigned int block_size_mult = 1;
254#ifdef HAVE_HOTSWAP 447#ifdef HAVE_HOTSWAP
255 tCardInfo* cinfo = card_get_info(lun); 448 tCardInfo* cinfo = card_get_info(lun);
256 block_size = cinfo->blocksize; 449 if(cinfo->initialized==1) {
257 if(cinfo->initialized==1) 450 block_size = cinfo->blocksize;
258 { 451 block_count = cinfo->numblocks;
259 sectors_per_transfer=(sizeof _transfer_buffer/ block_size); 452 }
453 else {
454 lun_present=false;
455 block_size = 0;
456 block_count = 0;
260 } 457 }
261#else 458#else
459 unsigned short* identify = ata_get_identify();
262 block_size = SECTOR_SIZE; 460 block_size = SECTOR_SIZE;
263 sectors_per_transfer=(sizeof _transfer_buffer/ block_size); 461 block_count = (identify[61] << 16 | identify[60]);
264#endif 462#endif
265 463
266#ifdef MAX_LOG_SECTOR_SIZE 464#ifdef MAX_LOG_SECTOR_SIZE
267 block_size_mult = disk_sector_multiplier; 465 block_size_mult = disk_sector_multiplier;
268#endif 466#endif
269 467
468 current_cmd.tag = cbw->tag;
469 current_cmd.lun = lun;
470
270 switch (cbw->command_block[0]) { 471 switch (cbw->command_block[0]) {
271 case SCSI_TEST_UNIT_READY: 472 case SCSI_TEST_UNIT_READY:
272 logf("scsi test_unit_ready %d",lun); 473 logf("scsi test_unit_ready %d",lun);
273#ifdef HAVE_HOTSWAP 474#ifdef HAVE_HOTSWAP
274 if(cinfo->initialized==1) 475 if(cinfo->initialized==1)
275 send_csw(cbw->tag, SCSI_STATUS_GOOD); 476 send_csw(SCSI_STATUS_GOOD);
276 else 477 else {
277 send_csw(cbw->tag, SCSI_STATUS_FAIL); 478 send_csw(SCSI_STATUS_FAIL);
479 cur_sense_data.sense_key=SENSE_NOT_READY;
480 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
481 }
278#else 482#else
279 send_csw(cbw->tag, SCSI_STATUS_GOOD); 483 send_csw(SCSI_STATUS_GOOD);
280#endif 484#endif
281 break; 485 break;
282 486
487 case SCSI_REPORT_LUNS: {
488 logf("scsi inquiry %d",lun);
489 int allocation_length=0;
490 allocation_length|=(cbw->command_block[6]<<24);
491 allocation_length|=(cbw->command_block[7]<<16);
492 allocation_length|=(cbw->command_block[8]<<8);
493 allocation_length|=(cbw->command_block[9]);
494 memset(lun_data,0,sizeof(struct report_lun_data));
495#ifdef HAVE_HOTSWAP
496 lun_data->lun_list_length=htobe32(16);
497 lun_data->lun1[1]=1;
498#else
499 lun_data->lun_list_length=htobe32(8);
500#endif
501 lun_data->lun0[1]=0;
502
503 send_command_result(lun_data, MIN(sizeof(struct report_lun_data), length));
504 break;
505 }
506
283 case SCSI_INQUIRY: 507 case SCSI_INQUIRY:
284 logf("scsi inquiry %d",lun); 508 logf("scsi inquiry %d",lun);
285 identify2inquiry(lun); 509 identify2inquiry(lun);
286 length = MIN(length, cbw->command_block[4]); 510 length = MIN(length, cbw->command_block[4]);
287 usb_drv_send(EP_TX, inquiry, MIN(sizeof _inquiry, length)); 511 send_command_result(inquiry, MIN(sizeof(struct inquiry_data), length));
288 send_csw(cbw->tag, SCSI_STATUS_GOOD);
289 break; 512 break;
290 513
291 case SCSI_REQUEST_SENSE: { 514 case SCSI_REQUEST_SENSE: {
292 sense_data->ResponseCode=0x70; 515 sense_data->ResponseCode=0x70;/*current error*/
293 sense_data->filemark_eom_ili_sensekey=2; 516 sense_data->filemark_eom_ili_sensekey=cur_sense_data.sense_key&0x0f;
294 sense_data->Information=2; 517 sense_data->Information=cur_sense_data.information;
295 sense_data->AdditionalSenseLength=10; 518 sense_data->AdditionalSenseLength=10;
296 sense_data->CommandSpecificInformation=0; 519 sense_data->CommandSpecificInformation=0;
297 sense_data->AdditionalSenseCode=0x3a; 520 sense_data->AdditionalSenseCode=cur_sense_data.asc;
298 sense_data->AdditionalSenseCodeQualifier=0; 521 sense_data->AdditionalSenseCodeQualifier=0;
299 sense_data->FieldReplaceableUnitCode=0; 522 sense_data->FieldReplaceableUnitCode=0;
300 sense_data->SKSV=0; 523 sense_data->SKSV=0;
301 sense_data->SenseKeySpecific=0; 524 sense_data->SenseKeySpecific=0;
302 logf("scsi request_sense %d",lun); 525 logf("scsi request_sense %d",lun);
303 usb_drv_send(EP_TX, sense_data, 526 send_command_result(sense_data, sizeof(struct sense_data));
304 sizeof(_sense_data));
305 send_csw(cbw->tag, SCSI_STATUS_GOOD);
306 break; 527 break;
307 } 528 }
308 529
309 case SCSI_MODE_SENSE: { 530 case SCSI_MODE_SENSE_10: {
310 static unsigned char sense_data[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 531 /*unsigned char pc = (cbw->command_block[2] & 0xc0) >>6;*/
311 logf("scsi mode_sense %d",lun); 532 unsigned char page_code = cbw->command_block[2] & 0x3f;
312 usb_drv_send(EP_TX, UNCACHED_ADDR(&sense_data), 533 logf("scsi mode_sense_10 %d %X",lun,page_code);
313 MIN(sizeof sense_data, length)); 534 switch(page_code) {
314 send_csw(cbw->tag, SCSI_STATUS_GOOD); 535 case 0x3f:
536 default:
537 mode_sense_data_10->mode_data_length=0;
538 mode_sense_data_10->medium_type=0;
539 mode_sense_data_10->device_specific=0;
540 mode_sense_data_10->block_descriptor_length=0;
541 send_command_result(mode_sense_data_10,
542 MIN(sizeof(struct mode_sense_header_10), length));
543 break;
544#if 0
545 default:
546 send_csw(SCSI_STATUS_CHECK_CONDITION);
547 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
548 cur_sense_data.asc=ASC_INVALID_FIELD_IN_CBD;
549 break;
550#endif
551 }
552 break;
553 }
554 case SCSI_MODE_SENSE_6: {
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_6 %d %X",lun,page_code);
558 switch(page_code) {
559 case 0x3f:
560 default:
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#if 0
570 default:
571 send_csw(SCSI_STATUS_CHECK_CONDITION);
572 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
573 cur_sense_data.asc=ASC_INVALID_FIELD_IN_CBD;
574 break;
575#endif
576 }
315 break; 577 break;
316 } 578 }
317 579
318 case SCSI_START_STOP_UNIT: 580 case SCSI_START_STOP_UNIT:
319 logf("scsi start_stop unit %d",lun); 581 logf("scsi start_stop unit %d",lun);
320 send_csw(cbw->tag, SCSI_STATUS_GOOD); 582 send_csw(SCSI_STATUS_GOOD);
321 break; 583 break;
322 584
323 case SCSI_ALLOW_MEDIUM_REMOVAL: 585 case SCSI_ALLOW_MEDIUM_REMOVAL:
324 logf("scsi allow_medium_removal %d",lun); 586 logf("scsi allow_medium_removal %d",lun);
325 send_csw(cbw->tag, SCSI_STATUS_GOOD); 587 /* TODO: use this to show the connect screen ? */
588 send_csw(SCSI_STATUS_GOOD);
326 break; 589 break;
327 590
328 case SCSI_READ_FORMAT_CAPACITY: { 591 case SCSI_READ_FORMAT_CAPACITY: {
329 logf("scsi read_format_capacity %d",lun); 592 logf("scsi read_format_capacity %d",lun);
330 format_capacity_data->following_length=htobe32(8); 593 format_capacity_data->following_length=htobe32(8);
331#ifdef HAVE_HOTSWAP
332 /* Careful: "block count" actually means "number of last block" */ 594 /* Careful: "block count" actually means "number of last block" */
333 if(cinfo->initialized==1) 595 format_capacity_data->block_count = htobe32(block_count/block_size_mult - 1);
334 { 596 format_capacity_data->block_size = htobe32(block_size*block_size_mult);
335 format_capacity_data->block_count = htobe32(cinfo->numblocks - 1);
336 format_capacity_data->block_size = htobe32(cinfo->blocksize);
337 }
338 else
339 {
340 format_capacity_data->block_count = htobe32(0);
341 format_capacity_data->block_size = htobe32(0);
342 }
343#else
344 unsigned short* identify = ata_get_identify();
345 /* Careful: "block count" actually means "number of last block" */
346 format_capacity_data->block_count = htobe32((identify[61] << 16 | identify[60]) / block_size_mult - 1);
347 format_capacity_data->block_size = htobe32(block_size * block_size_mult);
348#endif
349 format_capacity_data->block_size |= SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA; 597 format_capacity_data->block_size |= SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA;
350 598
351 usb_drv_send(EP_TX, format_capacity_data, 599 send_command_result(format_capacity_data,
352 MIN(sizeof _format_capacity_data, length)); 600 MIN(sizeof(struct format_capacity), length));
353 send_csw(cbw->tag, SCSI_STATUS_GOOD); 601
354 break; 602 break;
355 } 603 }
356 604
357 case SCSI_READ_CAPACITY: { 605 case SCSI_READ_CAPACITY: {
358 logf("scsi read_capacity %d",lun); 606 logf("scsi read_capacity %d",lun);
359#ifdef HAVE_HOTSWAP
360 /* Careful: "block count" actually means "number of last block" */ 607 /* Careful: "block count" actually means "number of last block" */
361 if(cinfo->initialized==1) 608 capacity_data->block_count = htobe32(block_count/block_size_mult - 1);
362 { 609 capacity_data->block_size = htobe32(block_size*block_size_mult);
363 capacity_data->block_count = htobe32(cinfo->numblocks - 1); 610
364 capacity_data->block_size = htobe32(cinfo->blocksize); 611 send_command_result(capacity_data, MIN(sizeof(struct capacity), length));
365 }
366 else
367 {
368 capacity_data->block_count = htobe32(0);
369 capacity_data->block_size = htobe32(0);
370 }
371#else
372 unsigned short* identify = ata_get_identify();
373 /* Careful : "block count" actually means the number of the last block */
374 capacity_data->block_count = htobe32((identify[61] << 16 | identify[60]) / block_size_mult - 1);
375 capacity_data->block_size = htobe32(block_size * block_size_mult);
376#endif
377 usb_drv_send(EP_TX, capacity_data,
378 MIN(sizeof _capacity_data, length));
379 send_csw(cbw->tag, SCSI_STATUS_GOOD);
380 break; 612 break;
381 } 613 }
382 614
383 case SCSI_READ_10: 615 case SCSI_READ_10:
616 logf("scsi read10 %d",lun);
617 if(! lun_present) {
618 send_csw(SCSI_STATUS_CHECK_CONDITION);
619 cur_sense_data.sense_key=SENSE_NOT_READY;
620 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
621 break;
622 }
623 trigger_cpu_boost();
624 current_cmd.data[0] = transfer_buffer;
625 current_cmd.data[1] = &transfer_buffer[BUFFER_SIZE];
626 current_cmd.data_select=0;
384 current_cmd.sector = block_size_mult * 627 current_cmd.sector = block_size_mult *
385 (cbw->command_block[2] << 24 | 628 (cbw->command_block[2] << 24 |
386 cbw->command_block[3] << 16 | 629 cbw->command_block[3] << 16 |
@@ -389,32 +632,35 @@ static void handle_scsi(struct command_block_wrapper* cbw)
389 current_cmd.count = block_size_mult * 632 current_cmd.count = block_size_mult *
390 (cbw->command_block[7] << 16 | 633 (cbw->command_block[7] << 16 |
391 cbw->command_block[8]); 634 cbw->command_block[8]);
392 current_cmd.tag = cbw->tag;
393 current_cmd.lun = cbw->lun;
394 635
395 //logf("scsi read %d %d", current_cmd.sector, current_cmd.count); 636 logf("scsi read %d %d", current_cmd.sector, current_cmd.count);
396 637
397 //logf("Asked for %d sectors",current_cmd.count); 638 if((current_cmd.sector + current_cmd.count) * block_size_mult > block_count) {
398 if(current_cmd.count > sectors_per_transfer) 639 send_csw(SCSI_STATUS_CHECK_CONDITION);
399 { 640 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
400 current_cmd.count = sectors_per_transfer; 641 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
401 }
402 //logf("Sending %d sectors",current_cmd.count);
403
404 if(current_cmd.count*block_size > sizeof(_transfer_buffer)) {
405 send_csw(current_cmd.tag, SCSI_STATUS_CHECK_CONDITION);
406 } 642 }
407 else { 643 else {
408 ata_read_sectors(IF_MV2(lun,) current_cmd.sector, 644 /* TODO: any way to do this nonblocking ? */
409 current_cmd.count, transfer_buffer); 645 current_cmd.last_result = ata_read_sectors(IF_MV2(current_cmd.lun,) current_cmd.sector,
410 usb_drv_send(EP_TX, transfer_buffer, 646 MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count),
411 current_cmd.count*block_size); 647 current_cmd.data[current_cmd.data_select]);
412 send_csw(current_cmd.tag, SCSI_STATUS_GOOD); 648 send_and_read_next();
413 } 649 }
414 break; 650 break;
415 651
416 case SCSI_WRITE_10: 652 case SCSI_WRITE_10:
417 //logf("scsi write10"); 653 logf("scsi write10 %d",lun);
654 if(! lun_present) {
655 send_csw(SCSI_STATUS_CHECK_CONDITION);
656 cur_sense_data.sense_key=SENSE_NOT_READY;
657 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
658 break;
659 }
660 trigger_cpu_boost();
661 current_cmd.data[0] = transfer_buffer;
662 current_cmd.data[1] = &transfer_buffer[BUFFER_SIZE];
663 current_cmd.data_select=0;
418 current_cmd.sector = block_size_mult * 664 current_cmd.sector = block_size_mult *
419 (cbw->command_block[2] << 24 | 665 (cbw->command_block[2] << 24 |
420 cbw->command_block[3] << 16 | 666 cbw->command_block[3] << 16 |
@@ -423,53 +669,74 @@ static void handle_scsi(struct command_block_wrapper* cbw)
423 current_cmd.count = block_size_mult * 669 current_cmd.count = block_size_mult *
424 (cbw->command_block[7] << 16 | 670 (cbw->command_block[7] << 16 |
425 cbw->command_block[8]); 671 cbw->command_block[8]);
426 current_cmd.tag = cbw->tag;
427 current_cmd.lun = cbw->lun;
428 /* expect data */ 672 /* expect data */
429 if(current_cmd.count*block_size > sizeof(_transfer_buffer)) { 673 if((current_cmd.sector + current_cmd.count) * block_size_mult > block_count) {
430 send_csw(current_cmd.tag, SCSI_STATUS_CHECK_CONDITION); 674 send_csw(SCSI_STATUS_CHECK_CONDITION);
675 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
676 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
431 } 677 }
432 else { 678 else {
433 usb_drv_recv(EP_RX, transfer_buffer, 679 receive_block_data(current_cmd.data[0],
434 current_cmd.count*block_size); 680 MIN(BUFFER_SIZE,current_cmd.count*SECTOR_SIZE));
435 state = RECEIVING;
436 } 681 }
437 682
438 break; 683 break;
439 684
440 default: 685 default:
441 logf("scsi unknown cmd %x",cbw->command_block[0x0]); 686 logf("scsi unknown cmd %x",cbw->command_block[0x0]);
442 usb_drv_stall(EP_TX, true); 687 usb_drv_stall(EP_MASS_STORAGE, true,true);
443 send_csw(current_cmd.tag, SCSI_STATUS_GOOD); 688 send_csw(SCSI_STATUS_GOOD);
444 break; 689 break;
445 } 690 }
446} 691}
447 692
448static void send_csw(unsigned int tag, int status) 693static void send_block_data(void *data,int size)
694{
695 usb_drv_send_nonblocking(EP_MASS_STORAGE, data,size);
696 state = SENDING_BLOCKS;
697}
698
699static void send_command_result(void *data,int size)
700{
701 usb_drv_send_nonblocking(EP_MASS_STORAGE, data,size);
702 state = SENDING_RESULT;
703}
704
705static void receive_block_data(void *data,int size)
449{ 706{
450 static struct command_status_wrapper _csw; 707 usb_drv_recv(EP_MASS_STORAGE, data, size);
451 struct command_status_wrapper* csw = UNCACHED_ADDR(&_csw); 708 state = RECEIVING_BLOCKS;
709}
710
711static void send_csw(int status)
712{
713 cancel_cpu_boost();
452 csw->signature = CSW_SIGNATURE; 714 csw->signature = CSW_SIGNATURE;
453 csw->tag = tag; 715 csw->tag = current_cmd.tag;
454 csw->data_residue = 0; 716 csw->data_residue = 0;
455 csw->status = status; 717 csw->status = status;
456 718
457 //logf("csw %x %x", csw->tag, csw->signature); 719 usb_drv_send_nonblocking(EP_MASS_STORAGE, csw, sizeof(struct command_status_wrapper));
458 usb_drv_send(EP_TX, csw, sizeof _csw); 720 state = SENDING_CSW;
721 logf("CSW: %X",status);
722
723 if(status == SCSI_STATUS_GOOD) {
724 cur_sense_data.sense_key=0;
725 cur_sense_data.information=0;
726 cur_sense_data.asc=0;
727 }
459} 728}
460 729
461/* convert ATA IDENTIFY to SCSI INQUIRY */ 730/* convert ATA IDENTIFY to SCSI INQUIRY */
462static void identify2inquiry(int lun) 731static void identify2inquiry(int lun)
463{ 732{
464#ifdef HAVE_FLASH_STORAGE 733#ifdef HAVE_FLASH_STORAGE
465 if(lun==0) 734 if(lun==0) {
466 {
467 memcpy(&inquiry->VendorId,"Rockbox ",8); 735 memcpy(&inquiry->VendorId,"Rockbox ",8);
468 memcpy(&inquiry->ProductId,"Internal Storage",16); 736 memcpy(&inquiry->ProductId,"Internal Storage",16);
469 memcpy(&inquiry->ProductRevisionLevel,"0.00",4); 737 memcpy(&inquiry->ProductRevisionLevel,"0.00",4);
470 } 738 }
471 else 739 else {
472 {
473 memcpy(&inquiry->VendorId,"Rockbox ",8); 740 memcpy(&inquiry->VendorId,"Rockbox ",8);
474 memcpy(&inquiry->ProductId,"SD Card Slot ",16); 741 memcpy(&inquiry->ProductId,"SD Card Slot ",16);
475 memcpy(&inquiry->ProductRevisionLevel,"0.00",4); 742 memcpy(&inquiry->ProductRevisionLevel,"0.00",4);
@@ -480,7 +747,7 @@ static void identify2inquiry(int lun)
480 unsigned short* src; 747 unsigned short* src;
481 unsigned short* identify = ata_get_identify(); 748 unsigned short* identify = ata_get_identify();
482 (void)lun; 749 (void)lun;
483 memset(inquiry, 0, sizeof _inquiry); 750 memset(inquiry, 0, sizeof(struct inquiry_data));
484 751
485 if (identify[82] & 4) 752 if (identify[82] & 4)
486 inquiry->DeviceTypeModifier = DEVICE_REMOVABLE; 753 inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
@@ -501,8 +768,8 @@ static void identify2inquiry(int lun)
501 768
502 inquiry->DeviceType = DIRECT_ACCESS_DEVICE; 769 inquiry->DeviceType = DIRECT_ACCESS_DEVICE;
503 inquiry->AdditionalLength = 0x1f; 770 inquiry->AdditionalLength = 0x1f;
504 inquiry->Versions = 3; /* ANSI SCSI level 2 */ 771 inquiry->Versions = 4; /* SPC-2 */
505 inquiry->Format = 3; /* ANSI SCSI level 2 INQUIRY format */ 772 inquiry->Format = 2; /* SPC-2/3 inquiry format */
506 773
507#ifdef HAVE_HOTSWAP 774#ifdef HAVE_HOTSWAP
508 inquiry->DeviceTypeModifier = DEVICE_REMOVABLE; 775 inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
@@ -510,3 +777,4 @@ static void identify2inquiry(int lun)
510 777
511} 778}
512 779
780#endif /* USB_STORAGE */