summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrank Gevaerts <frank@gevaerts.be>2008-02-20 22:54:26 +0000
committerFrank Gevaerts <frank@gevaerts.be>2008-02-20 22:54:26 +0000
commit07427592a928ab3d164fbcca842399af6d5ca7ef (patch)
treeeb7b1b748f8ac9ea28ce357290bc5992f5e2403f
parent6af732d17aa1eb882e3c52242b2bf7f2fcccc752 (diff)
downloadrockbox-07427592a928ab3d164fbcca842399af6d5ca7ef.tar.gz
rockbox-07427592a928ab3d164fbcca842399af6d5ca7ef.zip
Major USB stack improvements. It now works at nearly the maximum speed for a full speed connection, and does seem stable.
Still not enabled by default, #define USE_ROCKBOX_USB is still required to enable it. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16360 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/export/usb_ch9.h2
-rw-r--r--firmware/export/usb_core.h43
-rw-r--r--firmware/export/usb_drv.h7
-rw-r--r--firmware/target/arm/usb-drv-pp502x.c346
-rw-r--r--firmware/target/arm/usb-fw-pp502x.c5
-rw-r--r--firmware/usbstack/usb_benchmark.c21
-rw-r--r--firmware/usbstack/usb_benchmark.h2
-rw-r--r--firmware/usbstack/usb_core.c508
-rw-r--r--firmware/usbstack/usb_serial.c34
-rw-r--r--firmware/usbstack/usb_serial.h2
-rw-r--r--firmware/usbstack/usb_storage.c604
-rw-r--r--firmware/usbstack/usb_storage.h3
12 files changed, 977 insertions, 600 deletions
diff --git a/firmware/export/usb_ch9.h b/firmware/export/usb_ch9.h
index 1bfc152a8a..d5885ac9b8 100644
--- a/firmware/export/usb_ch9.h
+++ b/firmware/export/usb_ch9.h
@@ -245,7 +245,7 @@ struct usb_string_descriptor {
245 uint8_t bDescriptorType; 245 uint8_t bDescriptorType;
246 246
247 uint16_t wString[]; /* UTF-16LE encoded */ 247 uint16_t wString[]; /* UTF-16LE encoded */
248} __attribute__ ((packed)); 248} __attribute__ ((packed,aligned(2)));
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
251 * the device supports, not Unicode characters. 251 * the device supports, not Unicode characters.
diff --git a/firmware/export/usb_core.h b/firmware/export/usb_core.h
index 2027cca5e8..73cf5c0127 100644
--- a/firmware/export/usb_core.h
+++ b/firmware/export/usb_core.h
@@ -19,6 +19,22 @@
19#ifndef USB_CORE_H 19#ifndef USB_CORE_H
20#define USB_CORE_H 20#define USB_CORE_H
21 21
22#ifndef BOOTLOADER
23#define USB_THREAD
24
25#ifdef USE_ROCKBOX_USB
26//#define USB_SERIAL
27//#define USB_BENCHMARK
28#define USB_STORAGE
29
30#else
31#define USB_CHARGING_ONLY
32
33#endif /* USE_ROCKBOX_USB */
34#else
35#define USB_CHARGING_ONLY
36#endif /* BOOTLOADER */
37
22#include "usb_ch9.h" 38#include "usb_ch9.h"
23 39
24#if defined(CPU_PP) 40#if defined(CPU_PP)
@@ -26,14 +42,31 @@
26#define USB_IRAM_SIZE ((size_t)0xc000) 42#define USB_IRAM_SIZE ((size_t)0xc000)
27#endif 43#endif
28 44
45
46enum {
47 USB_CORE_QUIT,
48 USB_CORE_TRANSFER_COMPLETION
49};
50
29/* endpoints */ 51/* endpoints */
30enum { 52enum {
31 EP_CONTROL = 0, 53 EP_CONTROL = 0,
32 EP_RX, 54#ifdef USB_STORAGE
33 EP_TX, 55 EP_MASS_STORAGE,
34 NUM_ENDPOINTS 56#endif
57#ifdef USB_SERIAL
58 EP_SERIAL,
59#endif
60#ifdef USB_CHARGING_ONLY
61 EP_CHARGING_ONLY,
62#endif
63#ifdef USB_BENCHMARK
64 EP_BENCHMARK,
65#endif
66 NUM_ENDPOINTS
35}; 67};
36 68
69
37/* queue events */ 70/* queue events */
38#define USB_TRANSFER_COMPLETE 1 71#define USB_TRANSFER_COMPLETE 1
39 72
@@ -48,7 +81,7 @@ extern int usb_max_pkt_size;
48void usb_core_init(void); 81void usb_core_init(void);
49void usb_core_exit(void); 82void usb_core_exit(void);
50void usb_core_control_request(struct usb_ctrlrequest* req); 83void usb_core_control_request(struct usb_ctrlrequest* req);
51void usb_core_transfer_complete(int endpoint, bool in); 84void usb_core_transfer_complete(int endpoint, bool in, int status, int length);
52void usb_core_bus_reset(void); 85void usb_core_bus_reset(void);
53bool usb_core_data_connection(void); 86bool usb_core_data_connection(void);
54 87
diff --git a/firmware/export/usb_drv.h b/firmware/export/usb_drv.h
index 6a37144c1a..430f03bdc7 100644
--- a/firmware/export/usb_drv.h
+++ b/firmware/export/usb_drv.h
@@ -24,16 +24,17 @@
24void usb_drv_init(void); 24void usb_drv_init(void);
25void usb_drv_exit(void); 25void usb_drv_exit(void);
26void usb_drv_int(void); 26void usb_drv_int(void);
27void usb_drv_stall(int endpoint, bool stall); 27void usb_drv_stall(int endpoint, bool stall,bool in);
28bool usb_drv_stalled(int endpoint,bool in);
28int usb_drv_send(int endpoint, void* ptr, int length); 29int usb_drv_send(int endpoint, void* ptr, int length);
30int usb_drv_send_nonblocking(int endpoint, void* ptr, int length);
29int usb_drv_recv(int endpoint, void* ptr, int length); 31int usb_drv_recv(int endpoint, void* ptr, int length);
30void usb_drv_ack(struct usb_ctrlrequest* req); 32void usb_drv_ack(struct usb_ctrlrequest* req);
31void usb_drv_set_address(int address); 33void usb_drv_set_address(int address);
32void usb_drv_reset_endpoint(int endpoint, bool send); 34void usb_drv_reset_endpoint(int endpoint, bool send);
33void usb_drv_wait(int endpoint, bool send); 35void usb_drv_wait(int endpoint, bool send);
34bool usb_drv_powered(void); 36bool 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); 37int usb_drv_port_speed(void);
38void usb_drv_cancel_all_transfers(void);
38 39
39#endif 40#endif
diff --git a/firmware/target/arm/usb-drv-pp502x.c b/firmware/target/arm/usb-drv-pp502x.c
index 413d905293..2d51ce55e9 100644
--- a/firmware/target/arm/usb-drv-pp502x.c
+++ b/firmware/target/arm/usb-drv-pp502x.c
@@ -30,6 +30,10 @@
30 30
31#define REG_ID (*(volatile unsigned int *)(USB_BASE+0x000)) 31#define REG_ID (*(volatile unsigned int *)(USB_BASE+0x000))
32#define REG_HWGENERAL (*(volatile unsigned int *)(USB_BASE+0x004)) 32#define REG_HWGENERAL (*(volatile unsigned int *)(USB_BASE+0x004))
33#define REG_HWHOST (*(volatile unsigned int *)(USB_BASE+0x008))
34#define REG_HWDEVICE (*(volatile unsigned int *)(USB_BASE+0x00c))
35#define REG_TXBUF (*(volatile unsigned int *)(USB_BASE+0x010))
36#define REG_RXBUF (*(volatile unsigned int *)(USB_BASE+0x014))
33#define REG_CAPLENGTH (*(volatile unsigned char*)(USB_BASE+0x100)) 37#define REG_CAPLENGTH (*(volatile unsigned char*)(USB_BASE+0x100))
34#define REG_DCIVERSION (*(volatile unsigned int *)(USB_BASE+0x120)) 38#define REG_DCIVERSION (*(volatile unsigned int *)(USB_BASE+0x120))
35#define REG_DCCPARAMS (*(volatile unsigned int *)(USB_BASE+0x124)) 39#define REG_DCCPARAMS (*(volatile unsigned int *)(USB_BASE+0x124))
@@ -278,6 +282,10 @@
278 DTD_STATUS_DATA_BUFF_ERR | \ 282 DTD_STATUS_DATA_BUFF_ERR | \
279 DTD_STATUS_TRANSACTION_ERR) 283 DTD_STATUS_TRANSACTION_ERR)
280 284
285#define DTD_RESERVED_LENGTH_MASK 0x0001ffff
286#define DTD_RESERVED_IN_USE 0x80000000
287#define DTD_RESERVED_PIPE_MASK 0x0ff00000
288#define DTD_RESERVED_PIPE_OFFSET 20
281/*-------------------------------------------------------------------------*/ 289/*-------------------------------------------------------------------------*/
282 290
283/* manual: 32.13.2 Endpoint Transfer Descriptor (dTD) */ 291/* manual: 32.13.2 Endpoint Transfer Descriptor (dTD) */
@@ -294,7 +302,7 @@ struct transfer_descriptor {
294 unsigned int reserved; 302 unsigned int reserved;
295} __attribute__ ((packed)); 303} __attribute__ ((packed));
296 304
297static struct transfer_descriptor _td_array[32] __attribute((aligned (32))); 305static struct transfer_descriptor _td_array[NUM_ENDPOINTS*2] __attribute((aligned (32)));
298static struct transfer_descriptor* td_array; 306static struct transfer_descriptor* td_array;
299 307
300/* manual: 32.13.1 Endpoint Queue Head (dQH) */ 308/* manual: 32.13.1 Endpoint Queue Head (dQH) */
@@ -304,30 +312,36 @@ struct queue_head {
304 unsigned int curr_dtd_ptr; /* Current dTD Pointer(31-5) */ 312 unsigned int curr_dtd_ptr; /* Current dTD Pointer(31-5) */
305 struct transfer_descriptor dtd; /* dTD overlay */ 313 struct transfer_descriptor dtd; /* dTD overlay */
306 unsigned int setup_buffer[2]; /* Setup data 8 bytes */ 314 unsigned int setup_buffer[2]; /* Setup data 8 bytes */
307 unsigned int reserved[4]; 315 unsigned int reserved; /* for software use, pointer to the first TD */
316 unsigned int status; /* for software use, status of chain in progress */
317 unsigned int length; /* for software use, transfered bytes of chain in progress */
318 unsigned int wait; /* for softwate use, indicates if the transfer is blocking */
308} __attribute__((packed)); 319} __attribute__((packed));
309 320
310static struct queue_head _qh_array[NUM_ENDPOINTS*2] __attribute((aligned (2048))); 321static struct queue_head _qh_array[NUM_ENDPOINTS*2] __attribute((aligned (2048)));
311static struct queue_head* qh_array; 322static struct queue_head* qh_array;
323static struct event_queue transfer_completion_queue[NUM_ENDPOINTS*2];
312 324
313 325
314static const unsigned int pipe2mask[NUM_ENDPOINTS*2] = { 326static const unsigned int pipe2mask[] = {
315 0x01, 0x010000, 327 0x01, 0x010000,
316 0x02, 0x020000, 328 0x02, 0x020000,
317 0x04, 0x040000, 329 0x04, 0x040000,
330 0x08, 0x080000,
331 0x10, 0x100000,
318}; 332};
319 333
320static struct transfer_descriptor* first_td;
321static struct transfer_descriptor* last_td;
322
323/*-------------------------------------------------------------------------*/ 334/*-------------------------------------------------------------------------*/
324static void transfer_completed(void); 335static void transfer_completed(void);
325static int prime_transfer(int endpoint, void* ptr, int len, bool send); 336static void control_received(void);
337static int prime_transfer(int endpoint, void* ptr,
338 int len, bool send, bool wait);
326static void prepare_td(struct transfer_descriptor* td, 339static void prepare_td(struct transfer_descriptor* td,
327 struct transfer_descriptor* previous_td, 340 struct transfer_descriptor* previous_td,
328 void *ptr, int len); 341 void *ptr, int len,int pipe);
329static void bus_reset(void); 342static void bus_reset(void);
330static void init_queue_heads(void); 343static void init_control_queue_heads(void);
344static void init_bulk_queue_heads(void);
331static void init_endpoints(void); 345static void init_endpoints(void);
332/*-------------------------------------------------------------------------*/ 346/*-------------------------------------------------------------------------*/
333 347
@@ -344,6 +358,7 @@ void usb_drv_init(void)
344 REG_USBCMD |= USBCMD_CTRL_RESET; 358 REG_USBCMD |= USBCMD_CTRL_RESET;
345 while (REG_USBCMD & USBCMD_CTRL_RESET); 359 while (REG_USBCMD & USBCMD_CTRL_RESET);
346 360
361
347 REG_USBMODE = USBMODE_CTRL_MODE_DEVICE; 362 REG_USBMODE = USBMODE_CTRL_MODE_DEVICE;
348 363
349 /* Force device to full speed */ 364 /* Force device to full speed */
@@ -352,7 +367,7 @@ void usb_drv_init(void)
352 367
353 td_array = (struct transfer_descriptor*)UNCACHED_ADDR(&_td_array); 368 td_array = (struct transfer_descriptor*)UNCACHED_ADDR(&_td_array);
354 qh_array = (struct queue_head*)UNCACHED_ADDR(&_qh_array); 369 qh_array = (struct queue_head*)UNCACHED_ADDR(&_qh_array);
355 init_queue_heads(); 370 init_control_queue_heads();
356 memset(td_array, 0, sizeof _td_array); 371 memset(td_array, 0, sizeof _td_array);
357 372
358 REG_ENDPOINTLISTADDR = (unsigned int)qh_array; 373 REG_ENDPOINTLISTADDR = (unsigned int)qh_array;
@@ -372,6 +387,7 @@ void usb_drv_init(void)
372 /* go go go */ 387 /* go go go */
373 REG_USBCMD |= USBCMD_RUN; 388 REG_USBCMD |= USBCMD_RUN;
374 389
390
375 logf("usb_drv_init() finished"); 391 logf("usb_drv_init() finished");
376 logf("usb id %x", REG_ID); 392 logf("usb id %x", REG_ID);
377 logf("usb dciversion %x", REG_DCIVERSION); 393 logf("usb dciversion %x", REG_DCIVERSION);
@@ -407,15 +423,7 @@ void usb_drv_int(void)
407 423
408 /* a control packet? */ 424 /* a control packet? */
409 if (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0) { 425 if (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0) {
410 /* copy setup data from packet */ 426 control_received();
411 unsigned int tmp[2];
412 tmp[0] = qh_array[0].setup_buffer[0];
413 tmp[1] = qh_array[0].setup_buffer[1];
414
415 /* acknowledge packet recieved */
416 REG_ENDPTSETUPSTAT |= EPSETUP_STATUS_EP0;
417
418 usb_core_control_request((struct usb_ctrlrequest*)tmp);
419 } 427 }
420 428
421 if (REG_ENDPTCOMPLETE) 429 if (REG_ENDPTCOMPLETE)
@@ -441,29 +449,52 @@ void usb_drv_int(void)
441 } 449 }
442} 450}
443 451
444void usb_drv_stall(int endpoint, bool stall) 452bool usb_drv_stalled(int endpoint,bool in)
453{
454 if(in) {
455 return ((REG_ENDPTCTRL(endpoint) & EPCTRL_TX_EP_STALL)!=0);
456 }
457 else {
458 return ((REG_ENDPTCTRL(endpoint) & EPCTRL_RX_EP_STALL)!=0);
459 }
460
461}
462void usb_drv_stall(int endpoint, bool stall,bool in)
445{ 463{
446 logf("%sstall %d", stall?"":"un", endpoint); 464 logf("%sstall %d", stall?"":"un", endpoint);
447 465
448 if (stall) { 466 if(in) {
449 REG_ENDPTCTRL(endpoint) |= EPCTRL_RX_EP_STALL; 467 if (stall) {
450 REG_ENDPTCTRL(endpoint) |= EPCTRL_TX_EP_STALL; 468 REG_ENDPTCTRL(endpoint) |= EPCTRL_TX_EP_STALL;
469 }
470 else {
471 REG_ENDPTCTRL(endpoint) &= ~EPCTRL_TX_EP_STALL;
472 }
451 } 473 }
452 else { 474 else {
453 REG_ENDPTCTRL(endpoint) &= ~EPCTRL_RX_EP_STALL; 475 if (stall) {
454 REG_ENDPTCTRL(endpoint) &= ~EPCTRL_TX_EP_STALL; 476 REG_ENDPTCTRL(endpoint) |= EPCTRL_RX_EP_STALL;
477 }
478 else {
479 REG_ENDPTCTRL(endpoint) &= ~EPCTRL_RX_EP_STALL;
480 }
455 } 481 }
456} 482}
457 483
484int usb_drv_send_nonblocking(int endpoint, void* ptr, int length)
485{
486 return prime_transfer(endpoint, ptr, length, true, false);
487}
488
458int usb_drv_send(int endpoint, void* ptr, int length) 489int usb_drv_send(int endpoint, void* ptr, int length)
459{ 490{
460 return prime_transfer(endpoint, ptr, length, true); 491 return prime_transfer(endpoint, ptr, length, true, true);
461} 492}
462 493
463int usb_drv_recv(int endpoint, void* ptr, int length) 494int usb_drv_recv(int endpoint, void* ptr, int length)
464{ 495{
465 //logf("usbrecv(%x, %d)", ptr, length); 496 //logf("usbrecv(%x, %d)", ptr, length);
466 return prime_transfer(endpoint, ptr, length, false); 497 return prime_transfer(endpoint, ptr, length, false, false);
467} 498}
468 499
469void usb_drv_wait(int endpoint, bool send) 500void usb_drv_wait(int endpoint, bool send)
@@ -485,6 +516,7 @@ int usb_drv_port_speed(void)
485void usb_drv_set_address(int address) 516void usb_drv_set_address(int address)
486{ 517{
487 REG_DEVICEADDR = address << USBDEVICEADDRESS_BIT_POS; 518 REG_DEVICEADDR = address << USBDEVICEADDRESS_BIT_POS;
519 init_bulk_queue_heads();
488 init_endpoints(); 520 init_endpoints();
489} 521}
490 522
@@ -496,78 +528,43 @@ void usb_drv_reset_endpoint(int endpoint, bool send)
496 while (REG_ENDPTFLUSH & mask); 528 while (REG_ENDPTFLUSH & mask);
497} 529}
498 530
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 531
527/*-------------------------------------------------------------------------*/ 532/*-------------------------------------------------------------------------*/
528 533
529/* manual: 32.14.5.2 */ 534/* manual: 32.14.5.2 */
530static int prime_transfer(int endpoint, void* ptr, int len, bool send) 535static int prime_transfer(int endpoint, void* ptr, int len, bool send, bool wait)
531{ 536{
532 int pipe = endpoint * 2 + (send ? 1 : 0); 537 int pipe = endpoint * 2 + (send ? 1 : 0);
533 unsigned int mask = pipe2mask[pipe]; 538 unsigned int mask = pipe2mask[pipe];
534 last_td = 0;
535 struct queue_head* qh = &qh_array[pipe]; 539 struct queue_head* qh = &qh_array[pipe];
536 static long last_tick; 540 static long last_tick;
541 struct transfer_descriptor* new_td;
537 542
538/* 543/*
539 if (send && endpoint > EP_CONTROL) { 544 if (send && endpoint > EP_CONTROL) {
540 logf("usb: sent %d bytes", len); 545 logf("usb: sent %d bytes", len);
541 } 546 }
542*/ 547*/
548 qh->status = 0;
549 qh->length = 0;
550 qh->wait = wait;
543 551
544 if (len==0) {
545 struct transfer_descriptor* new_td = &td_array[0];
546 prepare_td(new_td, 0, ptr, 0);
547 552
548 last_td = new_td; 553 new_td=&td_array[pipe];
549 first_td = new_td; 554 prepare_td(new_td, 0, ptr, len,pipe);
550 } 555 //logf("starting ep %d %s",endpoint,send?"send":"receive");
551 else {
552 int td_idx = 0;
553 while (len > 0) {
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 556
566 qh->dtd.next_td_ptr = (unsigned int)first_td; 557 qh->dtd.next_td_ptr = (unsigned int)new_td;
567 qh->dtd.size_ioc_sts &= ~(QH_STATUS_HALT | QH_STATUS_ACTIVE); 558 qh->dtd.size_ioc_sts &= ~(QH_STATUS_HALT | QH_STATUS_ACTIVE);
568 559
569 REG_ENDPTPRIME |= mask; 560 REG_ENDPTPRIME |= mask;
570 561
562 if(endpoint == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) {
563 /* 32.14.3.2.2 */
564 logf("new setup arrived");
565 return -4;
566 }
567
571 last_tick = current_tick; 568 last_tick = current_tick;
572 while ((REG_ENDPTPRIME & mask)) { 569 while ((REG_ENDPTPRIME & mask)) {
573 if (REG_USBSTS & USBSTS_RESET) 570 if (REG_USBSTS & USBSTS_RESET)
@@ -583,38 +580,43 @@ static int prime_transfer(int endpoint, void* ptr, int len, bool send)
583 logf("no prime! %d %d %x", endpoint, pipe, qh->dtd.size_ioc_sts & 0xff ); 580 logf("no prime! %d %d %x", endpoint, pipe, qh->dtd.size_ioc_sts & 0xff );
584 return -3; 581 return -3;
585 } 582 }
583 if(endpoint == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) {
584 /* 32.14.3.2.2 */
585 logf("new setup arrived");
586 return -4;
587 }
586 588
587 if (send) { 589 if (wait) {
588 /* wait for transfer to finish */ 590 /* wait for transfer to finish */
589 struct transfer_descriptor* current_td = first_td; 591 struct queue_event ev;
590 592 queue_wait(&transfer_completion_queue[pipe], &ev);
591 while (!((unsigned int)current_td & DTD_NEXT_TERMINATE)) { 593 if(qh->status!=0) {
592 while ((current_td->size_ioc_sts & 0xff) == DTD_STATUS_ACTIVE) { 594 return -5;
593 if (REG_ENDPTCOMPLETE & mask)
594 REG_ENDPTCOMPLETE |= mask;
595
596 /* let the host handle timeouts */
597 if (REG_USBSTS & USBSTS_RESET) {
598 logf("td interrupted by reset");
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;
608 } 595 }
609 //logf("all tds done"); 596 //logf("all tds done");
610 } 597 }
611
612 return 0; 598 return 0;
613} 599}
614 600
601void usb_drv_cancel_all_transfers(void)
602{
603 int i;
604 REG_ENDPTFLUSH = ~0;
605 while (REG_ENDPTFLUSH);
606
607 memset(td_array, 0, sizeof _td_array);
608 for(i=0;i<NUM_ENDPOINTS*2;i++) {
609 if(qh_array[i].wait) {
610 qh_array[i].wait=0;
611 qh_array[i].status=DTD_STATUS_HALTED;
612 queue_post(&transfer_completion_queue[i],0, 0);
613 }
614 }
615}
616
615static void prepare_td(struct transfer_descriptor* td, 617static void prepare_td(struct transfer_descriptor* td,
616 struct transfer_descriptor* previous_td, 618 struct transfer_descriptor* previous_td,
617 void *ptr, int len) 619 void *ptr, int len,int pipe)
618{ 620{
619 //logf("adding a td : %d",len); 621 //logf("adding a td : %d",len);
620 memset(td, 0, sizeof(struct transfer_descriptor)); 622 memset(td, 0, sizeof(struct transfer_descriptor));
@@ -626,35 +628,72 @@ static void prepare_td(struct transfer_descriptor* td,
626 td->buff_ptr2 = ((unsigned int)ptr & 0xfffff000) + 0x2000; 628 td->buff_ptr2 = ((unsigned int)ptr & 0xfffff000) + 0x2000;
627 td->buff_ptr3 = ((unsigned int)ptr & 0xfffff000) + 0x3000; 629 td->buff_ptr3 = ((unsigned int)ptr & 0xfffff000) + 0x3000;
628 td->buff_ptr4 = ((unsigned int)ptr & 0xfffff000) + 0x4000; 630 td->buff_ptr4 = ((unsigned int)ptr & 0xfffff000) + 0x4000;
629 td->reserved = len; 631 td->reserved |= DTD_RESERVED_LENGTH_MASK & len;
632 td->reserved |= DTD_RESERVED_IN_USE;
633 td->reserved |= (pipe << DTD_RESERVED_PIPE_OFFSET);
630 634
631 if (previous_td != 0) { 635 if (previous_td != 0) {
632 previous_td->next_td_ptr=(unsigned int)td; 636 previous_td->next_td_ptr=(unsigned int)td;
633 previous_td->size_ioc_sts&=~DTD_IOC;// Only an interrupt on the last one
634 } 637 }
635} 638}
636 639
637static void transfer_completed(void) 640static void control_received(void)
638{ 641{
639 int i; 642 int i;
643 logf("control stuff");
644 /* copy setup data from packet */
645 static unsigned int tmp[2];
646 tmp[0] = qh_array[0].setup_buffer[0];
647 tmp[1] = qh_array[0].setup_buffer[1];
648
649 /* acknowledge packet recieved */
650 REG_ENDPTSETUPSTAT |= EPSETUP_STATUS_EP0;
651
652 /* Stop pending interrupt transfers */
653 for(i=0;i<2;i++) {
654 if(qh_array[i].wait) {
655 qh_array[i].wait=0;
656 qh_array[i].status=DTD_STATUS_HALTED;
657 queue_post(&transfer_completion_queue[i],0, 0);
658 }
659 }
660
661 usb_core_control_request((struct usb_ctrlrequest*)tmp);
662}
663
664static void transfer_completed(void)
665{
666 int ep;
640 unsigned int mask = REG_ENDPTCOMPLETE; 667 unsigned int mask = REG_ENDPTCOMPLETE;
641 REG_ENDPTCOMPLETE |= mask; 668 REG_ENDPTCOMPLETE |= mask;
642 669
643 //logf("usb comp %x", mask); 670 for (ep=0; ep<NUM_ENDPOINTS; ep++) {
644 671 int dir;
645 for (i=0; i<NUM_ENDPOINTS; i++) { 672 for (dir=0; dir<2; dir++) {
646 int x; 673 int pipe = ep * 2 + dir;
647 for (x=0; x<2; x++) { 674 if (mask & pipe2mask[pipe]) {
648 unsigned int status; 675 struct queue_head* qh = &qh_array[pipe];
649 int pipe = i * 2 + x; 676 struct transfer_descriptor *td = &td_array[pipe];
650 677
651 if (mask & pipe2mask[pipe]) 678 if(td->size_ioc_sts & DTD_STATUS_ACTIVE) {
652 usb_core_transfer_complete(i, x ? true : false); 679 /* TODO this shouldn't happen, but...*/
653 680 break;
654 status = usb_drv_get_last_transfer_status(); 681 }
655 if ((mask & pipe2mask[pipe]) && 682 if((td->size_ioc_sts & DTD_PACKET_SIZE) >> DTD_LENGTH_BIT_POS != 0 && dir==0) {
656 status & DTD_ERROR_MASK) { 683 /* We got less data than we asked for. */
657 logf("pipe %d err %x", pipe, status & DTD_ERROR_MASK); 684 }
685 qh->length = (td->reserved & DTD_RESERVED_LENGTH_MASK) -
686 ((td->size_ioc_sts & DTD_PACKET_SIZE) >> DTD_LENGTH_BIT_POS);
687 if(td->size_ioc_sts & DTD_ERROR_MASK) {
688 logf("pipe %d err %x", pipe, td->size_ioc_sts & DTD_ERROR_MASK);
689 qh->status |= td->size_ioc_sts & DTD_ERROR_MASK;
690 /* TODO we need to handle this somehow. Flush the endpoint ? */
691 }
692 if(qh->wait) {
693 qh->wait=0;
694 queue_post(&transfer_completion_queue[pipe],0, 0);
695 }
696 usb_core_transfer_complete(ep, dir, qh->status, qh->length);
658 } 697 }
659 } 698 }
660 } 699 }
@@ -685,61 +724,66 @@ static void bus_reset(void)
685 logf("usb: short reset timeout"); 724 logf("usb: short reset timeout");
686 } 725 }
687 726
688 REG_ENDPTFLUSH = ~0; 727 usb_drv_cancel_all_transfers();
689 //while (REG_ENDPTFLUSH);
690 728
691 if (!(REG_PORTSC1 & PORTSCX_PORT_RESET)) { 729 if (!(REG_PORTSC1 & PORTSCX_PORT_RESET)) {
692 logf("usb: slow reset!"); 730 logf("usb: slow reset!");
693 } 731 }
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);
702} 732}
703 733
704/* manual: 32.14.4.1 Queue Head Initialization */ 734/* manual: 32.14.4.1 Queue Head Initialization */
705static void init_queue_heads(void) 735static void init_control_queue_heads(void)
736{
737 int i;
738 memset(qh_array, 0, sizeof _qh_array);
739
740 /*** control ***/
741 qh_array[EP_CONTROL].max_pkt_length = 64 << QH_MAX_PKT_LEN_POS | QH_IOS;
742 qh_array[EP_CONTROL].dtd.next_td_ptr = QH_NEXT_TERMINATE;
743 qh_array[EP_CONTROL+1].max_pkt_length = 64 << QH_MAX_PKT_LEN_POS;
744 qh_array[EP_CONTROL+1].dtd.next_td_ptr = QH_NEXT_TERMINATE;
745
746 for(i=0;i<2;i++) {
747 queue_init(&transfer_completion_queue[i], false);
748 }
749}
750/* manual: 32.14.4.1 Queue Head Initialization */
751static void init_bulk_queue_heads(void)
706{ 752{
707 int tx_packetsize; 753 int tx_packetsize;
708 int rx_packetsize; 754 int rx_packetsize;
755 int i;
709 756
710 if (usb_drv_port_speed()) { 757 if (usb_drv_port_speed()) {
711 rx_packetsize = 512; 758 rx_packetsize = 512;
712 tx_packetsize = 512; 759 tx_packetsize = 512;
713 } 760 }
714 else { 761 else {
715 rx_packetsize = 16; 762 rx_packetsize = 64;
716 tx_packetsize = 16; 763 tx_packetsize = 64;
717 } 764 }
718 memset(qh_array, 0, sizeof _qh_array);
719
720 /*** control ***/
721 qh_array[EP_CONTROL].max_pkt_length = 64 << QH_MAX_PKT_LEN_POS | QH_IOS;
722 qh_array[EP_CONTROL].dtd.next_td_ptr = QH_NEXT_TERMINATE;
723 qh_array[EP_CONTROL+1].max_pkt_length = 64 << QH_MAX_PKT_LEN_POS;
724 qh_array[EP_CONTROL+1].dtd.next_td_ptr = QH_NEXT_TERMINATE;
725 765
726 /*** bulk ***/ 766 /*** bulk ***/
727 qh_array[EP_RX*2].max_pkt_length = rx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL; 767 for(i=1;i<NUM_ENDPOINTS;i++) {
728 qh_array[EP_RX*2].dtd.next_td_ptr = QH_NEXT_TERMINATE; 768 qh_array[i*2].max_pkt_length = rx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL;
729 qh_array[EP_TX*2+1].max_pkt_length = tx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL; 769 qh_array[i*2].dtd.next_td_ptr = QH_NEXT_TERMINATE;
730 qh_array[EP_TX*2+1].dtd.next_td_ptr = QH_NEXT_TERMINATE; 770 qh_array[i*2+1].max_pkt_length = tx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL;
771 qh_array[i*2+1].dtd.next_td_ptr = QH_NEXT_TERMINATE;
772 }
773 for(i=2;i<NUM_ENDPOINTS*2;i++) {
774 queue_init(&transfer_completion_queue[i], false);
775 }
731} 776}
732 777
733static void init_endpoints(void) 778static void init_endpoints(void)
734{ 779{
780 int i;
735 /* bulk */ 781 /* bulk */
736 REG_ENDPTCTRL(EP_RX) = 782 for(i=1;i<NUM_ENDPOINTS;i++) {
737 EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE | 783 REG_ENDPTCTRL(i) =
738 (EPCTRL_EP_TYPE_BULK << EPCTRL_RX_EP_TYPE_SHIFT) | 784 EPCTRL_RX_DATA_TOGGLE_RST | EPCTRL_RX_ENABLE |
739 (EPCTRL_EP_TYPE_BULK << EPCTRL_TX_EP_TYPE_SHIFT); 785 EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE |
740 786 (EPCTRL_EP_TYPE_BULK << EPCTRL_RX_EP_TYPE_SHIFT) |
741 REG_ENDPTCTRL(EP_TX) = 787 (EPCTRL_EP_TYPE_BULK << EPCTRL_TX_EP_TYPE_SHIFT);
742 EPCTRL_TX_DATA_TOGGLE_RST | EPCTRL_TX_ENABLE | 788 }
743 (EPCTRL_EP_TYPE_BULK << EPCTRL_RX_EP_TYPE_SHIFT) |
744 (EPCTRL_EP_TYPE_BULK << EPCTRL_TX_EP_TYPE_SHIFT);
745} 789}
diff --git a/firmware/target/arm/usb-fw-pp502x.c b/firmware/target/arm/usb-fw-pp502x.c
index 46a5b9942f..4ac515ba1c 100644
--- a/firmware/target/arm/usb-fw-pp502x.c
+++ b/firmware/target/arm/usb-fw-pp502x.c
@@ -34,6 +34,7 @@ void usb_init_device(void)
34{ 34{
35 /* enable usb module */ 35 /* enable usb module */
36 outl(inl(0x7000002C) | 0x3000000, 0x7000002C); 36 outl(inl(0x7000002C) | 0x3000000, 0x7000002C);
37
37 DEV_EN |= DEV_USB0; 38 DEV_EN |= DEV_USB0;
38 DEV_EN |= DEV_USB1; 39 DEV_EN |= DEV_USB1;
39 40
@@ -46,6 +47,7 @@ void usb_init_device(void)
46#if CONFIG_CPU == PP5020 47#if CONFIG_CPU == PP5020
47 DEV_INIT2 |= INIT_USB; 48 DEV_INIT2 |= INIT_USB;
48#endif 49#endif
50
49 while ((inl(0x70000028) & 0x80) == 0); 51 while ((inl(0x70000028) & 0x80) == 0);
50 outl(inl(0x70000028) | 0x2, 0x70000028); 52 outl(inl(0x70000028) | 0x2, 0x70000028);
51 udelay(0x186A0); 53 udelay(0x186A0);
@@ -68,9 +70,8 @@ void usb_init_device(void)
68void usb_enable(bool on) 70void usb_enable(bool on)
69{ 71{
70 if (on) { 72 if (on) {
71#ifdef USE_ROCKBOX_USB
72 usb_core_init(); 73 usb_core_init();
73#else 74#if !defined(USE_ROCKBOX_USB)
74 /* until we have native mass-storage mode, we want to reboot on 75 /* until we have native mass-storage mode, we want to reboot on
75 usb host connect */ 76 usb host connect */
76#if defined(IRIVER_H10) || defined (IRIVER_H10_5GB) 77#if defined(IRIVER_H10) || defined (IRIVER_H10_5GB)
diff --git a/firmware/usbstack/usb_benchmark.c b/firmware/usbstack/usb_benchmark.c
index a6e0e2d3e7..7cd5a3e987 100644
--- a/firmware/usbstack/usb_benchmark.c
+++ b/firmware/usbstack/usb_benchmark.c
@@ -22,6 +22,8 @@
22//#define LOGF_ENABLE 22//#define LOGF_ENABLE
23#include "logf.h" 23#include "logf.h"
24 24
25#ifdef USB_BENCHMARK
26
25static int current_length; 27static int current_length;
26 28
27static unsigned char _input_buffer[16384]; 29static unsigned char _input_buffer[16384];
@@ -56,8 +58,8 @@ void usb_benchmark_control_request(struct usb_ctrlrequest* req)
56 logf("bench: read %d", current_length); 58 logf("bench: read %d", current_length);
57 todo = MIN(usb_max_pkt_size, current_length); 59 todo = MIN(usb_max_pkt_size, current_length);
58 state = SENDING; 60 state = SENDING;
59 usb_drv_reset_endpoint(EP_TX, true); 61 usb_drv_reset_endpoint(EP_BENCHMARK, true);
60 usb_drv_send(EP_TX, &input_buffer, todo); 62 usb_drv_send(EP_BENCHMARK, &input_buffer, todo);
61 current_length -= todo; 63 current_length -= todo;
62 break; 64 break;
63 65
@@ -66,13 +68,13 @@ void usb_benchmark_control_request(struct usb_ctrlrequest* req)
66 current_length = req->wValue * req->wIndex; 68 current_length = req->wValue * req->wIndex;
67 logf("bench: write %d", current_length); 69 logf("bench: write %d", current_length);
68 state = RECEIVING; 70 state = RECEIVING;
69 usb_drv_reset_endpoint(EP_RX, false); 71 usb_drv_reset_endpoint(EP_BENCHMARK, false);
70 usb_drv_recv(EP_RX, &input_buffer, sizeof _input_buffer); 72 usb_drv_recv(EP_BENCHMARK, &input_buffer, sizeof _input_buffer);
71 break; 73 break;
72 } 74 }
73} 75}
74 76
75void usb_benchmark_transfer_complete(int endpoint, bool in) 77void usb_benchmark_transfer_complete(bool in)
76{ 78{
77 (void)in; 79 (void)in;
78 80
@@ -87,26 +89,26 @@ void usb_benchmark_transfer_complete(int endpoint, bool in)
87 { 89 {
88 case SENDING: { 90 case SENDING: {
89 int todo = MIN(usb_max_pkt_size, current_length); 91 int todo = MIN(usb_max_pkt_size, current_length);
90 if (endpoint == EP_RX) { 92 if (in == false) {
91 logf("unexpected ep_rx"); 93 logf("unexpected ep_rx");
92 break; 94 break;
93 } 95 }
94 96
95 logf("bench: %d more tx", current_length); 97 logf("bench: %d more tx", current_length);
96 usb_drv_send(EP_TX, &input_buffer, todo); 98 usb_drv_send(EP_BENCHMARK, &input_buffer, todo);
97 current_length -= todo; 99 current_length -= todo;
98 input_buffer[0]++; 100 input_buffer[0]++;
99 break; 101 break;
100 } 102 }
101 103
102 case RECEIVING: 104 case RECEIVING:
103 if (endpoint == EP_TX) { 105 if (in == true) {
104 logf("unexpected ep_tx"); 106 logf("unexpected ep_tx");
105 break; 107 break;
106 } 108 }
107 109
108 /* re-prime endpoint */ 110 /* re-prime endpoint */
109 usb_drv_recv(EP_RX, &input_buffer, sizeof _input_buffer); 111 usb_drv_recv(EP_BENCHMARK, &input_buffer, sizeof _input_buffer);
110 input_buffer[0]++; 112 input_buffer[0]++;
111 break; 113 break;
112 114
@@ -123,3 +125,4 @@ static void ack_control(struct usb_ctrlrequest* req)
123 else 125 else
124 usb_drv_send(EP_CONTROL, NULL, 0); 126 usb_drv_send(EP_CONTROL, NULL, 0);
125} 127}
128#endif /*USB_BENCHMARK*/
diff --git a/firmware/usbstack/usb_benchmark.h b/firmware/usbstack/usb_benchmark.h
index 84853a1656..12c32a724f 100644
--- a/firmware/usbstack/usb_benchmark.h
+++ b/firmware/usbstack/usb_benchmark.h
@@ -21,6 +21,6 @@
21 21
22void usb_benchmark_init(void); 22void usb_benchmark_init(void);
23void usb_benchmark_control_request(struct usb_ctrlrequest* req); 23void usb_benchmark_control_request(struct usb_ctrlrequest* req);
24void usb_benchmark_transfer_complete(int endpoint, bool in); 24void usb_benchmark_transfer_complete(bool in);
25 25
26#endif 26#endif
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c
index 13993f9271..c68093b0d2 100644
--- a/firmware/usbstack/usb_core.c
+++ b/firmware/usbstack/usb_core.c
@@ -23,44 +23,42 @@
23//#define LOGF_ENABLE 23//#define LOGF_ENABLE
24#include "logf.h" 24#include "logf.h"
25 25
26#ifndef BOOTLOADER
27//#define USB_SERIAL
28//#define USB_BENCHMARK
29#ifdef USE_ROCKBOX_USB
30#define USB_STORAGE
31#else
32#define USB_CHARGING_ONLY
33#endif /* USE_ROCKBOX_USB */
34#else
35#define USB_CHARGING_ONLY
36#endif
37
38#include "usb_ch9.h" 26#include "usb_ch9.h"
39#include "usb_drv.h" 27#include "usb_drv.h"
40#include "usb_core.h" 28#include "usb_core.h"
41 29
30#define USB_THREAD
31
42#if defined(USB_STORAGE) 32#if defined(USB_STORAGE)
43#include "usb_storage.h" 33#include "usb_storage.h"
44#define USB_THREAD 34#endif
45#elif defined(USB_SERIAL) 35
46#define USB_THREAD 36#if defined(USB_SERIAL)
47#include "usb_serial.h" 37#include "usb_serial.h"
48#elif defined(USB_BENCHMARK) 38#endif
39
40#if defined(USB_BENCHMARK)
49#include "usb_benchmark.h" 41#include "usb_benchmark.h"
50#endif 42#endif
51 43
44/* TODO: Move this target-specific stuff somewhere else (serial number reading) */
45
46#ifdef HAVE_AS3514
47#include "i2c-pp.h"
48#include "as3514.h"
49#endif
50
51
52/*-------------------------------------------------------------------------*/ 52/*-------------------------------------------------------------------------*/
53/* USB protocol descriptors: */ 53/* USB protocol descriptors: */
54 54
55#define USB_SC_SCSI 0x06 /* Transparent */ 55#define USB_SC_SCSI 0x06 /* Transparent */
56#define USB_PROT_BULK 0x50 /* bulk only */ 56#define USB_PROT_BULK 0x50 /* bulk only */
57 57
58int usb_max_pkt_size = 512; 58static const struct usb_device_descriptor device_descriptor= {
59
60static const struct usb_device_descriptor device_descriptor = {
61 .bLength = sizeof(struct usb_device_descriptor), 59 .bLength = sizeof(struct usb_device_descriptor),
62 .bDescriptorType = USB_DT_DEVICE, 60 .bDescriptorType = USB_DT_DEVICE,
63 .bcdUSB = 0x0200, /* USB version 2.0 */ 61 .bcdUSB = 0x0200,
64 .bDeviceClass = USB_CLASS_PER_INTERFACE, 62 .bDeviceClass = USB_CLASS_PER_INTERFACE,
65 .bDeviceSubClass = 0, 63 .bDeviceSubClass = 0,
66 .bDeviceProtocol = 0, 64 .bDeviceProtocol = 0,
@@ -74,158 +72,34 @@ static const struct usb_device_descriptor device_descriptor = {
74 .bNumConfigurations = 1 72 .bNumConfigurations = 1
75}; 73};
76 74
77static const struct { 75static struct {
78 struct usb_config_descriptor config_descriptor; 76 struct usb_config_descriptor config_descriptor;
79 struct usb_interface_descriptor interface_descriptor;
80 struct usb_endpoint_descriptor ep1_in_descriptor;
81 struct usb_endpoint_descriptor ep1_out_descriptor;
82} config_data_fs =
83{
84 {
85 .bLength = sizeof(struct usb_config_descriptor),
86 .bDescriptorType = USB_DT_CONFIG,
87 .wTotalLength = sizeof config_data_fs,
88 .bNumInterfaces = 1,
89 .bConfigurationValue = 1,
90 .iConfiguration = 0,
91 .bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
92 .bMaxPower = 250, /* 500mA in 2mA units */
93 },
94
95#ifdef USB_CHARGING_ONLY 77#ifdef USB_CHARGING_ONLY
96 /* dummy interface for charging-only */ 78 struct usb_interface_descriptor charging_interface_descriptor;
97 { 79 struct usb_endpoint_descriptor charging_ep_in_descriptor;
98 .bLength = sizeof(struct usb_interface_descriptor), 80 struct usb_endpoint_descriptor charging_ep_out_descriptor;
99 .bDescriptorType = USB_DT_INTERFACE,
100 .bInterfaceNumber = 0,
101 .bAlternateSetting = 0,
102 .bNumEndpoints = 2,
103 .bInterfaceClass = USB_CLASS_VENDOR_SPEC,
104 .bInterfaceSubClass = 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 81#endif
126
127#ifdef USB_STORAGE 82#ifdef USB_STORAGE
128 /* storage interface */ 83 struct usb_interface_descriptor mass_storage_interface_descriptor;
129 { 84 struct usb_endpoint_descriptor mass_storage_ep_in_descriptor;
130 .bLength = sizeof(struct usb_interface_descriptor), 85 struct usb_endpoint_descriptor mass_storage_ep_out_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 86#endif
158
159#ifdef USB_SERIAL 87#ifdef USB_SERIAL
160 /* serial interface */ 88 struct usb_interface_descriptor serial_interface_descriptor;
161 { 89 struct usb_endpoint_descriptor serial_ep_in_descriptor;
162 .bLength = sizeof(struct usb_interface_descriptor), 90 struct usb_endpoint_descriptor serial_ep_out_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 91#endif
190
191#ifdef USB_BENCHMARK 92#ifdef USB_BENCHMARK
192 /* bulk test interface */ 93 struct usb_interface_descriptor benchmark_interface_descriptor;
193 { 94 struct usb_endpoint_descriptor benchmark_ep_in_descriptor;
194 .bLength = sizeof(struct usb_interface_descriptor), 95 struct usb_endpoint_descriptor benchmark_ep_out_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,
202 .iInterface = 4
203 },
204
205 {
206 .bLength = sizeof(struct usb_endpoint_descriptor),
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 96#endif
222}, 97} __attribute__((packed)) *config_data, _config_data =
223config_data_hs =
224{ 98{
225 { 99 {
226 .bLength = sizeof(struct usb_config_descriptor), 100 .bLength = sizeof(struct usb_config_descriptor),
227 .bDescriptorType = USB_DT_CONFIG, 101 .bDescriptorType = USB_DT_CONFIG,
228 .wTotalLength = sizeof config_data_hs, 102 .wTotalLength = sizeof _config_data,
229 .bNumInterfaces = 1, 103 .bNumInterfaces = 1,
230 .bConfigurationValue = 1, 104 .bConfigurationValue = 1,
231 .iConfiguration = 0, 105 .iConfiguration = 0,
@@ -246,23 +120,23 @@ config_data_hs =
246 .bInterfaceProtocol = 0, 120 .bInterfaceProtocol = 0,
247 .iInterface = 5 121 .iInterface = 5
248 }, 122 },
249 123/* TODO: try with zero endpoints */
250 { 124 {
251 .bLength = sizeof(struct usb_endpoint_descriptor), 125 .bLength = sizeof(struct usb_endpoint_descriptor),
252 .bDescriptorType = USB_DT_ENDPOINT, 126 .bDescriptorType = USB_DT_ENDPOINT,
253 .bEndpointAddress = EP_TX | USB_DIR_IN, 127 .bEndpointAddress = EP_CHARGING_ONLY | USB_DIR_IN,
254 .bmAttributes = USB_ENDPOINT_XFER_BULK, 128 .bmAttributes = USB_ENDPOINT_XFER_BULK,
255 .wMaxPacketSize = 512, 129 .wMaxPacketSize = 16,
256 .bInterval = 0 130 .bInterval = 0
257 }, 131 },
258 { 132 {
259 .bLength = sizeof(struct usb_endpoint_descriptor), 133 .bLength = sizeof(struct usb_endpoint_descriptor),
260 .bDescriptorType = USB_DT_ENDPOINT, 134 .bDescriptorType = USB_DT_ENDPOINT,
261 .bEndpointAddress = EP_RX | USB_DIR_OUT, 135 .bEndpointAddress = EP_CHARGING_ONLY | USB_DIR_OUT,
262 .bmAttributes = USB_ENDPOINT_XFER_BULK, 136 .bmAttributes = USB_ENDPOINT_XFER_BULK,
263 .wMaxPacketSize = 512, 137 .wMaxPacketSize = 16,
264 .bInterval = 0 138 .bInterval = 0
265 } 139 },
266#endif 140#endif
267 141
268#ifdef USB_STORAGE 142#ifdef USB_STORAGE
@@ -282,19 +156,19 @@ config_data_hs =
282 { 156 {
283 .bLength = sizeof(struct usb_endpoint_descriptor), 157 .bLength = sizeof(struct usb_endpoint_descriptor),
284 .bDescriptorType = USB_DT_ENDPOINT, 158 .bDescriptorType = USB_DT_ENDPOINT,
285 .bEndpointAddress = EP_TX | USB_DIR_IN, 159 .bEndpointAddress = EP_MASS_STORAGE | USB_DIR_IN,
286 .bmAttributes = USB_ENDPOINT_XFER_BULK, 160 .bmAttributes = USB_ENDPOINT_XFER_BULK,
287 .wMaxPacketSize = 512, 161 .wMaxPacketSize = 16,
288 .bInterval = 0 162 .bInterval = 0
289 }, 163 },
290 { 164 {
291 .bLength = sizeof(struct usb_endpoint_descriptor), 165 .bLength = sizeof(struct usb_endpoint_descriptor),
292 .bDescriptorType = USB_DT_ENDPOINT, 166 .bDescriptorType = USB_DT_ENDPOINT,
293 .bEndpointAddress = EP_RX | USB_DIR_OUT, 167 .bEndpointAddress = EP_MASS_STORAGE | USB_DIR_OUT,
294 .bmAttributes = USB_ENDPOINT_XFER_BULK, 168 .bmAttributes = USB_ENDPOINT_XFER_BULK,
295 .wMaxPacketSize = 512, 169 .wMaxPacketSize = 16,
296 .bInterval = 0 170 .bInterval = 0
297 } 171 },
298#endif 172#endif
299 173
300#ifdef USB_SERIAL 174#ifdef USB_SERIAL
@@ -314,19 +188,19 @@ config_data_hs =
314 { 188 {
315 .bLength = sizeof(struct usb_endpoint_descriptor), 189 .bLength = sizeof(struct usb_endpoint_descriptor),
316 .bDescriptorType = USB_DT_ENDPOINT, 190 .bDescriptorType = USB_DT_ENDPOINT,
317 .bEndpointAddress = EP_TX | USB_DIR_IN, 191 .bEndpointAddress = EP_SERIAL | USB_DIR_IN,
318 .bmAttributes = USB_ENDPOINT_XFER_BULK, 192 .bmAttributes = USB_ENDPOINT_XFER_BULK,
319 .wMaxPacketSize = 512, 193 .wMaxPacketSize = 16,
320 .bInterval = 0 194 .bInterval = 0
321 }, 195 },
322 { 196 {
323 .bLength = sizeof(struct usb_endpoint_descriptor), 197 .bLength = sizeof(struct usb_endpoint_descriptor),
324 .bDescriptorType = USB_DT_ENDPOINT, 198 .bDescriptorType = USB_DT_ENDPOINT,
325 .bEndpointAddress = EP_RX | USB_DIR_OUT, 199 .bEndpointAddress = EP_SERIAL | USB_DIR_OUT,
326 .bmAttributes = USB_ENDPOINT_XFER_BULK, 200 .bmAttributes = USB_ENDPOINT_XFER_BULK,
327 .wMaxPacketSize = 512, 201 .wMaxPacketSize = 16,
328 .bInterval = 0 202 .bInterval = 0
329 } 203 },
330#endif 204#endif
331 205
332#ifdef USB_BENCHMARK 206#ifdef USB_BENCHMARK
@@ -346,19 +220,19 @@ config_data_hs =
346 { 220 {
347 .bLength = sizeof(struct usb_endpoint_descriptor), 221 .bLength = sizeof(struct usb_endpoint_descriptor),
348 .bDescriptorType = USB_DT_ENDPOINT, 222 .bDescriptorType = USB_DT_ENDPOINT,
349 .bEndpointAddress = EP_RX | USB_DIR_OUT, 223 .bEndpointAddress = EP_BENCHMARK | USB_DIR_OUT,
350 .bmAttributes = USB_ENDPOINT_XFER_BULK, 224 .bmAttributes = USB_ENDPOINT_XFER_BULK,
351 .wMaxPacketSize = 512, 225 .wMaxPacketSize = 16,
352 .bInterval = 0 226 .bInterval = 0
353 }, 227 },
354 { 228 {
355 .bLength = sizeof(struct usb_endpoint_descriptor), 229 .bLength = sizeof(struct usb_endpoint_descriptor),
356 .bDescriptorType = USB_DT_ENDPOINT, 230 .bDescriptorType = USB_DT_ENDPOINT,
357 .bEndpointAddress = EP_TX | USB_DIR_IN, 231 .bEndpointAddress = EP_BENCHMARK | USB_DIR_IN,
358 .bmAttributes = USB_ENDPOINT_XFER_BULK, 232 .bmAttributes = USB_ENDPOINT_XFER_BULK,
359 .wMaxPacketSize = 512, 233 .wMaxPacketSize = 16,
360 .bInterval = 0 234 .bInterval = 0
361 } 235 },
362#endif 236#endif
363}; 237};
364 238
@@ -388,13 +262,22 @@ static struct usb_string_descriptor usb_string_iProduct =
388 {'R','o','c','k','b','o','x',' ','m','e','d','i','a',' ','p','l','a','y','e','r'} 262 {'R','o','c','k','b','o','x',' ','m','e','d','i','a',' ','p','l','a','y','e','r'}
389}; 263};
390 264
265#if defined(HAVE_AS3514)
391static struct usb_string_descriptor usb_string_iSerial = 266static struct usb_string_descriptor usb_string_iSerial =
392{ 267{
393 34, 268 66,
394 USB_DT_STRING, 269 USB_DT_STRING,
395 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'} 270 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0',
271 '0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}
396}; 272};
397 273#else
274static struct usb_string_descriptor usb_string_iSerial =
275{
276 34,
277 USB_DT_STRING,
278 {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}
279 };
280#endif
398 281
399/* Generic for all targets */ 282/* Generic for all targets */
400 283
@@ -443,10 +326,25 @@ static long usbcore_stack[DEFAULT_STACK_SIZE];
443static void usb_core_thread(void); 326static void usb_core_thread(void);
444#endif 327#endif
445 328
446static void ack_control(struct usb_ctrlrequest* req); 329static void usb_core_control_request_handler(struct usb_ctrlrequest* req);
330static int ack_control(struct usb_ctrlrequest* req);
331
332static unsigned char *response_data;
333static unsigned char __response_data[CACHEALIGN_UP(2)] CACHEALIGN_ATTR;
334
335struct usb_core_event
336{
337 unsigned char endpoint;
338 bool in;
339 int status;
340 int length;
341 void* data;
342};
343
344static struct usb_core_event events[NUM_ENDPOINTS];
447 345
448#ifdef IPOD_ARCH 346#ifdef IPOD_ARCH
449void set_serial_descriptor(void) 347static void set_serial_descriptor(void)
450{ 348{
451 static short hex[16] = {'0','1','2','3','4','5','6','7', 349 static short hex[16] = {'0','1','2','3','4','5','6','7',
452 '8','9','A','B','C','D','E','F'}; 350 '8','9','A','B','C','D','E','F'};
@@ -471,7 +369,23 @@ void set_serial_descriptor(void)
471 x >>= 4; 369 x >>= 4;
472 } 370 }
473 } 371 }
372}
373#elif defined(HAVE_AS3514)
374static void set_serial_descriptor(void)
375{
376 static short hex[16] = {'0','1','2','3','4','5','6','7',
377 '8','9','A','B','C','D','E','F'};
474 378
379 unsigned char serial[16];
380 short* p = usb_string_iSerial.wString;
381 int i;
382
383 i2c_readbytes(AS3514_I2C_ADDR, 0x30, 0x10, serial);
384 for (i = 0; i < 16; i++)
385 {
386 *p++ = hex[(serial[i] >> 4) & 0xF];
387 *p++ = hex[(serial[i] >> 0) & 0xF];
388 }
475} 389}
476#endif 390#endif
477 391
@@ -480,9 +394,8 @@ void usb_core_init(void)
480 if (initialized) 394 if (initialized)
481 return; 395 return;
482 396
483#ifdef IPOD_ARCH 397 config_data = (void*)UNCACHED_ADDR(&_config_data);
484 set_serial_descriptor(); 398 response_data = (void*)UNCACHED_ADDR(&__response_data);
485#endif
486 399
487 queue_init(&usbcore_queue, false); 400 queue_init(&usbcore_queue, false);
488 usb_drv_init(); 401 usb_drv_init();
@@ -514,10 +427,11 @@ void usb_core_exit(void)
514{ 427{
515 if (initialized) { 428 if (initialized) {
516 usb_drv_exit(); 429 usb_drv_exit();
517 queue_delete(&usbcore_queue);
518#ifdef USB_THREAD 430#ifdef USB_THREAD
519 remove_thread(usbcore_thread); 431 queue_post(&usbcore_queue, USB_CORE_QUIT, 0);
432 thread_wait(usbcore_thread);
520#endif 433#endif
434 queue_delete(&usbcore_queue);
521 } 435 }
522 data_connection = false; 436 data_connection = false;
523 initialized = false; 437 initialized = false;
@@ -532,25 +446,52 @@ bool usb_core_data_connection(void)
532#ifdef USB_THREAD 446#ifdef USB_THREAD
533void usb_core_thread(void) 447void usb_core_thread(void)
534{ 448{
449#if defined(IPOD_ARCH) || defined(HAVE_AS3514)
450 set_serial_descriptor();
451#endif
452
535 while (1) { 453 while (1) {
536 struct queue_event ev; 454 struct queue_event ev;
537 455
538 queue_wait(&usbcore_queue, &ev); 456 queue_wait(&usbcore_queue, &ev);
457 if (ev.id == USB_CORE_QUIT) {
458 cancel_cpu_boost();
459 return;
460 }
539 461
462 if (ev.id == USB_CORE_TRANSFER_COMPLETION) {
463 struct usb_core_event* event = (struct usb_core_event*)ev.data;
464 switch(event->endpoint) {
465 case EP_CONTROL:
466 logf("ctrl handled %ld",current_tick);
467 usb_core_control_request_handler((struct usb_ctrlrequest*)event->data);
468 break;
540#ifdef USB_STORAGE 469#ifdef USB_STORAGE
541 usb_storage_transfer_complete(ev.id); 470 case EP_MASS_STORAGE:
471 usb_storage_transfer_complete(event->in,event->status,event->length);
472 break;
542#endif 473#endif
543
544#ifdef USB_SERIAL 474#ifdef USB_SERIAL
545 usb_serial_transfer_complete(ev.id); 475 case EP_SERIAL:
476 usb_serial_transfer_complete(event->in,event->status,event->length);
477 break;
546#endif 478#endif
547 479#ifdef USB_BENCHMARK
480 case EP_BENCHMARK:
481 usb_benchmark_transfer_complete(event->in);
482 break;
483#endif
484#ifdef USB_CHARGING_ONLY
485 case EP_CHARGING_ONLY:
486 break;
487#endif
488 }
489 }
548 } 490 }
549} 491}
550#endif 492#endif
551 493
552/* called by usb_drv_int() */ 494static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
553void usb_core_control_request(struct usb_ctrlrequest* req)
554{ 495{
555 /* note: interrupt context */ 496 /* note: interrupt context */
556 data_connection = true; 497 data_connection = true;
@@ -565,29 +506,31 @@ void usb_core_control_request(struct usb_ctrlrequest* req)
565 switch (req->bRequest) { 506 switch (req->bRequest) {
566 case USB_REQ_SET_CONFIGURATION: 507 case USB_REQ_SET_CONFIGURATION:
567 logf("usb_core: SET_CONFIG"); 508 logf("usb_core: SET_CONFIG");
509 usb_drv_cancel_all_transfers();
510 if (req->wValue){
511 usb_state = CONFIGURED;
568#ifdef USB_STORAGE 512#ifdef USB_STORAGE
569 usb_storage_control_request(req); 513 usb_storage_control_request(req);
570#endif 514#endif
571 515
572#ifdef USB_SERIAL 516#ifdef USB_SERIAL
573 usb_serial_control_request(req); 517 usb_serial_control_request(req);
574#endif 518#endif
575 ack_control(req); 519 }
576 if (req->wValue) 520 else {
577 usb_state = CONFIGURED;
578 else
579 usb_state = ADDRESS; 521 usb_state = ADDRESS;
522 }
523 ack_control(req);
580 break; 524 break;
581 525
582 case USB_REQ_GET_CONFIGURATION: { 526 case USB_REQ_GET_CONFIGURATION: {
583 static char confignum;
584 char* tmp = (void*)UNCACHED_ADDR(&confignum);
585 logf("usb_core: GET_CONFIG"); 527 logf("usb_core: GET_CONFIG");
586 if (usb_state == ADDRESS) 528 if (usb_state == ADDRESS)
587 *tmp = 0; 529 response_data[0] = 0;
588 else 530 else
589 *tmp = 1; 531 response_data[0] = 1;
590 usb_drv_send(EP_CONTROL, tmp, 1); 532 if(usb_drv_send(EP_CONTROL, response_data, 1)!= 0)
533 break;
591 ack_control(req); 534 ack_control(req);
592 break; 535 break;
593 } 536 }
@@ -597,29 +540,54 @@ void usb_core_control_request(struct usb_ctrlrequest* req)
597 ack_control(req); 540 ack_control(req);
598 break; 541 break;
599 542
543 case USB_REQ_GET_INTERFACE:
544 logf("usb_core: GET_INTERFACE");
545 response_data[0] = 0;
546 if(usb_drv_send(EP_CONTROL, response_data, 1)!=0)
547 break;
548 ack_control(req);
549 break;
600 case USB_REQ_CLEAR_FEATURE: 550 case USB_REQ_CLEAR_FEATURE:
601 logf("usb_core: CLEAR_FEATURE"); 551 logf("usb_core: CLEAR_FEATURE");
602 if (req->wValue) 552 if (req->wValue)
603 usb_drv_stall(req->wIndex, true); 553 usb_drv_stall(req->wIndex & 0xf, false,(req->wIndex & 0x80) !=0);
604 else 554 else
605 usb_drv_stall(req->wIndex, false); 555 usb_drv_stall(req->wIndex & 0xf, false,(req->wIndex & 0x80) !=0);
606 ack_control(req); 556 ack_control(req);
607 break; 557 break;
608 558
609 case USB_REQ_SET_ADDRESS: 559 case USB_REQ_SET_FEATURE:
610 usb_address = req->wValue; 560 logf("usb_core: SET_FEATURE");
611 logf("usb_core: SET_ADR %d", usb_address); 561 if (req->wValue)
562 usb_drv_stall(req->wIndex & 0xf, true,(req->wIndex & 0x80) !=0);
563 else
564 usb_drv_stall(req->wIndex & 0xf, false,(req->wIndex & 0x80) !=0);
612 ack_control(req); 565 ack_control(req);
566 break;
567
568 case USB_REQ_SET_ADDRESS: {
569 unsigned char address = req->wValue;
570 logf("usb_core: SET_ADR %d", address);
571 if(ack_control(req)!=0)
572 break;
573 usb_drv_cancel_all_transfers();
574 usb_address = address;
613 usb_drv_set_address(usb_address); 575 usb_drv_set_address(usb_address);
614 usb_state = ADDRESS; 576 usb_state = ADDRESS;
615 break; 577 break;
578 }
616 579
617 case USB_REQ_GET_STATUS: { 580 case USB_REQ_GET_STATUS: {
618 static char tmp[2] = {0,0}; 581 response_data[0]= 0;
619 tmp[0] = 0; 582 response_data[1]= 0;
620 tmp[1] = 0;
621 logf("usb_core: GET_STATUS"); 583 logf("usb_core: GET_STATUS");
622 usb_drv_send(EP_CONTROL, UNCACHED_ADDR(&tmp), 2); 584 if(req->wIndex>0) {
585 if(usb_drv_stalled(req->wIndex&0xf,(req->wIndex&0x80)!=0))
586 response_data[0] = 1;
587 }
588 logf("usb_core: %X %X",response_data[0],response_data[1]);
589 if(usb_drv_send(EP_CONTROL, response_data, 2)!=0)
590 break;
623 ack_control(req); 591 ack_control(req);
624 break; 592 break;
625 } 593 }
@@ -637,18 +605,59 @@ void usb_core_control_request(struct usb_ctrlrequest* req)
637 size = sizeof device_descriptor; 605 size = sizeof device_descriptor;
638 break; 606 break;
639 607
640 case USB_DT_CONFIG: 608 case USB_DT_OTHER_SPEED_CONFIG:
641 if(usb_drv_port_speed()) 609 case USB_DT_CONFIG: {
642 { 610 int max_packet_size;
643 ptr = &config_data_hs; 611 int interface_number=0;
644 size = sizeof config_data_hs; 612
613 if(req->wValue >> 8 == USB_DT_CONFIG) {
614 if(usb_drv_port_speed()) {
615 max_packet_size=512;
616 }
617 else {
618 max_packet_size=64;
619 }
620 config_data->config_descriptor.bDescriptorType=USB_DT_CONFIG;
645 } 621 }
646 else 622 else {
647 { 623 if(usb_drv_port_speed()) {
648 ptr = &config_data_fs; 624 max_packet_size=64;
649 size = sizeof config_data_fs; 625 }
626 else {
627 max_packet_size=512;
628 }
629 config_data->config_descriptor.bDescriptorType=USB_DT_OTHER_SPEED_CONFIG;
650 } 630 }
631
632#ifdef USB_CHARGING_ONLY
633 memcpy(&config_data->charging_ep_in_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short));
634 memcpy(&config_data->charging_ep_out_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short));
635 config_data->charging_interface_descriptor.bInterfaceNumber=interface_number;
636 interface_number++;
637#endif
638#ifdef USB_STORAGE
639 memcpy(&config_data->mass_storage_ep_in_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short));
640 memcpy(&config_data->mass_storage_ep_out_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short));
641 config_data->mass_storage_interface_descriptor.bInterfaceNumber=interface_number;
642 interface_number++;
643#endif
644#ifdef USB_SERIAL
645 memcpy(&config_data->serial_ep_in_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short));
646 memcpy(&config_data->serial_ep_out_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short));
647 config_data->serial_interface_descriptor.bInterfaceNumber=interface_number;
648 interface_number++;
649#endif
650#ifdef USB_BENCHMARK
651 memcpy(&config_data->benchmark_ep_in_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short));
652 memcpy(&config_data->benchmark_ep_out_descriptor.wMaxPacketSize,&max_packet_size,sizeof(unsigned short));
653 config_data.benchmark_interface_descriptor.bInterfaceNumber=interface_number;
654 interface_number++;
655#endif
656 config_data->config_descriptor.bNumInterfaces=interface_number;
657 ptr = config_data;
658 size = sizeof _config_data;
651 break; 659 break;
660 }
652 661
653 case USB_DT_STRING: 662 case USB_DT_STRING:
654 if ((unsigned)index < (sizeof(usb_strings)/sizeof(struct usb_string_descriptor*))) { 663 if ((unsigned)index < (sizeof(usb_strings)/sizeof(struct usb_string_descriptor*))) {
@@ -657,7 +666,7 @@ void usb_core_control_request(struct usb_ctrlrequest* req)
657 } 666 }
658 else { 667 else {
659 logf("bad string id %d", index); 668 logf("bad string id %d", index);
660 usb_drv_stall(EP_CONTROL, true); 669 usb_drv_stall(EP_CONTROL, true,true);
661 } 670 }
662 break; 671 break;
663 672
@@ -668,13 +677,14 @@ void usb_core_control_request(struct usb_ctrlrequest* req)
668 677
669 default: 678 default:
670 logf("bad desc %d", req->wValue >> 8); 679 logf("bad desc %d", req->wValue >> 8);
671 usb_drv_stall(EP_CONTROL, true); 680 usb_drv_stall(EP_CONTROL, true,true);
672 break; 681 break;
673 } 682 }
674 683
675 if (ptr) { 684 if (ptr) {
676 length = MIN(size, length); 685 length = MIN(size, length);
677 usb_drv_send(EP_CONTROL, (void*)UNCACHED_ADDR(ptr), length); 686 if(usb_drv_send(EP_CONTROL, (void*)UNCACHED_ADDR(ptr), length)!=0)
687 break;
678 } 688 }
679 ack_control(req); 689 ack_control(req);
680 break; 690 break;
@@ -693,7 +703,7 @@ void usb_core_control_request(struct usb_ctrlrequest* req)
693 { 703 {
694 /* nope. flag error */ 704 /* nope. flag error */
695 logf("usb bad req %d", req->bRequest); 705 logf("usb bad req %d", req->bRequest);
696 usb_drv_stall(EP_CONTROL, true); 706 usb_drv_stall(EP_CONTROL, true,true);
697 ack_control(req); 707 ack_control(req);
698 } 708 }
699 break; 709 break;
@@ -709,9 +719,9 @@ void usb_core_bus_reset(void)
709} 719}
710 720
711/* called by usb_drv_transfer_completed() */ 721/* called by usb_drv_transfer_completed() */
712void usb_core_transfer_complete(int endpoint, bool in) 722void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
713{ 723{
714#ifdef USB_CHARGING_ONLY 724#if defined(USB_CHARGING_ONLY) || defined(USB_STORAGE)
715 (void)in; 725 (void)in;
716#endif 726#endif
717 727
@@ -720,25 +730,35 @@ void usb_core_transfer_complete(int endpoint, bool in)
720 /* already handled */ 730 /* already handled */
721 break; 731 break;
722 732
723 case EP_RX:
724 case EP_TX:
725#if defined(USB_BENCHMARK)
726 usb_benchmark_transfer_complete(endpoint, in);
727#elif defined(USB_STORAGE) || defined(USB_SERIAL)
728 queue_post(&usbcore_queue, endpoint, 0);
729#endif
730 break;
731
732 default: 733 default:
734 events[endpoint].endpoint=endpoint;
735 events[endpoint].in=in;
736 events[endpoint].data=0;
737 events[endpoint].status=status;
738 events[endpoint].length=length;
739 /* All other endoints. Let the thread deal with it */
740 queue_post(&usbcore_queue, USB_CORE_TRANSFER_COMPLETION, (intptr_t)&events[endpoint]);
733 break; 741 break;
734 } 742 }
735} 743}
736 744
737static void ack_control(struct usb_ctrlrequest* req) 745/* called by usb_drv_int() */
746void usb_core_control_request(struct usb_ctrlrequest* req)
747{
748 events[0].endpoint=0;
749 events[0].in=0;
750 events[0].data=(void *)req;
751 events[0].status=0;
752 events[0].length=0;
753 logf("ctrl received %ld",current_tick);
754 queue_post(&usbcore_queue, USB_CORE_TRANSFER_COMPLETION,(intptr_t)&events[0]);
755}
756
757static int ack_control(struct usb_ctrlrequest* req)
738{ 758{
739 if (req->bRequestType & 0x80) 759 if (req->bRequestType & 0x80)
740 usb_drv_recv(EP_CONTROL, NULL, 0); 760 return usb_drv_recv(EP_CONTROL, NULL, 0);
741 else 761 else
742 usb_drv_send(EP_CONTROL, NULL, 0); 762 return usb_drv_send(EP_CONTROL, NULL, 0);
743} 763}
744 764
diff --git a/firmware/usbstack/usb_serial.c b/firmware/usbstack/usb_serial.c
index 5513c56910..77878092d7 100644
--- a/firmware/usbstack/usb_serial.c
+++ b/firmware/usbstack/usb_serial.c
@@ -23,6 +23,8 @@
23//#define LOGF_ENABLE 23//#define LOGF_ENABLE
24#include "logf.h" 24#include "logf.h"
25 25
26#ifdef USB_SERIAL
27
26static unsigned char _transfer_buffer[16]; 28static unsigned char _transfer_buffer[16];
27static unsigned char* transfer_buffer; 29static unsigned char* transfer_buffer;
28 30
@@ -34,20 +36,26 @@ void usb_serial_init(void)
34} 36}
35 37
36/* called by usb_core_transfer_complete() */ 38/* called by usb_core_transfer_complete() */
37void usb_serial_transfer_complete(int endpoint) 39void usb_serial_transfer_complete(bool in, int status, int length)
38{ 40{
39 switch (endpoint) { 41 int i;
40 case EP_RX: 42 switch (in) {
43 case false:
41 logf("serial: %s", transfer_buffer); 44 logf("serial: %s", transfer_buffer);
42 45 /* Data received. Send it back */
43 /* re-prime endpoint */ 46 for(i=0;i<length;i++) {
44 usb_drv_recv(EP_RX, transfer_buffer, sizeof _transfer_buffer); 47 if(transfer_buffer[i]>0x40 && transfer_buffer[i]<0x5b)
45 48 transfer_buffer[i]+=0x20;
46 /* echo back :) */ 49 else if(transfer_buffer[i]>0x60 && transfer_buffer[i]<0x7b)
47 usb_drv_send(EP_TX, transfer_buffer, sizeof transfer_buffer); 50 transfer_buffer[i]-=0x20;
51 }
52 usb_drv_send_nonblocking(EP_SERIAL, transfer_buffer, length);
48 break; 53 break;
49 54
50 case EP_TX: 55 case true:
56 /* Data sent out (maybe correctly, but we don't actually care.
57 * Re-prime read endpoint */
58 usb_drv_recv(EP_SERIAL, transfer_buffer, sizeof _transfer_buffer);
51 break; 59 break;
52 } 60 }
53} 61}
@@ -55,14 +63,12 @@ void usb_serial_transfer_complete(int endpoint)
55/* called by usb_core_control_request() */ 63/* called by usb_core_control_request() */
56bool usb_serial_control_request(struct usb_ctrlrequest* req) 64bool usb_serial_control_request(struct usb_ctrlrequest* req)
57{ 65{
58 /* note: interrupt context */
59
60 bool handled = false; 66 bool handled = false;
61 switch (req->bRequest) { 67 switch (req->bRequest) {
62 case USB_REQ_SET_CONFIGURATION: 68 case USB_REQ_SET_CONFIGURATION:
63 logf("serial: set config"); 69 logf("serial: set config");
64 /* prime rx endpoint */ 70 /* prime rx endpoint */
65 usb_drv_recv(EP_RX, transfer_buffer, sizeof _transfer_buffer); 71 usb_drv_recv(EP_SERIAL, transfer_buffer, sizeof _transfer_buffer);
66 handled = true; 72 handled = true;
67 break; 73 break;
68 74
@@ -72,3 +78,5 @@ bool usb_serial_control_request(struct usb_ctrlrequest* req)
72 78
73 return handled; 79 return handled;
74} 80}
81
82#endif /*USB_SERIAL*/
diff --git a/firmware/usbstack/usb_serial.h b/firmware/usbstack/usb_serial.h
index d6f970bc9f..60cede9bda 100644
--- a/firmware/usbstack/usb_serial.h
+++ b/firmware/usbstack/usb_serial.h
@@ -22,7 +22,7 @@
22#include "usb_ch9.h" 22#include "usb_ch9.h"
23 23
24void usb_serial_init(void); 24void usb_serial_init(void);
25void usb_serial_transfer_complete(int endpoint); 25void usb_serial_transfer_complete(bool in, int status, int length);
26bool usb_serial_control_request(struct usb_ctrlrequest* req); 26bool usb_serial_control_request(struct usb_ctrlrequest* req);
27 27
28#endif 28#endif
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c
index a1faf3d1c4..0904e17e75 100644
--- a/firmware/usbstack/usb_storage.c
+++ b/firmware/usbstack/usb_storage.c
@@ -26,8 +26,22 @@
26#include "hotswap.h" 26#include "hotswap.h"
27#include "disk.h" 27#include "disk.h"
28 28
29#ifdef USB_STORAGE
30
31/* Enable the following define to export only the SD card slot. This
32 * is useful for USBCV MSC tests, as those are destructive.
33 * This won't work right if the device doesn't have a card slot.
34 */
35//#define ONLY_EXPOSE_CARD_SLOT
36
29#define SECTOR_SIZE 512 37#define SECTOR_SIZE 512
30 38
39/* We can currently use up to 20k buffer size. More than that requires
40 * transfer chaining in the driver. Tests on sansa c200 show that the 16k
41 * limitation causes no more than 2% slowdown.
42 */
43#define BUFFER_SIZE 16384
44
31/* bulk-only class specific requests */ 45/* bulk-only class specific requests */
32#define USB_BULK_RESET_REQUEST 0xff 46#define USB_BULK_RESET_REQUEST 0xff
33#define USB_BULK_GET_MAX_LUN 0xfe 47#define USB_BULK_GET_MAX_LUN 0xfe
@@ -40,7 +54,8 @@
40 54
41#define SCSI_TEST_UNIT_READY 0x00 55#define SCSI_TEST_UNIT_READY 0x00
42#define SCSI_INQUIRY 0x12 56#define SCSI_INQUIRY 0x12
43#define SCSI_MODE_SENSE 0x1a 57#define SCSI_MODE_SENSE_6 0x1a
58#define SCSI_MODE_SENSE_10 0x5a
44#define SCSI_REQUEST_SENSE 0x03 59#define SCSI_REQUEST_SENSE 0x03
45#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1e 60#define SCSI_ALLOW_MEDIUM_REMOVAL 0x1e
46#define SCSI_READ_CAPACITY 0x25 61#define SCSI_READ_CAPACITY 0x25
@@ -48,11 +63,23 @@
48#define SCSI_READ_10 0x28 63#define SCSI_READ_10 0x28
49#define SCSI_WRITE_10 0x2a 64#define SCSI_WRITE_10 0x2a
50#define SCSI_START_STOP_UNIT 0x1b 65#define SCSI_START_STOP_UNIT 0x1b
66#define SCSI_REPORT_LUNS 0xa0
51 67
52#define SCSI_STATUS_GOOD 0x00 68#define SCSI_STATUS_GOOD 0x00
53#define SCSI_STATUS_FAIL 0x01 69#define SCSI_STATUS_FAIL 0x01
54#define SCSI_STATUS_CHECK_CONDITION 0x02 70#define SCSI_STATUS_CHECK_CONDITION 0x02
55 71
72#define SENSE_NOT_READY 0x02
73#define SENSE_MEDIUM_ERROR 0x03
74#define SENSE_ILLEGAL_REQUEST 0x05
75#define SENSE_UNIT_ATTENTION 0x06
76
77#define ASC_MEDIUM_NOT_PRESENT 0x3a
78#define ASC_INVALID_FIELD_IN_CBD 0x24
79#define ASC_LBA_OUT_OF_RANGE 0x21
80#define ASC_WRITE_ERROR 0x0C
81#define ASC_READ_ERROR 0x11
82
56#define SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA 0x02000000 83#define SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA 0x02000000
57 84
58 85
@@ -69,6 +96,15 @@ struct inquiry_data {
69 unsigned char ProductRevisionLevel[4]; 96 unsigned char ProductRevisionLevel[4];
70} __attribute__ ((packed)); 97} __attribute__ ((packed));
71 98
99struct report_lun_data {
100 unsigned int lun_list_length;
101 unsigned int reserved1;
102 unsigned char lun0[8];
103#ifdef HAVE_HOTSWAP
104 unsigned char lun1[8];
105#endif
106} __attribute__ ((packed));
107
72struct sense_data { 108struct sense_data {
73 unsigned char ResponseCode; 109 unsigned char ResponseCode;
74 unsigned char Obsolete; 110 unsigned char Obsolete;
@@ -83,6 +119,21 @@ struct sense_data {
83 unsigned short SenseKeySpecific; 119 unsigned short SenseKeySpecific;
84} __attribute__ ((packed)); 120} __attribute__ ((packed));
85 121
122struct mode_sense_header_10 {
123 unsigned short mode_data_length;
124 unsigned char medium_type;
125 unsigned char device_specific;
126 unsigned char reserved1[2];
127 unsigned short block_descriptor_length;
128} __attribute__ ((packed));
129
130struct mode_sense_header_6 {
131 unsigned char mode_data_length;
132 unsigned char medium_type;
133 unsigned char device_specific;
134 unsigned char block_descriptor_length;
135} __attribute__ ((packed));
136
86struct command_block_wrapper { 137struct command_block_wrapper {
87 unsigned int signature; 138 unsigned int signature;
88 unsigned int tag; 139 unsigned int tag;
@@ -111,93 +162,195 @@ struct format_capacity {
111 unsigned int block_size; 162 unsigned int block_size;
112} __attribute__ ((packed)); 163} __attribute__ ((packed));
113 164
114/* the ARC USB controller can at most buffer 16KB unaligned data */ 165static unsigned char _transfer_buffer[2*BUFFER_SIZE] __attribute((aligned (4096)));
115static unsigned char _transfer_buffer[16384*8] __attribute((aligned (4096)));
116static unsigned char* transfer_buffer; 166static unsigned char* transfer_buffer;
117static struct inquiry_data _inquiry CACHEALIGN_ATTR; 167
118static struct inquiry_data* inquiry; 168static struct inquiry_data* inquiry;
119static struct capacity _capacity_data CACHEALIGN_ATTR; 169static unsigned char __inquiry[CACHEALIGN_UP(sizeof(struct inquiry_data))] CACHEALIGN_ATTR;
170
120static struct capacity* capacity_data; 171static struct capacity* capacity_data;
121static struct format_capacity _format_capacity_data CACHEALIGN_ATTR; 172static unsigned char __capacity_data[CACHEALIGN_UP(sizeof(struct capacity))] CACHEALIGN_ATTR;
173
122static struct format_capacity* format_capacity_data; 174static struct format_capacity* format_capacity_data;
123static struct sense_data _sense_data CACHEALIGN_ATTR; 175static unsigned char __format_capacity_data[CACHEALIGN_UP(sizeof(struct format_capacity))] CACHEALIGN_ATTR;
176
124static struct sense_data *sense_data; 177static struct sense_data *sense_data;
178static unsigned char __sense_data[CACHEALIGN_UP(sizeof(struct sense_data))] CACHEALIGN_ATTR;
179
180static struct mode_sense_header_6 *mode_sense_data_6;
181static unsigned char __mode_sense_data_6[CACHEALIGN_UP(sizeof(struct mode_sense_header_6))] CACHEALIGN_ATTR;
182
183static struct mode_sense_header_10 *mode_sense_data_10;
184static unsigned char __mode_sense_data_10[CACHEALIGN_UP(sizeof(struct mode_sense_header_10))] CACHEALIGN_ATTR;
185
186static struct report_lun_data *lun_data;
187static unsigned char __lun_data[CACHEALIGN_UP(sizeof(struct report_lun_data))] CACHEALIGN_ATTR;
188
189static struct command_status_wrapper* csw;
190static unsigned char __csw[CACHEALIGN_UP(sizeof(struct command_status_wrapper))] CACHEALIGN_ATTR;
191
192static char *max_lun;
193static unsigned char __max_lun[CACHEALIGN_UP(1)] CACHEALIGN_ATTR;
125 194
126static struct { 195static struct {
127 unsigned int sector; 196 unsigned int sector;
128 unsigned int count; 197 unsigned int count;
129 unsigned int tag; 198 unsigned int tag;
130 unsigned int lun; 199 unsigned int lun;
200 unsigned char *data[2];
201 unsigned char data_select;
202 unsigned int last_result;
131} current_cmd; 203} current_cmd;
132 204
205static struct {
206 unsigned char sense_key;
207 unsigned char information;
208 unsigned char asc;
209} cur_sense_data;
210
133static void handle_scsi(struct command_block_wrapper* cbw); 211static void handle_scsi(struct command_block_wrapper* cbw);
134static void send_csw(unsigned int tag, int status); 212static void send_csw(int status);
213static void send_command_result(void *data,int size);
214static void send_block_data(void *data,int size);
215static void receive_block_data(void *data,int size);
135static void identify2inquiry(int lun); 216static void identify2inquiry(int lun);
217static void send_and_read_next(void);
136 218
137static enum { 219static enum {
138 IDLE, 220 WAITING_FOR_COMMAND,
139 SENDING, 221 SENDING_BLOCKS,
140 RECEIVING 222 SENDING_RESULT,
141} state = IDLE; 223 RECEIVING_BLOCKS,
224 SENDING_CSW
225} state = WAITING_FOR_COMMAND;
142 226
143/* called by usb_code_init() */ 227/* called by usb_code_init() */
144void usb_storage_init(void) 228void usb_storage_init(void)
145{ 229{
146 inquiry = (void*)UNCACHED_ADDR(&_inquiry);
147 transfer_buffer = (void*)UNCACHED_ADDR(&_transfer_buffer); 230 transfer_buffer = (void*)UNCACHED_ADDR(&_transfer_buffer);
148 capacity_data = (void*)UNCACHED_ADDR(&_capacity_data); 231 inquiry = (void*)UNCACHED_ADDR(&__inquiry);
149 format_capacity_data = (void*)UNCACHED_ADDR(&_format_capacity_data); 232 capacity_data = (void*)UNCACHED_ADDR(&__capacity_data);
150 sense_data = (void*)UNCACHED_ADDR(&_sense_data); 233 format_capacity_data = (void*)UNCACHED_ADDR(&__format_capacity_data);
151 state = IDLE; 234 sense_data = (void*)UNCACHED_ADDR(&__sense_data);
235 mode_sense_data_6 = (void*)UNCACHED_ADDR(&__mode_sense_data_6);
236 mode_sense_data_10 = (void*)UNCACHED_ADDR(&__mode_sense_data_10);
237 lun_data = (void*)UNCACHED_ADDR(&__lun_data);
238 max_lun = (void*)UNCACHED_ADDR(&__max_lun);
239 csw = (void*)UNCACHED_ADDR(&__csw);
152 logf("usb_storage_init done"); 240 logf("usb_storage_init done");
153} 241}
154 242
155/* called by usb_core_transfer_complete() */ 243/* called by usb_core_transfer_complete() */
156void usb_storage_transfer_complete(int endpoint) 244void usb_storage_transfer_complete(bool in,int status,int length)
157{ 245{
158 struct command_block_wrapper* cbw = (void*)transfer_buffer; 246 struct command_block_wrapper* cbw = (void*)transfer_buffer;
159 247
160 switch (endpoint) { 248 //logf("transfer result %X %d", status, length);
161 case EP_RX: 249 switch(state) {
162 //logf("ums: %d bytes in", length); 250 case RECEIVING_BLOCKS:
163 if(state == RECEIVING) 251 if(in==true) {
164 { 252 logf("IN received in RECEIVING");
165 int receive_count=usb_drv_get_last_transfer_length(); 253 }
166 logf("scsi write %d %d", current_cmd.sector, current_cmd.count); 254 logf("scsi write %d %d", current_cmd.sector, current_cmd.count);
167 if(usb_drv_get_last_transfer_status()==0) 255 if(status==0) {
168 { 256 if((unsigned int)length!=(SECTOR_SIZE*current_cmd.count)
169 if((unsigned int)receive_count!=(SECTOR_SIZE*current_cmd.count)) 257 && (unsigned int)length!=BUFFER_SIZE) {
170 { 258 logf("unexpected length :%d",length);
171 logf("%d >= %d",SECTOR_SIZE*current_cmd.count,receive_count);
172 }
173 ata_write_sectors(IF_MV2(current_cmd.lun,)
174 current_cmd.sector, current_cmd.count,
175 transfer_buffer);
176 send_csw(current_cmd.tag, SCSI_STATUS_GOOD);
177 } 259 }
178 else 260
179 { 261 unsigned int next_sector = current_cmd.sector + (BUFFER_SIZE/SECTOR_SIZE);
180 logf("Transfer failed %X",usb_drv_get_last_transfer_status()); 262 unsigned int next_count = current_cmd.count - MIN(current_cmd.count,BUFFER_SIZE/SECTOR_SIZE);
181 send_csw(current_cmd.tag, SCSI_STATUS_CHECK_CONDITION); 263
264 if(next_count!=0) {
265 /* Ask the host to send more, to the other buffer */
266 receive_block_data(current_cmd.data[!current_cmd.data_select],
267 MIN(BUFFER_SIZE,next_count*SECTOR_SIZE));
182 } 268 }
269
270 /* Now write the data that just came in, while the host is sending the next bit */
271 int result = ata_write_sectors(IF_MV2(current_cmd.lun,)
272 current_cmd.sector, MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count),
273 current_cmd.data[current_cmd.data_select]);
274 if(result != 0) {
275 send_csw(SCSI_STATUS_CHECK_CONDITION);
276 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR;
277 cur_sense_data.asc=ASC_WRITE_ERROR;
278 break;
279 }
280
281 if(next_count==0) {
282 send_csw(SCSI_STATUS_GOOD);
283 }
284
285 /* Switch buffers for the next one */
286 current_cmd.data_select=!current_cmd.data_select;
287
288 current_cmd.sector = next_sector;
289 current_cmd.count = next_count;
290
183 } 291 }
184 else 292 else {
185 { 293 logf("Transfer failed %X",status);
186 state = SENDING; 294 send_csw(SCSI_STATUS_CHECK_CONDITION);
187 handle_scsi(cbw); 295 /* TODO fill in cur_sense_data */
296 cur_sense_data.sense_key=0;
297 cur_sense_data.information=0;
298 cur_sense_data.asc=0;
188 } 299 }
189
190 break; 300 break;
191 301 case WAITING_FOR_COMMAND:
192 case EP_TX: 302 if(in==true) {
193 //logf("ums: out complete"); 303 logf("IN received in WAITING_FOR_COMMAND");
194 if(state != IDLE) 304 }
195 { 305 //logf("command received");
196 /* re-prime endpoint. We only need room for commands */ 306 handle_scsi(cbw);
197 state = IDLE; 307 break;
198 usb_drv_recv(EP_RX, transfer_buffer, 1024); 308 case SENDING_CSW:
309 if(in==false) {
310 logf("OUT received in SENDING_CSW");
311 }
312 //logf("csw sent, now go back to idle");
313 state = WAITING_FOR_COMMAND;
314 usb_drv_recv(EP_MASS_STORAGE, transfer_buffer, 1024);
315 break;
316 case SENDING_RESULT:
317 if(in==false) {
318 logf("OUT received in SENDING");
319 }
320 if(status==0) {
321 //logf("data sent, now send csw");
322 send_csw(SCSI_STATUS_GOOD);
323 }
324 else {
325 logf("Transfer failed %X",status);
326 send_csw(SCSI_STATUS_CHECK_CONDITION);
327 /* TODO fill in cur_sense_data */
328 cur_sense_data.sense_key=0;
329 cur_sense_data.information=0;
330 cur_sense_data.asc=0;
331 }
332 break;
333 case SENDING_BLOCKS:
334 if(in==false) {
335 logf("OUT received in SENDING");
336 }
337 if(status==0) {
338 if(current_cmd.count==0) {
339 //logf("data sent, now send csw");
340 send_csw(SCSI_STATUS_GOOD);
341 }
342 else {
343 send_and_read_next();
344 }
345 }
346 else {
347 logf("Transfer failed %X",status);
348 send_csw(SCSI_STATUS_CHECK_CONDITION);
349 /* TODO fill in cur_sense_data */
350 cur_sense_data.sense_key=0;
351 cur_sense_data.information=0;
352 cur_sense_data.asc=0;
199 } 353 }
200
201 break; 354 break;
202 } 355 }
203} 356}
@@ -205,15 +358,24 @@ void usb_storage_transfer_complete(int endpoint)
205/* called by usb_core_control_request() */ 358/* called by usb_core_control_request() */
206bool usb_storage_control_request(struct usb_ctrlrequest* req) 359bool usb_storage_control_request(struct usb_ctrlrequest* req)
207{ 360{
208 /* note: interrupt context */
209
210 bool handled = false; 361 bool handled = false;
211 362
212 switch (req->bRequest) { 363 switch (req->bRequest) {
213 case USB_BULK_GET_MAX_LUN: { 364 case USB_BULK_GET_MAX_LUN: {
214 static char maxlun = NUM_VOLUMES - 1; 365#ifdef ONLY_EXPOSE_CARD_SLOT
366 *max_lun = 0;
367#else
368 *max_lun = NUM_VOLUMES - 1;
369#endif
370#ifdef HAVE_HOTSWAP
371 /* Workaround until we find out how to do removable devices properly */
372 tCardInfo* cinfo = card_get_info(1);
373 if(cinfo->initialized==0) {
374 *max_lun=0;
375 }
376#endif
215 logf("ums: getmaxlun"); 377 logf("ums: getmaxlun");
216 usb_drv_send(EP_CONTROL, UNCACHED_ADDR(&maxlun), 1); 378 usb_drv_send(EP_CONTROL, UNCACHED_ADDR(max_lun), 1);
217 usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */ 379 usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */
218 handled = true; 380 handled = true;
219 break; 381 break;
@@ -221,8 +383,8 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req)
221 383
222 case USB_BULK_RESET_REQUEST: 384 case USB_BULK_RESET_REQUEST:
223 logf("ums: bulk reset"); 385 logf("ums: bulk reset");
224 usb_drv_reset_endpoint(EP_RX, false); 386 usb_drv_reset_endpoint(EP_MASS_STORAGE, false);
225 usb_drv_reset_endpoint(EP_TX, true); 387 usb_drv_reset_endpoint(EP_MASS_STORAGE, true);
226 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */ 388 usb_drv_send(EP_CONTROL, NULL, 0); /* ack */
227 handled = true; 389 handled = true;
228 break; 390 break;
@@ -230,8 +392,8 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req)
230 case USB_REQ_SET_CONFIGURATION: 392 case USB_REQ_SET_CONFIGURATION:
231 logf("ums: set config"); 393 logf("ums: set config");
232 /* prime rx endpoint. We only need room for commands */ 394 /* prime rx endpoint. We only need room for commands */
233 state = IDLE; 395 state = WAITING_FOR_COMMAND;
234 usb_drv_recv(EP_RX, transfer_buffer, 1024); 396 usb_drv_recv(EP_MASS_STORAGE, transfer_buffer, 1024);
235 handled = true; 397 handled = true;
236 break; 398 break;
237 } 399 }
@@ -239,6 +401,32 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req)
239 return handled; 401 return handled;
240} 402}
241 403
404static void send_and_read_next(void)
405{
406 if(current_cmd.last_result!=0) {
407 /* The last read failed. */
408 send_csw(SCSI_STATUS_CHECK_CONDITION);
409 cur_sense_data.sense_key=SENSE_MEDIUM_ERROR;
410 cur_sense_data.asc=ASC_READ_ERROR;
411 return;
412 }
413 send_block_data(current_cmd.data[current_cmd.data_select],
414 MIN(BUFFER_SIZE,current_cmd.count*SECTOR_SIZE));
415
416 /* Switch buffers for the next one */
417 current_cmd.data_select=!current_cmd.data_select;
418
419 current_cmd.sector+=(BUFFER_SIZE/SECTOR_SIZE);
420 current_cmd.count-=MIN(current_cmd.count,BUFFER_SIZE/SECTOR_SIZE);
421
422 if(current_cmd.count!=0){
423 /* already read the next bit, so we can send it out immediately when the
424 * current transfer completes. */
425 current_cmd.last_result = ata_read_sectors(IF_MV2(current_cmd.lun,) current_cmd.sector,
426 MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count),
427 current_cmd.data[current_cmd.data_select]);
428 }
429}
242/****************************************************************************/ 430/****************************************************************************/
243 431
244static void handle_scsi(struct command_block_wrapper* cbw) 432static void handle_scsi(struct command_block_wrapper* cbw)
@@ -246,141 +434,196 @@ static void handle_scsi(struct command_block_wrapper* cbw)
246 /* USB Mass Storage assumes LBA capability. 434 /* USB Mass Storage assumes LBA capability.
247 TODO: support 48-bit LBA */ 435 TODO: support 48-bit LBA */
248 436
249 unsigned int sectors_per_transfer=0;
250 unsigned int length = cbw->data_transfer_length; 437 unsigned int length = cbw->data_transfer_length;
251 unsigned int block_size; 438 unsigned int block_size;
439 unsigned int block_count;
440 bool lun_present=true;
441#ifdef ONLY_EXPOSE_CARD_SLOT
442 unsigned char lun = cbw->lun+1;
443#else
252 unsigned char lun = cbw->lun; 444 unsigned char lun = cbw->lun;
445#endif
253 unsigned int block_size_mult = 1; 446 unsigned int block_size_mult = 1;
254#ifdef HAVE_HOTSWAP 447#ifdef HAVE_HOTSWAP
255 tCardInfo* cinfo = card_get_info(lun); 448 tCardInfo* cinfo = card_get_info(lun);
256 block_size = cinfo->blocksize; 449 if(cinfo->initialized==1) {
257 if(cinfo->initialized==1) 450 block_size = cinfo->blocksize;
258 { 451 block_count = cinfo->numblocks;
259 sectors_per_transfer=(sizeof _transfer_buffer/ block_size); 452 }
453 else {
454 lun_present=false;
455 block_size = 0;
456 block_count = 0;
260 } 457 }
261#else 458#else
459 unsigned short* identify = ata_get_identify();
262 block_size = SECTOR_SIZE; 460 block_size = SECTOR_SIZE;
263 sectors_per_transfer=(sizeof _transfer_buffer/ block_size); 461 block_count = (identify[61] << 16 | identify[60]);
264#endif 462#endif
265 463
266#ifdef MAX_LOG_SECTOR_SIZE 464#ifdef MAX_LOG_SECTOR_SIZE
267 block_size_mult = disk_sector_multiplier; 465 block_size_mult = disk_sector_multiplier;
268#endif 466#endif
269 467
468 current_cmd.tag = cbw->tag;
469 current_cmd.lun = lun;
470
270 switch (cbw->command_block[0]) { 471 switch (cbw->command_block[0]) {
271 case SCSI_TEST_UNIT_READY: 472 case SCSI_TEST_UNIT_READY:
272 logf("scsi test_unit_ready %d",lun); 473 logf("scsi test_unit_ready %d",lun);
273#ifdef HAVE_HOTSWAP 474#ifdef HAVE_HOTSWAP
274 if(cinfo->initialized==1) 475 if(cinfo->initialized==1)
275 send_csw(cbw->tag, SCSI_STATUS_GOOD); 476 send_csw(SCSI_STATUS_GOOD);
276 else 477 else {
277 send_csw(cbw->tag, SCSI_STATUS_FAIL); 478 send_csw(SCSI_STATUS_FAIL);
479 cur_sense_data.sense_key=SENSE_NOT_READY;
480 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
481 }
278#else 482#else
279 send_csw(cbw->tag, SCSI_STATUS_GOOD); 483 send_csw(SCSI_STATUS_GOOD);
280#endif 484#endif
281 break; 485 break;
282 486
487 case SCSI_REPORT_LUNS: {
488 logf("scsi inquiry %d",lun);
489 int allocation_length=0;
490 allocation_length|=(cbw->command_block[6]<<24);
491 allocation_length|=(cbw->command_block[7]<<16);
492 allocation_length|=(cbw->command_block[8]<<8);
493 allocation_length|=(cbw->command_block[9]);
494 memset(lun_data,0,sizeof(struct report_lun_data));
495#ifdef HAVE_HOTSWAP
496 lun_data->lun_list_length=htobe32(16);
497 lun_data->lun1[1]=1;
498#else
499 lun_data->lun_list_length=htobe32(8);
500#endif
501 lun_data->lun0[1]=0;
502
503 send_command_result(lun_data, MIN(sizeof(struct report_lun_data), length));
504 break;
505 }
506
283 case SCSI_INQUIRY: 507 case SCSI_INQUIRY:
284 logf("scsi inquiry %d",lun); 508 logf("scsi inquiry %d",lun);
285 identify2inquiry(lun); 509 identify2inquiry(lun);
286 length = MIN(length, cbw->command_block[4]); 510 length = MIN(length, cbw->command_block[4]);
287 usb_drv_send(EP_TX, inquiry, MIN(sizeof _inquiry, length)); 511 send_command_result(inquiry, MIN(sizeof(struct inquiry_data), length));
288 send_csw(cbw->tag, SCSI_STATUS_GOOD);
289 break; 512 break;
290 513
291 case SCSI_REQUEST_SENSE: { 514 case SCSI_REQUEST_SENSE: {
292 sense_data->ResponseCode=0x70; 515 sense_data->ResponseCode=0x70;/*current error*/
293 sense_data->filemark_eom_ili_sensekey=2; 516 sense_data->filemark_eom_ili_sensekey=cur_sense_data.sense_key&0x0f;
294 sense_data->Information=2; 517 sense_data->Information=cur_sense_data.information;
295 sense_data->AdditionalSenseLength=10; 518 sense_data->AdditionalSenseLength=10;
296 sense_data->CommandSpecificInformation=0; 519 sense_data->CommandSpecificInformation=0;
297 sense_data->AdditionalSenseCode=0x3a; 520 sense_data->AdditionalSenseCode=cur_sense_data.asc;
298 sense_data->AdditionalSenseCodeQualifier=0; 521 sense_data->AdditionalSenseCodeQualifier=0;
299 sense_data->FieldReplaceableUnitCode=0; 522 sense_data->FieldReplaceableUnitCode=0;
300 sense_data->SKSV=0; 523 sense_data->SKSV=0;
301 sense_data->SenseKeySpecific=0; 524 sense_data->SenseKeySpecific=0;
302 logf("scsi request_sense %d",lun); 525 logf("scsi request_sense %d",lun);
303 usb_drv_send(EP_TX, sense_data, 526 send_command_result(sense_data, sizeof(struct sense_data));
304 sizeof(_sense_data));
305 send_csw(cbw->tag, SCSI_STATUS_GOOD);
306 break; 527 break;
307 } 528 }
308 529
309 case SCSI_MODE_SENSE: { 530 case SCSI_MODE_SENSE_10: {
310 static unsigned char sense_data[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 531 /*unsigned char pc = (cbw->command_block[2] & 0xc0) >>6;*/
311 logf("scsi mode_sense %d",lun); 532 unsigned char page_code = cbw->command_block[2] & 0x3f;
312 usb_drv_send(EP_TX, UNCACHED_ADDR(&sense_data), 533 logf("scsi mode_sense_10 %d %X",lun,page_code);
313 MIN(sizeof sense_data, length)); 534 switch(page_code) {
314 send_csw(cbw->tag, SCSI_STATUS_GOOD); 535 case 0x3f:
536 default:
537 mode_sense_data_10->mode_data_length=0;
538 mode_sense_data_10->medium_type=0;
539 mode_sense_data_10->device_specific=0;
540 mode_sense_data_10->block_descriptor_length=0;
541 send_command_result(mode_sense_data_10,
542 MIN(sizeof(struct mode_sense_header_10), length));
543 break;
544#if 0
545 default:
546 send_csw(SCSI_STATUS_CHECK_CONDITION);
547 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
548 cur_sense_data.asc=ASC_INVALID_FIELD_IN_CBD;
549 break;
550#endif
551 }
552 break;
553 }
554 case SCSI_MODE_SENSE_6: {
555 /*unsigned char pc = (cbw->command_block[2] & 0xc0) >>6;*/
556 unsigned char page_code = cbw->command_block[2] & 0x3f;
557 logf("scsi mode_sense_6 %d %X",lun,page_code);
558 switch(page_code) {
559 case 0x3f:
560 default:
561 /* All supported pages Since we support only one this is easy*/
562 mode_sense_data_6->mode_data_length=0;
563 mode_sense_data_6->medium_type=0;
564 mode_sense_data_6->device_specific=0;
565 mode_sense_data_6->block_descriptor_length=0;
566 send_command_result(mode_sense_data_6,
567 MIN(sizeof(struct mode_sense_header_6), length));
568 break;
569#if 0
570 default:
571 send_csw(SCSI_STATUS_CHECK_CONDITION);
572 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
573 cur_sense_data.asc=ASC_INVALID_FIELD_IN_CBD;
574 break;
575#endif
576 }
315 break; 577 break;
316 } 578 }
317 579
318 case SCSI_START_STOP_UNIT: 580 case SCSI_START_STOP_UNIT:
319 logf("scsi start_stop unit %d",lun); 581 logf("scsi start_stop unit %d",lun);
320 send_csw(cbw->tag, SCSI_STATUS_GOOD); 582 send_csw(SCSI_STATUS_GOOD);
321 break; 583 break;
322 584
323 case SCSI_ALLOW_MEDIUM_REMOVAL: 585 case SCSI_ALLOW_MEDIUM_REMOVAL:
324 logf("scsi allow_medium_removal %d",lun); 586 logf("scsi allow_medium_removal %d",lun);
325 send_csw(cbw->tag, SCSI_STATUS_GOOD); 587 /* TODO: use this to show the connect screen ? */
588 send_csw(SCSI_STATUS_GOOD);
326 break; 589 break;
327 590
328 case SCSI_READ_FORMAT_CAPACITY: { 591 case SCSI_READ_FORMAT_CAPACITY: {
329 logf("scsi read_format_capacity %d",lun); 592 logf("scsi read_format_capacity %d",lun);
330 format_capacity_data->following_length=htobe32(8); 593 format_capacity_data->following_length=htobe32(8);
331#ifdef HAVE_HOTSWAP
332 /* Careful: "block count" actually means "number of last block" */ 594 /* Careful: "block count" actually means "number of last block" */
333 if(cinfo->initialized==1) 595 format_capacity_data->block_count = htobe32(block_count/block_size_mult - 1);
334 { 596 format_capacity_data->block_size = htobe32(block_size*block_size_mult);
335 format_capacity_data->block_count = htobe32(cinfo->numblocks - 1);
336 format_capacity_data->block_size = htobe32(cinfo->blocksize);
337 }
338 else
339 {
340 format_capacity_data->block_count = htobe32(0);
341 format_capacity_data->block_size = htobe32(0);
342 }
343#else
344 unsigned short* identify = ata_get_identify();
345 /* Careful: "block count" actually means "number of last block" */
346 format_capacity_data->block_count = htobe32((identify[61] << 16 | identify[60]) / block_size_mult - 1);
347 format_capacity_data->block_size = htobe32(block_size * block_size_mult);
348#endif
349 format_capacity_data->block_size |= SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA; 597 format_capacity_data->block_size |= SCSI_FORMAT_CAPACITY_FORMATTED_MEDIA;
350 598
351 usb_drv_send(EP_TX, format_capacity_data, 599 send_command_result(format_capacity_data,
352 MIN(sizeof _format_capacity_data, length)); 600 MIN(sizeof(struct format_capacity), length));
353 send_csw(cbw->tag, SCSI_STATUS_GOOD); 601
354 break; 602 break;
355 } 603 }
356 604
357 case SCSI_READ_CAPACITY: { 605 case SCSI_READ_CAPACITY: {
358 logf("scsi read_capacity %d",lun); 606 logf("scsi read_capacity %d",lun);
359#ifdef HAVE_HOTSWAP
360 /* Careful: "block count" actually means "number of last block" */ 607 /* Careful: "block count" actually means "number of last block" */
361 if(cinfo->initialized==1) 608 capacity_data->block_count = htobe32(block_count/block_size_mult - 1);
362 { 609 capacity_data->block_size = htobe32(block_size*block_size_mult);
363 capacity_data->block_count = htobe32(cinfo->numblocks - 1); 610
364 capacity_data->block_size = htobe32(cinfo->blocksize); 611 send_command_result(capacity_data, MIN(sizeof(struct capacity), length));
365 }
366 else
367 {
368 capacity_data->block_count = htobe32(0);
369 capacity_data->block_size = htobe32(0);
370 }
371#else
372 unsigned short* identify = ata_get_identify();
373 /* Careful : "block count" actually means the number of the last block */
374 capacity_data->block_count = htobe32((identify[61] << 16 | identify[60]) / block_size_mult - 1);
375 capacity_data->block_size = htobe32(block_size * block_size_mult);
376#endif
377 usb_drv_send(EP_TX, capacity_data,
378 MIN(sizeof _capacity_data, length));
379 send_csw(cbw->tag, SCSI_STATUS_GOOD);
380 break; 612 break;
381 } 613 }
382 614
383 case SCSI_READ_10: 615 case SCSI_READ_10:
616 logf("scsi read10 %d",lun);
617 if(! lun_present) {
618 send_csw(SCSI_STATUS_CHECK_CONDITION);
619 cur_sense_data.sense_key=SENSE_NOT_READY;
620 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
621 break;
622 }
623 trigger_cpu_boost();
624 current_cmd.data[0] = transfer_buffer;
625 current_cmd.data[1] = &transfer_buffer[BUFFER_SIZE];
626 current_cmd.data_select=0;
384 current_cmd.sector = block_size_mult * 627 current_cmd.sector = block_size_mult *
385 (cbw->command_block[2] << 24 | 628 (cbw->command_block[2] << 24 |
386 cbw->command_block[3] << 16 | 629 cbw->command_block[3] << 16 |
@@ -389,32 +632,35 @@ static void handle_scsi(struct command_block_wrapper* cbw)
389 current_cmd.count = block_size_mult * 632 current_cmd.count = block_size_mult *
390 (cbw->command_block[7] << 16 | 633 (cbw->command_block[7] << 16 |
391 cbw->command_block[8]); 634 cbw->command_block[8]);
392 current_cmd.tag = cbw->tag;
393 current_cmd.lun = cbw->lun;
394 635
395 //logf("scsi read %d %d", current_cmd.sector, current_cmd.count); 636 logf("scsi read %d %d", current_cmd.sector, current_cmd.count);
396 637
397 //logf("Asked for %d sectors",current_cmd.count); 638 if((current_cmd.sector + current_cmd.count) * block_size_mult > block_count) {
398 if(current_cmd.count > sectors_per_transfer) 639 send_csw(SCSI_STATUS_CHECK_CONDITION);
399 { 640 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
400 current_cmd.count = sectors_per_transfer; 641 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
401 }
402 //logf("Sending %d sectors",current_cmd.count);
403
404 if(current_cmd.count*block_size > sizeof(_transfer_buffer)) {
405 send_csw(current_cmd.tag, SCSI_STATUS_CHECK_CONDITION);
406 } 642 }
407 else { 643 else {
408 ata_read_sectors(IF_MV2(lun,) current_cmd.sector, 644 /* TODO: any way to do this nonblocking ? */
409 current_cmd.count, transfer_buffer); 645 current_cmd.last_result = ata_read_sectors(IF_MV2(current_cmd.lun,) current_cmd.sector,
410 usb_drv_send(EP_TX, transfer_buffer, 646 MIN(BUFFER_SIZE/SECTOR_SIZE,current_cmd.count),
411 current_cmd.count*block_size); 647 current_cmd.data[current_cmd.data_select]);
412 send_csw(current_cmd.tag, SCSI_STATUS_GOOD); 648 send_and_read_next();
413 } 649 }
414 break; 650 break;
415 651
416 case SCSI_WRITE_10: 652 case SCSI_WRITE_10:
417 //logf("scsi write10"); 653 logf("scsi write10 %d",lun);
654 if(! lun_present) {
655 send_csw(SCSI_STATUS_CHECK_CONDITION);
656 cur_sense_data.sense_key=SENSE_NOT_READY;
657 cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
658 break;
659 }
660 trigger_cpu_boost();
661 current_cmd.data[0] = transfer_buffer;
662 current_cmd.data[1] = &transfer_buffer[BUFFER_SIZE];
663 current_cmd.data_select=0;
418 current_cmd.sector = block_size_mult * 664 current_cmd.sector = block_size_mult *
419 (cbw->command_block[2] << 24 | 665 (cbw->command_block[2] << 24 |
420 cbw->command_block[3] << 16 | 666 cbw->command_block[3] << 16 |
@@ -423,53 +669,74 @@ static void handle_scsi(struct command_block_wrapper* cbw)
423 current_cmd.count = block_size_mult * 669 current_cmd.count = block_size_mult *
424 (cbw->command_block[7] << 16 | 670 (cbw->command_block[7] << 16 |
425 cbw->command_block[8]); 671 cbw->command_block[8]);
426 current_cmd.tag = cbw->tag;
427 current_cmd.lun = cbw->lun;
428 /* expect data */ 672 /* expect data */
429 if(current_cmd.count*block_size > sizeof(_transfer_buffer)) { 673 if((current_cmd.sector + current_cmd.count) * block_size_mult > block_count) {
430 send_csw(current_cmd.tag, SCSI_STATUS_CHECK_CONDITION); 674 send_csw(SCSI_STATUS_CHECK_CONDITION);
675 cur_sense_data.sense_key=SENSE_ILLEGAL_REQUEST;
676 cur_sense_data.asc=ASC_LBA_OUT_OF_RANGE;
431 } 677 }
432 else { 678 else {
433 usb_drv_recv(EP_RX, transfer_buffer, 679 receive_block_data(current_cmd.data[0],
434 current_cmd.count*block_size); 680 MIN(BUFFER_SIZE,current_cmd.count*SECTOR_SIZE));
435 state = RECEIVING;
436 } 681 }
437 682
438 break; 683 break;
439 684
440 default: 685 default:
441 logf("scsi unknown cmd %x",cbw->command_block[0x0]); 686 logf("scsi unknown cmd %x",cbw->command_block[0x0]);
442 usb_drv_stall(EP_TX, true); 687 usb_drv_stall(EP_MASS_STORAGE, true,true);
443 send_csw(current_cmd.tag, SCSI_STATUS_GOOD); 688 send_csw(SCSI_STATUS_GOOD);
444 break; 689 break;
445 } 690 }
446} 691}
447 692
448static void send_csw(unsigned int tag, int status) 693static void send_block_data(void *data,int size)
694{
695 usb_drv_send_nonblocking(EP_MASS_STORAGE, data,size);
696 state = SENDING_BLOCKS;
697}
698
699static void send_command_result(void *data,int size)
700{
701 usb_drv_send_nonblocking(EP_MASS_STORAGE, data,size);
702 state = SENDING_RESULT;
703}
704
705static void receive_block_data(void *data,int size)
449{ 706{
450 static struct command_status_wrapper _csw; 707 usb_drv_recv(EP_MASS_STORAGE, data, size);
451 struct command_status_wrapper* csw = UNCACHED_ADDR(&_csw); 708 state = RECEIVING_BLOCKS;
709}
710
711static void send_csw(int status)
712{
713 cancel_cpu_boost();
452 csw->signature = CSW_SIGNATURE; 714 csw->signature = CSW_SIGNATURE;
453 csw->tag = tag; 715 csw->tag = current_cmd.tag;
454 csw->data_residue = 0; 716 csw->data_residue = 0;
455 csw->status = status; 717 csw->status = status;
456 718
457 //logf("csw %x %x", csw->tag, csw->signature); 719 usb_drv_send_nonblocking(EP_MASS_STORAGE, csw, sizeof(struct command_status_wrapper));
458 usb_drv_send(EP_TX, csw, sizeof _csw); 720 state = SENDING_CSW;
721 logf("CSW: %X",status);
722
723 if(status == SCSI_STATUS_GOOD) {
724 cur_sense_data.sense_key=0;
725 cur_sense_data.information=0;
726 cur_sense_data.asc=0;
727 }
459} 728}
460 729
461/* convert ATA IDENTIFY to SCSI INQUIRY */ 730/* convert ATA IDENTIFY to SCSI INQUIRY */
462static void identify2inquiry(int lun) 731static void identify2inquiry(int lun)
463{ 732{
464#ifdef HAVE_FLASH_STORAGE 733#ifdef HAVE_FLASH_STORAGE
465 if(lun==0) 734 if(lun==0) {
466 {
467 memcpy(&inquiry->VendorId,"Rockbox ",8); 735 memcpy(&inquiry->VendorId,"Rockbox ",8);
468 memcpy(&inquiry->ProductId,"Internal Storage",16); 736 memcpy(&inquiry->ProductId,"Internal Storage",16);
469 memcpy(&inquiry->ProductRevisionLevel,"0.00",4); 737 memcpy(&inquiry->ProductRevisionLevel,"0.00",4);
470 } 738 }
471 else 739 else {
472 {
473 memcpy(&inquiry->VendorId,"Rockbox ",8); 740 memcpy(&inquiry->VendorId,"Rockbox ",8);
474 memcpy(&inquiry->ProductId,"SD Card Slot ",16); 741 memcpy(&inquiry->ProductId,"SD Card Slot ",16);
475 memcpy(&inquiry->ProductRevisionLevel,"0.00",4); 742 memcpy(&inquiry->ProductRevisionLevel,"0.00",4);
@@ -480,7 +747,7 @@ static void identify2inquiry(int lun)
480 unsigned short* src; 747 unsigned short* src;
481 unsigned short* identify = ata_get_identify(); 748 unsigned short* identify = ata_get_identify();
482 (void)lun; 749 (void)lun;
483 memset(inquiry, 0, sizeof _inquiry); 750 memset(inquiry, 0, sizeof(struct inquiry_data));
484 751
485 if (identify[82] & 4) 752 if (identify[82] & 4)
486 inquiry->DeviceTypeModifier = DEVICE_REMOVABLE; 753 inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
@@ -501,8 +768,8 @@ static void identify2inquiry(int lun)
501 768
502 inquiry->DeviceType = DIRECT_ACCESS_DEVICE; 769 inquiry->DeviceType = DIRECT_ACCESS_DEVICE;
503 inquiry->AdditionalLength = 0x1f; 770 inquiry->AdditionalLength = 0x1f;
504 inquiry->Versions = 3; /* ANSI SCSI level 2 */ 771 inquiry->Versions = 4; /* SPC-2 */
505 inquiry->Format = 3; /* ANSI SCSI level 2 INQUIRY format */ 772 inquiry->Format = 2; /* SPC-2/3 inquiry format */
506 773
507#ifdef HAVE_HOTSWAP 774#ifdef HAVE_HOTSWAP
508 inquiry->DeviceTypeModifier = DEVICE_REMOVABLE; 775 inquiry->DeviceTypeModifier = DEVICE_REMOVABLE;
@@ -510,3 +777,4 @@ static void identify2inquiry(int lun)
510 777
511} 778}
512 779
780#endif /* USB_STORAGE */
diff --git a/firmware/usbstack/usb_storage.h b/firmware/usbstack/usb_storage.h
index 9067c92c61..23903a855a 100644
--- a/firmware/usbstack/usb_storage.h
+++ b/firmware/usbstack/usb_storage.h
@@ -22,8 +22,7 @@
22#include "usb_ch9.h" 22#include "usb_ch9.h"
23 23
24void usb_storage_init(void); 24void usb_storage_init(void);
25void usb_storage_transfer(void* data); 25void usb_storage_transfer_complete(bool in,int state,int length);
26void usb_storage_transfer_complete(int endpoint);
27bool usb_storage_control_request(struct usb_ctrlrequest* req); 26bool usb_storage_control_request(struct usb_ctrlrequest* req);
28 27
29#endif 28#endif