mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2025-01-19 12:24:34 +08:00
isdn: hisax/elsa: fix sleep_on race in elsa FSM
The state machine code in the elsa driver uses interruptible_sleep_on to wait for state changes, which is racy. A closer look at the possible states reveals that it is always used to wait for getting back into ARCOFI_NOP, so we can use wait_event_interruptible instead. Signed-off-by: Arnd Bergmann <arnd@arndb.de> Cc: Karsten Keil <isdn@linux-pingi.de> Cc: netdev@vger.kernel.org Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
e5b3fa1547
commit
c728cc88ce
@ -509,7 +509,8 @@ static void
|
||||
set_arcofi(struct IsdnCardState *cs, int bc) {
|
||||
cs->dc.isac.arcofi_bc = bc;
|
||||
arcofi_fsm(cs, ARCOFI_START, &ARCOFI_COP_5);
|
||||
interruptible_sleep_on(&cs->dc.isac.arcofi_wait);
|
||||
wait_event_interruptible(cs->dc.isac.arcofi_wait,
|
||||
cs->dc.isac.arcofi_state == ARCOFI_NOP);
|
||||
}
|
||||
|
||||
static int
|
||||
@ -528,7 +529,8 @@ check_arcofi(struct IsdnCardState *cs)
|
||||
}
|
||||
cs->dc.isac.arcofi_bc = 0;
|
||||
arcofi_fsm(cs, ARCOFI_START, &ARCOFI_VERSION);
|
||||
interruptible_sleep_on(&cs->dc.isac.arcofi_wait);
|
||||
wait_event_interruptible(cs->dc.isac.arcofi_wait,
|
||||
cs->dc.isac.arcofi_state == ARCOFI_NOP);
|
||||
if (!test_and_clear_bit(FLG_ARCOFI_ERROR, &cs->HW_Flags)) {
|
||||
debugl1(cs, "Arcofi response received %d bytes", cs->dc.isac.mon_rxp);
|
||||
p = cs->dc.isac.mon_rx;
|
||||
@ -595,7 +597,8 @@ check_arcofi(struct IsdnCardState *cs)
|
||||
Elsa_Types[cs->subtyp],
|
||||
cs->hw.elsa.base + 8);
|
||||
arcofi_fsm(cs, ARCOFI_START, &ARCOFI_XOP_0);
|
||||
interruptible_sleep_on(&cs->dc.isac.arcofi_wait);
|
||||
wait_event_interruptible(cs->dc.isac.arcofi_wait,
|
||||
cs->dc.isac.arcofi_state == ARCOFI_NOP);
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
|
@ -573,7 +573,8 @@ modem_l2l1(struct PStack *st, int pr, void *arg)
|
||||
test_and_clear_bit(BC_FLG_ACTIV, &bcs->Flag);
|
||||
bcs->cs->dc.isac.arcofi_bc = st->l1.bc;
|
||||
arcofi_fsm(bcs->cs, ARCOFI_START, &ARCOFI_XOP_0);
|
||||
interruptible_sleep_on(&bcs->cs->dc.isac.arcofi_wait);
|
||||
wait_event_interruptible(bcs->cs->dc.isac.arcofi_wait,
|
||||
bcs->cs->dc.isac.arcofi_state == ARCOFI_NOP);
|
||||
bcs->cs->hw.elsa.MFlag = 1;
|
||||
} else {
|
||||
printk(KERN_WARNING "ElsaSer: unknown pr %x\n", pr);
|
||||
|
Loading…
Reference in New Issue
Block a user