Skip to content

Commit 820765e

Browse files
committed
Prevent deadlocks in interrupt handlers
1 parent 90d9250 commit 820765e

File tree

4 files changed

+39
-16
lines changed

4 files changed

+39
-16
lines changed

libogc/card.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ static s32 __card_sync(s32 chn)
343343

344344
_CPU_ISR_Disable(level);
345345
while((ret=CARD_GetErrorCode(chn))==CARD_ERROR_BUSY) {
346-
LWP_ThreadSleep(card->wait_sync_queue);
346+
if(LWP_ThreadSleep(card->wait_sync_queue)) break;
347347
}
348348
_CPU_ISR_Restore(level);
349349
return ret;

libogc/lwp.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,11 @@ static s32 __lwp_tqueue_sleepsupp(lwpq_t thequeue,u64 timeout)
421421
tq = __lwp_tqueue_open(thequeue);
422422
if(!tq) return -1;
423423

424+
if(__lwp_isr_in_progress()) {
425+
__lwp_thread_dispatchenable();
426+
return EDEADLK;
427+
}
428+
424429
exec = _thr_executing;
425430
_CPU_ISR_Disable(level);
426431
__lwp_threadqueue_csenter(&tq->tqueue);

libogc/mic.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,8 @@ static s32 __MICSync(s32 chan)
303303

304304
while (cb->result_code == MIC_RESULT_BUSY)
305305
{
306-
LWP_ThreadSleep(cb->thread_queue);
306+
if (LWP_ThreadSleep(cb->thread_queue))
307+
break;
307308
}
308309

309310
IRQ_Restore(level);

libogc/usbgecko.c

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,18 @@ static void __usbgecko_init(void)
3434
usbgecko_inited = 1;
3535
}
3636

37-
static __inline__ void __usbgecko_exi_wait(s32 chn)
37+
static __inline__ int __usbgecko_exi_wait(s32 chn)
3838
{
39+
s32 ret;
3940
u32 level;
4041

4142
_CPU_ISR_Disable(level);
4243
if(!usbgecko_inited) __usbgecko_init();
43-
while(EXI_Lock(chn,EXI_DEVICE_0,__usbgecko_exi_unlock)==0) {
44-
LWP_ThreadSleep(wait_exi_queue[chn]);
44+
while((ret=EXI_Lock(chn,EXI_DEVICE_0,__usbgecko_exi_unlock))==0) {
45+
if(LWP_ThreadSleep(wait_exi_queue[chn])) break;
4546
}
4647
_CPU_ISR_Restore(level);
48+
return ret;
4749
}
4850

4951
static __inline__ int __send_command(s32 chn,u16 *cmd)
@@ -147,9 +149,10 @@ void usb_flush(s32 chn)
147149
{
148150
char tmp;
149151

150-
__usbgecko_exi_wait(chn);
151-
while(__usb_recvbyte(chn,&tmp));
152-
EXI_Unlock(chn);
152+
if(__usbgecko_exi_wait(chn)) {
153+
while(__usb_recvbyte(chn,&tmp));
154+
EXI_Unlock(chn);
155+
}
153156
}
154157

155158
int usb_isgeckoalive(s32 chn)
@@ -166,7 +169,8 @@ int usb_isgeckoalive(s32 chn)
166169
if (id != 0)
167170
return 0;
168171

169-
__usbgecko_exi_wait(chn);
172+
if (!__usbgecko_exi_wait(chn))
173+
return 0;
170174

171175
val = 0x9000;
172176
ret = __send_command(chn,&val);
@@ -183,7 +187,9 @@ int usb_recvbuffer_ex(s32 chn,void *buffer,int size, int retries)
183187
s32 left = size;
184188
char *ptr = (char*)buffer;
185189

186-
__usbgecko_exi_wait(chn);
190+
if (!__usbgecko_exi_wait(chn))
191+
return 0;
192+
187193
while(left>0) {
188194
ret = __usb_recvbyte(chn,ptr);
189195
if(ret==0) break;
@@ -212,7 +218,9 @@ int usb_sendbuffer_ex(s32 chn,const void *buffer,int size, int retries)
212218
s32 left = size;
213219
char *ptr = (char*)buffer;
214220

215-
__usbgecko_exi_wait(chn);
221+
if (!__usbgecko_exi_wait(chn))
222+
return 0;
223+
216224
while(left>0) {
217225
ret = __usb_sendbyte(chn,*ptr);
218226
if(ret==0) break;
@@ -241,7 +249,9 @@ int usb_recvbuffer_safe_ex(s32 chn,void *buffer,int size, int retries)
241249
s32 left = size;
242250
char *ptr = (char*)buffer;
243251

244-
__usbgecko_exi_wait(chn);
252+
if (!__usbgecko_exi_wait(chn))
253+
return 0;
254+
245255
while(left>0) {
246256
if(__usb_checkrecv(chn)) {
247257
ret = __usb_recvbyte(chn,ptr);
@@ -272,7 +282,9 @@ int usb_sendbuffer_safe_ex(s32 chn,const void *buffer,int size, int retries)
272282
s32 left = size;
273283
char *ptr = (char*)buffer;
274284

275-
__usbgecko_exi_wait(chn);
285+
if (!__usbgecko_exi_wait(chn))
286+
return 0;
287+
276288
while(left>0) {
277289
if(__usb_checksend(chn)) {
278290
ret = __usb_sendbyte(chn,*ptr);
@@ -324,7 +336,9 @@ int usb_flashread(s32 chn, u32 offset, void *buffer, size_t length)
324336
s32 ret=1;
325337
u8 *data = (u8*)buffer;
326338

327-
__usbgecko_exi_wait(chn);
339+
if (!__usbgecko_exi_wait(chn))
340+
return 0;
341+
328342
while (ret && length--)
329343
ret = __flashreadcommand(chn, offset++, data++);
330344

@@ -339,7 +353,9 @@ int usb_flashwrite(s32 chn, u32 offset, const void *buffer, size_t length)
339353
const u8 *data = (const u8*)buffer;
340354
u8 verify;
341355

342-
__usbgecko_exi_wait(chn);
356+
if (!__usbgecko_exi_wait(chn))
357+
return 0;
358+
343359
while (ret && length--)
344360
{
345361
if (!__flashwritecommand(chn, 0x5555, 0xAA) || !__flashwritecommand(chn, 0x2AAA, 0x55) ||
@@ -362,7 +378,8 @@ int usb_flashverify(s32 chn)
362378
u8 id[2];
363379
s32 ret=0;
364380

365-
__usbgecko_exi_wait(chn);
381+
if (!__usbgecko_exi_wait(chn))
382+
return 0;
366383

367384
if (__flashsoftwareid_entry(chn) &&__flashreadcommand(chn, 0, id+0) &&
368385
__flashreadcommand(chn, 1, id+1) && id[0] == 0xBF && id[1] == 0xD7 &&

0 commit comments

Comments
 (0)