From 1645c148e35becff9668cc541be5c850153370eb Mon Sep 17 00:00:00 2001 From: Thomas Martitz Date: Thu, 17 Nov 2011 18:40:00 +0000 Subject: 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 --- uisimulator/common/sim_tasks.c | 90 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) (limited to 'uisimulator/common/sim_tasks.c') 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; +} -- cgit v1.2.3