diff --git a/bootloader/gigabeat-s.c b/bootloader/gigabeat-s.c index 3ca41d989c..dbacaaa901 100644 --- a/bootloader/gigabeat-s.c +++ b/bootloader/gigabeat-s.c @@ -46,6 +46,7 @@ #include "lcd-target.h" #include "avic-imx31.h" #include +#include "usb-target.h" #define TAR_CHUNK 512 #define TAR_HEADER_SIZE 157 @@ -55,6 +56,7 @@ char basedir[] = "/Content/0b00/00/"; /* Where files sent via MTP are stored */ int (*kernel_entry)(void); char *tarbuf = (char *)0x00000040; extern void reference_system_c(void); +static struct event_queue usb_wait_queue; /* Dummy stub that creates C references for C functions only used by assembly - never called */ @@ -63,6 +65,15 @@ void reference_files(void) reference_system_c(); } +void show_splash(int timeout, const char *msg) +{ + lcd_putsxy( (LCD_WIDTH - (SYSFONT_WIDTH * strlen(msg))) / 2, + (LCD_HEIGHT - SYSFONT_HEIGHT) / 2, msg); + lcd_update(); + + sleep(timeout); +} + void untar(int tar_fd) { char header[TAR_HEADER_SIZE]; @@ -145,7 +156,7 @@ void main(void) lcd_clear_display(); printf("Hello world!"); - printf("Gigabeat S Rockbox Bootloader v.00000006"); + printf("Gigabeat S Rockbox Bootloader v.00000007"); system_init(); kernel_init(); printf("kernel init done"); @@ -223,6 +234,47 @@ void main(void) } } + if (usb_plugged()) + { + /* Enter USB mode */ + struct queue_event ev; + queue_init(&usb_wait_queue, true); + + /* Start the USB driver */ + usb_init(); + usb_start_monitoring(); + + /* Wait for threads to connect or cable is pulled */ + reset_screen(); + show_splash(0, "Waiting for USB"); + + while (1) + { + queue_wait_w_tmo(&usb_wait_queue, &ev, HZ/2); + + if (ev.id == SYS_USB_CONNECTED) + break; /* Hit */ + + if (!usb_plugged()) + break; /* Cable pulled */ + } + + if (ev.id == SYS_USB_CONNECTED) + { + /* Got the message - wait for disconnect */ + reset_screen(); + show_splash(0, "Bootloader USB mode"); + + usb_acknowledge(SYS_USB_CONNECTED_ACK); + usb_wait_for_disconnect(&usb_wait_queue); + } + + /* No more monitoring */ + usb_stop_monitoring(); + + reset_screen(); + } + unsigned char *loadbuffer = (unsigned char *)0x0; int buffer_size = 31*1024*1024; @@ -239,6 +291,8 @@ void main(void) rc = kernel_entry(); } - while (1); + /* Halt */ + while (1) + core_idle(); } diff --git a/firmware/SOURCES b/firmware/SOURCES index c0f6c81d9f..6acf81d76b 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -233,8 +233,8 @@ drivers/audio/mas35xx.c usbstack/usb_core.c usbstack/usb_storage.c usbstack/usb_serial.c -#ifdef CPU_PP502x -target/arm/usb-drv-pp502x.c +#if CONFIG_USBOTG == USBOTG_ARC +target/arm/usb-drv-arc.c #endif #else /* !defined(HAVE_USBSTACK) */ #if CONFIG_USBOTG == USBOTG_ISP1362 diff --git a/firmware/export/config-gigabeat-s.h b/firmware/export/config-gigabeat-s.h index 353055f2cb..bc70956ced 100644 --- a/firmware/export/config-gigabeat-s.h +++ b/firmware/export/config-gigabeat-s.h @@ -112,7 +112,18 @@ #define CPU_FREQ 16934400 /* define this if the unit can be powered or charged via USB */ -#define HAVE_USB_POWER +//#define HAVE_USB_POWER /* Disable for now */ + +/* USB On-the-go */ +#define CONFIG_USBOTG USBOTG_ARC + +/* enable these for the experimental usb stack */ +#define USE_HIGH_SPEED +#define USE_ROCKBOX_USB +#define HAVE_USBSTACK +#define USB_STORAGE +#define USB_VENDOR_ID 0x0930 +#define USB_PRODUCT_ID 0x0010 /* Define this if you have ATA power-off control */ #define HAVE_ATA_POWER_OFF diff --git a/firmware/export/config.h b/firmware/export/config.h index ccd24d0233..c108171d37 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -324,13 +324,11 @@ #define HAVE_MAS35XX #endif -#if CONFIG_CODEC == SWCODEC && !defined(BOOTLOADER) -#define HAVE_EXTENDED_MESSAGING_AND_NAME -#endif - #if (CONFIG_CODEC == SWCODEC) #ifndef BOOTLOADER +#define HAVE_EXTENDED_MESSAGING_AND_NAME + #ifndef SIMULATOR #define HAVE_PRIORITY_SCHEDULING #define HAVE_SCHEDULER_BOOSTCTRL @@ -345,10 +343,11 @@ #endif /* BOOTLOADER */ -#ifdef TOSHIBA_GIGABEAT_S +#ifdef HAVE_USBSTACK #define HAVE_WAKEUP_OBJECTS #endif -#endif + +#endif /* (CONFIG_CODEC == SWCODEC) */ /* define for all cpus from SH family */ #if (CONFIG_CPU == SH7034) diff --git a/firmware/export/imx31l.h b/firmware/export/imx31l.h index 3e7abe344b..9544603412 100755 --- a/firmware/export/imx31l.h +++ b/firmware/export/imx31l.h @@ -26,12 +26,14 @@ #define REG32_PTR_T volatile unsigned long * /* Place in the section with the framebuffer */ -#define TTB_BASE_ADDR (0x80100000 + 0x00100000 - TTB_SIZE) - -#define FRAME ((short *)0x80100000) /* Framebuffer */ -#define LCD_BUFFER_SIZE ((320*240*2)) -#define TTB_SIZE (0x4000) -#define TTB_BASE ((unsigned int *)TTB_BASE_ADDR) +#define TTB_BASE_ADDR (0x80100000 + 0x00100000 - TTB_SIZE) +#define TTB_SIZE (0x4000) +#define IRAM_SIZE (0x4000) +#define TTB_BASE ((unsigned int *)TTB_BASE_ADDR) +#define FRAME ((void*)0x80100000) +#define FRAME_SIZE (240*320*2) + +#define DEVBSS_ATTR __attribute__((section(".devbss"),nocommon)) /* * AIPS 1 @@ -1032,4 +1034,6 @@ #define writew(v,a) (*(REG16_PTR_T)(a) = (v)) #define readw(a) (*(REG16_PTR_T)(a)) +#define USB_BASE OTG_BASE_ADDR + #endif /* __IMX31L_H__ */ diff --git a/firmware/export/mc13783.h b/firmware/export/mc13783.h index bde1dc419d..bb9cf589aa 100644 --- a/firmware/export/mc13783.h +++ b/firmware/export/mc13783.h @@ -104,8 +104,10 @@ enum mc13783_regs_enum #define MC13783_LOBATL (1 << 13) #define MC13783_LOBATH (1 << 14) #define MC13783_UDP (1 << 15) -#define MC13783_USB (1 << 16) -#define MC13783_ID (1 << 19) +#define MC13783_USB4V4 (1 << 16) +#define MC13783_USB2V0 (1 << 17) +#define MC13783_USB0V8 (1 << 18) +#define MC13783_IDFLOAT (1 << 19) #define MC13783_SE1 (1 << 21) #define MC13783_CKDET (1 << 22) #define MC13783_UDM (1 << 23) diff --git a/firmware/export/usb.h b/firmware/export/usb.h index a80dd82667..4500cb2cde 100644 --- a/firmware/export/usb.h +++ b/firmware/export/usb.h @@ -89,6 +89,7 @@ struct usb_transfer_completion_event_data void usb_init(void); void usb_enable(bool on); void usb_start_monitoring(void); +void usb_stop_monitoring(void); void usb_acknowledge(long id); void usb_wait_for_disconnect(struct event_queue *q); int usb_wait_for_disconnect_w_tmo(struct event_queue *q, int ticks); diff --git a/firmware/export/usb_core.h b/firmware/export/usb_core.h index c37a3e3387..10040dd11c 100644 --- a/firmware/export/usb_core.h +++ b/firmware/export/usb_core.h @@ -33,7 +33,13 @@ /* endpoints */ #define EP_CONTROL 0 +#if CONFIG_CPU == IMX31L +#define NUM_ENDPOINTS 8 +#define USBDEVBSS_ATTR DEVBSS_ATTR +#else +#define USBDEVBSS_ATTR NOCACHEBSS_ATTR #define NUM_ENDPOINTS 3 +#endif extern int usb_max_pkt_size; diff --git a/firmware/target/arm/imx31/app.lds b/firmware/target/arm/imx31/app.lds index d814a976be..7a7bd550d1 100644 --- a/firmware/target/arm/imx31/app.lds +++ b/firmware/target/arm/imx31/app.lds @@ -23,7 +23,7 @@ INPUT(target/arm/imx31/crt0.o) /* #define IRAMORIG 0x1FFFC000 */ #define IRAMORIG DRAMORIG #define IRAM DRAM -#define IRAMSIZE 0x4000 +#define IRAMSIZE IRAM_SIZE /* End of the audio buffer, where the codec buffer starts */ #define ENDAUDIOADDR (DRAMORIG + DRAMSIZE) @@ -34,6 +34,7 @@ INPUT(target/arm/imx31/crt0.o) MEMORY { DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE + DEVBSS : ORIGIN = 0x80100000 + FRAME_SIZE, LENGTH = 0x100000 - FRAME_SIZE - TTB_SIZE } SECTIONS @@ -147,5 +148,12 @@ SECTIONS _pluginbuf = .; pluginbuf = .; } + + .devbss (NOLOAD) : + { + _devbssdata = .; + *(.devbss*) + _devbssend = .; + } > DEVBSS } diff --git a/firmware/target/arm/imx31/boot.lds b/firmware/target/arm/imx31/boot.lds index 84597d5ad1..7110264c1b 100644 --- a/firmware/target/arm/imx31/boot.lds +++ b/firmware/target/arm/imx31/boot.lds @@ -17,6 +17,7 @@ INPUT(target/arm/imx31/crt0.o) MEMORY { DRAM : ORIGIN = DRAMORIG, LENGTH = DRAMSIZE + DEVBSS : ORIGIN = 0x80100000 + FRAME_SIZE, LENGTH = 0x100000 - FRAME_SIZE - TTB_SIZE } SECTIONS @@ -81,4 +82,11 @@ SECTIONS _vectorsend = .; } AT > DRAM _vectorscopy = LOADADDR(.vectors); + + .devbss (NOLOAD) : + { + _devbssdata = .; + *(.devbss*) + _devbssend = .; + } > DEVBSS } diff --git a/firmware/target/arm/imx31/crt0.S b/firmware/target/arm/imx31/crt0.S index 4e79cd1352..ab8e5199e2 100644 --- a/firmware/target/arm/imx31/crt0.S +++ b/firmware/target/arm/imx31/crt0.S @@ -259,6 +259,15 @@ remap_end: strhi r4, [r2], #4 bhi 1b + /* Initialise the device bss section to zero */ + ldr r2, =_devbssdata + ldr r3, =_devbssend + mov r4, #0 +1: + cmp r3, r2 + strhi r4, [r2], #4 + bhi 1b + /* Set up some stack and munge it with 0xdeadbeef */ ldr sp, =stackend ldr r2, =stackbegin diff --git a/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c b/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c index d62df92ac5..8f504746c3 100644 --- a/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c @@ -27,6 +27,7 @@ #include "power-imx31.h" #include "button-target.h" #include "adc-target.h" +#include "usb-target.h" /* This is all based on communicating with the MC13783 PMU which is on * CSPI2 with the chip select at 0. The LCD controller resides on @@ -67,6 +68,7 @@ static __attribute__((noreturn)) void mc13783_interrupt_thread(void) /* Check initial states for events with a sense bit */ value = mc13783_read(MC13783_INTERRUPT_SENSE0); + usb_set_status(value & MC13783_USB4V4); set_charger_inserted(value & MC13783_CHGDET); value = mc13783_read(MC13783_INTERRUPT_SENSE1); @@ -98,12 +100,15 @@ static __attribute__((noreturn)) void mc13783_interrupt_thread(void) /* Handle interrupts that have a sense bit that needs to * be checked */ - if (pending[0] & MC13783_CHGDET) + if (pending[0] & (MC13783_CHGDET | MC13783_USB4V4)) { value = mc13783_read(MC13783_INTERRUPT_SENSE0); if (pending[0] & MC13783_CHGDET) set_charger_inserted(value & MC13783_CHGDET); + + if (pending[0] & MC13783_USB4V4) + usb_set_status(value & MC13783_USB4V4); } } diff --git a/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c b/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c index 130e884d70..2ef0bc6f6e 100644 --- a/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c +++ b/firmware/target/arm/imx31/gigabeat-s/usb-imx31.c @@ -22,17 +22,50 @@ #include "kernel.h" #include "ata.h" #include "usb.h" +#include "usb_core.h" +#include "clkctl-imx31.h" +#include "mc13783.h" -inline int usb_detect(void) +static int usb_status = USB_EXTRACTED; + +void usb_set_status(bool plugged) { - return USB_EXTRACTED; + usb_status = plugged ? USB_INSERTED : USB_EXTRACTED; +} + +int usb_detect(void) +{ + return usb_status; +} + +/* Read the immediate state of the cable from the PMIC */ +bool usb_plugged(void) +{ + return mc13783_read(MC13783_INTERRUPT_SENSE0) & MC13783_USB4V4; } void usb_init_device(void) { + mc13783_clear(MC13783_INTERRUPT_MASK0, MC13783_USB4V4); } void usb_enable(bool on) { - (void)on; + if (on) + { + imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL); + GPIO3_DR &= ~(1 << 16); /* Reset ISP1504 */ + GPIO3_DR |= (1 << 16); + GPIO1_DR &= ~(1 << 30); /* Select ISP1504 */ + usb_core_init(); + } + else + { + /* Module clock should be on since this could be called first */ + imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_ON_ALL); + GPIO1_DR &= ~(1 << 30); /* Select ISP1504 */ + usb_core_exit(); + GPIO1_DR |= (1 << 30); /* Deselect ISP1504 */ + imx31_clkctl_module_clock_gating(CG_USBOTG, CGM_OFF); + } } diff --git a/firmware/target/arm/imx31/gigabeat-s/usb-target.h b/firmware/target/arm/imx31/gigabeat-s/usb-target.h index de5bdac52b..8c9dcfc65f 100644 --- a/firmware/target/arm/imx31/gigabeat-s/usb-target.h +++ b/firmware/target/arm/imx31/gigabeat-s/usb-target.h @@ -19,8 +19,11 @@ #ifndef USB_TARGET_H #define USB_TARGET_H +void usb_set_status(bool plugged); bool usb_init_device(void); int usb_detect(void); +/* Read the immediate state of the cable from the PMIC */ +bool usb_plugged(void); void usb_enable(bool on); #endif diff --git a/firmware/target/arm/usb-drv-pp502x.c b/firmware/target/arm/usb-drv-arc.c similarity index 90% rename from firmware/target/arm/usb-drv-pp502x.c rename to firmware/target/arm/usb-drv-arc.c index bf2076f988..3bf53fa431 100644 --- a/firmware/target/arm/usb-drv-pp502x.c +++ b/firmware/target/arm/usb-drv-arc.c @@ -5,7 +5,7 @@ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ - * $Id: $ + * $Id$ * * Driver for ARC USBOTG Device Controller * @@ -20,12 +20,20 @@ ****************************************************************************/ #include "system.h" +#include "config.h" #include "string.h" #include "usb_ch9.h" #include "usb_core.h" +#include "kernel.h" +#include "panic.h" //#define LOGF_ENABLE #include "logf.h" +#if CONFIG_CPU == IMX31L +#include "avic-imx31.h" +static void __attribute__((interrupt("IRQ"))) USB_OTG_HANDLER(void); +#endif + /* USB device mode registers (Little Endian) */ #define REG_ID (*(volatile unsigned int *)(USB_BASE+0x000)) @@ -44,6 +52,7 @@ #define REG_DEVICEADDR (*(volatile unsigned int *)(USB_BASE+0x154)) #define REG_ENDPOINTLISTADDR (*(volatile unsigned int *)(USB_BASE+0x158)) #define REG_BURSTSIZE (*(volatile unsigned int *)(USB_BASE+0x160)) +#define REG_ULPI (*(volatile unsigned int *)(USB_BASE+0x170)) #define REG_CONFIGFLAG (*(volatile unsigned int *)(USB_BASE+0x180)) #define REG_PORTSC1 (*(volatile unsigned int *)(USB_BASE+0x184)) #define REG_OTGSC (*(volatile unsigned int *)(USB_BASE+0x1a4)) @@ -127,6 +136,16 @@ #define USBINTR_SOF_EN (0x00000080) #define USBINTR_DEVICE_SUSPEND (0x00000100) +/* ULPI Register Bit Masks */ +#define ULPI_ULPIWU (0x80000000) +#define ULPI_ULPIRUN (0x40000000) +#define ULPI_ULPIRW (0x20000000) +#define ULPI_ULPISS (0x08000000) +#define ULPI_ULPIPORT (0x07000000) +#define ULPI_ULPIADDR (0x00FF0000) +#define ULPI_ULPIDATRD (0x0000FF00) +#define ULPI_ULPIDATWR (0x000000FF) + /* Device Address bit masks */ #define USBDEVICEADDRESS_MASK (0xFE000000) #define USBDEVICEADDRESS_BIT_POS (25) @@ -194,6 +213,7 @@ /* bit 31-30 are port transceiver select */ #define PORTSCX_PTS_UTMI (0x00000000) +#define PORTSCX_PTS_CLASSIC (0x40000000) #define PORTSCX_PTS_ULPI (0x80000000) #define PORTSCX_PTS_FSLS (0xC0000000) #define PORTSCX_PTS_BIT_POS (30) @@ -303,7 +323,7 @@ struct transfer_descriptor { } __attribute__ ((packed)); static struct transfer_descriptor td_array[NUM_ENDPOINTS*2] - NOCACHEBSS_ATTR; + USBDEVBSS_ATTR __attribute__((aligned(32))); /* manual: 32.13.1 Endpoint Queue Head (dQH) */ struct queue_head { @@ -319,10 +339,10 @@ struct queue_head { } __attribute__((packed)); static struct queue_head qh_array[NUM_ENDPOINTS*2] - NOCACHEBSS_ATTR __attribute((aligned (2048))); - -static struct event_queue transfer_completion_queue[NUM_ENDPOINTS*2]; + USBDEVBSS_ATTR __attribute__((aligned (2048))); +static struct wakeup transfer_completion_signal[NUM_ENDPOINTS*2] + SHAREDBSS_ATTR; static const unsigned int pipe2mask[] = { 0x01, 0x010000, @@ -332,6 +352,8 @@ static const unsigned int pipe2mask[] = { 0x10, 0x100000, }; +static bool first_init = true; + /*-------------------------------------------------------------------------*/ static void transfer_completed(void); static void control_received(void); @@ -355,13 +377,30 @@ bool usb_drv_powered(void) void usb_drv_init(void) { REG_USBCMD &= ~USBCMD_RUN; - udelay(50000); + + if (first_init) + { + /* Initialize all the signal objects once */ + int i; + for(i=0;ilength = 0; qh->wait = wait; - new_td=&td_array[pipe]; prepare_td(new_td, 0, ptr, len,pipe); //logf("starting ep %d %s",endpoint,send?"send":"receive"); @@ -603,40 +656,58 @@ static int prime_transfer(int endpoint, void* ptr, int len, bool send, bool wait if(endpoint == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) { /* 32.14.3.2.2 */ logf("new setup arrived"); - return -4; + rc = -4; + goto pt_error; } last_tick = current_tick; while ((REG_ENDPTPRIME & mask)) { - if (REG_USBSTS & USBSTS_RESET) - return -1; + if (REG_USBSTS & USBSTS_RESET) { + rc = -1; + goto pt_error; + } if (TIME_AFTER(current_tick, last_tick + HZ/4)) { logf("prime timeout"); - return -2; + rc = -2; + goto pt_error; } } if (!(REG_ENDPTSTATUS & mask)) { logf("no prime! %d %d %x", endpoint, pipe, qh->dtd.size_ioc_sts & 0xff ); - return -3; + rc = -3; + goto pt_error; } if(endpoint == EP_CONTROL && (REG_ENDPTSETUPSTAT & EPSETUP_STATUS_EP0)) { /* 32.14.3.2.2 */ logf("new setup arrived"); - return -4; + rc = -4; + goto pt_error; } if (wait) { /* wait for transfer to finish */ - struct queue_event ev; - queue_wait(&transfer_completion_queue[pipe], &ev); + wakeup_wait(&transfer_completion_signal[pipe], TIMEOUT_BLOCK); if(qh->status!=0) { - return -5; + /* No need to cancel wait here since it was done and the signal + * came. */ + return 5; } //logf("all tds done"); } - return 0; + +pt_error: + /* Error status must make sure an abandoned wakeup signal isn't left */ + if (rc < 0 && wait) { + /* Cancel wait */ + qh->wait = 0; + /* Make sure to remove any signal if interrupt fired before we zeroed + * qh->wait. Could happen during a bus reset for example. */ + wakeup_wait(&transfer_completion_signal[pipe], TIMEOUT_NOBLOCK); + } + + return rc; } void usb_drv_cancel_all_transfers(void) @@ -650,7 +721,7 @@ void usb_drv_cancel_all_transfers(void) if(qh_array[i].wait) { qh_array[i].wait=0; qh_array[i].status=DTD_STATUS_HALTED; - queue_post(&transfer_completion_queue[i],0, 0); + wakeup_signal(&transfer_completion_signal[i]); } } } @@ -694,7 +765,7 @@ static void control_received(void) if(qh_array[i].wait) { qh_array[i].wait=0; qh_array[i].status=DTD_STATUS_HALTED; - queue_post(&transfer_completion_queue[i],0, 0); + wakeup_signal(&transfer_completion_signal[i]); } } @@ -731,7 +802,7 @@ static void transfer_completed(void) } if(qh->wait) { qh->wait=0; - queue_post(&transfer_completion_queue[pipe],0, 0); + wakeup_signal(&transfer_completion_signal[pipe]); } usb_core_transfer_complete(ep, dir, qh->status, qh->length); } @@ -757,8 +828,13 @@ static void bus_reset(void) logf("usb: double reset"); return; } - +#if CONFIG_CPU == IMX31L + int x; + for (x = 0; x < 30000; x++) + asm volatile (""); +#else udelay(100); +#endif } if (REG_ENDPTPRIME) { logf("usb: short reset timeout"); @@ -774,7 +850,6 @@ static void bus_reset(void) /* manual: 32.14.4.1 Queue Head Initialization */ static void init_control_queue_heads(void) { - int i; memset(qh_array, 0, sizeof qh_array); /*** control ***/ @@ -782,10 +857,6 @@ static void init_control_queue_heads(void) qh_array[EP_CONTROL].dtd.next_td_ptr = QH_NEXT_TERMINATE; qh_array[EP_CONTROL+1].max_pkt_length = 64 << QH_MAX_PKT_LEN_POS; qh_array[EP_CONTROL+1].dtd.next_td_ptr = QH_NEXT_TERMINATE; - - for(i=0;i<2;i++) { - queue_init(&transfer_completion_queue[i], false); - } } /* manual: 32.14.4.1 Queue Head Initialization */ static void init_bulk_queue_heads(void) @@ -810,9 +881,6 @@ static void init_bulk_queue_heads(void) qh_array[i*2+1].max_pkt_length = tx_packetsize << QH_MAX_PKT_LEN_POS | QH_ZLT_SEL; qh_array[i*2+1].dtd.next_td_ptr = QH_NEXT_TERMINATE; } - for(i=2;i ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ - * $Id: $ + * $Id$ * * Copyright (C) 2007 by Bj�rn Stenberg * @@ -244,7 +244,7 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] = static void usb_core_control_request_handler(struct usb_ctrlrequest* req); static int ack_control(struct usb_ctrlrequest* req); -static unsigned char response_data[256] NOCACHEBSS_ATTR; +static unsigned char response_data[256] USBDEVBSS_ATTR; static struct usb_transfer_completion_event_data events[NUM_ENDPOINTS]; @@ -558,9 +558,7 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req) sizeof(struct usb_string_descriptor*))) { size = usb_strings[index]->bLength; - memcpy(&response_data[0],usb_strings[index], - size); - ptr = response_data; + ptr = usb_strings[index]; } else { logf("bad string id %d", index); @@ -580,9 +578,13 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req) } if (ptr) { - unsigned char *uncached = (void*)UNCACHED_ADDR(ptr); length = MIN(size, length); - if(usb_drv_send(EP_CONTROL, uncached, length)!=0) + + if (ptr != response_data) { + memcpy(response_data, ptr, length); + } + + if(usb_drv_send(EP_CONTROL, response_data, length)!=0) break; } ack_control(req); diff --git a/firmware/usbstack/usb_serial.c b/firmware/usbstack/usb_serial.c index 55b76adc69..f39035462f 100644 --- a/firmware/usbstack/usb_serial.c +++ b/firmware/usbstack/usb_serial.c @@ -5,7 +5,7 @@ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ - * $Id: $ + * $Id$ * * Copyright (C) 2007 by Christian Gmeiner * @@ -53,11 +53,10 @@ struct usb_endpoint_descriptor __attribute__((aligned(2))) endpoint_descriptor = }; #define BUFFER_SIZE 512 /* Max 16k because of controller limitations */ -static unsigned char _send_buffer[BUFFER_SIZE] __attribute__((aligned(32))); -static unsigned char* send_buffer; - -static unsigned char _receive_buffer[512] __attribute__((aligned(32))); -static unsigned char* receive_buffer; +static unsigned char send_buffer[BUFFER_SIZE] + USBDEVBSS_ATTR __attribute__((aligned(32))); +static unsigned char receive_buffer[512] + USBDEVBSS_ATTR __attribute__((aligned(32))); static bool busy_sending = false; static int buffer_start; static int buffer_length; @@ -66,7 +65,7 @@ static bool active = false; static int usb_endpoint; static int usb_interface; -static struct mutex sendlock; +static struct mutex sendlock SHAREDBSS_ATTR; static void sendout(void) { @@ -111,7 +110,7 @@ void usb_serial_init_connection(int interface,int endpoint) usb_endpoint = endpoint; /* prime rx endpoint */ - usb_drv_recv(usb_endpoint, receive_buffer, sizeof _receive_buffer); + usb_drv_recv(usb_endpoint, receive_buffer, sizeof receive_buffer); /* we come here too after a bus reset, so reset some data */ mutex_lock(&sendlock); @@ -127,8 +126,6 @@ void usb_serial_init_connection(int interface,int endpoint) void usb_serial_init(void) { logf("serial: init"); - send_buffer = (void*)UNCACHED_ADDR(&_send_buffer); - receive_buffer = (void*)UNCACHED_ADDR(&_receive_buffer); busy_sending = false; buffer_start = 0; buffer_length = 0; @@ -190,7 +187,7 @@ void usb_serial_transfer_complete(bool in, int status, int length) case false: logf("serial: %s", receive_buffer); /* Data received. TODO : Do something with it ? */ - usb_drv_recv(usb_endpoint, receive_buffer, sizeof _receive_buffer); + usb_drv_recv(usb_endpoint, receive_buffer, sizeof receive_buffer); break; case true: diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c index dfcd51b19e..9e9e356c36 100644 --- a/firmware/usbstack/usb_storage.c +++ b/firmware/usbstack/usb_storage.c @@ -5,7 +5,7 @@ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ - * $Id: $ + * $Id$ * * Copyright (C) 2007 by Björn Stenberg * @@ -352,9 +352,6 @@ int usb_storage_get_config_descriptor(unsigned char *dest,int max_packet_size, void usb_storage_init_connection(int interface,int endpoint) { - size_t bufsize; - unsigned char * audio_buffer; - usb_interface = interface; usb_endpoint = endpoint; @@ -362,10 +359,20 @@ void usb_storage_init_connection(int interface,int endpoint) /* prime rx endpoint. We only need room for commands */ state = WAITING_FOR_COMMAND; +#if CONFIG_CPU == IMX31L + static unsigned char _transfer_buffer[BUFFER_SIZE*2] + USBDEVBSS_ATTR __attribute__((aligned(32))); + tb.transfer_buffer = (void *)_transfer_buffer; +#else /* TODO : check if bufsize is at least 32K ? */ + size_t bufsize; + unsigned char * audio_buffer; + audio_buffer = audio_get_buffer(false,&bufsize); tb.transfer_buffer = (void *)UNCACHED_ADDR((unsigned int)(audio_buffer + 31) & 0xffffffe0); + invalidate_icache(); +#endif usb_drv_recv(usb_endpoint, tb.transfer_buffer, 1024); } @@ -519,7 +526,7 @@ bool usb_storage_control_request(struct usb_ctrlrequest* req) *tb.max_lun = NUM_VOLUMES - 1; #endif logf("ums: getmaxlun"); - usb_drv_send(EP_CONTROL, UNCACHED_ADDR(tb.max_lun), 1); + usb_drv_send(EP_CONTROL, tb.max_lun, 1); usb_drv_recv(EP_CONTROL, NULL, 0); /* ack */ handled = true; break; @@ -1042,7 +1049,11 @@ static void identify2inquiry(int lun) #endif /* Mac OSX 10.5 doesn't like this driver if DEVICE_REMOVABLE is not set. TODO : this can probably be solved by providing caching mode page */ +#ifdef TOSHIBA_GIGABEAT_S + tb.inquiry->DeviceTypeModifier = 0; +#else tb.inquiry->DeviceTypeModifier = DEVICE_REMOVABLE; +#endif } #endif /* USB_STORAGE */