summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES4
-rw-r--r--firmware/export/config-gigabeat-s.h13
-rw-r--r--firmware/export/config.h11
-rwxr-xr-xfirmware/export/imx31l.h16
-rw-r--r--firmware/export/mc13783.h6
-rw-r--r--firmware/export/usb.h1
-rw-r--r--firmware/export/usb_core.h6
-rw-r--r--firmware/target/arm/imx31/app.lds10
-rw-r--r--firmware/target/arm/imx31/boot.lds8
-rw-r--r--firmware/target/arm/imx31/crt0.S9
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/mc13783-imx31.c7
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/usb-imx31.c39
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/usb-target.h3
-rw-r--r--firmware/target/arm/usb-drv-arc.c (renamed from firmware/target/arm/usb-drv-pp502x.c)130
-rw-r--r--firmware/usb.c32
-rw-r--r--firmware/usbstack/usb_core.c16
-rw-r--r--firmware/usbstack/usb_serial.c19
-rw-r--r--firmware/usbstack/usb_storage.c21
18 files changed, 267 insertions, 84 deletions
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)
+{
+ 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 USB_EXTRACTED;
+ 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
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;i<NUM_ENDPOINTS*2;i++) {
+ wakeup_init(&transfer_completion_signal[i]);
+ }
+
+ first_init = false;
+ }
+
+ sleep(HZ/20);
REG_USBCMD |= USBCMD_CTRL_RESET;
while (REG_USBCMD & USBCMD_CTRL_RESET);
REG_USBMODE = USBMODE_CTRL_MODE_DEVICE;
+#if CONFIG_CPU == IMX31L
+ /* Set to ULPI */
+ REG_PORTSC1 = (REG_PORTSC1 & ~PORTSCX_PHY_TYPE_SEL) | PORTSCX_PTS_ULPI;
+#endif
+
#ifndef USE_HIGH_SPEED
/* Force device to full speed */
/* See 32.9.5.9.2 */
@@ -382,8 +421,12 @@ void usb_drv_init(void)
USBINTR_RESET_EN |
USBINTR_SYS_ERR_EN;
+#if CONFIG_CPU == IMX31L
+ avic_enable_int(USB_OTG, IRQ, 7, USB_OTG_HANDLER);
+#else
/* enable USB IRQ in CPU */
- CPU_INT_EN |= USB_MASK;
+ CPU_INT_EN = USB_MASK;
+#endif
/* go go go */
REG_USBCMD |= USBCMD_RUN;
@@ -410,10 +453,20 @@ void usb_drv_exit(void)
REG_USBCMD |= USBCMD_CTRL_RESET;
*/
+#if CONFIG_CPU == IMX31L
+ avic_disable_int(USB_OTG);
+#else
+ CPU_INT_CLR = USB_MASK;
+#endif
+
cancel_cpu_boost();
}
+#if CONFIG_CPU == IMX31L
+static void __attribute__((interrupt("IRQ"))) USB_OTG_HANDLER(void)
+#else
void usb_drv_int(void)
+#endif
{
unsigned int status = REG_USBSTS;
@@ -564,7 +617,7 @@ void usb_drv_set_test_mode(int mode)
break;
}
REG_USBCMD &= ~USBCMD_RUN;
- udelay(50000);
+ sleep(HZ/20);
REG_USBCMD |= USBCMD_CTRL_RESET;
while (REG_USBCMD & USBCMD_CTRL_RESET);
REG_USBCMD |= USBCMD_RUN;
@@ -575,6 +628,7 @@ void usb_drv_set_test_mode(int mode)
/* manual: 32.14.5.2 */
static int prime_transfer(int endpoint, void* ptr, int len, bool send, bool wait)
{
+ int rc = 0;
int pipe = endpoint * 2 + (send ? 1 : 0);
unsigned int mask = pipe2mask[pipe];
struct queue_head* qh = &qh_array[pipe];
@@ -590,7 +644,6 @@ static int prime_transfer(int endpoint, void* ptr, int len, bool send, bool wait
qh->length = 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<NUM_ENDPOINTS*2;i++) {
- queue_init(&transfer_completion_queue[i], false);
- }
}
static void init_endpoints(void)
diff --git a/firmware/usb.c b/firmware/usb.c
index 99b2f64612..6cc3337d82 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -45,12 +45,22 @@
#endif
#include "logf.h"
+/* Conditions under which we want the entire driver */
+#if !defined(BOOTLOADER) || \
+ (defined(TOSHIBA_GIGABEAT_S) && defined(USE_ROCKBOX_USB) && defined(USB_STORAGE))
+#define USB_FULL_INIT
+#endif
+
extern void dbg_ports(void); /* NASTY! defined in apps/ */
#ifdef HAVE_LCD_BITMAP
bool do_screendump_instead_of_usb = false;
+#if defined(USB_FULL_INIT) && defined(BOOTLOADER)
+static void screen_dump(void) {}
+#else
void screen_dump(void); /* Nasty again. Defined in apps/ too */
#endif
+#endif
#if !defined(SIMULATOR) && !defined(USB_NONE)
@@ -59,13 +69,13 @@ static int countdown;
static int usb_state;
-#if defined(HAVE_MMC) && !defined(BOOTLOADER)
+#if defined(HAVE_MMC) && defined(USB_FULL_INIT)
static int usb_mmc_countdown = 0;
#endif
/* FIXME: The extra 0x800 is consumed by fat_mount() when the fsinfo
needs updating */
-#ifndef BOOTLOADER
+#ifdef USB_FULL_INIT
static long usb_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)];
static const char usb_thread_name[] = "usb";
static struct thread_entry *usb_thread_entry;
@@ -84,9 +94,7 @@ static int firewire_countdown;
static bool last_firewire_status;
#endif
-
-
-#ifndef BOOTLOADER
+#ifdef USB_FULL_INIT
#ifndef HAVE_USBSTACK
static void usb_slave_mode(bool on)
{
@@ -377,7 +385,7 @@ void usb_signal_transfer_completion(struct usb_transfer_completion_event_data* e
}
#endif
-#ifndef BOOTLOADER
+#ifdef USB_FULL_INIT
static void usb_tick(void)
{
int current_status;
@@ -461,14 +469,14 @@ void usb_init(void)
#endif
usb_init_device();
-#ifndef BOOTLOADER
+#ifdef USB_FULL_INIT
usb_enable(false);
#endif
/* We assume that the USB cable is extracted */
last_usb_status = USB_EXTRACTED;
-#ifndef BOOTLOADER
+#ifdef USB_FULL_INIT
queue_init(&usb_queue, true);
usb_thread_entry = create_thread(usb_thread, usb_stack,
@@ -522,6 +530,14 @@ void usb_start_monitoring(void)
usb_monitor_enabled = true;
}
+#ifdef TOSHIBA_GIGABEAT_S
+void usb_stop_monitoring(void)
+{
+ tick_remove_task(usb_tick);
+ usb_monitor_enabled = false;
+}
+#endif
+
bool usb_inserted(void)
{
#ifdef HAVE_USB_POWER
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c
index 5bd18fb6be..084b8893af 100644
--- a/firmware/usbstack/usb_core.c
+++ b/firmware/usbstack/usb_core.c
@@ -5,7 +5,7 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* 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 */