summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2008-02-11 14:26:25 +0000
committerBjörn Stenberg <bjorn@haxx.se>2008-02-11 14:26:25 +0000
commit2f7cffa204eaa2675b0c6782462b19f4f09bff12 (patch)
tree54ffb4cada2c8db9d0feb4c31efc02cb3ab18a1d
parent9811fc9abf6c3b2bb9500a99c14a64ee29641b09 (diff)
downloadrockbox-2f7cffa204eaa2675b0c6782462b19f4f09bff12.tar.gz
rockbox-2f7cffa204eaa2675b0c6782462b19f4f09bff12.zip
Major USB fixes by Frank Gevaerts. Still disabled in builds, #define USE_ROCKBOX_USB to test.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16279 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--bootloader/main-pp.c2
-rw-r--r--docs/CREDITS1
-rw-r--r--firmware/common/disk.c5
-rw-r--r--firmware/export/disk.h5
-rw-r--r--firmware/export/usb_ch9.h2
-rw-r--r--firmware/export/usb_drv.h3
-rw-r--r--firmware/target/arm/usb-drv-pp502x.c184
-rw-r--r--firmware/target/arm/usb-fw-pp502x.c8
-rw-r--r--firmware/usbstack/usb_core.c339
-rw-r--r--firmware/usbstack/usb_storage.c316
10 files changed, 662 insertions, 203 deletions
diff --git a/bootloader/main-pp.c b/bootloader/main-pp.c
index 74c66233c0..5af6e57fff 100644
--- a/bootloader/main-pp.c
+++ b/bootloader/main-pp.c
@@ -465,6 +465,7 @@ void* main(void)
465 465
466 btn = button_read_device(); 466 btn = button_read_device();
467#if defined(SANSA_E200) || defined(SANSA_C200) 467#if defined(SANSA_E200) || defined(SANSA_C200)
468#if !defined(USE_ROCKBOX_USB)
468 usb_init(); 469 usb_init();
469 while (usb_drv_powered() && usb_retry < 5 && !usb) 470 while (usb_drv_powered() && usb_retry < 5 && !usb)
470 { 471 {
@@ -474,6 +475,7 @@ void* main(void)
474 } 475 }
475 if (usb) 476 if (usb)
476 btn |= BOOTLOADER_BOOT_OF; 477 btn |= BOOTLOADER_BOOT_OF;
478#endif /* USE_ROCKBOX_USB */
477#endif 479#endif
478 /* Enable bootloader messages if any button is pressed */ 480 /* Enable bootloader messages if any button is pressed */
479 if (btn) 481 if (btn)
diff --git a/docs/CREDITS b/docs/CREDITS
index 7c95ab8804..955b81109e 100644
--- a/docs/CREDITS
+++ b/docs/CREDITS
@@ -368,6 +368,7 @@ George Tamplaru
368Apoorva Mahajan 368Apoorva Mahajan
369Vuong Minh Hiep 369Vuong Minh Hiep
370Mateusz Kubica 370Mateusz Kubica
371Frank Gevaerts
371 372
372The libmad team 373The libmad team
373The wavpack team 374The wavpack team
diff --git a/firmware/common/disk.c b/firmware/common/disk.c
index 9fb73f0070..c26fdb37a4 100644
--- a/firmware/common/disk.c
+++ b/firmware/common/disk.c
@@ -48,6 +48,9 @@
48static struct partinfo part[8]; /* space for 4 partitions on 2 drives */ 48static struct partinfo part[8]; /* space for 4 partitions on 2 drives */
49static int vol_drive[NUM_VOLUMES]; /* mounted to which drive (-1 if none) */ 49static int vol_drive[NUM_VOLUMES]; /* mounted to which drive (-1 if none) */
50 50
51#ifdef MAX_LOG_SECTOR_SIZE
52int disk_sector_multiplier = 1;
53#endif
51struct partinfo* disk_init(IF_MV_NONVOID(int drive)) 54struct partinfo* disk_init(IF_MV_NONVOID(int drive))
52{ 55{
53 int i; 56 int i;
@@ -168,6 +171,8 @@ int disk_mount(int drive)
168 mounted++; 171 mounted++;
169 vol_drive[volume] = drive; /* remember the drive for this volume */ 172 vol_drive[volume] = drive; /* remember the drive for this volume */
170 volume = get_free_volume(); /* prepare next entry */ 173 volume = get_free_volume(); /* prepare next entry */
174 if (drive == 0)
175 disk_sector_multiplier = j;
171 break; 176 break;
172 } 177 }
173 } 178 }
diff --git a/firmware/export/disk.h b/firmware/export/disk.h
index 9672a6d318..d6d6796e9e 100644
--- a/firmware/export/disk.h
+++ b/firmware/export/disk.h
@@ -39,4 +39,9 @@ int disk_mount_all(void); /* returns the # of successful mounts */
39int disk_mount(int drive); 39int disk_mount(int drive);
40int disk_unmount(int drive); 40int disk_unmount(int drive);
41 41
42/* The number of 512-byte sectors in a "logical" sector. Needed for ipod 5.5G */
43#ifdef MAX_LOG_SECTOR_SIZE
44extern int disk_sector_multiplier;
45#endif
46
42#endif 47#endif
diff --git a/firmware/export/usb_ch9.h b/firmware/export/usb_ch9.h
index b8fe181158..1bfc152a8a 100644
--- a/firmware/export/usb_ch9.h
+++ b/firmware/export/usb_ch9.h
@@ -244,7 +244,7 @@ struct usb_string_descriptor {
244 uint8_t bLength; 244 uint8_t bLength;
245 uint8_t bDescriptorType; 245 uint8_t bDescriptorType;
246 246
247 uint16_t wData[1]; /* UTF-16LE encoded */ 247 uint16_t wString[]; /* UTF-16LE encoded */
248} __attribute__ ((packed)); 248} __attribute__ ((packed));
249 249
250/* note that "string" zero is special, it holds language codes that 250/* note that "string" zero is special, it holds language codes that
diff --git a/firmware/export/usb_drv.h b/firmware/export/usb_drv.h
index c503a846ed..6a37144c1a 100644
--- a/firmware/export/usb_drv.h
+++ b/firmware/export/usb_drv.h
@@ -32,5 +32,8 @@ void usb_drv_set_address(int address);
32void usb_drv_reset_endpoint(int endpoint, bool send); 32void usb_drv_reset_endpoint(int endpoint, bool send);
33void usb_drv_wait(int endpoint, bool send); 33void usb_drv_wait(int endpoint, bool send);
34bool usb_drv_powered(void); 34bool usb_drv_powered(void);
35int usb_drv_get_last_transfer_status(void);
36int usb_drv_get_last_transfer_length(void);
37int usb_drv_port_speed(void);
35 38
36#endif 39#endif
diff --git a/firmware/target/arm/usb-drv-pp502x.c b/firmware/target/arm/usb-drv-pp502x.c
index 1db3ebd42f..413d905293 100644
--- a/firmware/target/arm/usb-drv-pp502x.c
+++ b/firmware/target/arm/usb-drv-pp502x.c
@@ -294,7 +294,7 @@ struct transfer_descriptor {
294 unsigned int reserved; 294 unsigned int reserved;
295} __attribute__ ((packed)); 295} __attribute__ ((packed));
296 296
297static struct transfer_descriptor _td_array[NUM_ENDPOINTS*2] __attribute((aligned (32))); 297static struct transfer_descriptor _td_array[32] __attribute((aligned (32)));
298static struct transfer_descriptor* td_array; 298static struct transfer_descriptor* td_array;
299 299
300/* manual: 32.13.1 Endpoint Queue Head (dQH) */ 300/* manual: 32.13.1 Endpoint Queue Head (dQH) */
@@ -317,9 +317,15 @@ static const unsigned int pipe2mask[NUM_ENDPOINTS*2] = {
317 0x04, 0x040000, 317 0x04, 0x040000,
318}; 318};
319 319
320static struct transfer_descriptor* first_td;
321static struct transfer_descriptor* last_td;
322
320/*-------------------------------------------------------------------------*/ 323/*-------------------------------------------------------------------------*/
321static void transfer_completed(void); 324static void transfer_completed(void);
322static int prime_transfer(int endpoint, void* ptr, int len, bool send); 325static int prime_transfer(int endpoint, void* ptr, int len, bool send);
326static void prepare_td(struct transfer_descriptor* td,
327 struct transfer_descriptor* previous_td,
328 void *ptr, int len);
323static void bus_reset(void); 329static void bus_reset(void);
324static void init_queue_heads(void); 330static void init_queue_heads(void);
325static void init_endpoints(void); 331static void init_endpoints(void);
@@ -340,6 +346,10 @@ void usb_drv_init(void)
340 346
341 REG_USBMODE = USBMODE_CTRL_MODE_DEVICE; 347 REG_USBMODE = USBMODE_CTRL_MODE_DEVICE;
342 348
349 /* Force device to full speed */
350 /* See 32.9.5.9.2 */
351 REG_PORTSC1 |= PORTSCX_PORT_FORCE_FULL_SPEED;
352
343 td_array = (struct transfer_descriptor*)UNCACHED_ADDR(&_td_array); 353 td_array = (struct transfer_descriptor*)UNCACHED_ADDR(&_td_array);
344 qh_array = (struct queue_head*)UNCACHED_ADDR(&_qh_array); 354 qh_array = (struct queue_head*)UNCACHED_ADDR(&_qh_array);
345 init_queue_heads(); 355 init_queue_heads();
@@ -467,6 +477,10 @@ void usb_drv_wait(int endpoint, bool send)
467 } 477 }
468} 478}
469 479
480int usb_drv_port_speed(void)
481{
482 return (REG_PORTSC1 & 0x08000000) ? 1 : 0;
483}
470 484
471void usb_drv_set_address(int address) 485void usb_drv_set_address(int address)
472{ 486{
@@ -482,44 +496,87 @@ void usb_drv_reset_endpoint(int endpoint, bool send)
482 while (REG_ENDPTFLUSH & mask); 496 while (REG_ENDPTFLUSH & mask);
483} 497}
484 498
499int usb_drv_get_last_transfer_length(void)
500{
501 struct transfer_descriptor* current_td = first_td;
502 int length = 0;
503
504 while (!((unsigned int)current_td & DTD_NEXT_TERMINATE)) {
505 if ((current_td->size_ioc_sts & 0xff) != 0)
506 return -1;
507
508 length += current_td->reserved -
509 ((current_td->size_ioc_sts & DTD_PACKET_SIZE) >> DTD_LENGTH_BIT_POS);
510 current_td = (struct transfer_descriptor*)current_td->next_td_ptr;
511 }
512 return length;
513}
514int usb_drv_get_last_transfer_status(void)
515{
516 struct transfer_descriptor* current_td = first_td;
517
518 while (!((unsigned int)current_td & DTD_NEXT_TERMINATE)) {
519 if ((current_td->size_ioc_sts & 0xff) != 0)
520 return current_td->size_ioc_sts & 0xff;
521
522 current_td = (struct transfer_descriptor*)current_td->next_td_ptr;
523 }
524 return 0;
525}
526
485/*-------------------------------------------------------------------------*/ 527/*-------------------------------------------------------------------------*/
486 528
487/* manual: 32.14.5.2 */ 529/* manual: 32.14.5.2 */
488static int prime_transfer(int endpoint, void* ptr, int len, bool send) 530static int prime_transfer(int endpoint, void* ptr, int len, bool send)
489{ 531{
490 int timeout;
491 int pipe = endpoint * 2 + (send ? 1 : 0); 532 int pipe = endpoint * 2 + (send ? 1 : 0);
492 unsigned int mask = pipe2mask[pipe]; 533 unsigned int mask = pipe2mask[pipe];
493 struct transfer_descriptor* td = &td_array[pipe]; 534 last_td = 0;
494 struct queue_head* qh = &qh_array[pipe]; 535 struct queue_head* qh = &qh_array[pipe];
536 static long last_tick;
495 537
538/*
496 if (send && endpoint > EP_CONTROL) { 539 if (send && endpoint > EP_CONTROL) {
497 logf("usb: sent %d bytes", len); 540 logf("usb: sent %d bytes", len);
498 } 541 }
542*/
499 543
500 memset(td, 0, sizeof(struct transfer_descriptor)); 544 if (len==0) {
501 td->next_td_ptr = DTD_NEXT_TERMINATE; 545 struct transfer_descriptor* new_td = &td_array[0];
502 td->size_ioc_sts = (len << DTD_LENGTH_BIT_POS) | 546 prepare_td(new_td, 0, ptr, 0);
503 DTD_STATUS_ACTIVE | DTD_IOC; 547
504 td->buff_ptr0 = (unsigned int)ptr; 548 last_td = new_td;
505 td->buff_ptr1 = (unsigned int)ptr + 0x1000; 549 first_td = new_td;
506 td->buff_ptr2 = (unsigned int)ptr + 0x2000; 550 }
507 td->buff_ptr3 = (unsigned int)ptr + 0x3000; 551 else {
508 td->buff_ptr4 = (unsigned int)ptr + 0x4000; 552 int td_idx = 0;
509 td->reserved = len; 553 while (len > 0) {
510 qh->dtd.next_td_ptr = (unsigned int)td; 554 int current_transfer_length = MIN(16384,len);
555 struct transfer_descriptor* new_td = &td_array[td_idx];
556 prepare_td(new_td, last_td, ptr, current_transfer_length);
557
558 last_td = new_td;
559 len -= current_transfer_length;
560 td_idx++;
561 ptr += current_transfer_length;
562 }
563 first_td = &td_array[0];
564 }
565
566 qh->dtd.next_td_ptr = (unsigned int)first_td;
511 qh->dtd.size_ioc_sts &= ~(QH_STATUS_HALT | QH_STATUS_ACTIVE); 567 qh->dtd.size_ioc_sts &= ~(QH_STATUS_HALT | QH_STATUS_ACTIVE);
512 568
513 REG_ENDPTPRIME |= mask; 569 REG_ENDPTPRIME |= mask;
514 570
515 timeout = 10000; 571 last_tick = current_tick;
516 while ((REG_ENDPTPRIME & mask) && --timeout) { 572 while ((REG_ENDPTPRIME & mask)) {
517 if (REG_USBSTS & USBSTS_RESET) 573 if (REG_USBSTS & USBSTS_RESET)
518 return -1; 574 return -1;
519 } 575
520 if (!timeout) { 576 if (TIME_AFTER(current_tick, last_tick + HZ/4)) {
521 logf("prime timeout"); 577 logf("prime timeout");
522 return -2; 578 return -2;
579 }
523 } 580 }
524 581
525 if (!(REG_ENDPTSTATUS & mask)) { 582 if (!(REG_ENDPTSTATUS & mask)) {
@@ -529,23 +586,54 @@ static int prime_transfer(int endpoint, void* ptr, int len, bool send)
529 586
530 if (send) { 587 if (send) {
531 /* wait for transfer to finish */ 588 /* wait for transfer to finish */
532 timeout = 100000; 589 struct transfer_descriptor* current_td = first_td;
533 while ((td->size_ioc_sts & DTD_STATUS_ACTIVE) && --timeout) { 590
534 if (REG_ENDPTCOMPLETE & mask) 591 while (!((unsigned int)current_td & DTD_NEXT_TERMINATE)) {
535 REG_ENDPTCOMPLETE |= mask; 592 while ((current_td->size_ioc_sts & 0xff) == DTD_STATUS_ACTIVE) {
536 593 if (REG_ENDPTCOMPLETE & mask)
537 if (REG_USBSTS & USBSTS_RESET) 594 REG_ENDPTCOMPLETE |= mask;
538 return -4; 595
539 } 596 /* let the host handle timeouts */
540 if (!timeout) { 597 if (REG_USBSTS & USBSTS_RESET) {
541 logf("td never finished"); 598 logf("td interrupted by reset");
542 return -5; 599 return -4;
600 }
601 }
602 if ((current_td->size_ioc_sts & 0xff) != 0) {
603 logf("td failed with error %X",(current_td->size_ioc_sts & 0xff));
604 return -6;
605 }
606 //logf("td finished : %X",current_td->size_ioc_sts & 0xff);
607 current_td=(struct transfer_descriptor*)current_td->next_td_ptr;
543 } 608 }
609 //logf("all tds done");
544 } 610 }
545 611
546 return 0; 612 return 0;
547} 613}
548 614
615static void prepare_td(struct transfer_descriptor* td,
616 struct transfer_descriptor* previous_td,
617 void *ptr, int len)
618{
619 //logf("adding a td : %d",len);
620 memset(td, 0, sizeof(struct transfer_descriptor));
621 td->next_td_ptr = DTD_NEXT_TERMINATE;
622 td->size_ioc_sts = (len<< DTD_LENGTH_BIT_POS) |
623 DTD_STATUS_ACTIVE | DTD_IOC;
624 td->buff_ptr0 = (unsigned int)ptr;
625 td->buff_ptr1 = ((unsigned int)ptr & 0xfffff000) + 0x1000;
626 td->buff_ptr2 = ((unsigned int)ptr & 0xfffff000) + 0x2000;
627 td->buff_ptr3 = ((unsigned int)ptr & 0xfffff000) + 0x3000;
628 td->buff_ptr4 = ((unsigned int)ptr & 0xfffff000) + 0x4000;
629 td->reserved = len;
630
631 if (previous_td != 0) {
632 previous_td->next_td_ptr=(unsigned int)td;
633 previous_td->size_ioc_sts&=~DTD_IOC;// Only an interrupt on the last one
634 }
635}
636
549static void transfer_completed(void) 637static void transfer_completed(void)
550{ 638{
551 int i; 639 int i;
@@ -557,13 +645,16 @@ static void transfer_completed(void)
557 for (i=0; i<NUM_ENDPOINTS; i++) { 645 for (i=0; i<NUM_ENDPOINTS; i++) {
558 int x; 646 int x;
559 for (x=0; x<2; x++) { 647 for (x=0; x<2; x++) {
648 unsigned int status;
560 int pipe = i * 2 + x; 649 int pipe = i * 2 + x;
650
561 if (mask & pipe2mask[pipe]) 651 if (mask & pipe2mask[pipe])
562 usb_core_transfer_complete(i, x ? true : false); 652 usb_core_transfer_complete(i, x ? true : false);
563 653
654 status = usb_drv_get_last_transfer_status();
564 if ((mask & pipe2mask[pipe]) && 655 if ((mask & pipe2mask[pipe]) &&
565 (td_array[pipe].size_ioc_sts & DTD_ERROR_MASK)) { 656 status & DTD_ERROR_MASK) {
566 logf("pipe %d err %x", pipe, td_array[pipe].size_ioc_sts & DTD_ERROR_MASK); 657 logf("pipe %d err %x", pipe, status & DTD_ERROR_MASK);
567 } 658 }
568 } 659 }
569 } 660 }
@@ -600,23 +691,42 @@ static void bus_reset(void)
600 if (!(REG_PORTSC1 & PORTSCX_PORT_RESET)) { 691 if (!(REG_PORTSC1 & PORTSCX_PORT_RESET)) {
601 logf("usb: slow reset!"); 692 logf("usb: slow reset!");
602 } 693 }
694
695 logf("PTS : %X",(REG_PORTSC1 & 0xC0000000)>>30);
696 logf("STS : %X",(REG_PORTSC1 & 0x20000000)>>29);
697 logf("PTW : %X",(REG_PORTSC1 & 0x10000000)>>28);
698 logf("PSPD : %X",(REG_PORTSC1 & 0x0C000000)>>26);
699 logf("PFSC : %X",(REG_PORTSC1 & 0x01000000)>>24);
700 logf("PTC : %X",(REG_PORTSC1 & 0x000F0000)>>16);
701 logf("PO : %X",(REG_PORTSC1 & 0x00002000)>>13);
603} 702}
604 703
605/* manual: 32.14.4.1 Queue Head Initialization */ 704/* manual: 32.14.4.1 Queue Head Initialization */
606static void init_queue_heads(void) 705static void init_queue_heads(void)
607{ 706{
707 int tx_packetsize;
708 int rx_packetsize;
709
710 if (usb_drv_port_speed()) {
711 rx_packetsize = 512;
712 tx_packetsize = 512;
713 }
714 else {
715 rx_packetsize = 16;
716 tx_packetsize = 16;
717 }
608 memset(qh_array, 0, sizeof _qh_array); 718 memset(qh_array, 0, sizeof _qh_array);
609 719
610 /*** control ***/ 720 /*** control ***/
611 qh_array[EP_CONTROL].max_pkt_length = 512 << QH_MAX_PKT_LEN_POS | QH_IOS; 721 qh_array[EP_CONTROL].max_pkt_length = 64 << QH_MAX_PKT_LEN_POS | QH_IOS;
612 qh_array[EP_CONTROL].dtd.next_td_ptr = QH_NEXT_TERMINATE; 722 qh_array[EP_CONTROL].dtd.next_td_ptr = QH_NEXT_TERMINATE;
613 qh_array[EP_CONTROL+1].max_pkt_length = 512 << QH_MAX_PKT_LEN_POS; 723 qh_array[EP_CONTROL+1].max_pkt_length = 64 << QH_MAX_PKT_LEN_POS;
614 qh_array[EP_CONTROL+1].dtd.next_td_ptr = QH_NEXT_TERMINATE; 724 qh_array[EP_CONTROL+1].dtd.next_td_ptr = QH_NEXT_TERMINATE;
615 725
616 /*** bulk ***/ 726 /*** bulk ***/
617 qh_array[EP_RX*2].max_pkt_length = 512 << QH_MAX_PKT_LEN_POS; 727 qh_array[EP_RX*2].max_pkt_length = rx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL;
618 qh_array[EP_RX*2].dtd.next_td_ptr = QH_NEXT_TERMINATE; 728 qh_array[EP_RX*2].dtd.next_td_ptr = QH_NEXT_TERMINATE;
619 qh_array[EP_TX*2+1].max_pkt_length = 512 << QH_MAX_PKT_LEN_POS; 729 qh_array[EP_TX*2+1].max_pkt_length = tx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL;
620 qh_array[EP_TX*2+1].dtd.next_td_ptr = QH_NEXT_TERMINATE; 730 qh_array[EP_TX*2+1].dtd.next_td_ptr = QH_NEXT_TERMINATE;
621} 731}
622 732
diff --git a/firmware/target/arm/usb-fw-pp502x.c b/firmware/target/arm/usb-fw-pp502x.c
index 0813ae1c59..5b71fbd847 100644
--- a/firmware/target/arm/usb-fw-pp502x.c
+++ b/firmware/target/arm/usb-fw-pp502x.c
@@ -68,6 +68,9 @@ void usb_init_device(void)
68void usb_enable(bool on) 68void usb_enable(bool on)
69{ 69{
70 if (on) { 70 if (on) {
71#ifdef USE_ROCKBOX_USB
72 usb_core_init();
73#else
71 /* until we have native mass-storage mode, we want to reboot on 74 /* until we have native mass-storage mode, we want to reboot on
72 usb host connect */ 75 usb host connect */
73#if defined(IRIVER_H10) || defined (IRIVER_H10_5GB) 76#if defined(IRIVER_H10) || defined (IRIVER_H10_5GB)
@@ -89,6 +92,7 @@ void usb_enable(bool on)
89 92
90 system_reboot(); /* Reboot */ 93 system_reboot(); /* Reboot */
91 } 94 }
95#endif /* USE_ROCKBOX_USB */
92 } 96 }
93 else 97 else
94 usb_core_exit(); 98 usb_core_exit();
@@ -195,9 +199,9 @@ int usb_detect(void)
195 return status; 199 return status;
196 } 200 }
197 201
198 /* Wait up to 50 ticks (500ms) before deciding there is no computer 202 /* Wait up to 100 ticks (1s) before deciding there is no computer
199 attached. */ 203 attached. */
200 countdown = 50; 204 countdown = 100;
201 205
202 return status; 206 return status;
203} 207}
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c
index 7e86086dd4..13993f9271 100644
--- a/firmware/usbstack/usb_core.c
+++ b/firmware/usbstack/usb_core.c
@@ -23,10 +23,17 @@
23//#define LOGF_ENABLE 23//#define LOGF_ENABLE
24#include "logf.h" 24#include "logf.h"
25 25
26//#define USB_STORAGE 26#ifndef BOOTLOADER
27//#define USB_SERIAL 27//#define USB_SERIAL
28//#define USB_BENCHMARK 28//#define USB_BENCHMARK
29#ifdef USE_ROCKBOX_USB
30#define USB_STORAGE
31#else
29#define USB_CHARGING_ONLY 32#define USB_CHARGING_ONLY
33#endif /* USE_ROCKBOX_USB */
34#else
35#define USB_CHARGING_ONLY
36#endif
30 37
31#include "usb_ch9.h" 38#include "usb_ch9.h"
32#include "usb_drv.h" 39#include "usb_drv.h"
@@ -63,21 +70,21 @@ static const struct usb_device_descriptor device_descriptor = {
63 .bcdDevice = 0x0100, 70 .bcdDevice = 0x0100,
64 .iManufacturer = 1, 71 .iManufacturer = 1,
65 .iProduct = 2, 72 .iProduct = 2,
66 .iSerialNumber = 0, 73 .iSerialNumber = 3,
67 .bNumConfigurations = 1 74 .bNumConfigurations = 1
68}; 75};
69 76
70static const struct { 77static const struct {
71 struct usb_config_descriptor config_descriptor; 78 struct usb_config_descriptor config_descriptor;
72 struct usb_interface_descriptor interface_descriptor; 79 struct usb_interface_descriptor interface_descriptor;
73 struct usb_endpoint_descriptor ep1_hs_in_descriptor; 80 struct usb_endpoint_descriptor ep1_in_descriptor;
74 struct usb_endpoint_descriptor ep1_hs_out_descriptor; 81 struct usb_endpoint_descriptor ep1_out_descriptor;
75} config_data = 82} config_data_fs =
76{ 83{
77 { 84 {
78 .bLength = sizeof(struct usb_config_descriptor), 85 .bLength = sizeof(struct usb_config_descriptor),
79 .bDescriptorType = USB_DT_CONFIG, 86 .bDescriptorType = USB_DT_CONFIG,
80 .wTotalLength = sizeof config_data, 87 .wTotalLength = sizeof config_data_fs,
81 .bNumInterfaces = 1, 88 .bNumInterfaces = 1,
82 .bConfigurationValue = 1, 89 .bConfigurationValue = 1,
83 .iConfiguration = 0, 90 .iConfiguration = 0,
@@ -96,12 +103,153 @@ static const struct {
96 .bInterfaceClass = USB_CLASS_VENDOR_SPEC, 103 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
97 .bInterfaceSubClass = 0, 104 .bInterfaceSubClass = 0,
98 .bInterfaceProtocol = 0, 105 .bInterfaceProtocol = 0,
106 .iInterface = 5
107 },
108
109 {
110 .bLength = sizeof(struct usb_endpoint_descriptor),
111 .bDescriptorType = USB_DT_ENDPOINT,
112 .bEndpointAddress = EP_TX | USB_DIR_IN,
113 .bmAttributes = USB_ENDPOINT_XFER_BULK,
114 .wMaxPacketSize = 512,
115 .bInterval = 0
116 },
117 {
118 .bLength = sizeof(struct usb_endpoint_descriptor),
119 .bDescriptorType = USB_DT_ENDPOINT,
120 .bEndpointAddress = EP_RX | USB_DIR_OUT,
121 .bmAttributes = USB_ENDPOINT_XFER_BULK,
122 .wMaxPacketSize = 512,
123 .bInterval = 0
124 }
125#endif
126
127#ifdef USB_STORAGE
128 /* storage interface */
129 {
130 .bLength = sizeof(struct usb_interface_descriptor),
131 .bDescriptorType = USB_DT_INTERFACE,
132 .bInterfaceNumber = 0,
133 .bAlternateSetting = 0,
134 .bNumEndpoints = 2,
135 .bInterfaceClass = USB_CLASS_MASS_STORAGE,
136 .bInterfaceSubClass = USB_SC_SCSI,
137 .bInterfaceProtocol = USB_PROT_BULK,
138 .iInterface = 0
139 },
140
141 {
142 .bLength = sizeof(struct usb_endpoint_descriptor),
143 .bDescriptorType = USB_DT_ENDPOINT,
144 .bEndpointAddress = EP_TX | USB_DIR_IN,
145 .bmAttributes = USB_ENDPOINT_XFER_BULK,
146 .wMaxPacketSize = 16,
147 .bInterval = 0
148 },
149 {
150 .bLength = sizeof(struct usb_endpoint_descriptor),
151 .bDescriptorType = USB_DT_ENDPOINT,
152 .bEndpointAddress = EP_RX | USB_DIR_OUT,
153 .bmAttributes = USB_ENDPOINT_XFER_BULK,
154 .wMaxPacketSize = 16,
155 .bInterval = 0
156 }
157#endif
158
159#ifdef USB_SERIAL
160 /* serial interface */
161 {
162 .bLength = sizeof(struct usb_interface_descriptor),
163 .bDescriptorType = USB_DT_INTERFACE,
164 .bInterfaceNumber = 0,
165 .bAlternateSetting = 0,
166 .bNumEndpoints = 2,
167 .bInterfaceClass = USB_CLASS_CDC_DATA,
168 .bInterfaceSubClass = 0,
169 .bInterfaceProtocol = 0,
170 .iInterface = 0
171 },
172
173 {
174 .bLength = sizeof(struct usb_endpoint_descriptor),
175 .bDescriptorType = USB_DT_ENDPOINT,
176 .bEndpointAddress = EP_TX | USB_DIR_IN,
177 .bmAttributes = USB_ENDPOINT_XFER_BULK,
178 .wMaxPacketSize = 64,
179 .bInterval = 0
180 },
181 {
182 .bLength = sizeof(struct usb_endpoint_descriptor),
183 .bDescriptorType = USB_DT_ENDPOINT,
184 .bEndpointAddress = EP_RX | USB_DIR_OUT,
185 .bmAttributes = USB_ENDPOINT_XFER_BULK,
186 .wMaxPacketSize = 64,
187 .bInterval = 0
188 }
189#endif
190
191#ifdef USB_BENCHMARK
192 /* bulk test interface */
193 {
194 .bLength = sizeof(struct usb_interface_descriptor),
195 .bDescriptorType = USB_DT_INTERFACE,
196 .bInterfaceNumber = 0,
197 .bAlternateSetting = 0,
198 .bNumEndpoints = 2,
199 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
200 .bInterfaceSubClass = 255,
201 .bInterfaceProtocol = 255,
99 .iInterface = 4 202 .iInterface = 4
100 }, 203 },
101 204
102 { 205 {
103 .bLength = sizeof(struct usb_endpoint_descriptor), 206 .bLength = sizeof(struct usb_endpoint_descriptor),
104 .bDescriptorType = USB_DT_ENDPOINT, 207 .bDescriptorType = USB_DT_ENDPOINT,
208 .bEndpointAddress = EP_RX | USB_DIR_OUT,
209 .bmAttributes = USB_ENDPOINT_XFER_BULK,
210 .wMaxPacketSize = 64,
211 .bInterval = 0
212 },
213 {
214 .bLength = sizeof(struct usb_endpoint_descriptor),
215 .bDescriptorType = USB_DT_ENDPOINT,
216 .bEndpointAddress = EP_TX | USB_DIR_IN,
217 .bmAttributes = USB_ENDPOINT_XFER_BULK,
218 .wMaxPacketSize = 64,
219 .bInterval = 0
220 }
221#endif
222},
223config_data_hs =
224{
225 {
226 .bLength = sizeof(struct usb_config_descriptor),
227 .bDescriptorType = USB_DT_CONFIG,
228 .wTotalLength = sizeof config_data_hs,
229 .bNumInterfaces = 1,
230 .bConfigurationValue = 1,
231 .iConfiguration = 0,
232 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
233 .bMaxPower = 250, /* 500mA in 2mA units */
234 },
235
236#ifdef USB_CHARGING_ONLY
237 /* dummy interface for charging-only */
238 {
239 .bLength = sizeof(struct usb_interface_descriptor),
240 .bDescriptorType = USB_DT_INTERFACE,
241 .bInterfaceNumber = 0,
242 .bAlternateSetting = 0,
243 .bNumEndpoints = 2,
244 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
245 .bInterfaceSubClass = 0,
246 .bInterfaceProtocol = 0,
247 .iInterface = 5
248 },
249
250 {
251 .bLength = sizeof(struct usb_endpoint_descriptor),
252 .bDescriptorType = USB_DT_ENDPOINT,
105 .bEndpointAddress = EP_TX | USB_DIR_IN, 253 .bEndpointAddress = EP_TX | USB_DIR_IN,
106 .bmAttributes = USB_ENDPOINT_XFER_BULK, 254 .bmAttributes = USB_ENDPOINT_XFER_BULK,
107 .wMaxPacketSize = 512, 255 .wMaxPacketSize = 512,
@@ -168,7 +316,7 @@ static const struct {
168 .bDescriptorType = USB_DT_ENDPOINT, 316 .bDescriptorType = USB_DT_ENDPOINT,
169 .bEndpointAddress = EP_TX | USB_DIR_IN, 317 .bEndpointAddress = EP_TX | USB_DIR_IN,
170 .bmAttributes = USB_ENDPOINT_XFER_BULK, 318 .bmAttributes = USB_ENDPOINT_XFER_BULK,
171 .wMaxPacketSize = 64, 319 .wMaxPacketSize = 512,
172 .bInterval = 0 320 .bInterval = 0
173 }, 321 },
174 { 322 {
@@ -176,7 +324,7 @@ static const struct {
176 .bDescriptorType = USB_DT_ENDPOINT, 324 .bDescriptorType = USB_DT_ENDPOINT,
177 .bEndpointAddress = EP_RX | USB_DIR_OUT, 325 .bEndpointAddress = EP_RX | USB_DIR_OUT,
178 .bmAttributes = USB_ENDPOINT_XFER_BULK, 326 .bmAttributes = USB_ENDPOINT_XFER_BULK,
179 .wMaxPacketSize = 64, 327 .wMaxPacketSize = 512,
180 .bInterval = 0 328 .bInterval = 0
181 } 329 }
182#endif 330#endif
@@ -192,7 +340,7 @@ static const struct {
192 .bInterfaceClass = USB_CLASS_VENDOR_SPEC, 340 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
193 .bInterfaceSubClass = 255, 341 .bInterfaceSubClass = 255,
194 .bInterfaceProtocol = 255, 342 .bInterfaceProtocol = 255,
195 .iInterface = 3 343 .iInterface = 4
196 }, 344 },
197 345
198 { 346 {
@@ -200,7 +348,6 @@ static const struct {
200 .bDescriptorType = USB_DT_ENDPOINT, 348 .bDescriptorType = USB_DT_ENDPOINT,
201 .bEndpointAddress = EP_RX | USB_DIR_OUT, 349 .bEndpointAddress = EP_RX | USB_DIR_OUT,
202 .bmAttributes = USB_ENDPOINT_XFER_BULK, 350 .bmAttributes = USB_ENDPOINT_XFER_BULK,
203// .wMaxPacketSize = 64,
204 .wMaxPacketSize = 512, 351 .wMaxPacketSize = 512,
205 .bInterval = 0 352 .bInterval = 0
206 }, 353 },
@@ -209,7 +356,6 @@ static const struct {
209 .bDescriptorType = USB_DT_ENDPOINT, 356 .bDescriptorType = USB_DT_ENDPOINT,
210 .bEndpointAddress = EP_TX | USB_DIR_IN, 357 .bEndpointAddress = EP_TX | USB_DIR_IN,
211 .bmAttributes = USB_ENDPOINT_XFER_BULK, 358 .bmAttributes = USB_ENDPOINT_XFER_BULK,
212// .wMaxPacketSize = 64,
213 .wMaxPacketSize = 512, 359 .wMaxPacketSize = 512,
214 .bInterval = 0 360 .bInterval = 0
215 } 361 }
@@ -228,72 +374,61 @@ static const struct usb_qualifier_descriptor qualifier_descriptor =
228 .bNumConfigurations = 1 374 .bNumConfigurations = 1
229}; 375};
230 376
231/* full speed = 12 Mbit */ 377static struct usb_string_descriptor usb_string_iManufacturer =
232static const struct usb_endpoint_descriptor ep1_fs_in_descriptor =
233{ 378{
234 .bLength = sizeof(struct usb_endpoint_descriptor), 379 24,
235 .bDescriptorType = USB_DT_ENDPOINT, 380 USB_DT_STRING,
236 .bEndpointAddress = 1 | USB_DIR_IN, 381 {'R','o','c','k','b','o','x','.','o','r','g'}
237 .bmAttributes = USB_ENDPOINT_XFER_BULK,
238 .wMaxPacketSize = 64,
239 .bInterval = 0
240}; 382};
241 383
242static const struct usb_endpoint_descriptor ep1_fs_out_descriptor = 384static struct usb_string_descriptor usb_string_iProduct =
243{ 385{
244 .bLength = sizeof(struct usb_endpoint_descriptor), 386 42,
245 .bDescriptorType = USB_DT_ENDPOINT, 387 USB_DT_STRING,
246 .bEndpointAddress = 1 | USB_DIR_OUT, 388 {'R','o','c','k','b','o','x',' ','m','e','d','i','a',' ','p','l','a','y','e','r'}
247 .bmAttributes = USB_ENDPOINT_XFER_BULK,
248 .wMaxPacketSize = 64,
249 .bInterval = 0
250}; 389};
251 390
252static const struct usb_endpoint_descriptor* ep_descriptors[4] = 391static struct usb_string_descriptor usb_string_iSerial =
253{ 392{
254 &config_data.ep1_hs_in_descriptor, 393 34,
255 &config_data.ep1_hs_out_descriptor, 394 USB_DT_STRING,
256 &ep1_fs_in_descriptor, 395 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}
257 &ep1_fs_out_descriptor
258}; 396};
259 397
398
399/* Generic for all targets */
400
260/* this is stringid #0: languages supported */ 401/* this is stringid #0: languages supported */
261static const struct usb_string_descriptor lang_descriptor = 402static struct usb_string_descriptor lang_descriptor =
262{ 403{
263 sizeof(struct usb_string_descriptor), 404 4,
264 USB_DT_STRING, 405 USB_DT_STRING,
265 {0x0409} /* LANGID US English */ 406 {0x0409} /* LANGID US English */
266}; 407};
267 408
268/* this is stringid #1 and up: the actual strings */ 409static struct usb_string_descriptor usb_string_usb_benchmark =
269static const struct {
270 unsigned char size;
271 unsigned char type;
272 unsigned short string[32];
273} usb_strings[] =
274{ 410{
275 { 411 40,
276 24, 412 USB_DT_STRING,
277 USB_DT_STRING, 413 {'B','u','l','k',' ','t','e','s','t',' ','i','n','t','e','r','f','a','c','e'}
278 {'R','o','c','k','b','o','x','.','o','r','g'}
279 },
280 {
281 42,
282 USB_DT_STRING,
283 {'R','o','c','k','b','o','x',' ','m','e','d','i','a',' ','p','l','a','y','e','r'}
284 },
285 {
286 40,
287 USB_DT_STRING,
288 {'B','u','l','k',' ','t','e','s','t',' ','i','n','t','e','r','f','a','c','e'}
289 },
290 {
291 28,
292 USB_DT_STRING,
293 {'C','h','a','r','g','i','n','g',' ','o','n','l','y'}
294 }
295}; 414};
296 415
416static struct usb_string_descriptor usb_string_charging_only =
417{
418 28,
419 USB_DT_STRING,
420 {'C','h','a','r','g','i','n','g',' ','o','n','l','y'}
421};
422
423static struct usb_string_descriptor* usb_strings[] =
424{
425 &lang_descriptor,
426 &usb_string_iManufacturer,
427 &usb_string_iProduct,
428 &usb_string_iSerial,
429 &usb_string_usb_benchmark,
430 &usb_string_charging_only
431};
297 432
298static int usb_address = 0; 433static int usb_address = 0;
299static bool initialized = false; 434static bool initialized = false;
@@ -310,11 +445,45 @@ static void usb_core_thread(void);
310 445
311static void ack_control(struct usb_ctrlrequest* req); 446static void ack_control(struct usb_ctrlrequest* req);
312 447
448#ifdef IPOD_ARCH
449void set_serial_descriptor(void)
450{
451 static short hex[16] = {'0','1','2','3','4','5','6','7',
452 '8','9','A','B','C','D','E','F'};
453#ifdef IPOD_VIDEO
454 uint32_t* serial = (uint32_t*)(0x20004034);
455#else
456 uint32_t* serial = (uint32_t*)(0x20002034);
457#endif
458
459 /* We need to convert from a little-endian 64-bit int
460 into a utf-16 string of hex characters */
461 short* p = &usb_string_iSerial.wString[15];
462 uint32_t x;
463 int i,j;
464
465 for (i = 0; i < 2; i++)
466 {
467 x = serial[i];
468 for (j=0;j<8;j++)
469 {
470 *p-- = hex[x & 0xf];
471 x >>= 4;
472 }
473 }
474
475}
476#endif
477
313void usb_core_init(void) 478void usb_core_init(void)
314{ 479{
315 if (initialized) 480 if (initialized)
316 return; 481 return;
317 482
483#ifdef IPOD_ARCH
484 set_serial_descriptor();
485#endif
486
318 queue_init(&usbcore_queue, false); 487 queue_init(&usbcore_queue, false);
319 usb_drv_init(); 488 usb_drv_init();
320#ifdef USB_STORAGE 489#ifdef USB_STORAGE
@@ -469,43 +638,25 @@ void usb_core_control_request(struct usb_ctrlrequest* req)
469 break; 638 break;
470 639
471 case USB_DT_CONFIG: 640 case USB_DT_CONFIG:
472 ptr = &config_data; 641 if(usb_drv_port_speed())
473 size = sizeof config_data; 642 {
474 break; 643 ptr = &config_data_hs;
475 644 size = sizeof config_data_hs;
476 case USB_DT_STRING: 645 }
477 switch (index) { 646 else
478 case 0: /* lang descriptor */ 647 {
479 ptr = &lang_descriptor; 648 ptr = &config_data_fs;
480 size = sizeof lang_descriptor; 649 size = sizeof config_data_fs;
481 break;
482
483 default:
484 if ((unsigned)index <= (sizeof(usb_strings)/sizeof(usb_strings[0]))) {
485 index -= 1;
486 ptr = &usb_strings[index];
487 size = usb_strings[index].size;
488 }
489 else {
490 logf("bad string id %d", index);
491 usb_drv_stall(EP_CONTROL, true);
492 }
493 break;
494 } 650 }
495 break; 651 break;
496 652
497 case USB_DT_INTERFACE: 653 case USB_DT_STRING:
498 ptr = &config_data.interface_descriptor; 654 if ((unsigned)index < (sizeof(usb_strings)/sizeof(struct usb_string_descriptor*))) {
499 size = sizeof config_data.interface_descriptor; 655 ptr = usb_strings[index];
500 break; 656 size = usb_strings[index]->bLength;
501
502 case USB_DT_ENDPOINT:
503 if (index <= NUM_ENDPOINTS) {
504 ptr = &ep_descriptors[index];
505 size = sizeof ep_descriptors[index];
506 } 657 }
507 else { 658 else {
508 logf("bad endpoint %d", index); 659 logf("bad string id %d", index);
509 usb_drv_stall(EP_CONTROL, true); 660 usb_drv_stall(EP_CONTROL, true);
510 } 661 }
511 break; 662 break;
@@ -515,12 +666,6 @@ void usb_core_control_request(struct usb_ctrlrequest* req)
515 size = sizeof qualifier_descriptor; 666 size = sizeof qualifier_descriptor;
516 break; 667 break;
517 668
518/*
519 case USB_DT_OTHER_SPEED_CONFIG:
520 ptr = &other_speed_descriptor;
521 size = sizeof other_speed_descriptor;
522 break;
523*/
524 default: 669 default:
525 logf("bad desc %d", req->wValue >> 8); 670 logf("bad desc %d", req->wValue >> 8);
526 usb_drv_stall(EP_CONTROL, true); 671 usb_drv_stall(EP_CONTROL, true);
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c
index b852475663..1fbfe5296d 100644
--- a/firmware/usbstack/usb_storage.c
+++ b/firmware/usbstack/usb_storage.c
@@ -24,6 +24,7 @@
24#include "logf.h" 24#include "logf.h"
25#include "ata.h" 25#include "ata.h"
26#include "hotswap.h" 26#include "hotswap.h"
27#include "disk.h"
27 28
28#define SECTOR_SIZE 512 29#define SECTOR_SIZE 512
29 30
@@ -40,14 +41,20 @@
40#define SCSI_TEST_UNIT_READY 0x00 41#define SCSI_TEST_UNIT_READY 0x00
41#define SCSI_INQUIRY 0x12 42#define SCSI_INQUIRY 0x12
42#define SCSI_MODE_SENSE 0x1a 43#define SCSI_MODE_SENSE 0x1a
44#define SCSI_REQUEST_SENSE 0x03
43#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1e 45#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1e
44#define SCSI_READ_CAPACITY 0x25 46#define SCSI_READ_CAPACITY 0x25
47#define SCSI_READ_FORMAT_CAPACITY 0x23
45#define SCSI_READ_10 0x28 48#define SCSI_READ_10 0x28
46#define SCSI_WRITE_10 0x2a 49#define SCSI_WRITE_10 0x2a
50#define SCSI_START_STOP_UNIT 0x1b
47 51
48#define SCSI_STATUS_GOOD 0x00 52#define SCSI_STATUS_GOOD 0x00
53#define SCSI_STATUS_FAIL 0x01
49#define SCSI_STATUS_CHECK_CONDITION 0x02 54#define SCSI_STATUS_CHECK_CONDITION 0x02
50 55
56#define SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA 0x02000000
57
51 58
52struct inquiry_data { 59struct inquiry_data {
53 unsigned char DeviceType; 60 unsigned char DeviceType;
@@ -62,6 +69,20 @@ struct inquiry_data {
62 unsigned char ProductRevisionLevel[4]; 69 unsigned char ProductRevisionLevel[4];
63} __attribute__ ((packed)); 70} __attribute__ ((packed));
64 71
72struct sense_data {
73 unsigned char ResponseCode;
74 unsigned char Obsolete;
75 unsigned char filemark_eom_ili_sensekey;
76 unsigned int Information;
77 unsigned char AdditionalSenseLength;
78 unsigned int CommandSpecificInformation;
79 unsigned char AdditionalSenseCode;
80 unsigned char AdditionalSenseCodeQualifier;
81 unsigned char FieldReplaceableUnitCode;
82 unsigned char SKSV;
83 unsigned short SenseKeySpecific;
84} __attribute__ ((packed));
85
65struct command_block_wrapper { 86struct command_block_wrapper {
66 unsigned int signature; 87 unsigned int signature;
67 unsigned int tag; 88 unsigned int tag;
@@ -84,26 +105,34 @@ struct capacity {
84 unsigned int block_size; 105 unsigned int block_size;
85} __attribute__ ((packed)); 106} __attribute__ ((packed));
86 107
108struct format_capacity {
109 unsigned int following_length;
110 unsigned int block_count;
111 unsigned int block_size;
112} __attribute__ ((packed));
113
87/* the ARC USB controller can at most buffer 16KB unaligned data */ 114/* the ARC USB controller can at most buffer 16KB unaligned data */
88static unsigned char _transfer_buffer[16384]; 115static unsigned char _transfer_buffer[16384*8] __attribute((aligned (4096)));
89static unsigned char* transfer_buffer; 116static unsigned char* transfer_buffer;
90static struct inquiry_data _inquiry; 117static struct inquiry_data _inquiry CACHEALIGN_ATTR;
91static struct inquiry_data* inquiry; 118static struct inquiry_data* inquiry;
92static struct capacity _capacity_data; 119static struct capacity _capacity_data CACHEALIGN_ATTR;
93static struct capacity* capacity_data; 120static struct capacity* capacity_data;
94 121static struct format_capacity _format_capacity_data CACHEALIGN_ATTR;
95//static unsigned char partial_sector[SECTOR_SIZE]; 122static struct format_capacity* format_capacity_data;
123static struct sense_data _sense_data CACHEALIGN_ATTR;
124static struct sense_data *sense_data;
96 125
97static struct { 126static struct {
98 unsigned int sector; 127 unsigned int sector;
99 unsigned int offset; /* if partial sector */
100 unsigned int count; 128 unsigned int count;
101 unsigned int tag; 129 unsigned int tag;
130 unsigned int lun;
102} current_cmd; 131} current_cmd;
103 132
104 void handle_scsi(struct command_block_wrapper* cbw); 133static void handle_scsi(struct command_block_wrapper* cbw);
105 void send_csw(unsigned int tag, int status); 134static void send_csw(unsigned int tag, int status);
106static void identify2inquiry(void); 135static void identify2inquiry(int lun);
107 136
108static enum { 137static enum {
109 IDLE, 138 IDLE,
@@ -117,7 +146,10 @@ void usb_storage_init(void)
117 inquiry = (void*)UNCACHED_ADDR(&_inquiry); 146 inquiry = (void*)UNCACHED_ADDR(&_inquiry);
118 transfer_buffer = (void*)UNCACHED_ADDR(&_transfer_buffer); 147 transfer_buffer = (void*)UNCACHED_ADDR(&_transfer_buffer);
119 capacity_data = (void*)UNCACHED_ADDR(&_capacity_data); 148 capacity_data = (void*)UNCACHED_ADDR(&_capacity_data);
120 identify2inquiry(); 149 format_capacity_data = (void*)UNCACHED_ADDR(&_format_capacity_data);
150 sense_data = (void*)UNCACHED_ADDR(&_sense_data);
151 state = IDLE;
152 logf("usb_storage_init done");
121} 153}
122 154
123/* called by usb_core_transfer_complete() */ 155/* called by usb_core_transfer_complete() */
@@ -128,21 +160,44 @@ void usb_storage_transfer_complete(int endpoint)
128 switch (endpoint) { 160 switch (endpoint) {
129 case EP_RX: 161 case EP_RX:
130 //logf("ums: %d bytes in", length); 162 //logf("ums: %d bytes in", length);
131 switch (state) { 163 if(state == RECEIVING)
132 case IDLE: 164 {
133 handle_scsi(cbw); 165 int receive_count=usb_drv_get_last_transfer_length();
134 break; 166 logf("scsi write %d %d", current_cmd.sector, current_cmd.count);
135 167 if(usb_drv_get_last_transfer_status()==0)
136 default: 168 {
137 break; 169 if((unsigned int)receive_count!=(SECTOR_SIZE*current_cmd.count))
170 {
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 }
178 else
179 {
180 logf("Transfer failed %X",usb_drv_get_last_transfer_status());
181 send_csw(current_cmd.tag, SCSI_STATUS_CHECK_CONDITION);
182 }
138 } 183 }
139 184 else
140 /* re-prime endpoint */ 185 {
141 usb_drv_recv(EP_RX, transfer_buffer, sizeof _transfer_buffer); 186 state = SENDING;
187 handle_scsi(cbw);
188 }
189
142 break; 190 break;
143 191
144 case EP_TX: 192 case EP_TX:
145 //logf("ums: %d bytes out", length); 193 //logf("ums: out complete");
194 if(state != IDLE)
195 {
196 /* re-prime endpoint. We only need room for commands */
197 state = IDLE;
198 usb_drv_recv(EP_RX, transfer_buffer, 1024);
199 }
200
146 break; 201 break;
147 } 202 }
148} 203}
@@ -156,7 +211,7 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req)
156 211
157 switch (req->bRequest) { 212 switch (req->bRequest) {
158 case USB_BULK_GET_MAX_LUN: { 213 case USB_BULK_GET_MAX_LUN: {
159 static char maxlun = 0; 214 static char maxlun = NUM_VOLUMES - 1;
160 logf("ums: getmaxlun"); 215 logf("ums: getmaxlun");
161 usb_drv_send(EP_CONTROL, UNCACHED_ADDR(&maxlun), 1); 216 usb_drv_send(EP_CONTROL, UNCACHED_ADDR(&maxlun), 1);
162 usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */ 217 usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */
@@ -174,8 +229,9 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req)
174 229
175 case USB_REQ_SET_CONFIGURATION: 230 case USB_REQ_SET_CONFIGURATION:
176 logf("ums: set config"); 231 logf("ums: set config");
177 /* prime rx endpoint */ 232 /* prime rx endpoint. We only need room for commands */
178 usb_drv_recv(EP_RX, transfer_buffer, sizeof _transfer_buffer); 233 state = IDLE;
234 usb_drv_recv(EP_RX, transfer_buffer, 1024);
179 handled = true; 235 handled = true;
180 break; 236 break;
181 } 237 }
@@ -185,50 +241,138 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req)
185 241
186/****************************************************************************/ 242/****************************************************************************/
187 243
188void handle_scsi(struct command_block_wrapper* cbw) 244static void handle_scsi(struct command_block_wrapper* cbw)
189{ 245{
190 /* USB Mass Storage assumes LBA capability. 246 /* USB Mass Storage assumes LBA capability.
191 TODO: support 48-bit LBA */ 247 TODO: support 48-bit LBA */
192 248
249 unsigned int sectors_per_transfer=0;
193 unsigned int length = cbw->data_transfer_length; 250 unsigned int length = cbw->data_transfer_length;
251 unsigned int block_size;
252 unsigned char lun = cbw->lun;
253 unsigned int block_size_mult = 1;
254#ifdef HAVE_HOTSWAP
255 tCardInfo* cinfo = card_get_info(lun);
256 block_size = cinfo->blocksize;
257 if(cinfo->initialized==1)
258 {
259 sectors_per_transfer=(sizeof _transfer_buffer/ block_size);
260 }
261#else
262 block_size = SECTOR_SIZE;
263 sectors_per_transfer=(sizeof _transfer_buffer/ block_size);
264#endif
265
266#ifdef MAX_LOG_SECTOR_SIZE
267 block_size_mult = disk_sector_multiplier;
268#endif
194 269
195 switch (cbw->command_block[0]) { 270 switch (cbw->command_block[0]) {
196 case SCSI_TEST_UNIT_READY: 271 case SCSI_TEST_UNIT_READY:
197 logf("scsi test_unit_ready"); 272 logf("scsi test_unit_ready %d",lun);
273#ifdef HAVE_HOTSWAP
274 if(cinfo->initialized==1)
275 send_csw(cbw->tag, SCSI_STATUS_GOOD);
276 else
277 send_csw(cbw->tag, SCSI_STATUS_FAIL);
278#else
198 send_csw(cbw->tag, SCSI_STATUS_GOOD); 279 send_csw(cbw->tag, SCSI_STATUS_GOOD);
280#endif
199 break; 281 break;
200 282
201 case SCSI_INQUIRY: 283 case SCSI_INQUIRY:
202 logf("scsi inquiry"); 284 logf("scsi inquiry %d",lun);
285 identify2inquiry(lun);
203 length = MIN(length, cbw->command_block[4]); 286 length = MIN(length, cbw->command_block[4]);
204 usb_drv_send(EP_TX, inquiry, MIN(sizeof _inquiry, length)); 287 usb_drv_send(EP_TX, inquiry, MIN(sizeof _inquiry, length));
205 send_csw(cbw->tag, SCSI_STATUS_GOOD); 288 send_csw(cbw->tag, SCSI_STATUS_GOOD);
206 break; 289 break;
207 290
291 case SCSI_REQUEST_SENSE: {
292 sense_data->ResponseCode=0x70;
293 sense_data->filemark_eom_ili_sensekey=2;
294 sense_data->Information=2;
295 sense_data->AdditionalSenseLength=10;
296 sense_data->CommandSpecificInformation=0;
297 sense_data->AdditionalSenseCode=0x3a;
298 sense_data->AdditionalSenseCodeQualifier=0;
299 sense_data->FieldReplaceableUnitCode=0;
300 sense_data->SKSV=0;
301 sense_data->SenseKeySpecific=0;
302 logf("scsi request_sense %d",lun);
303 usb_drv_send(EP_TX, sense_data,
304 sizeof(_sense_data));
305 send_csw(cbw->tag, SCSI_STATUS_GOOD);
306 break;
307 }
308
208 case SCSI_MODE_SENSE: { 309 case SCSI_MODE_SENSE: {
209 static unsigned char sense_data[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 310 static unsigned char sense_data[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
210 logf("scsi mode_sense"); 311 logf("scsi mode_sense %d",lun);
211 usb_drv_send(EP_TX, UNCACHED_ADDR(&sense_data), 312 usb_drv_send(EP_TX, UNCACHED_ADDR(&sense_data),
212 MIN(sizeof sense_data, length)); 313 MIN(sizeof sense_data, length));
213 send_csw(cbw->tag, SCSI_STATUS_GOOD); 314 send_csw(cbw->tag, SCSI_STATUS_GOOD);
214 break; 315 break;
215 } 316 }
216 317
318 case SCSI_START_STOP_UNIT:
319 logf("scsi start_stop unit %d",lun);
320 send_csw(cbw->tag, SCSI_STATUS_GOOD);
321 break;
322
217 case SCSI_ALLOW_MEDIUM_REMOVAL: 323 case SCSI_ALLOW_MEDIUM_REMOVAL:
218 logf("scsi allow_medium_removal"); 324 logf("scsi allow_medium_removal %d",lun);
325 send_csw(cbw->tag, SCSI_STATUS_GOOD);
326 break;
327
328 case SCSI_READ_FORMAT_CAPACITY: {
329 logf("scsi read_format_capacity %d",lun);
330 format_capacity_data->following_length=htobe32(8);
331#ifdef HAVE_HOTSWAP
332 /* Careful: "block count" actually means "number of last block" */
333 if(cinfo->initialized==1)
334 {
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;
350
351 usb_drv_send(EP_TX, format_capacity_data,
352 MIN(sizeof _format_capacity_data, length));
219 send_csw(cbw->tag, SCSI_STATUS_GOOD); 353 send_csw(cbw->tag, SCSI_STATUS_GOOD);
220 break; 354 break;
355 }
221 356
222 case SCSI_READ_CAPACITY: { 357 case SCSI_READ_CAPACITY: {
223 logf("scsi read_capacity"); 358 logf("scsi read_capacity %d",lun);
224#ifdef HAVE_FLASH_STORAGE 359#ifdef HAVE_HOTSWAP
225 tCardInfo* cinfo = card_get_info(0); 360 /* Careful: "block count" actually means "number of last block" */
226 capacity_data->block_count = htobe32(cinfo->numblocks); 361 if(cinfo->initialized==1)
227 capacity_data->block_size = htobe32(cinfo->blocksize); 362 {
363 capacity_data->block_count = htobe32(cinfo->numblocks - 1);
364 capacity_data->block_size = htobe32(cinfo->blocksize);
365 }
366 else
367 {
368 capacity_data->block_count = htobe32(0);
369 capacity_data->block_size = htobe32(0);
370 }
228#else 371#else
229 unsigned short* identify = ata_get_identify(); 372 unsigned short* identify = ata_get_identify();
230 capacity_data->block_count = htobe32(identify[60] << 16 | identify[61]); 373 /* Careful : "block count" actually means the number of the last block */
231 capacity_data->block_size = htobe32(SECTOR_SIZE); 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);
232#endif 376#endif
233 usb_drv_send(EP_TX, capacity_data, 377 usb_drv_send(EP_TX, capacity_data,
234 MIN(sizeof _capacity_data, length)); 378 MIN(sizeof _capacity_data, length));
@@ -237,43 +381,71 @@ void handle_scsi(struct command_block_wrapper* cbw)
237 } 381 }
238 382
239 case SCSI_READ_10: 383 case SCSI_READ_10:
240 current_cmd.sector = 384 current_cmd.sector = block_size_mult *
241 cbw->command_block[2] << 24 | 385 (cbw->command_block[2] << 24 |
242 cbw->command_block[3] << 16 | 386 cbw->command_block[3] << 16 |
243 cbw->command_block[4] << 8 | 387 cbw->command_block[4] << 8 |
244 cbw->command_block[5] ; 388 cbw->command_block[5] );
245 current_cmd.count = 389 current_cmd.count = block_size_mult *
246 cbw->command_block[7] << 16 | 390 (cbw->command_block[7] << 16 |
247 cbw->command_block[8]; 391 cbw->command_block[8]);
248 current_cmd.offset = 0;
249 current_cmd.tag = cbw->tag; 392 current_cmd.tag = cbw->tag;
393 current_cmd.lun = cbw->lun;
250 394
251 logf("scsi read %d %d", current_cmd.sector, current_cmd.count); 395 //logf("scsi read %d %d", current_cmd.sector, current_cmd.count);
252 396
253 /* too much? */ 397 //logf("Asked for %d sectors",current_cmd.count);
254 if (current_cmd.count > (sizeof _transfer_buffer / SECTOR_SIZE)) { 398 if(current_cmd.count > sectors_per_transfer)
255 send_csw(current_cmd.tag, SCSI_STATUS_CHECK_CONDITION); 399 {
256 break; 400 current_cmd.count = sectors_per_transfer;
257 } 401 }
402 //logf("Sending %d sectors",current_cmd.count);
258 403
259 ata_read_sectors(IF_MV2(0,) current_cmd.sector, current_cmd.count, 404 if(current_cmd.count*block_size > sizeof(_transfer_buffer)) {
260 transfer_buffer); 405 send_csw(current_cmd.tag, SCSI_STATUS_CHECK_CONDITION);
261 state = SENDING; 406 }
262 usb_drv_send(EP_TX, transfer_buffer, 407 else {
263 MIN(current_cmd.count * SECTOR_SIZE, length)); 408 ata_read_sectors(IF_MV2(lun,) current_cmd.sector,
409 current_cmd.count, transfer_buffer);
410 usb_drv_send(EP_TX, transfer_buffer,
411 current_cmd.count*block_size);
412 send_csw(current_cmd.tag, SCSI_STATUS_GOOD);
413 }
264 break; 414 break;
265 415
266 case SCSI_WRITE_10: 416 case SCSI_WRITE_10:
267 logf("scsi write10"); 417 //logf("scsi write10");
418 current_cmd.sector = block_size_mult *
419 (cbw->command_block[2] << 24 |
420 cbw->command_block[3] << 16 |
421 cbw->command_block[4] << 8 |
422 cbw->command_block[5] );
423 current_cmd.count = block_size_mult *
424 (cbw->command_block[7] << 16 |
425 cbw->command_block[8]);
426 current_cmd.tag = cbw->tag;
427 current_cmd.lun = cbw->lun;
428 /* expect data */
429 if(current_cmd.count*block_size > sizeof(_transfer_buffer)) {
430 send_csw(current_cmd.tag, SCSI_STATUS_CHECK_CONDITION);
431 }
432 else {
433 usb_drv_recv(EP_RX, transfer_buffer,
434 current_cmd.count*block_size);
435 state = RECEIVING;
436 }
437
268 break; 438 break;
269 439
270 default: 440 default:
271 logf("scsi unknown cmd %x", cbw->command_block[0]); 441 logf("scsi unknown cmd %x",cbw->command_block[0x0]);
442 usb_drv_stall(EP_TX, true);
443 send_csw(current_cmd.tag, SCSI_STATUS_GOOD);
272 break; 444 break;
273 } 445 }
274} 446}
275 447
276void send_csw(unsigned int tag, int status) 448static void send_csw(unsigned int tag, int status)
277{ 449{
278 static struct command_status_wrapper _csw; 450 static struct command_status_wrapper _csw;
279 struct command_status_wrapper* csw = UNCACHED_ADDR(&_csw); 451 struct command_status_wrapper* csw = UNCACHED_ADDR(&_csw);
@@ -287,16 +459,23 @@ void send_csw(unsigned int tag, int status)
287} 459}
288 460
289/* convert ATA IDENTIFY to SCSI INQUIRY */ 461/* convert ATA IDENTIFY to SCSI INQUIRY */
290static void identify2inquiry(void) 462static void identify2inquiry(int lun)
291{ 463{
292 unsigned int i;
293#ifdef HAVE_FLASH_STORAGE 464#ifdef HAVE_FLASH_STORAGE
294 for (i=0; i<8; i++) 465 if(lun==0)
295 inquiry->VendorId[i] = i + 'A'; 466 {
296 467 memcpy(&inquiry->VendorId,"Rockbox ",8);
297 for (i=0; i<8; i++) 468 memcpy(&inquiry->ProductId,"Internal Storage",16);
298 inquiry->ProductId[i] = i + 'm'; 469 memcpy(&inquiry->ProductRevisionLevel,"0.00",4);
470 }
471 else
472 {
473 memcpy(&inquiry->VendorId,"Rockbox ",8);
474 memcpy(&inquiry->ProductId,"SD Card Slot ",16);
475 memcpy(&inquiry->ProductRevisionLevel,"0.00",4);
476 }
299#else 477#else
478 unsigned int i;
300 unsigned short* dest; 479 unsigned short* dest;
301 unsigned short* src; 480 unsigned short* src;
302 unsigned short* identify = ata_get_identify(); 481 unsigned short* identify = ata_get_identify();
@@ -310,22 +489,27 @@ static void identify2inquiry(void)
310 src = (unsigned short*)&identify[27]; 489 src = (unsigned short*)&identify[27];
311 dest = (unsigned short*)&inquiry->VendorId; 490 dest = (unsigned short*)&inquiry->VendorId;
312 for (i=0;i<4;i++) 491 for (i=0;i<4;i++)
313 dest[i] = src[i]; 492 dest[i] = htobe16(src[i]);
314 493
315 src = (unsigned short*)&identify[27+8]; 494 src = (unsigned short*)&identify[27+8];
316 dest = (unsigned short*)&inquiry->ProductId; 495 dest = (unsigned short*)&inquiry->ProductId;
317 for (i=0;i<8;i++) 496 for (i=0;i<8;i++)
318 dest[i] = src[i]; 497 dest[i] = htobe16(src[i]);
319 498
320 src = (unsigned short*)&identify[23]; 499 src = (unsigned short*)&identify[23];
321 dest = (unsigned short*)&inquiry->ProductRevisionLevel; 500 dest = (unsigned short*)&inquiry->ProductRevisionLevel;
322 for (i=0;i<2;i++) 501 for (i=0;i<2;i++)
323 dest[i] = src[i]; 502 dest[i] = htobe16(src[i]);
324#endif 503#endif
325 504
326 inquiry->DeviceType = DIRECT_ACCESS_DEVICE; 505 inquiry->DeviceType = DIRECT_ACCESS_DEVICE;
327 inquiry->AdditionalLength = 0x1f; 506 inquiry->AdditionalLength = 0x1f;
328 inquiry->Versions = 3; /* ANSI SCSI level 2 */ 507 inquiry->Versions = 3; /* ANSI SCSI level 2 */
329 inquiry->Format = 3; /* ANSI SCSI level 2 INQUIRY format */ 508 inquiry->Format = 3; /* ANSI SCSI level 2 INQUIRY format */
509
510#ifdef HAVE_HOTSWAP
511 inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
512#endif
513
330} 514}
331 515