pc_serial: fix KDL on close
It's working \o/ Just need to figure out why it waits for \n to transmit. We now only destroy the cookies in the free hook. Mention pending DPC as soon as when inside the irq handler. Also limit the number of loops in the IRQ handler to avoid busy looping. It only happened when testing with normal priority but you never know...
This commit is contained in:
parent
7b97fd6dd8
commit
c5c041a5ba
@ -346,7 +346,13 @@ SerialDevice::IsInterruptPending()
|
||||
// the next time we'll read we'll miss the IRQ condition
|
||||
// so we just cache the value for the real handler
|
||||
fCachedIIR = ReadReg8(IIR);
|
||||
return ((fCachedIIR & IIR_PENDING) == 0); // 0 means yes
|
||||
|
||||
bool pending = (fCachedIIR & IIR_PENDING) == 0;
|
||||
|
||||
if (pending)
|
||||
atomic_add(&fPendingDPC, 1);
|
||||
|
||||
return pending; // 0 means yes
|
||||
}
|
||||
|
||||
|
||||
@ -358,10 +364,9 @@ SerialDevice::InterruptHandler()
|
||||
|
||||
uint8 iir, lsr, msr;
|
||||
uint8 buffer[64];
|
||||
int tries = 8; // avoid busy looping
|
||||
TRACE(("InterruptHandler()\n"));
|
||||
|
||||
atomic_add(&fPendingDPC, 1);
|
||||
|
||||
// start with the first (cached) irq condition
|
||||
iir = fCachedIIR;
|
||||
while ((iir & IIR_PENDING) == 0) { // 0 means yes
|
||||
@ -455,6 +460,10 @@ SerialDevice::InterruptHandler()
|
||||
ret = B_HANDLED_INTERRUPT;
|
||||
TRACE(("IRQ:h\n"));
|
||||
|
||||
// enough for now
|
||||
if (tries-- == 0)
|
||||
break;
|
||||
|
||||
// check the next IRQ condition
|
||||
iir = ReadReg8(IIR);
|
||||
}
|
||||
@ -654,19 +663,12 @@ SerialDevice::Close()
|
||||
|
||||
fDeviceOpen = false;
|
||||
|
||||
gTTYModule->tty_close_cookie(fSystemTTYCookie);
|
||||
gTTYModule->tty_close_cookie(fDeviceTTYCookie);
|
||||
|
||||
//XXX: we shouldn't have to do this!
|
||||
bool en = false;
|
||||
Service(fMasterTTY, TTYENABLE, &en, sizeof(en));
|
||||
// XXX: shouldn't we tty_close_cookie() as well ??
|
||||
|
||||
// wait until currently executing DPC is done. In case another one
|
||||
// is run beyond this point it will just bail out on !IsOpen().
|
||||
while (atomic_get(&fPendingDPC))
|
||||
snooze(1000);
|
||||
|
||||
gTTYModule->tty_destroy_cookie(fSystemTTYCookie);
|
||||
gTTYModule->tty_destroy_cookie(fDeviceTTYCookie);
|
||||
fSystemTTYCookie = fDeviceTTYCookie = NULL;
|
||||
|
||||
return status;
|
||||
}
|
||||
@ -677,6 +679,15 @@ SerialDevice::Free()
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
// wait until currently executing DPC is done. In case another one
|
||||
// is run beyond this point it will just bail out on !IsOpen().
|
||||
while (atomic_get(&fPendingDPC))
|
||||
snooze(1000);
|
||||
|
||||
gTTYModule->tty_destroy_cookie(fSystemTTYCookie);
|
||||
gTTYModule->tty_destroy_cookie(fDeviceTTYCookie);
|
||||
fSystemTTYCookie = fDeviceTTYCookie = NULL;
|
||||
|
||||
gTTYModule->tty_destroy(fMasterTTY);
|
||||
gTTYModule->tty_destroy(fSlaveTTY);
|
||||
fMasterTTY = fSlaveTTY = NULL;
|
||||
|
Loading…
x
Reference in New Issue
Block a user