summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-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
8 files changed, 659 insertions, 203 deletions
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