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.c70
1 files changed, 41 insertions, 29 deletions
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c
index f774d14cbc..9c524a37b8 100644
--- a/firmware/usbstack/usb_storage.c
+++ b/firmware/usbstack/usb_storage.c
@@ -22,7 +22,7 @@
22#include "system.h" 22#include "system.h"
23#include "usb_core.h" 23#include "usb_core.h"
24#include "usb_drv.h" 24#include "usb_drv.h"
25//#define LOGF_ENABLE 25#define LOGF_ENABLE
26#include "logf.h" 26#include "logf.h"
27#include "ata.h" 27#include "ata.h"
28#include "hotswap.h" 28#include "hotswap.h"
@@ -263,8 +263,8 @@ static void identify2inquiry(int lun);
263static void send_and_read_next(void); 263static void send_and_read_next(void);
264static bool ejected[NUM_VOLUMES]; 264static bool ejected[NUM_VOLUMES];
265 265
266static int usb_endpoint;
267static int usb_interface; 266static int usb_interface;
267static int ep_in, ep_out;
268 268
269static enum { 269static enum {
270 WAITING_FOR_COMMAND, 270 WAITING_FOR_COMMAND,
@@ -321,7 +321,7 @@ void usb_storage_reconnect(void)
321 && usb_inserted()) { 321 && usb_inserted()) {
322 for(i=0;i<NUM_VOLUMES;i++) 322 for(i=0;i<NUM_VOLUMES;i++)
323 ejected[i] = !check_disk_present(IF_MV(i)); 323 ejected[i] = !check_disk_present(IF_MV(i));
324 324 logf("%s", __func__);
325 usb_request_exclusive_ata(); 325 usb_request_exclusive_ata();
326 } 326 }
327} 327}
@@ -336,12 +336,23 @@ void usb_storage_init(void)
336 logf("usb_storage_init done"); 336 logf("usb_storage_init done");
337} 337}
338 338
339 339int usb_storage_request_endpoints(struct usb_class_driver *drv)
340int usb_storage_set_first_endpoint(int endpoint)
341{ 340{
342 usb_endpoint = endpoint; 341 ep_in = usb_core_request_endpoint(USB_DIR_IN, drv);
343 return endpoint + 1; 342
343 if (ep_in < 0)
344 return -1;
345
346 ep_out = usb_core_request_endpoint(USB_DIR_OUT, drv);
347
348 if (ep_out < 0) {
349 usb_core_release_endpoint(ep_in);
350 return -1;
351 }
352
353 return 0;
344} 354}
355
345int usb_storage_set_first_interface(int interface) 356int usb_storage_set_first_interface(int interface)
346{ 357{
347 usb_interface = interface; 358 usb_interface = interface;
@@ -357,12 +368,12 @@ int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size)
357 sizeof(struct usb_interface_descriptor)); 368 sizeof(struct usb_interface_descriptor));
358 dest+=sizeof(struct usb_interface_descriptor); 369 dest+=sizeof(struct usb_interface_descriptor);
359 370
360 endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_IN; 371 endpoint_descriptor.bEndpointAddress = ep_in;
361 memcpy(dest,&endpoint_descriptor, 372 memcpy(dest,&endpoint_descriptor,
362 sizeof(struct usb_endpoint_descriptor)); 373 sizeof(struct usb_endpoint_descriptor));
363 dest+=sizeof(struct usb_endpoint_descriptor); 374 dest+=sizeof(struct usb_endpoint_descriptor);
364 375
365 endpoint_descriptor.bEndpointAddress = usb_endpoint | USB_DIR_OUT; 376 endpoint_descriptor.bEndpointAddress = ep_out;
366 memcpy(dest,&endpoint_descriptor, 377 memcpy(dest,&endpoint_descriptor,
367 sizeof(struct usb_endpoint_descriptor)); 378 sizeof(struct usb_endpoint_descriptor));
368 379
@@ -376,7 +387,8 @@ void usb_storage_init_connection(void)
376 /* prime rx endpoint. We only need room for commands */ 387 /* prime rx endpoint. We only need room for commands */
377 state = WAITING_FOR_COMMAND; 388 state = WAITING_FOR_COMMAND;
378 389
379#if CONFIG_CPU == IMX31L || CONFIG_USBOTG == USBOTG_ISP1583 390#if CONFIG_CPU == IMX31L || CONFIG_USBOTG == USBOTG_ISP1583 || \
391 defined(CPU_TCC77X) || defined(CPU_TCC780X)
380 static unsigned char _transfer_buffer[BUFFER_SIZE*2] 392 static unsigned char _transfer_buffer[BUFFER_SIZE*2]
381 USBDEVBSS_ATTR __attribute__((aligned(32))); 393 USBDEVBSS_ATTR __attribute__((aligned(32)));
382 tb.transfer_buffer = (void *)_transfer_buffer; 394 tb.transfer_buffer = (void *)_transfer_buffer;
@@ -390,11 +402,11 @@ void usb_storage_init_connection(void)
390 (void *)UNCACHED_ADDR((unsigned int)(audio_buffer + 31) & 0xffffffe0); 402 (void *)UNCACHED_ADDR((unsigned int)(audio_buffer + 31) & 0xffffffe0);
391 invalidate_icache(); 403 invalidate_icache();
392#endif 404#endif
393 usb_drv_recv(usb_endpoint, tb.transfer_buffer, 1024); 405 usb_drv_recv(ep_out, tb.transfer_buffer, 1024);
394} 406}
395 407
396/* called by usb_core_transfer_complete() */ 408/* called by usb_core_transfer_complete() */
397void usb_storage_transfer_complete(int ep,bool in,int status,int length) 409void usb_storage_transfer_complete(int ep,int dir,int status,int length)
398{ 410{
399 (void)ep; 411 (void)ep;
400 struct command_block_wrapper* cbw = (void*)tb.transfer_buffer; 412 struct command_block_wrapper* cbw = (void*)tb.transfer_buffer;
@@ -402,7 +414,7 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length)
402 //logf("transfer result %X %d", status, length); 414 //logf("transfer result %X %d", status, length);
403 switch(state) { 415 switch(state) {
404 case RECEIVING_BLOCKS: 416 case RECEIVING_BLOCKS:
405 if(in==true) { 417 if(dir==USB_DIR_IN) {
406 logf("IN received in RECEIVING"); 418 logf("IN received in RECEIVING");
407 } 419 }
408 logf("scsi write %d %d", cur_cmd.sector, cur_cmd.count); 420 logf("scsi write %d %d", cur_cmd.sector, cur_cmd.count);
@@ -470,7 +482,7 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length)
470 } 482 }
471 break; 483 break;
472 case WAITING_FOR_COMMAND: 484 case WAITING_FOR_COMMAND:
473 if(in==true) { 485 if(dir==USB_DIR_IN) {
474 logf("IN received in WAITING_FOR_COMMAND"); 486 logf("IN received in WAITING_FOR_COMMAND");
475 } 487 }
476 //logf("command received"); 488 //logf("command received");
@@ -478,20 +490,20 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length)
478 handle_scsi(cbw); 490 handle_scsi(cbw);
479 } 491 }
480 else { 492 else {
481 usb_drv_stall(usb_endpoint, true,true); 493 usb_drv_stall(ep_in, true,true);
482 usb_drv_stall(usb_endpoint, true,false); 494 usb_drv_stall(ep_out, true,false);
483 } 495 }
484 break; 496 break;
485 case SENDING_CSW: 497 case SENDING_CSW:
486 if(in==false) { 498 if(dir==USB_DIR_OUT) {
487 logf("OUT received in SENDING_CSW"); 499 logf("OUT received in SENDING_CSW");
488 } 500 }
489 //logf("csw sent, now go back to idle"); 501 //logf("csw sent, now go back to idle");
490 state = WAITING_FOR_COMMAND; 502 state = WAITING_FOR_COMMAND;
491 usb_drv_recv(usb_endpoint, tb.transfer_buffer, 1024); 503 usb_drv_recv(ep_out, tb.transfer_buffer, 1024);
492 break; 504 break;
493 case SENDING_RESULT: 505 case SENDING_RESULT:
494 if(in==false) { 506 if(dir==USB_DIR_OUT) {
495 logf("OUT received in SENDING"); 507 logf("OUT received in SENDING");
496 } 508 }
497 if(status==0) { 509 if(status==0) {
@@ -509,13 +521,13 @@ void usb_storage_transfer_complete(int ep,bool in,int status,int length)
509 } 521 }
510 break; 522 break;
511 case SENDING_FAILED_RESULT: 523 case SENDING_FAILED_RESULT:
512 if(in==false) { 524 if(dir==USB_DIR_OUT) {
513 logf("OUT received in SENDING"); 525 logf("OUT received in SENDING");
514 } 526 }
515 send_csw(UMS_STATUS_FAIL); 527 send_csw(UMS_STATUS_FAIL);
516 break; 528 break;
517 case SENDING_BLOCKS: 529 case SENDING_BLOCKS:
518 if(in==false) { 530 if(dir==USB_DIR_OUT) {
519 logf("OUT received in SENDING"); 531 logf("OUT received in SENDING");
520 } 532 }
521 if(status==0) { 533 if(status==0) {
@@ -567,8 +579,8 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req)
567 data toggle bits and endpoint STALL conditions despite 579 data toggle bits and endpoint STALL conditions despite
568 the Bulk-Only Mass Storage Reset. */ 580 the Bulk-Only Mass Storage Reset. */
569#if 0 581#if 0
570 usb_drv_reset_endpoint(usb_endpoint, false); 582 usb_drv_reset_endpoint(ep_in, false);
571 usb_drv_reset_endpoint(usb_endpoint, true); 583 usb_drv_reset_endpoint(ep_out, true);
572#endif 584#endif
573 585
574 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */ 586 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */
@@ -972,7 +984,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
972 984
973 default: 985 default:
974 logf("scsi unknown cmd %x",cbw->command_block[0x0]); 986 logf("scsi unknown cmd %x",cbw->command_block[0x0]);
975 usb_drv_stall(usb_endpoint, true,true); 987 usb_drv_stall(ep_in, true,true);
976 send_csw(UMS_STATUS_FAIL); 988 send_csw(UMS_STATUS_FAIL);
977 break; 989 break;
978 } 990 }
@@ -980,25 +992,25 @@ static void handle_scsi(struct command_block_wrapper* cbw)
980 992
981static void send_block_data(void *data,int size) 993static void send_block_data(void *data,int size)
982{ 994{
983 usb_drv_send_nonblocking(usb_endpoint, data,size); 995 usb_drv_send_nonblocking(ep_in, data,size);
984 state = SENDING_BLOCKS; 996 state = SENDING_BLOCKS;
985} 997}
986 998
987static void send_command_result(void *data,int size) 999static void send_command_result(void *data,int size)
988{ 1000{
989 usb_drv_send_nonblocking(usb_endpoint, data,size); 1001 usb_drv_send_nonblocking(ep_in, data,size);
990 state = SENDING_RESULT; 1002 state = SENDING_RESULT;
991} 1003}
992 1004
993static void send_command_failed_result(void) 1005static void send_command_failed_result(void)
994{ 1006{
995 usb_drv_send_nonblocking(usb_endpoint, NULL, 0); 1007 usb_drv_send_nonblocking(ep_in, NULL, 0);
996 state = SENDING_FAILED_RESULT; 1008 state = SENDING_FAILED_RESULT;
997} 1009}
998 1010
999static void receive_block_data(void *data,int size) 1011static void receive_block_data(void *data,int size)
1000{ 1012{
1001 usb_drv_recv(usb_endpoint, data, size); 1013 usb_drv_recv(ep_out, data, size);
1002 state = RECEIVING_BLOCKS; 1014 state = RECEIVING_BLOCKS;
1003} 1015}
1004 1016
@@ -1009,7 +1021,7 @@ static void send_csw(int status)
1009 tb.csw->data_residue = 0; 1021 tb.csw->data_residue = 0;
1010 tb.csw->status = status; 1022 tb.csw->status = status;
1011 1023
1012 usb_drv_send_nonblocking(usb_endpoint, tb.csw, 1024 usb_drv_send_nonblocking(ep_in, tb.csw,
1013 sizeof(struct command_status_wrapper)); 1025 sizeof(struct command_status_wrapper));
1014 state = SENDING_CSW; 1026 state = SENDING_CSW;
1015 //logf("CSW: %X",status); 1027 //logf("CSW: %X",status);