move the usb_core thread functionality to the main usb thread
fix button-detection so screenshots and charge-only mode work without enabling UMS firewire detection is now handled separately from usb detection increase the usb thread priority while an UMS connection is active git-svn-id: svn://svn.rockbox.org/rockbox/trunk@16435 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
41c1f17296
commit
6e7fac7c34
6 changed files with 223 additions and 219 deletions
|
@ -457,7 +457,9 @@ static void init(void)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
usb_screen();
|
usb_screen();
|
||||||
|
#ifndef HAVE_USBSTACK
|
||||||
mounted = true; /* mounting done @ end of USB mode */
|
mounted = true; /* mounting done @ end of USB mode */
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef HAVE_USB_POWER
|
#ifdef HAVE_USB_POWER
|
||||||
if (usb_powered()) /* avoid deadlock */
|
if (usb_powered()) /* avoid deadlock */
|
||||||
|
|
|
@ -23,15 +23,17 @@
|
||||||
#include "button.h"
|
#include "button.h"
|
||||||
|
|
||||||
/* Messages from usb_tick and thread states */
|
/* Messages from usb_tick and thread states */
|
||||||
#define USB_INSERTED 1
|
enum {
|
||||||
#define USB_EXTRACTED 2
|
USB_INSERTED,
|
||||||
#ifdef HAVE_MMC
|
USB_EXTRACTED,
|
||||||
#define USB_REENABLE 3
|
USB_REENABLE,
|
||||||
#endif
|
USB_POWERED,
|
||||||
|
USB_TRANSFER_COMPLETION,
|
||||||
|
USB_REQUEST_REBOOT
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_USB_POWER
|
#ifdef HAVE_USB_POWER
|
||||||
#define USB_POWERED 4
|
|
||||||
|
|
||||||
#if CONFIG_KEYPAD == RECORDER_PAD
|
#if CONFIG_KEYPAD == RECORDER_PAD
|
||||||
#define USBPOWER_BUTTON BUTTON_F1
|
#define USBPOWER_BUTTON BUTTON_F1
|
||||||
#define USBPOWER_BTN_IGNORE BUTTON_ON
|
#define USBPOWER_BTN_IGNORE BUTTON_ON
|
||||||
|
@ -70,6 +72,16 @@ enum {
|
||||||
USB_DRIVER_COUNT
|
USB_DRIVER_COUNT
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_USBSTACK
|
||||||
|
struct usb_transfer_completion_event_data
|
||||||
|
{
|
||||||
|
unsigned char endpoint;
|
||||||
|
bool in;
|
||||||
|
int status;
|
||||||
|
int length;
|
||||||
|
void* data;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
void usb_init(void);
|
void usb_init(void);
|
||||||
|
@ -87,5 +99,14 @@ bool usb_charging_enable(bool on);
|
||||||
bool usb_charging_enabled(void);
|
bool usb_charging_enabled(void);
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef HAVE_USBSTACK
|
||||||
|
void usb_signal_transfer_completion(struct usb_transfer_completion_event_data* event_data);
|
||||||
|
bool usb_driver_enabled(int driver);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(IPOD_COLOR) || defined(IPOD_4G) \
|
||||||
|
|| defined(IPOD_MINI) || defined(IPOD_MINI2G)
|
||||||
|
bool firewire_detect(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,34 +20,23 @@
|
||||||
#define USB_CORE_H
|
#define USB_CORE_H
|
||||||
|
|
||||||
#ifndef BOOTLOADER
|
#ifndef BOOTLOADER
|
||||||
#define USB_THREAD
|
|
||||||
|
|
||||||
#ifdef USE_ROCKBOX_USB
|
|
||||||
//#define USB_SERIAL
|
//#define USB_SERIAL
|
||||||
//#define USB_BENCHMARK
|
//#define USB_BENCHMARK
|
||||||
#define USB_STORAGE
|
#define USB_STORAGE
|
||||||
|
|
||||||
#else
|
|
||||||
#define USB_CHARGING_ONLY
|
#define USB_CHARGING_ONLY
|
||||||
|
#else /* BOOTLOADER */
|
||||||
#endif /* USE_ROCKBOX_USB */
|
|
||||||
#else
|
|
||||||
#define USB_CHARGING_ONLY
|
#define USB_CHARGING_ONLY
|
||||||
#endif /* BOOTLOADER */
|
#endif /* BOOTLOADER */
|
||||||
|
|
||||||
#include "usb_ch9.h"
|
#include "usb_ch9.h"
|
||||||
|
#include "usb.h"
|
||||||
|
|
||||||
#if defined(CPU_PP)
|
#if defined(CPU_PP)
|
||||||
#define USB_IRAM_ORIGIN ((unsigned char *)0x4000c000)
|
#define USB_IRAM_ORIGIN ((unsigned char *)0x4000c000)
|
||||||
#define USB_IRAM_SIZE ((size_t)0xc000)
|
#define USB_IRAM_SIZE ((size_t)0xc000)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
enum {
|
|
||||||
USB_CORE_QUIT,
|
|
||||||
USB_CORE_TRANSFER_COMPLETION
|
|
||||||
};
|
|
||||||
|
|
||||||
/* endpoints */
|
/* endpoints */
|
||||||
enum {
|
enum {
|
||||||
EP_CONTROL = 0,
|
EP_CONTROL = 0,
|
||||||
|
@ -66,16 +55,6 @@ enum {
|
||||||
NUM_ENDPOINTS
|
NUM_ENDPOINTS
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* queue events */
|
|
||||||
#define USB_TRANSFER_COMPLETE 1
|
|
||||||
|
|
||||||
struct queue_msg {
|
|
||||||
int endpoint;
|
|
||||||
int length;
|
|
||||||
void* data;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern int usb_max_pkt_size;
|
extern int usb_max_pkt_size;
|
||||||
|
|
||||||
void usb_core_init(void);
|
void usb_core_init(void);
|
||||||
|
@ -83,7 +62,8 @@ void usb_core_exit(void);
|
||||||
void usb_core_control_request(struct usb_ctrlrequest* req);
|
void usb_core_control_request(struct usb_ctrlrequest* req);
|
||||||
void usb_core_transfer_complete(int endpoint, bool in, int status, int length);
|
void usb_core_transfer_complete(int endpoint, bool in, int status, int length);
|
||||||
void usb_core_bus_reset(void);
|
void usb_core_bus_reset(void);
|
||||||
bool usb_core_data_connection(void);
|
bool usb_core_exclusive_connection(void);
|
||||||
|
void usb_core_enable_protocol(int driver,bool enabled);
|
||||||
|
void usb_core_handle_transfer_completion(struct usb_transfer_completion_event_data* event);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -70,33 +70,25 @@ void usb_init_device(void)
|
||||||
void usb_enable(bool on)
|
void usb_enable(bool on)
|
||||||
{
|
{
|
||||||
if (on) {
|
if (on) {
|
||||||
usb_core_init();
|
/* if USB is detected, re-enable the USB-devices, otherwise make sure it's disabled */
|
||||||
#if !defined(USE_ROCKBOX_USB)
|
DEV_EN |= DEV_USB0;
|
||||||
/* until we have native mass-storage mode, we want to reboot on
|
DEV_RS &=~DEV_USB0;
|
||||||
usb host connect */
|
DEV_EN |= DEV_USB1;
|
||||||
#if defined(IRIVER_H10) || defined (IRIVER_H10_5GB)
|
DEV_RS &=~DEV_USB1;
|
||||||
if (button_status()==BUTTON_RIGHT)
|
|
||||||
#endif /* defined(IRIVER_H10) || defined (IRIVER_H10_5GB) */
|
|
||||||
{
|
|
||||||
#ifndef HAVE_FLASH_STORAGE
|
|
||||||
ata_sleepnow(); /* Immediately spindown the disk. */
|
|
||||||
sleep(HZ*2);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef IPOD_ARCH /* The following code is based on ipodlinux */
|
|
||||||
#if CONFIG_CPU == PP5020
|
#if CONFIG_CPU == PP5020
|
||||||
memcpy((void *)0x40017f00, "diskmode\0\0hotstuff\0\0\1", 21);
|
DEV_INIT2 |= INIT_USB;
|
||||||
#elif CONFIG_CPU == PP5022
|
#endif
|
||||||
memcpy((void *)0x4001ff00, "diskmode\0\0hotstuff\0\0\1", 21);
|
usb_core_init();
|
||||||
#endif /* CONFIG_CPU */
|
|
||||||
#endif /* IPOD_ARCH */
|
|
||||||
|
|
||||||
system_reboot(); /* Reboot */
|
|
||||||
}
|
|
||||||
#endif /* USE_ROCKBOX_USB */
|
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
usb_core_exit();
|
usb_core_exit();
|
||||||
|
/* Disable USB devices */
|
||||||
|
DEV_EN &=~ DEV_USB0;
|
||||||
|
DEV_EN &=~ DEV_USB1;
|
||||||
|
#if CONFIG_CPU == PP5020
|
||||||
|
DEV_INIT2 &=~ INIT_USB;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool usb_pin_detect(void)
|
static bool usb_pin_detect(void)
|
||||||
|
@ -136,80 +128,23 @@ static bool usb_pin_detect(void)
|
||||||
/* detect host or charger (INSERTED or POWERED) */
|
/* detect host or charger (INSERTED or POWERED) */
|
||||||
int usb_detect(void)
|
int usb_detect(void)
|
||||||
{
|
{
|
||||||
static int countdown = 0;
|
if(usb_pin_detect()) {
|
||||||
static int status = USB_EXTRACTED;
|
return USB_INSERTED;
|
||||||
static bool prev_usbstatus1 = false;
|
}
|
||||||
bool usbstatus1, usbstatus2;
|
else {
|
||||||
|
return USB_EXTRACTED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(IPOD_COLOR) || defined(IPOD_4G) \
|
#if defined(IPOD_COLOR) || defined(IPOD_4G) \
|
||||||
|| defined(IPOD_MINI) || defined(IPOD_MINI2G)
|
|| defined(IPOD_MINI) || defined(IPOD_MINI2G)
|
||||||
|
bool firewire_detect(void)
|
||||||
|
{
|
||||||
/* GPIO C bit 1 is firewire detect */
|
/* GPIO C bit 1 is firewire detect */
|
||||||
if (!(GPIOC_INPUT_VAL & 0x02))
|
if (!(GPIOC_INPUT_VAL & 0x02))
|
||||||
/* no charger detection needed for firewire */
|
/* no charger detection needed for firewire */
|
||||||
return USB_INSERTED;
|
return true;
|
||||||
#endif
|
else
|
||||||
|
return false;
|
||||||
if (countdown > 0)
|
|
||||||
{
|
|
||||||
countdown--;
|
|
||||||
|
|
||||||
usbstatus2 = usb_core_data_connection();
|
|
||||||
if ((countdown == 0) || usbstatus2)
|
|
||||||
{
|
|
||||||
/* We now know that we have been connected to either a charger
|
|
||||||
or a computer */
|
|
||||||
countdown = 0;
|
|
||||||
status = usbstatus2 ? USB_INSERTED : USB_POWERED;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
usbstatus1 = usb_pin_detect();
|
|
||||||
|
|
||||||
if (usbstatus1 == prev_usbstatus1)
|
|
||||||
{
|
|
||||||
/* Nothing has changed, so just return previous status */
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
prev_usbstatus1 = usbstatus1;
|
|
||||||
|
|
||||||
if (!usbstatus1)
|
|
||||||
{ /* We have just been disconnected */
|
|
||||||
status = USB_EXTRACTED;
|
|
||||||
|
|
||||||
/* Disable USB devices */
|
|
||||||
DEV_EN &=~ DEV_USB0;
|
|
||||||
DEV_EN &=~ DEV_USB1;
|
|
||||||
#if CONFIG_CPU == PP5020
|
|
||||||
DEV_INIT2 &=~ INIT_USB;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return status;
|
|
||||||
} else {
|
|
||||||
/* if USB is detected, re-enable the USB-devices, otherwise make sure it's disabled */
|
|
||||||
DEV_EN |= DEV_USB0;
|
|
||||||
DEV_RS &=~DEV_USB0;
|
|
||||||
DEV_EN |= DEV_USB1;
|
|
||||||
DEV_RS &=~DEV_USB1;
|
|
||||||
#if CONFIG_CPU == PP5020
|
|
||||||
DEV_INIT2 |= INIT_USB;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Run the USB stack to request full bus power */
|
|
||||||
usb_core_init();
|
|
||||||
|
|
||||||
if((button_status() & ~USBPOWER_BTN_IGNORE) == USBPOWER_BUTTON)
|
|
||||||
{
|
|
||||||
/* The user wants to charge, so it doesn't matter what we are
|
|
||||||
connected to. */
|
|
||||||
status = USB_POWERED;
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait up to 100 ticks (1s) before deciding there is no computer
|
|
||||||
attached. */
|
|
||||||
countdown = 100;
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
124
firmware/usb.c
124
firmware/usb.c
|
@ -37,6 +37,9 @@
|
||||||
#include "sprintf.h"
|
#include "sprintf.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "usb-target.h"
|
#include "usb-target.h"
|
||||||
|
#ifdef HAVE_USBSTACK
|
||||||
|
#include "usb_core.h"
|
||||||
|
#endif
|
||||||
#ifdef IRIVER_H300_SERIES
|
#ifdef IRIVER_H300_SERIES
|
||||||
#include "pcf50606.h" /* for pcf50606_usb_charging_... */
|
#include "pcf50606.h" /* for pcf50606_usb_charging_... */
|
||||||
#endif
|
#endif
|
||||||
|
@ -65,13 +68,23 @@ static int usb_mmc_countdown = 0;
|
||||||
#ifndef BOOTLOADER
|
#ifndef BOOTLOADER
|
||||||
static long usb_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)];
|
static long usb_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)];
|
||||||
static const char usb_thread_name[] = "usb";
|
static const char usb_thread_name[] = "usb";
|
||||||
|
static struct thread_entry *usb_thread_entry;
|
||||||
#endif
|
#endif
|
||||||
static struct event_queue usb_queue;
|
static struct event_queue usb_queue;
|
||||||
static int last_usb_status;
|
static int last_usb_status;
|
||||||
static bool usb_monitor_enabled;
|
static bool usb_monitor_enabled;
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(IPOD_COLOR) || defined(IPOD_4G) \
|
||||||
|
|| defined(IPOD_MINI) || defined(IPOD_MINI2G)
|
||||||
|
static int firewire_countdown;
|
||||||
|
static bool last_firewire_status;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef BOOTLOADER
|
#ifndef BOOTLOADER
|
||||||
|
#ifndef HAVE_USBSTACK
|
||||||
static void usb_slave_mode(bool on)
|
static void usb_slave_mode(bool on)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -88,10 +101,8 @@ static void usb_slave_mode(bool on)
|
||||||
{
|
{
|
||||||
DEBUGF("Leaving USB slave mode\n");
|
DEBUGF("Leaving USB slave mode\n");
|
||||||
|
|
||||||
#ifndef HAVE_USBSTACK
|
|
||||||
/* Let the ISDx00 settle */
|
/* Let the ISDx00 settle */
|
||||||
sleep(HZ*1);
|
sleep(HZ*1);
|
||||||
#endif
|
|
||||||
|
|
||||||
usb_enable(false);
|
usb_enable(false);
|
||||||
|
|
||||||
|
@ -116,6 +127,30 @@ static void usb_slave_mode(bool on)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void try_reboot(void)
|
||||||
|
{
|
||||||
|
#if defined(IRIVER_H10) || defined (IRIVER_H10_5GB)
|
||||||
|
if (button_status()==BUTTON_RIGHT)
|
||||||
|
#endif /* defined(IRIVER_H10) || defined (IRIVER_H10_5GB) */
|
||||||
|
{
|
||||||
|
#ifndef HAVE_FLASH_STORAGE
|
||||||
|
ata_sleepnow(); /* Immediately spindown the disk. */
|
||||||
|
sleep(HZ*2);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IPOD_ARCH /* The following code is based on ipodlinux */
|
||||||
|
#if CONFIG_CPU == PP5020
|
||||||
|
memcpy((void *)0x40017f00, "diskmode\0\0hotstuff\0\0\1", 21);
|
||||||
|
#elif CONFIG_CPU == PP5022
|
||||||
|
memcpy((void *)0x4001ff00, "diskmode\0\0hotstuff\0\0\1", 21);
|
||||||
|
#endif /* CONFIG_CPU */
|
||||||
|
#endif /* IPOD_ARCH */
|
||||||
|
|
||||||
|
system_reboot(); /* Reboot */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void usb_thread(void)
|
static void usb_thread(void)
|
||||||
{
|
{
|
||||||
|
@ -130,6 +165,11 @@ static void usb_thread(void)
|
||||||
queue_wait(&usb_queue, &ev);
|
queue_wait(&usb_queue, &ev);
|
||||||
switch(ev.id)
|
switch(ev.id)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_USBSTACK
|
||||||
|
case USB_TRANSFER_COMPLETION:
|
||||||
|
usb_core_handle_transfer_completion((struct usb_transfer_completion_event_data*)ev.data);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
#ifdef HAVE_USB_POWER
|
#ifdef HAVE_USB_POWER
|
||||||
case USB_POWERED:
|
case USB_POWERED:
|
||||||
usb_state = USB_POWERED;
|
usb_state = USB_POWERED;
|
||||||
|
@ -147,6 +187,12 @@ static void usb_thread(void)
|
||||||
if((button_status() & ~USBPOWER_BTN_IGNORE) == USBPOWER_BUTTON)
|
if((button_status() & ~USBPOWER_BTN_IGNORE) == USBPOWER_BUTTON)
|
||||||
{
|
{
|
||||||
usb_state = USB_POWERED;
|
usb_state = USB_POWERED;
|
||||||
|
#ifdef HAVE_USBSTACK
|
||||||
|
usb_core_enable_protocol(USB_DRIVER_MASS_STORAGE,false);
|
||||||
|
usb_core_enable_protocol(USB_DRIVER_SERIAL,false);/* TODO: add debug setting */
|
||||||
|
usb_core_enable_protocol(USB_DRIVER_CHARGING_ONLY,true);
|
||||||
|
usb_enable(true);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@ -168,9 +214,26 @@ static void usb_thread(void)
|
||||||
if(num_acks_to_expect == 0)
|
if(num_acks_to_expect == 0)
|
||||||
{
|
{
|
||||||
DEBUGF("All threads have acknowledged the connect.\n");
|
DEBUGF("All threads have acknowledged the connect.\n");
|
||||||
|
#ifdef HAVE_USBSTACK
|
||||||
|
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||||
|
thread_set_priority(usb_thread_entry,PRIORITY_REALTIME);
|
||||||
|
#endif
|
||||||
|
#ifdef USE_ROCKBOX_USB
|
||||||
|
usb_core_enable_protocol(USB_DRIVER_MASS_STORAGE,true);
|
||||||
|
usb_core_enable_protocol(USB_DRIVER_SERIAL,false);/* TODO: add debug setting */
|
||||||
|
usb_core_enable_protocol(USB_DRIVER_CHARGING_ONLY,false);
|
||||||
|
usb_enable(true);
|
||||||
|
#else /* USE_ROCKBOX_USB */
|
||||||
|
/* until we have native mass-storage mode, we want to reboot on
|
||||||
|
usb host connect */
|
||||||
|
try_reboot();
|
||||||
|
#endif /* USE_ROCKBOX_USB */
|
||||||
|
|
||||||
|
#else
|
||||||
usb_slave_mode(true);
|
usb_slave_mode(true);
|
||||||
usb_state = USB_INSERTED;
|
|
||||||
cpu_idle_mode(true);
|
cpu_idle_mode(true);
|
||||||
|
#endif
|
||||||
|
usb_state = USB_INSERTED;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -181,6 +244,12 @@ static void usb_thread(void)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case USB_EXTRACTED:
|
case USB_EXTRACTED:
|
||||||
|
#ifdef HAVE_USBSTACK
|
||||||
|
usb_enable(false);
|
||||||
|
#ifdef HAVE_PRIORITY_SCHEDULING
|
||||||
|
thread_set_priority(usb_thread_entry,PRIORITY_SYSTEM);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
#ifdef HAVE_LCD_BITMAP
|
#ifdef HAVE_LCD_BITMAP
|
||||||
if(do_screendump_instead_of_usb)
|
if(do_screendump_instead_of_usb)
|
||||||
break;
|
break;
|
||||||
|
@ -192,6 +261,7 @@ static void usb_thread(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef HAVE_USBSTACK
|
||||||
if(usb_state == USB_INSERTED)
|
if(usb_state == USB_INSERTED)
|
||||||
{
|
{
|
||||||
/* Only disable the USB mode if we really have enabled it
|
/* Only disable the USB mode if we really have enabled it
|
||||||
|
@ -200,6 +270,7 @@ static void usb_thread(void)
|
||||||
usb_slave_mode(false);
|
usb_slave_mode(false);
|
||||||
cpu_idle_mode(false);
|
cpu_idle_mode(false);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
usb_state = USB_EXTRACTED;
|
usb_state = USB_EXTRACTED;
|
||||||
|
|
||||||
|
@ -243,11 +314,21 @@ static void usb_thread(void)
|
||||||
usb_enable(true); /* reenable only if still inserted */
|
usb_enable(true); /* reenable only if still inserted */
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
case USB_REQUEST_REBOOT:
|
||||||
|
if((button_status() & ~USBPOWER_BTN_IGNORE) != USBPOWER_BUTTON)
|
||||||
|
try_reboot();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_USBSTACK
|
||||||
|
void usb_signal_transfer_completion(struct usb_transfer_completion_event_data* event_data)
|
||||||
|
{
|
||||||
|
queue_post(&usb_queue, USB_TRANSFER_COMPLETION, (intptr_t)event_data);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef BOOTLOADER
|
#ifndef BOOTLOADER
|
||||||
static void usb_tick(void)
|
static void usb_tick(void)
|
||||||
|
@ -256,6 +337,29 @@ static void usb_tick(void)
|
||||||
|
|
||||||
if(usb_monitor_enabled)
|
if(usb_monitor_enabled)
|
||||||
{
|
{
|
||||||
|
#if defined(IPOD_COLOR) || defined(IPOD_4G) \
|
||||||
|
|| defined(IPOD_MINI) || defined(IPOD_MINI2G)
|
||||||
|
int current_firewire_status = firewire_detect();
|
||||||
|
if(current_firewire_status != last_firewire_status)
|
||||||
|
{
|
||||||
|
last_firewire_status = current_firewire_status;
|
||||||
|
firewire_countdown = NUM_POLL_READINGS;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Count down until it gets negative */
|
||||||
|
if(firewire_countdown >= 0)
|
||||||
|
firewire_countdown--;
|
||||||
|
|
||||||
|
/* Report to the thread if we have had 3 identical status
|
||||||
|
readings in a row */
|
||||||
|
if(firewire_countdown == 0)
|
||||||
|
{
|
||||||
|
queue_post(&usb_queue, USB_REQUEST_REBOOT, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
current_status = usb_detect();
|
current_status = usb_detect();
|
||||||
|
|
||||||
/* Only report when the status has changed */
|
/* Only report when the status has changed */
|
||||||
|
@ -300,18 +404,24 @@ void usb_init(void)
|
||||||
usb_monitor_enabled = false;
|
usb_monitor_enabled = false;
|
||||||
countdown = -1;
|
countdown = -1;
|
||||||
|
|
||||||
|
#if defined(IPOD_COLOR) || defined(IPOD_4G) \
|
||||||
|
|| defined(IPOD_MINI) || defined(IPOD_MINI2G)
|
||||||
|
firewire_countdown = -1;
|
||||||
|
last_firewire_status = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
usb_init_device();
|
usb_init_device();
|
||||||
usb_enable(false);
|
usb_enable(false);
|
||||||
|
|
||||||
/* We assume that the USB cable is extracted */
|
/* We assume that the USB cable is extracted */
|
||||||
last_usb_status = false;
|
last_usb_status = USB_EXTRACTED;
|
||||||
|
|
||||||
#ifndef BOOTLOADER
|
#ifndef BOOTLOADER
|
||||||
queue_init(&usb_queue, true);
|
queue_init(&usb_queue, true);
|
||||||
|
|
||||||
create_thread(usb_thread, usb_stack, sizeof(usb_stack), 0,
|
usb_thread_entry = create_thread(usb_thread, usb_stack,
|
||||||
usb_thread_name IF_PRIO(, PRIORITY_SYSTEM)
|
sizeof(usb_stack), 0, usb_thread_name
|
||||||
IF_COP(, CPU));
|
IF_PRIO(, PRIORITY_SYSTEM) IF_COP(, CPU));
|
||||||
|
|
||||||
tick_add_task(usb_tick);
|
tick_add_task(usb_tick);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,8 +28,6 @@
|
||||||
#include "usb_drv.h"
|
#include "usb_drv.h"
|
||||||
#include "usb_core.h"
|
#include "usb_core.h"
|
||||||
|
|
||||||
#define USB_THREAD
|
|
||||||
|
|
||||||
#if defined(USB_STORAGE)
|
#if defined(USB_STORAGE)
|
||||||
#include "usb_storage.h"
|
#include "usb_storage.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -289,28 +287,14 @@ static struct usb_string_descriptor* usb_strings[] =
|
||||||
|
|
||||||
static int usb_address = 0;
|
static int usb_address = 0;
|
||||||
static bool initialized = false;
|
static bool initialized = false;
|
||||||
static bool data_connection = false;
|
|
||||||
static struct event_queue usbcore_queue;
|
|
||||||
static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
|
static enum { DEFAULT, ADDRESS, CONFIGURED } usb_state;
|
||||||
|
|
||||||
#ifdef USB_THREAD
|
static bool usb_core_storage_enabled = false;
|
||||||
static const char usbcore_thread_name[] = "usb_core";
|
static bool usb_core_serial_enabled = false;
|
||||||
static struct thread_entry* usbcore_thread;
|
|
||||||
static long usbcore_stack[DEFAULT_STACK_SIZE];
|
|
||||||
static void usb_core_thread(void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USE_ROCKBOX_USB
|
|
||||||
static bool usb_core_charging_enabled = false;
|
static bool usb_core_charging_enabled = false;
|
||||||
static bool usb_core_storage_enabled = true;
|
|
||||||
static bool usb_core_serial_enabled = true;
|
|
||||||
#if defined(USB_BENCHMARK)
|
#if defined(USB_BENCHMARK)
|
||||||
static bool usb_core_benchmark_enabled = false;
|
static bool usb_core_benchmark_enabled = false;
|
||||||
#endif
|
#endif
|
||||||
#else
|
|
||||||
static bool usb_core_charging_enabled = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
static void usb_core_control_request_handler(struct usb_ctrlrequest* req);
|
static void usb_core_control_request_handler(struct usb_ctrlrequest* req);
|
||||||
static int ack_control(struct usb_ctrlrequest* req);
|
static int ack_control(struct usb_ctrlrequest* req);
|
||||||
|
@ -318,16 +302,7 @@ static int ack_control(struct usb_ctrlrequest* req);
|
||||||
static unsigned char *response_data;
|
static unsigned char *response_data;
|
||||||
static unsigned char __response_data[CACHEALIGN_UP(256)] CACHEALIGN_ATTR;
|
static unsigned char __response_data[CACHEALIGN_UP(256)] CACHEALIGN_ATTR;
|
||||||
|
|
||||||
struct usb_core_event
|
static struct usb_transfer_completion_event_data events[NUM_ENDPOINTS];
|
||||||
{
|
|
||||||
unsigned char endpoint;
|
|
||||||
bool in;
|
|
||||||
int status;
|
|
||||||
int length;
|
|
||||||
void* data;
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct usb_core_event events[NUM_ENDPOINTS];
|
|
||||||
|
|
||||||
#ifdef IPOD_ARCH
|
#ifdef IPOD_ARCH
|
||||||
static void set_serial_descriptor(void)
|
static void set_serial_descriptor(void)
|
||||||
|
@ -408,8 +383,11 @@ void usb_core_init(void)
|
||||||
|
|
||||||
response_data = (void*)UNCACHED_ADDR(&__response_data);
|
response_data = (void*)UNCACHED_ADDR(&__response_data);
|
||||||
|
|
||||||
queue_init(&usbcore_queue, false);
|
|
||||||
usb_drv_init();
|
usb_drv_init();
|
||||||
|
|
||||||
|
/* class driver init functions should be safe to call even if the driver
|
||||||
|
* won't be used. This simplifies other logic (i.e. we don't need to know
|
||||||
|
* yet which drivers will be enabled */
|
||||||
#ifdef USB_STORAGE
|
#ifdef USB_STORAGE
|
||||||
usb_storage_init();
|
usb_storage_init();
|
||||||
#endif
|
#endif
|
||||||
|
@ -418,14 +396,6 @@ void usb_core_init(void)
|
||||||
usb_serial_init();
|
usb_serial_init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USB_THREAD
|
|
||||||
usbcore_thread =
|
|
||||||
create_thread(usb_core_thread, usbcore_stack, sizeof(usbcore_stack), 0,
|
|
||||||
usbcore_thread_name
|
|
||||||
IF_PRIO(, PRIORITY_SYSTEM)
|
|
||||||
IF_COP(, CPU));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USB_BENCHMARK
|
#ifdef USB_BENCHMARK
|
||||||
usb_benchmark_init();
|
usb_benchmark_init();
|
||||||
#endif
|
#endif
|
||||||
|
@ -438,71 +408,57 @@ void usb_core_exit(void)
|
||||||
{
|
{
|
||||||
if (initialized) {
|
if (initialized) {
|
||||||
usb_drv_exit();
|
usb_drv_exit();
|
||||||
#ifdef USB_THREAD
|
|
||||||
queue_post(&usbcore_queue, USB_CORE_QUIT, 0);
|
|
||||||
thread_wait(usbcore_thread);
|
|
||||||
#endif
|
|
||||||
queue_delete(&usbcore_queue);
|
|
||||||
}
|
}
|
||||||
data_connection = false;
|
|
||||||
initialized = false;
|
initialized = false;
|
||||||
logf("usb_core_exit() finished");
|
logf("usb_core_exit() finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool usb_core_data_connection(void)
|
void usb_core_handle_transfer_completion(struct usb_transfer_completion_event_data* event)
|
||||||
{
|
{
|
||||||
return data_connection;
|
switch(event->endpoint) {
|
||||||
}
|
case EP_CONTROL:
|
||||||
|
logf("ctrl handled %ld",current_tick);
|
||||||
#ifdef USB_THREAD
|
usb_core_control_request_handler((struct usb_ctrlrequest*)event->data);
|
||||||
void usb_core_thread(void)
|
break;
|
||||||
{
|
|
||||||
while (1) {
|
|
||||||
struct queue_event ev;
|
|
||||||
|
|
||||||
queue_wait(&usbcore_queue, &ev);
|
|
||||||
if (ev.id == USB_CORE_QUIT) {
|
|
||||||
cancel_cpu_boost();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ev.id == USB_CORE_TRANSFER_COMPLETION) {
|
|
||||||
struct usb_core_event* event = (struct usb_core_event*)ev.data;
|
|
||||||
switch(event->endpoint) {
|
|
||||||
case EP_CONTROL:
|
|
||||||
logf("ctrl handled %ld",current_tick);
|
|
||||||
usb_core_control_request_handler((struct usb_ctrlrequest*)event->data);
|
|
||||||
break;
|
|
||||||
#ifdef USB_STORAGE
|
#ifdef USB_STORAGE
|
||||||
case EP_MASS_STORAGE:
|
case EP_MASS_STORAGE:
|
||||||
usb_storage_transfer_complete(event->in,event->status,event->length);
|
usb_storage_transfer_complete(event->in,event->status,event->length);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef USB_SERIAL
|
#ifdef USB_SERIAL
|
||||||
case EP_SERIAL:
|
case EP_SERIAL:
|
||||||
usb_serial_transfer_complete(event->in,event->status,event->length);
|
usb_serial_transfer_complete(event->in,event->status,event->length);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef USB_BENCHMARK
|
#ifdef USB_BENCHMARK
|
||||||
case EP_BENCHMARK:
|
case EP_BENCHMARK:
|
||||||
usb_benchmark_transfer_complete(event->in);
|
usb_benchmark_transfer_complete(event->in);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#ifdef USB_CHARGING_ONLY
|
#ifdef USB_CHARGING_ONLY
|
||||||
case EP_CHARGING_ONLY:
|
case EP_CHARGING_ONLY:
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
void usb_core_enable_protocol(int driver,bool enabled)
|
||||||
|
{
|
||||||
|
switch(driver) {
|
||||||
|
case USB_DRIVER_MASS_STORAGE:
|
||||||
|
usb_core_storage_enabled = enabled;
|
||||||
|
break;
|
||||||
|
case USB_DRIVER_SERIAL:
|
||||||
|
usb_core_serial_enabled = enabled;
|
||||||
|
break;
|
||||||
|
case USB_DRIVER_CHARGING_ONLY:
|
||||||
|
usb_core_charging_enabled = enabled;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
|
static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
|
||||||
{
|
{
|
||||||
/* note: interrupt context */
|
|
||||||
data_connection = true;
|
|
||||||
|
|
||||||
if(usb_state == DEFAULT) {
|
if(usb_state == DEFAULT) {
|
||||||
set_serial_descriptor();
|
set_serial_descriptor();
|
||||||
}
|
}
|
||||||
|
@ -766,13 +722,13 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
logf("control handled");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called by usb_drv_int() */
|
/* called by usb_drv_int() */
|
||||||
void usb_core_bus_reset(void)
|
void usb_core_bus_reset(void)
|
||||||
{
|
{
|
||||||
usb_address = 0;
|
usb_address = 0;
|
||||||
data_connection = false;
|
|
||||||
usb_state = DEFAULT;
|
usb_state = DEFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -795,7 +751,7 @@ void usb_core_transfer_complete(int endpoint, bool in, int status,int length)
|
||||||
events[endpoint].status=status;
|
events[endpoint].status=status;
|
||||||
events[endpoint].length=length;
|
events[endpoint].length=length;
|
||||||
/* All other endoints. Let the thread deal with it */
|
/* All other endoints. Let the thread deal with it */
|
||||||
queue_post(&usbcore_queue, USB_CORE_TRANSFER_COMPLETION, (intptr_t)&events[endpoint]);
|
usb_signal_transfer_completion(&events[endpoint]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -809,7 +765,7 @@ void usb_core_control_request(struct usb_ctrlrequest* req)
|
||||||
events[0].status=0;
|
events[0].status=0;
|
||||||
events[0].length=0;
|
events[0].length=0;
|
||||||
logf("ctrl received %ld",current_tick);
|
logf("ctrl received %ld",current_tick);
|
||||||
queue_post(&usbcore_queue, USB_CORE_TRANSFER_COMPLETION,(intptr_t)&events[0]);
|
usb_signal_transfer_completion(&events[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ack_control(struct usb_ctrlrequest* req)
|
static int ack_control(struct usb_ctrlrequest* req)
|
||||||
|
|
Loading…
Reference in a new issue