summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/debug_menu.c4
-rw-r--r--firmware/drivers/ata.c35
-rw-r--r--firmware/export/usb.h40
-rw-r--r--firmware/export/usb_core.h2
-rw-r--r--firmware/usb.c357
-rw-r--r--firmware/usbstack/usb_charging_only.h2
-rw-r--r--firmware/usbstack/usb_class_driver.h2
-rw-r--r--firmware/usbstack/usb_core.c39
-rw-r--r--firmware/usbstack/usb_storage.c9
9 files changed, 245 insertions, 245 deletions
diff --git a/apps/debug_menu.c b/apps/debug_menu.c
index 7477bb0..d3022df 100644
--- a/apps/debug_menu.c
+++ b/apps/debug_menu.c
@@ -2575,7 +2575,7 @@ static bool logf_usb_serial(void)
}
#endif
-#if defined(HAVE_USBSTACK) && defined(USB_STORAGE)
+#if 0 && defined(HAVE_USBSTACK) && defined(USB_STORAGE)
static bool usb_reconnect(void)
{
splash(HZ, "Reconnect mass storage");
@@ -2720,7 +2720,7 @@ static const struct the_menu_item menuitems[] = {
#if defined(HAVE_USBSTACK) && defined(ROCKBOX_HAS_LOGF) && defined(USB_SERIAL)
{"logf over usb",logf_usb_serial },
#endif
-#if defined(HAVE_USBSTACK) && defined(USB_STORAGE)
+#if 0 && defined(HAVE_USBSTACK) && defined(USB_STORAGE)
{"reconnect usb storage",usb_reconnect},
#endif
#ifdef CPU_BOOST_LOGGING
diff --git a/firmware/drivers/ata.c b/firmware/drivers/ata.c
index edef507..5f58297 100644
--- a/firmware/drivers/ata.c
+++ b/firmware/drivers/ata.c
@@ -61,8 +61,9 @@
#define CMD_SET_FEATURES 0xEF
#define CMD_SECURITY_FREEZE_LOCK 0xF5
-#define Q_SLEEP 0
-#define Q_CLOSE 1
+/* Should all be < 0x100 (which are reserved for control messages) */
+#define Q_SLEEP 0
+#define Q_CLOSE 1
#define READ_TIMEOUT 5*HZ
@@ -143,7 +144,7 @@ static void ata_lock_unlock(struct ata_lock *l)
#define mutex_unlock ata_lock_unlock
#endif /* MAX_PHYS_SECTOR_SIZE */
-#if defined(HAVE_USBSTACK) && defined(USE_ROCKBOX_USB) && !defined(BOOTLOADER)
+#if defined(HAVE_USBSTACK) && defined(USE_ROCKBOX_USB)
#define ALLOW_USB_SPINDOWN
#endif
@@ -164,7 +165,7 @@ static bool lba48 = false; /* set for 48 bit addressing */
#endif
static long ata_stack[(DEFAULT_STACK_SIZE*3)/sizeof(long)];
static const char ata_thread_name[] = "ata";
-static struct event_queue ata_queue;
+static struct event_queue ata_queue SHAREDBSS_ATTR;
static bool initialized = false;
static long last_user_activity = -1;
@@ -910,7 +911,9 @@ static void ata_thread(void)
#ifdef ALLOW_USB_SPINDOWN
if(!usb_mode)
#endif
+ {
call_storage_idle_notifys(false);
+ }
last_seen_mtx_unlock = 0;
}
}
@@ -923,7 +926,9 @@ static void ata_thread(void)
#ifdef ALLOW_USB_SPINDOWN
if(!usb_mode)
#endif
+ {
call_storage_idle_notifys(true);
+ }
ata_perform_sleep();
last_sleep = current_tick;
}
@@ -935,14 +940,21 @@ static void ata_thread(void)
{
mutex_lock(&ata_mtx);
ide_power_enable(false);
- mutex_unlock(&ata_mtx);
poweroff = true;
+ mutex_unlock(&ata_mtx);
}
#endif
break;
#ifndef USB_NONE
case SYS_USB_CONNECTED:
+ /* Tell the USB thread that we are safe */
+ DEBUGF("ata_thread got SYS_USB_CONNECTED\n");
+#ifdef ALLOW_USB_SPINDOWN
+ usb_mode = true;
+ usb_acknowledge(SYS_USB_CONNECTED_ACK);
+ /* There is no need to force ATA power on */
+#else
if (poweroff) {
mutex_lock(&ata_mtx);
ata_led(true);
@@ -951,14 +963,8 @@ static void ata_thread(void)
mutex_unlock(&ata_mtx);
}
- /* Tell the USB thread that we are safe */
- DEBUGF("ata_thread got SYS_USB_CONNECTED\n");
- usb_acknowledge(SYS_USB_CONNECTED_ACK);
-
-#ifdef ALLOW_USB_SPINDOWN
- usb_mode = true;
-#else
/* Wait until the USB cable is extracted again */
+ usb_acknowledge(SYS_USB_CONNECTED_ACK);
usb_wait_for_disconnect(&ata_queue);
#endif
break;
@@ -971,12 +977,15 @@ static void ata_thread(void)
usb_mode = false;
break;
#endif
-#endif
+#endif /* USB_NONE */
+
case Q_SLEEP:
#ifdef ALLOW_USB_SPINDOWN
if(!usb_mode)
#endif
+ {
call_storage_idle_notifys(false);
+ }
last_disk_activity = current_tick - sleep_timeout + (HZ/2);
break;
diff --git a/firmware/export/usb.h b/firmware/export/usb.h
index c8bbf28..49b70f6 100644
--- a/firmware/export/usb.h
+++ b/firmware/export/usb.h
@@ -24,20 +24,33 @@
#include "kernel.h"
#include "button.h"
+#if defined(IPOD_COLOR) || defined(IPOD_4G) \
+ || defined(IPOD_MINI) || defined(IPOD_MINI2G)
+#define USB_FIREWIRE_HANDLING
+#endif
+
/* Messages from usb_tick and thread states */
enum {
- USB_INSERTED,
- USB_EXTRACTED,
- USB_REENABLE,
- USB_POWERED,
- USB_TRANSFER_COMPLETION,
- USB_REQUEST_DISK,
- USB_RELEASE_DISK,
- USB_REQUEST_REBOOT,
- USB_QUIT,
+ USB_INSERTED, /* Event+State */
+ USB_EXTRACTED, /* Event+State */
+#ifdef HAVE_USB_POWER
+ USB_POWERED, /* State */
+#endif
+#ifdef HAVE_LCD_BITMAP
+ USB_SCREENDUMP, /* State */
+#endif
+#if (CONFIG_STORAGE & STORAGE_MMC)
+ USB_REENABLE, /* Event */
+#endif
+#ifdef HAVE_USBSTACK
+ USB_TRANSFER_COMPLETION, /* Event */
+#endif
+#ifdef USB_FIREWIRE_HANDLING
+ USB_REQUEST_REBOOT, /* Event */
+#endif
+ USB_QUIT, /* Event */
};
-
#ifdef HAVE_USB_POWER
#if CONFIG_KEYPAD == RECORDER_PAD
#define USBPOWER_BUTTON BUTTON_F1
@@ -111,13 +124,10 @@ bool usb_charging_enabled(void);
#ifdef HAVE_USBSTACK
void usb_signal_transfer_completion(struct usb_transfer_completion_event_data* event_data);
bool usb_driver_enabled(int driver);
-bool usb_exclusive_ata(void); /* ata is available for usb */
-void usb_request_exclusive_ata(void);
-void usb_release_exclusive_ata(void);
+bool usb_exclusive_storage(void); /* storage is available for usb */
#endif
-#if defined(IPOD_COLOR) || defined(IPOD_4G) \
- || defined(IPOD_MINI) || defined(IPOD_MINI2G)
+#ifdef USB_FIREWIRE_HANDLING
bool firewire_detect(void);
#endif
diff --git a/firmware/export/usb_core.h b/firmware/export/usb_core.h
index 9d9e327..7af8e43 100644
--- a/firmware/export/usb_core.h
+++ b/firmware/export/usb_core.h
@@ -52,7 +52,7 @@ void usb_core_exit(void);
void usb_core_control_request(struct usb_ctrlrequest* req);
void usb_core_transfer_complete(int endpoint, int dir, int status, int length);
void usb_core_bus_reset(void);
-bool usb_core_exclusive_connection(void);
+bool usb_core_any_exclusive_storage(void);
void usb_core_enable_driver(int driver,bool enabled);
bool usb_core_driver_enabled (int driver);
void usb_core_handle_transfer_completion(
diff --git a/firmware/usb.c b/firmware/usb.c
index ec47e06..b52a255 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -79,7 +79,7 @@ static int usb_mmc_countdown = 0;
static long usb_stack[(DEFAULT_STACK_SIZE + 0x800)/sizeof(long)];
static const char usb_thread_name[] = "usb";
static unsigned int usb_thread_entry = 0;
-#endif
+#endif /* USB_FULL_INIT */
static struct event_queue usb_queue;
static int last_usb_status;
static bool usb_monitor_enabled;
@@ -87,16 +87,80 @@ static bool usb_monitor_enabled;
static bool exclusive_storage_access;
#endif
-
-#if defined(IPOD_COLOR) || defined(IPOD_4G) \
- || defined(IPOD_MINI) || defined(IPOD_MINI2G)
+#ifdef USB_FIREWIRE_HANDLING
static int firewire_countdown;
static bool last_firewire_status;
#endif
#ifdef USB_FULL_INIT
-#ifndef HAVE_USBSTACK
-static void usb_slave_mode(bool on)
+
+#if defined(USB_FIREWIRE_HANDLING) \
+ || (defined(HAVE_USBSTACK) && !defined(USE_ROCKBOX_USB))
+static void try_reboot(void)
+{
+#ifdef HAVE_DISK_STORAGE
+ storage_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 */
+}
+#endif /* USB_FIRWIRE_HANDLING || (HAVE_USBSTACK && !USE_ROCKBOX_USB) */
+
+#ifdef HAVE_USBSTACK
+/* inline since branch is chosen at compile time */
+static inline void usb_slave_mode(bool on)
+{
+#ifdef USE_ROCKBOX_USB
+ int rc;
+
+ if (on)
+ {
+ trigger_cpu_boost();
+#ifdef HAVE_PRIORITY_SCHEDULING
+ thread_set_priority(THREAD_ID_CURRENT, PRIORITY_REALTIME);
+#endif
+ usb_enable(true);
+ }
+ else /* usb_state == USB_INSERTED (only!) */
+ {
+ usb_enable(false);
+#ifdef HAVE_PRIORITY_SCHEDULING
+ thread_set_priority(THREAD_ID_CURRENT, PRIORITY_SYSTEM);
+#endif
+ /* Entered exclusive mode */
+ rc = disk_mount_all();
+ if (rc <= 0) /* no partition */
+ panicf("mount: %d",rc);
+
+ cancel_cpu_boost();
+ }
+#else /* !USB_ROCKBOX_USB */
+ if (on)
+ {
+ /* until we have native mass-storage mode, we want to reboot on
+ usb host connect */
+ try_reboot();
+ }
+#endif /* USE_ROCKBOX_USB */
+}
+
+void usb_signal_transfer_completion(
+ struct usb_transfer_completion_event_data* event_data)
+{
+ queue_post(&usb_queue, USB_TRANSFER_COMPLETION, (intptr_t)event_data);
+}
+#else /* !HAVE_USBSTACK */
+/* inline since branch is chosen at compile time */
+static inline void usb_slave_mode(bool on)
{
int rc;
@@ -107,11 +171,14 @@ static void usb_slave_mode(bool on)
storage_init();
storage_enable(false);
usb_enable(true);
+ cpu_idle_mode(true);
}
else
{
DEBUGF("Leaving USB slave mode\n");
+ cpu_idle_mode(false);
+
/* Let the ISDx00 settle */
sleep(HZ*1);
@@ -126,34 +193,31 @@ static void usb_slave_mode(bool on)
panicf("mount: %d",rc);
}
}
-#endif
+#endif /* HAVE_USBSTACK */
-static void try_reboot(void)
+#ifdef HAVE_USB_POWER
+static inline bool usb_power_button(void)
{
-#ifdef HAVE_DISK_STORAGE
- storage_sleepnow(); /* Immediately spindown the disk. */
- sleep(HZ*2);
+#if defined(IRIVER_H10) || defined (IRIVER_H10_5GB)
+ return (button_status() & ~USBPOWER_BTN_IGNORE) != USBPOWER_BUTTON;
+#else
+ return (button_status() & ~USBPOWER_BTN_IGNORE) == USBPOWER_BUTTON;
#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 */
+#ifdef USB_FIREWIRE_HANDLING
+static inline bool usb_reboot_button(void)
+{
+ return (button_status() & ~USBPOWER_BTN_IGNORE) != USBPOWER_BUTTON;
}
+#endif
+#endif /* HAVE_USB_POWER */
static void usb_thread(void)
{
- int num_acks_to_expect = -1;
- bool waiting_for_ack;
+ int num_acks_to_expect = 0;
struct queue_event ev;
- waiting_for_ack = false;
-
while(1)
{
queue_wait(&usb_queue, &ev);
@@ -165,180 +229,116 @@ static void usb_thread(void)
#endif
#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
- case USB_POWERED:
- usb_state = USB_POWERED;
+ usb_core_handle_transfer_completion(
+ (struct usb_transfer_completion_event_data*)ev.data);
break;
#endif
case USB_INSERTED:
#ifdef HAVE_LCD_BITMAP
if(do_screendump_instead_of_usb)
{
+ usb_state = USB_SCREENDUMP;
screen_dump();
+ break;
}
- else
#endif
#ifdef HAVE_USB_POWER
-#if defined(IRIVER_H10) || defined (IRIVER_H10_5GB)
- if((button_status() & ~USBPOWER_BTN_IGNORE) != USBPOWER_BUTTON)
-#else
- if((button_status() & ~USBPOWER_BTN_IGNORE) == USBPOWER_BUTTON)
-#endif
+ if (usb_power_button())
{
+ /* Only charging is desired */
usb_state = USB_POWERED;
#ifdef HAVE_USBSTACK
- usb_core_enable_driver(USB_DRIVER_MASS_STORAGE,false);
- usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY,true);
- usb_enable(true);
-#endif
- }
- else
-#endif
- {
-#ifdef HAVE_USBSTACK
- /* Set the state to USB_POWERED for now. if a real
- connection is detected it will switch to USB_INSERTED */
- usb_state = USB_POWERED;
- usb_core_enable_driver(USB_DRIVER_MASS_STORAGE,true);
- usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY,false);
+ usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, false);
+ usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, true);
usb_enable(true);
-#else
- /* Tell all threads that they have to back off the ATA.
- We subtract one for our own thread. */
- num_acks_to_expect =
- queue_broadcast(SYS_USB_CONNECTED, 0) - 1;
- waiting_for_ack = true;
- DEBUGF("USB inserted. Waiting for ack from %d threads...\n",
- num_acks_to_expect);
#endif
+ break;
}
- break;
+#endif /* HAVE_USB_POWER */
#ifdef HAVE_USBSTACK
- case USB_REQUEST_DISK:
- if(!waiting_for_ack)
+ /* Set the state to USB_POWERED for now. If permission to connect
+ * by threads and storage is granted it will be changed to
+ * USB_CONNECTED. */
+ usb_state = USB_POWERED;
+ usb_core_enable_driver(USB_DRIVER_MASS_STORAGE, true);
+ usb_core_enable_driver(USB_DRIVER_CHARGING_ONLY, false);
+
+ /* Check any drivers enabled at this point for exclusive storage
+ * access requirements. */
+ exclusive_storage_access = usb_core_any_exclusive_storage();
+
+ if (exclusive_storage_access)
+#endif /* HAVE_USBSTACK */
{
- /* Tell all threads that they have to back off the ATA.
+ /* Tell all threads that they have to back off the storage.
We subtract one for our own thread. */
- num_acks_to_expect =
- queue_broadcast(SYS_USB_CONNECTED, 0) - 1;
- waiting_for_ack = true;
+ num_acks_to_expect = queue_broadcast(SYS_USB_CONNECTED, 0) - 1;
DEBUGF("USB inserted. Waiting for ack from %d threads...\n",
- num_acks_to_expect);
+ num_acks_for_connect);
}
break;
- case USB_RELEASE_DISK:
- if(!waiting_for_ack)
+
+ case SYS_USB_CONNECTED_ACK:
+ if(num_acks_to_expect > 0 && --num_acks_to_expect == 0)
{
- /* Tell all threads that they have to back off the ATA.
- We subtract one for our own thread. */
- num_acks_to_expect =
- queue_broadcast(SYS_USB_DISCONNECTED, 0) - 1;
- waiting_for_ack = true;
- DEBUGF("USB inserted. Waiting for ack from %d threads...\n",
- num_acks_to_expect);
+ DEBUGF("All threads have acknowledged the connect.\n");
+ usb_slave_mode(true);
+ usb_state = USB_INSERTED;
}
- break;
-#endif
- case SYS_USB_CONNECTED_ACK:
- if(waiting_for_ack)
+ else
{
- num_acks_to_expect--;
- if(num_acks_to_expect == 0)
- {
- DEBUGF("All threads have acknowledged the connect.\n");
-#ifdef HAVE_USBSTACK
-#ifndef USE_ROCKBOX_USB
- /* until we have native mass-storage mode, we want to reboot on
- usb host connect */
- try_reboot();
-#endif /* USE_ROCKBOX_USB */
-#ifdef HAVE_PRIORITY_SCHEDULING
- thread_set_priority(usb_thread_entry,PRIORITY_REALTIME);
-#endif
- exclusive_storage_access = true;
-
-#else
- usb_slave_mode(true);
- cpu_idle_mode(true);
-#endif
- usb_state = USB_INSERTED;
- waiting_for_ack = false;
- }
- else
- {
- DEBUGF("usb: got ack, %d to go...\n",
- num_acks_to_expect);
- }
+ DEBUGF("usb: got ack, %d to go...\n",
+ num_acks_to_expect);
}
break;
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
- if(do_screendump_instead_of_usb)
- break;
-#endif
-#ifdef HAVE_USB_POWER
+ if(usb_state == USB_SCREENDUMP)
+ {
+ usb_state = USB_EXTRACTED;
+ break; /* Connected for screendump only */
+ }
+#endif /* HAVE_LCD_BITMAP */
+#ifndef HAVE_USBSTACK /* Stack must undo this if POWERED state was transitional */
if(usb_state == USB_POWERED)
{
usb_state = USB_EXTRACTED;
break;
}
-#endif
-#ifndef HAVE_USBSTACK
+#endif /* HAVE_USBSTACK */
if(usb_state == USB_INSERTED)
{
/* Only disable the USB mode if we really have enabled it
some threads might not have acknowledged the
insertion */
usb_slave_mode(false);
- cpu_idle_mode(false);
}
-#endif
usb_state = USB_EXTRACTED;
#ifdef HAVE_USBSTACK
- if(exclusive_storage_access)
- {
- int rc = disk_mount_all();
- if (rc <= 0) /* no partition */
- panicf("mount: %d",rc);
- exclusive_storage_access = false;
-#endif
- /* Tell all threads that we are back in business */
- num_acks_to_expect =
- queue_broadcast(SYS_USB_DISCONNECTED, 0) - 1;
- waiting_for_ack = true;
- DEBUGF("USB extracted. Waiting for ack from %d threads...\n",
- num_acks_to_expect);
-#ifdef HAVE_USBSTACK
- }
-#endif
+ if (!exclusive_storage_access)
+ break;
+
+ exclusive_storage_access = false;
+#endif /* HAVE_USBSTACK */
+ /* Tell all threads that we are back in business */
+ num_acks_to_expect =
+ queue_broadcast(SYS_USB_DISCONNECTED, 0) - 1;
+ DEBUGF("USB extracted. Waiting for ack from %d threads...\n",
+ num_acks_to_expect);
break;
case SYS_USB_DISCONNECTED_ACK:
- if(waiting_for_ack)
+ if(num_acks_to_expect > 0 && --num_acks_to_expect == 0)
{
- num_acks_to_expect--;
- if(num_acks_to_expect == 0)
- {
- DEBUGF("All threads have acknowledged. "
- "We're in business.\n");
- waiting_for_ack = false;
- }
- else
- {
- DEBUGF("usb: got ack, %d to go...\n",
- num_acks_to_expect);
- }
+ DEBUGF("All threads have acknowledged. "
+ "We're in business.\n");
+ }
+ else
+ {
+ DEBUGF("usb: got ack, %d to go...\n",
+ num_acks_to_expect);
}
break;
@@ -347,49 +347,44 @@ static void usb_thread(void)
case SYS_HOTSWAP_EXTRACTED:
#ifdef HAVE_USBSTACK
usb_core_hotswap_event(1,ev.id == SYS_HOTSWAP_INSERTED);
-#else
+#else /* !HAVE_USBSTACK */
if(usb_state == USB_INSERTED)
{
usb_enable(false);
#if (CONFIG_STORAGE & STORAGE_MMC)
usb_mmc_countdown = HZ/2; /* re-enable after 0.5 sec */
-#endif
+#endif /* STORAGE_MMC */
}
-#endif
+#endif /* HAVE_USBSTACK */
break;
+#if (CONFIG_STORAGE & STORAGE_MMC)
case USB_REENABLE:
if(usb_state == USB_INSERTED)
usb_enable(true); /* reenable only if still inserted */
break;
+#endif /* STORAGE_MMC */
#endif /* HAVE_HOTSWAP */
+
+#ifdef USB_FIREWIRE_HANDLING
case USB_REQUEST_REBOOT:
#ifdef HAVE_USB_POWER
- if((button_status() & ~USBPOWER_BTN_IGNORE) != USBPOWER_BUTTON)
+ if (usb_reboot_button())
#endif
try_reboot();
break;
+#endif /* USB_FIREWIRE_HANDLING */
}
}
}
-#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
-
-#ifdef USB_FULL_INIT
static void usb_tick(void)
{
int current_status;
if(usb_monitor_enabled)
{
-#if defined(IPOD_COLOR) || defined(IPOD_4G) \
- || defined(IPOD_MINI) || defined(IPOD_MINI2G)
+#ifdef USB_FIREWIRE_HANDLING
int current_firewire_status = firewire_detect();
if(current_firewire_status != last_firewire_status)
{
@@ -409,7 +404,7 @@ static void usb_tick(void)
queue_post(&usb_queue, USB_REQUEST_REBOOT, 0);
}
}
-#endif
+#endif /* USB_FIREWIRE_HANDLING */
current_status = usb_detect();
@@ -442,7 +437,7 @@ static void usb_tick(void)
}
#endif
}
-#endif
+#endif /* USB_FULL_INIT */
void usb_acknowledge(long id)
{
@@ -458,8 +453,7 @@ void usb_init(void)
usb_monitor_enabled = false;
countdown = -1;
-#if defined(IPOD_COLOR) || defined(IPOD_4G) \
- || defined(IPOD_MINI) || defined(IPOD_MINI2G)
+#ifdef USB_FIREWIRE_HANDLING
firewire_countdown = -1;
last_firewire_status = false;
#endif
@@ -480,8 +474,7 @@ void usb_init(void)
IF_PRIO(, PRIORITY_SYSTEM) IF_COP(, CPU));
tick_add_task(usb_tick);
-#endif
-
+#endif /* USB_FULL_INIT */
}
void usb_wait_for_disconnect(struct event_queue *q)
@@ -518,10 +511,8 @@ int usb_wait_for_disconnect_w_tmo(struct event_queue *q, int ticks)
case SYS_USB_DISCONNECTED:
usb_acknowledge(SYS_USB_DISCONNECTED_ACK);
return 0;
- break;
case SYS_TIMEOUT:
return 1;
- break;
}
}
#else
@@ -562,27 +553,7 @@ bool usb_inserted(void)
}
#ifdef HAVE_USBSTACK
-void usb_request_exclusive_ata(void)
-{
- /* This is not really a clean place to start boosting the cpu. but it's
- * currently the best one. We want to get rid of having to boost the cpu
- * for usb anyway */
- trigger_cpu_boost();
- if(!exclusive_storage_access) {
- queue_post(&usb_queue, USB_REQUEST_DISK, 0);
- }
-}
-
-void usb_release_exclusive_ata(void)
-{
- cancel_cpu_boost();
- if(exclusive_storage_access) {
- queue_post(&usb_queue, USB_RELEASE_DISK, 0);
- exclusive_storage_access = false;
- }
-}
-
-bool usb_exclusive_ata(void)
+bool usb_exclusive_storage(void)
{
return exclusive_storage_access;
}
diff --git a/firmware/usbstack/usb_charging_only.h b/firmware/usbstack/usb_charging_only.h
index 8bdf58f..839e07d 100644
--- a/firmware/usbstack/usb_charging_only.h
+++ b/firmware/usbstack/usb_charging_only.h
@@ -5,7 +5,7 @@
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
- * $Id: $
+ * $Id$
*
* Copyright (C) 2008 by Frank Gevaerts
*
diff --git a/firmware/usbstack/usb_class_driver.h b/firmware/usbstack/usb_class_driver.h
index e089c48..b037e1d 100644
--- a/firmware/usbstack/usb_class_driver.h
+++ b/firmware/usbstack/usb_class_driver.h
@@ -33,7 +33,7 @@ struct usb_class_driver {
/* Driver api starts here */
/* Set this to true if the driver needs exclusive disk access (e.g. usb storage) */
- bool needs_exclusive_ata;
+ bool needs_exclusive_storage;
/* Let the driver request endpoints it need. Returns zero on success */
int (*request_endpoints)(struct usb_class_driver *);
diff --git a/firmware/usbstack/usb_core.c b/firmware/usbstack/usb_core.c
index ea5d659..50c9d85 100644
--- a/firmware/usbstack/usb_core.c
+++ b/firmware/usbstack/usb_core.c
@@ -54,6 +54,9 @@
#include "ata.h"
#endif
+#ifndef USB_MAX_CURRENT
+#define USB_MAX_CURRENT 500
+#endif
/*-------------------------------------------------------------------------*/
/* USB protocol descriptors: */
@@ -94,7 +97,7 @@ static struct usb_config_descriptor __attribute__((aligned(2)))
.bConfigurationValue = 1,
.iConfiguration = 0,
.bmAttributes = USB_CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFPOWER,
- .bMaxPower = 250, /* 500mA in 2mA units */
+ .bMaxPower = (USB_MAX_CURRENT+1) / 2, /* In 2mA units */
};
@@ -179,7 +182,7 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
#ifdef USB_STORAGE
[USB_DRIVER_MASS_STORAGE] = {
.enabled = false,
- .needs_exclusive_ata = true,
+ .needs_exclusive_storage = true,
.first_interface = 0,
.last_interface = 0,
.request_endpoints = usb_storage_request_endpoints,
@@ -198,7 +201,7 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
#ifdef USB_SERIAL
[USB_DRIVER_SERIAL] = {
.enabled = false,
- .needs_exclusive_ata = false,
+ .needs_exclusive_storage = false,
.first_interface = 0,
.last_interface = 0,
.request_endpoints = usb_serial_request_endpoints,
@@ -217,7 +220,7 @@ static struct usb_class_driver drivers[USB_NUM_DRIVERS] =
#ifdef USB_CHARGING_ONLY
[USB_DRIVER_CHARGING_ONLY] = {
.enabled = false,
- .needs_exclusive_ata = false,
+ .needs_exclusive_storage = false,
.first_interface = 0,
.last_interface = 0,
.request_endpoints = usb_charging_only_request_endpoints,
@@ -353,13 +356,17 @@ void usb_core_exit(void)
int i;
for(i=0;i<USB_NUM_DRIVERS;i++) {
if(drivers[i].enabled && drivers[i].disconnect != NULL)
+ {
drivers[i].disconnect ();
+ drivers[i].enabled = false;
+ }
}
if (initialized) {
usb_drv_exit();
}
initialized = false;
+ usb_state = DEFAULT;
logf("usb_core_exit() finished");
}
@@ -392,6 +399,20 @@ bool usb_core_driver_enabled(int driver)
return drivers[driver].enabled;
}
+bool usb_core_any_exclusive_storage(void)
+{
+ int i;
+ for(i=0;i<USB_NUM_DRIVERS;i++) {
+ if(drivers[i].enabled &&
+ drivers[i].needs_exclusive_storage)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
#ifdef HAVE_HOTSWAP
void usb_core_hotswap_event(int volume,bool inserted)
{
@@ -484,14 +505,6 @@ static void usb_core_control_request_handler(struct usb_ctrlrequest* req)
usb_core_set_serial_function_id();
allocate_interfaces_and_endpoints();
-
- for(i=0;i<USB_NUM_DRIVERS;i++) {
- if(drivers[i].enabled &&
- drivers[i].needs_exclusive_ata) {
- usb_request_exclusive_ata();
- break;
- }
- }
}
switch(req->bRequestType & 0x1f) {
@@ -788,7 +801,7 @@ unsigned short usb_allowed_current()
{
if (usb_state == CONFIGURED)
{
- return 500;
+ return MAX(USB_MAX_CURRENT, 100);
}
else
{
diff --git a/firmware/usbstack/usb_storage.c b/firmware/usbstack/usb_storage.c
index 8a49151..a70681d 100644
--- a/firmware/usbstack/usb_storage.c
+++ b/firmware/usbstack/usb_storage.c
@@ -293,6 +293,7 @@ static bool check_disk_present(IF_MV_NONVOID(int volume))
#endif
}
+#if 0
static void try_release_ata(void)
{
/* Check if there is a connected drive left. If not,
@@ -310,6 +311,7 @@ static void try_release_ata(void)
usb_release_exclusive_ata();
}
}
+#endif
#ifdef HAVE_HOTSWAP
void usb_storage_notify_hotswap(int volume,bool inserted)
@@ -320,9 +322,7 @@ void usb_storage_notify_hotswap(int volume,bool inserted)
}
else {
ejected[volume] = true;
- try_release_ata();
}
-
}
#endif
@@ -334,7 +334,6 @@ void usb_storage_reconnect(void)
for(i=0;i<NUM_VOLUMES;i++)
ejected[i] = !check_disk_present(IF_MV(i));
logf("%s", __func__);
- usb_request_exclusive_ata();
}
}
@@ -682,7 +681,6 @@ static void handle_scsi(struct command_block_wrapper* cbw)
#ifdef HAVE_HOTSWAP
if(storage_removable(lun) && !storage_present(lun)) {
ejected[lun] = true;
- try_release_ata();
}
#endif
@@ -699,7 +697,7 @@ static void handle_scsi(struct command_block_wrapper* cbw)
switch (cbw->command_block[0]) {
case SCSI_TEST_UNIT_READY:
logf("scsi test_unit_ready %d",lun);
- if(!usb_exclusive_ata()) {
+ if(!usb_exclusive_storage()) {
send_csw(UMS_STATUS_FAIL);
cur_sense_data.sense_key=SENSE_NOT_READY;
cur_sense_data.asc=ASC_MEDIUM_NOT_PRESENT;
@@ -885,7 +883,6 @@ static void handle_scsi(struct command_block_wrapper* cbw)
{
logf("scsi eject");
ejected[lun]=true;
- try_release_ata();
}
}
}