diff options
Diffstat (limited to 'firmware/usbstack/usb_storage.c')
-rw-r--r-- | firmware/usbstack/usb_storage.c | 70 |
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); | |||
263 | static void send_and_read_next(void); | 263 | static void send_and_read_next(void); |
264 | static bool ejected[NUM_VOLUMES]; | 264 | static bool ejected[NUM_VOLUMES]; |
265 | 265 | ||
266 | static int usb_endpoint; | ||
267 | static int usb_interface; | 266 | static int usb_interface; |
267 | static int ep_in, ep_out; | ||
268 | 268 | ||
269 | static enum { | 269 | static 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 | 339 | int usb_storage_request_endpoints(struct usb_class_driver *drv) | |
340 | int 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 | |||
345 | int usb_storage_set_first_interface(int interface) | 356 | int 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() */ |
397 | void usb_storage_transfer_complete(int ep,bool in,int status,int length) | 409 | void 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 | ||
981 | static void send_block_data(void *data,int size) | 993 | static 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 | ||
987 | static void send_command_result(void *data,int size) | 999 | static 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 | ||
993 | static void send_command_failed_result(void) | 1005 | static 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 | ||
999 | static void receive_block_data(void *data,int size) | 1011 | static 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); |