summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Nielsen Feltzing <linus@haxx.se>2002-07-01 11:02:54 +0000
committerLinus Nielsen Feltzing <linus@haxx.se>2002-07-01 11:02:54 +0000
commit53b8c995218647321e0e6d6a421af1ae9fa24710 (patch)
tree031bdfa6a08816104f659f6d716e369b14351835
parenta550b07886f8c3b2eda624c02970bc6e93773f57 (diff)
downloadrockbox-53b8c995218647321e0e6d6a421af1ae9fa24710.tar.gz
rockbox-53b8c995218647321e0e6d6a421af1ae9fa24710.zip
Better handling of non-responding threads
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@1281 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/usb.c210
1 files changed, 111 insertions, 99 deletions
diff --git a/firmware/usb.c b/firmware/usb.c
index 763dd53e99..c748094396 100644
--- a/firmware/usb.c
+++ b/firmware/usb.c
@@ -38,6 +38,8 @@
38#define USB_INSERTED 1 38#define USB_INSERTED 1
39#define USB_EXTRACTED 2 39#define USB_EXTRACTED 2
40 40
41static int usb_state;
42
41static char usb_stack[0x100]; 43static char usb_stack[0x100];
42static struct event_queue usb_queue; 44static struct event_queue usb_queue;
43static bool last_usb_status; 45static bool last_usb_status;
@@ -63,30 +65,30 @@ static void usb_slave_mode(bool on)
63 65
64 if(on) 66 if(on)
65 { 67 {
66 DEBUGF("Entering USB slave mode\n"); 68 DEBUGF("Entering USB slave mode\n");
67 ata_enable(false); 69 ata_enable(false);
68 usb_enable(true); 70 usb_enable(true);
69 } 71 }
70 else 72 else
71 { 73 {
72 DEBUGF("Leaving USB slave mode\n"); 74 DEBUGF("Leaving USB slave mode\n");
73 75
74 /* Let the ISDx00 settle */ 76 /* Let the ISDx00 settle */
75 sleep(HZ*1); 77 sleep(HZ*1);
78
79 usb_enable(false);
76 80
77 usb_enable(false); 81 rc = ata_init();
78 82 if(rc)
79 rc = ata_init(); 83 panicf("ata: %d",rc);
80 if(rc) 84
81 panicf("ata: %d",rc); 85 pinfo = disk_init();
82 86 if (!pinfo)
83 pinfo = disk_init(); 87 panicf("disk: NULL");
84 if (!pinfo) 88
85 panicf("disk: NULL"); 89 rc = fat_mount(pinfo[0].start);
86 90 if(rc)
87 rc = fat_mount(pinfo[0].start); 91 panicf("mount: %d",rc);
88 if(rc)
89 panicf("mount: %d",rc);
90 } 92 }
91} 93}
92 94
@@ -100,70 +102,79 @@ static void usb_thread(void)
100 102
101 while(1) 103 while(1)
102 { 104 {
103 queue_wait(&usb_queue, &ev); 105 queue_wait(&usb_queue, &ev);
104 switch(ev.id) 106 switch(ev.id)
105 { 107 {
106 case USB_INSERTED: 108 case USB_INSERTED:
107 /* Tell all threads that they have to back off the ATA. 109 /* Tell all threads that they have to back off the ATA.
108 We subtract one for our own thread. */ 110 We subtract one for our own thread. */
109 num_acks_to_expect = queue_broadcast(SYS_USB_CONNECTED, NULL) - 1; 111 num_acks_to_expect = queue_broadcast(SYS_USB_CONNECTED, NULL) - 1;
110 waiting_for_ack = true; 112 waiting_for_ack = true;
111 DEBUGF("USB inserted. Waiting for ack from %d threads...\n", 113 DEBUGF("USB inserted. Waiting for ack from %d threads...\n",
112 num_acks_to_expect); 114 num_acks_to_expect);
113 break; 115 break;
114 116
115 case SYS_USB_CONNECTED_ACK: 117 case SYS_USB_CONNECTED_ACK:
116 if(waiting_for_ack) 118 if(waiting_for_ack)
117 { 119 {
118 num_acks_to_expect--; 120 num_acks_to_expect--;
119 if(num_acks_to_expect == 0) 121 if(num_acks_to_expect == 0)
120 { 122 {
121 /* This is where we are supposed to be cool and keep 123 /* This is where we are supposed to be cool and keep
122 the Rockbox firmware running while the USB is enabled, 124 the Rockbox firmware running while the USB is enabled,
123 maybe even play some games and stuff. However, the 125 maybe even play some games and stuff. However, the
124 current firmware isn't quite ready for this yet. 126 current firmware isn't quite ready for this yet.
125 Let's just chicken out and reboot. */ 127 Let's just chicken out and reboot. */
126 DEBUGF("All threads have acknowledged. Continuing...\n"); 128 DEBUGF("All threads have acknowledged. Continuing...\n");
127#ifdef USB_REALLY_BRAVE 129#ifdef USB_REALLY_BRAVE
128 usb_slave_mode(true); 130 usb_slave_mode(true);
131 usb_state = USB_INSERTED;
132 usb_display_info();
129#else 133#else
130 system_reboot(); 134 system_reboot();
131#endif 135#endif
132 } 136 }
133 else 137 else
134 { 138 {
135 DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect); 139 DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect);
136 } 140 }
137 } 141 }
138 break; 142 break;
143
144 case USB_EXTRACTED:
145 if(usb_state == USB_INSERTED)
146 {
147 /* Only disable the USB mode if we really have enabled it
148 some threads might not have acknowledged the
149 insertion */
150 usb_slave_mode(false);
151 }
139 152
140 case USB_EXTRACTED: 153 usb_state = USB_EXTRACTED;
141 /* First disable the USB mode */ 154
142 usb_slave_mode(false); 155 /* Tell all threads that we are back in business */
143 156 num_acks_to_expect =
144 /* Tell all threads that we are back in business */ 157 queue_broadcast(SYS_USB_DISCONNECTED, NULL) - 1;
145 num_acks_to_expect = 158 waiting_for_ack = true;
146 queue_broadcast(SYS_USB_DISCONNECTED, NULL) - 1; 159 DEBUGF("USB extracted. Waiting for ack from %d threads...\n",
147 waiting_for_ack = true; 160 num_acks_to_expect);
148 DEBUGF("USB extracted. Waiting for ack from %d threads...\n", 161 break;
149 num_acks_to_expect); 162
150 break; 163 case SYS_USB_DISCONNECTED_ACK:
151 164 if(waiting_for_ack)
152 case SYS_USB_DISCONNECTED_ACK: 165 {
153 if(waiting_for_ack) 166 num_acks_to_expect--;
154 { 167 if(num_acks_to_expect == 0)
155 num_acks_to_expect--; 168 {
156 if(num_acks_to_expect == 0) 169 DEBUGF("All threads have acknowledged. We're in business.\n");
157 { 170 }
158 DEBUGF("All threads have acknowledged. We're in business.\n"); 171 else
159 } 172 {
160 else 173 DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect);
161 { 174 }
162 DEBUGF("usb: got ack, %d to go...\n", num_acks_to_expect); 175 }
163 } 176 break;
164 } 177 }
165 break;
166 }
167 } 178 }
168} 179}
169 180
@@ -174,21 +185,21 @@ static void usb_tick(void)
174 if(usb_monitor_enabled) 185 if(usb_monitor_enabled)
175 { 186 {
176#ifdef ARCHOS_RECORDER 187#ifdef ARCHOS_RECORDER
177 /* If AN2 reads more than about 500, the USB is inserted */ 188 /* If AN2 reads more than about 500, the USB is inserted */
178 current_status = (adc_read(2) > 500); 189 current_status = (adc_read(2) > 500);
179#else 190#else
180 current_status = (PADR & 0x8000)?false:true; 191 current_status = (PADR & 0x8000)?false:true;
181#endif 192#endif
182 193
183 /* Only report when the status has changed */ 194 /* Only report when the status has changed */
184 if(current_status != last_usb_status) 195 if(current_status != last_usb_status)
185 { 196 {
186 last_usb_status = current_status; 197 last_usb_status = current_status;
187 if(current_status) 198 if(current_status)
188 queue_post(&usb_queue, USB_INSERTED, NULL); 199 queue_post(&usb_queue, USB_INSERTED, NULL);
189 else 200 else
190 queue_post(&usb_queue, USB_EXTRACTED, NULL); 201 queue_post(&usb_queue, USB_EXTRACTED, NULL);
191 } 202 }
192 } 203 }
193} 204}
194 205
@@ -199,6 +210,7 @@ void usb_acknowledge(int id)
199 210
200void usb_init(void) 211void usb_init(void)
201{ 212{
213 usb_state = USB_EXTRACTED;
202 usb_monitor_enabled = false; 214 usb_monitor_enabled = false;
203 215
204 usb_enable(false); 216 usb_enable(false);
@@ -219,12 +231,12 @@ void usb_wait_for_disconnect(struct event_queue *q)
219 /* Don't return until we get SYS_USB_DISCONNECTED */ 231 /* Don't return until we get SYS_USB_DISCONNECTED */
220 while(1) 232 while(1)
221 { 233 {
222 queue_wait(q, &ev); 234 queue_wait(q, &ev);
223 if(ev.id == SYS_USB_DISCONNECTED) 235 if(ev.id == SYS_USB_DISCONNECTED)
224 { 236 {
225 usb_acknowledge(SYS_USB_DISCONNECTED_ACK); 237 usb_acknowledge(SYS_USB_DISCONNECTED_ACK);
226 return; 238 return;
227 } 239 }
228 } 240 }
229} 241}
230 242