summaryrefslogtreecommitdiffstats
path: root/uisimulator/common/sim_tasks.c
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2011-11-17 18:40:00 +0000
committerThomas Martitz <kugel@rockbox.org>2011-11-17 18:40:00 +0000
commit1645c148e35becff9668cc541be5c850153370eb (patch)
treeff4af71980a290ed1877facee590b39280940c45 /uisimulator/common/sim_tasks.c
parent2a8eacdbfc5d98b016c480ddaddff100301f721f (diff)
downloadrockbox-1645c148e35becff9668cc541be5c850153370eb.tar.gz
rockbox-1645c148e35becff9668cc541be5c850153370eb.zip
Simulate usb plugging on the sim better using sim_tasks.
Now all threads need to ack the connection like on real target, dircache is unloaded and playback stops accordingly. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31009 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'uisimulator/common/sim_tasks.c')
-rw-r--r--uisimulator/common/sim_tasks.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/uisimulator/common/sim_tasks.c b/uisimulator/common/sim_tasks.c
index 2fc887cc37..f154dacce6 100644
--- a/uisimulator/common/sim_tasks.c
+++ b/uisimulator/common/sim_tasks.c
@@ -8,6 +8,7 @@
* $Id$
*
* Copyright (C) 2009 by Jens Arnold
+ * Copyright (C) 2011 by Thomas Martitz
*
* Rockbox simulator specific tasks
*
@@ -25,6 +26,8 @@
#include "kernel.h"
#include "screendump.h"
#include "thread.h"
+#include "debug.h"
+#include "usb.h"
static void sim_thread(void);
static long sim_thread_stack[DEFAULT_STACK_SIZE/sizeof(long)];
@@ -35,11 +38,15 @@ static struct event_queue sim_queue;
/* possible events for the sim thread */
enum {
SIM_SCREENDUMP,
+ SIM_USB_INSERTED,
+ SIM_USB_EXTRACTED,
};
void sim_thread(void)
{
struct queue_event ev;
+ long last_broadcast_tick = current_tick;
+ int num_acks_to_expect;
while (1)
{
@@ -52,6 +59,45 @@ void sim_thread(void)
remote_screen_dump();
#endif
break;
+ case SIM_USB_INSERTED:
+ /* from firmware/usb.c: */
+ /* Tell all threads that they have to back off the storage.
+ We subtract one for our own thread. Expect an ACK for every
+ listener for each broadcast they received. If it has been too
+ long, the user might have entered a screen that didn't ACK
+ when inserting the cable, such as a debugging screen. In that
+ case, reset the count or else USB would be locked out until
+ rebooting because it most likely won't ever come. Simply
+ resetting to the most recent broadcast count is racy. */
+ if(TIME_AFTER(current_tick, last_broadcast_tick + HZ*5))
+ {
+ num_acks_to_expect = 0;
+ last_broadcast_tick = current_tick;
+ }
+
+ num_acks_to_expect += queue_broadcast(SYS_USB_CONNECTED, 0) - 1;
+ DEBUGF("USB inserted. Waiting for %d acks...\n",
+ num_acks_to_expect);
+ break;
+ case SYS_USB_CONNECTED_ACK:
+ if(num_acks_to_expect > 0 && --num_acks_to_expect == 0)
+ {
+ DEBUGF("All threads have acknowledged the connect.\n");
+ }
+ else
+ {
+ DEBUGF("usb: got ack, %d to go...\n",
+ num_acks_to_expect);
+ }
+ break;
+ case SIM_USB_EXTRACTED:
+ /* in usb.c, this is only done for exclusive storage
+ * do it here anyway but don't depend on the acks */
+ queue_broadcast(SYS_USB_DISCONNECTED, 0);
+ break;
+ default:
+ DEBUGF("sim_tasks: unhandled event: %ld\n", ev.id);
+ break;
}
}
}
@@ -68,3 +114,47 @@ void sim_trigger_screendump(void)
{
queue_post(&sim_queue, SIM_SCREENDUMP, 0);
}
+
+static bool is_usb_inserted;
+void sim_trigger_usb(bool inserted)
+{
+ if (inserted)
+ queue_post(&sim_queue, SIM_USB_INSERTED, 0);
+ else
+ queue_post(&sim_queue, SIM_USB_EXTRACTED, 0);
+ is_usb_inserted = inserted;
+}
+
+int usb_detect(void)
+{
+ return is_usb_inserted ? USB_INSERTED : USB_EXTRACTED;
+}
+
+void usb_init(void)
+{
+}
+
+void usb_start_monitoring(void)
+{
+}
+
+void usb_acknowledge(long id)
+{
+ queue_post(&sim_queue, id, 0);
+}
+
+void usb_wait_for_disconnect(struct event_queue *q)
+{
+#ifdef USB_FULL_INIT
+ struct queue_event ev;
+
+ /* Don't return until we get SYS_USB_DISCONNECTED */
+ while(1)
+ {
+ queue_wait(q, &ev);
+ if(ev.id == SYS_USB_DISCONNECTED)
+ return;
+ }
+#endif /* USB_FULL_INIT */
+ (void)q;
+}