diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index 4f91b10b1..09261b3cd 100644 --- a/src/scsi/scsi_aha154x.c +++ b/src/scsi/scsi_aha154x.c @@ -12,7 +12,7 @@ * * NOTE: THIS IS CURRENTLY A MESS, but will be cleaned up as I go. * - * Version: @(#)scsi_aha154x.c 1.0.14 2017/08/27 + * Version: @(#)scsi_aha154x.c 1.0.15 2017/09/01 * * Authors: Fred N. van Kempen, * Original Buslogic version by SA1988 and Miran Grca. @@ -33,6 +33,7 @@ #include "../pic.h" #include "../timer.h" #include "../device.h" +#include "../win/plat_thread.h" #include "scsi.h" #include "scsi_bios_command.h" #include "scsi_device.h" @@ -393,12 +394,8 @@ typedef struct { wchar_t *nvr_path; /* path to NVR image file */ uint8_t *nvr; /* EEPROM buffer */ - int Callback; - int InOperation; int ResetCB; - int8_t IrqEnabled; - int StrictRoundRobinMode; int ExtendedLUNCCBFormat; Req_t Req; uint8_t Status; @@ -422,6 +419,8 @@ typedef struct { int MbiActive[256]; int PendingInterrupt; int Lock; + event_t *evt; + int scan_restart; } aha_t; #pragma pack(pop) @@ -431,6 +430,11 @@ static uint16_t aha_ports[] = { 0x0130, 0x0134, 0x0000, 0x0000 }; + +static void aha_cmd_thread(void *priv); +static thread_t *poll_tid; + + #if ENABLE_AHA154X_LOG int aha_do_log = ENABLE_AHA154X_LOG; #endif @@ -575,6 +579,42 @@ aha154x_mmap(aha_t *dev, uint8_t cmd) } +static void +RaiseIntr(aha_t *dev, int suppress, uint8_t Interrupt) +{ + if (Interrupt & (INTR_MBIF | INTR_MBOA)) + { + if (!(dev->Interrupt & INTR_HACC)) + { + dev->Interrupt |= Interrupt; /* Report now. */ + } + else + { + dev->PendingInterrupt |= Interrupt; /* Report later. */ + } + } + else if (Interrupt & INTR_HACC) + { + if (dev->Interrupt == 0 || dev->Interrupt == (INTR_ANY | INTR_HACC)) + { + aha_log("%s: BuslogicRaiseInterrupt(): Interrupt=%02X\n", dev->name, dev->Interrupt); + } + dev->Interrupt |= Interrupt; + } + else + { + aha_log("%s: BuslogicRaiseInterrupt(): Invalid interrupt state!\n", dev->name); + } + + dev->Interrupt |= INTR_ANY; + + if (!suppress) + { + picint(1 << dev->Irq); + } +} + + static void ClearIntr(aha_t *dev) { @@ -583,52 +623,41 @@ ClearIntr(aha_t *dev) dev->name, dev->Irq, dev->Interrupt); picintc(1 << dev->Irq); if (dev->PendingInterrupt) { - dev->Interrupt = dev->PendingInterrupt; aha_log("%s: Raising Interrupt 0x%02X (Pending)\n", dev->name, dev->Interrupt); if (dev->MailboxOutInterrupts || !(dev->Interrupt & INTR_MBOA)) { - if (dev->IrqEnabled) picint(1 << dev->Irq); + RaiseIntr(dev, 0, dev->PendingInterrupt); } dev->PendingInterrupt = 0; } } -static void -RaiseIntr(aha_t *dev, uint8_t Interrupt) -{ - if (dev->Interrupt & INTR_HACC) { - aha_log("%s: Pending IRQ\n", dev->name); - dev->PendingInterrupt = Interrupt; - } else { - dev->Interrupt = Interrupt; - aha_log("%s: Raising IRQ %i\n", dev->name, dev->Irq); - if (dev->IrqEnabled) - picint(1 << dev->Irq); - } -} - - static void aha_reset(aha_t *dev) { + if (dev->evt) { + thread_destroy_event(dev->evt); + dev->evt = NULL; + if (poll_tid) { + poll_tid = NULL; + } + } + dev->ResetCB = 0; - dev->Callback = 0; + dev->scan_restart = 0; dev->Status = STAT_IDLE | STAT_INIT; dev->Geometry = 0x80; dev->Command = 0xFF; dev->CmdParam = 0; dev->CmdParamLeft = 0; - dev->IrqEnabled = 1; - dev->StrictRoundRobinMode = 0; dev->ExtendedLUNCCBFormat = 0; dev->MailboxOutPosCur = 0; dev->MailboxInPosCur = 0; dev->MailboxOutInterrupts = 0; dev->PendingInterrupt = 0; dev->Lock = 0; - dev->InOperation = 0; ClearIntr(dev); } @@ -667,17 +696,15 @@ aha_reset_poll(void *priv) static void -aha_cmd_done(aha_t *dev) +aha_cmd_done(aha_t *dev, int suppress) { dev->DataReply = 0; dev->Status |= STAT_IDLE; if ((dev->Command != CMD_START_SCSI) && (dev->Command != CMD_BIOS_SCSI)) { dev->Status &= ~STAT_DFULL; - dev->Interrupt = (INTR_ANY | INTR_HACC); aha_log("%s: Raising IRQ %i\n", dev->name, dev->Irq); - if (dev->IrqEnabled) - picint(1 << dev->Irq); + RaiseIntr(dev, suppress, INTR_HACC); } dev->Command = 0xff; @@ -699,8 +726,6 @@ aha_mbi_setup(aha_t *dev, uint32_t CCBPointer, CCBU *CmdBlock, req->MailboxCompletionCode = mbcc; aha_log("Mailbox in setup\n"); - - dev->InOperation = 2; } @@ -755,9 +780,7 @@ aha_mbi(aha_t *dev) if (dev->MailboxInPosCur >= dev->MailboxCount) dev->MailboxInPosCur = 0; - RaiseIntr(dev, INTR_MBIF | INTR_ANY); - - dev->InOperation = 0; + RaiseIntr(dev, 0, INTR_MBIF | INTR_ANY); } @@ -1113,6 +1136,8 @@ aha_req_setup(aha_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) if ((id > max_id) || (lun > 7)) { aha_mbi_setup(dev, CCBPointer, &req->CmdBlock, CCB_INVALID_CCB, SCSI_STATUS_OK, MBI_ERROR); + aha_log("%s: Callback: Send incoming mailbox\n", dev->name); + aha_mbi(dev); return; } @@ -1129,6 +1154,8 @@ aha_req_setup(aha_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) SenseBufferFree(req, 0); aha_mbi_setup(dev, CCBPointer, &req->CmdBlock, CCB_SELECTION_TIMEOUT,SCSI_STATUS_OK,MBI_ERROR); + aha_log("%s: Callback: Send incoming mailbox\n", dev->name); + aha_mbi(dev); } else { aha_log("SCSI Target ID %i and LUN %i detected and working\n", id, lun); @@ -1140,7 +1167,11 @@ aha_req_setup(aha_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) req->CmdBlock.common.ControlByte); } - dev->InOperation = 1; + aha_log("%s: Callback: Process SCSI request\n", dev->name); + aha_scsi_cmd(dev); + + aha_log("%s: Callback: Send incoming mailbox\n", dev->name); + aha_mbi(dev); } } @@ -1155,6 +1186,8 @@ aha_req_abort(aha_t *dev, uint32_t CCBPointer) aha_mbi_setup(dev, CCBPointer, &CmdBlock, 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND); + aha_log("%s: Callback: Send incoming mailbox\n", dev->name); + aha_mbi(dev); } @@ -1187,7 +1220,7 @@ aha_mbo_adv(aha_t *dev) } -static void +static uint8_t aha_do_mail(aha_t *dev) { Mailbox32_t mb32; @@ -1197,32 +1230,25 @@ aha_do_mail(aha_t *dev) CodeOffset = dev->Mbx24bit ? 0 : 7; - if (! dev->StrictRoundRobinMode) { - uint8_t MailboxCur = dev->MailboxOutPosCur; - - /* Search for a filled mailbox - stop if we have scanned all mailboxes. */ - do { - /* Fetch mailbox from guest memory. */ - Outgoing = aha_mbo(dev, &mb32); - - /* Check the next mailbox. */ - aha_mbo_adv(dev); - } while ((mb32.u.out.ActionCode == MBO_FREE) && (MailboxCur != dev->MailboxOutPosCur)); - } else { - Outgoing = aha_mbo(dev, &mb32); + if (dev->Interrupt || dev->PendingInterrupt) + { + aha_log("%s: Interrupt set, waiting...\n", dev->name); + return 1; } + Outgoing = aha_mbo(dev, &mb32); + if (mb32.u.out.ActionCode != MBO_FREE) { /* We got the mailbox, mark it as free in the guest. */ aha_log("aha_do_mail(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset); DMAPageWrite(Outgoing + CodeOffset, (char *)&CmdStatus, sizeof(CmdStatus)); } + else { + return 0; + } if (dev->MailboxOutInterrupts) - RaiseIntr(dev, INTR_MBOA | INTR_ANY); - - /* Check if the mailbox is actually loaded. */ - if (mb32.u.out.ActionCode == MBO_FREE) return; + RaiseIntr(dev, 0, INTR_MBOA | INTR_ANY); if (mb32.u.out.ActionCode == MBO_START) { aha_log("Start Mailbox Command\n"); @@ -1235,40 +1261,42 @@ aha_do_mail(aha_t *dev) } /* Advance to the next mailbox. */ - if (dev->StrictRoundRobinMode) - aha_mbo_adv(dev); + aha_mbo_adv(dev); + + return 1; } static void -aha_cmd_cb(void *priv) +aha_cmd_thread(void *priv) { aha_t *dev = (aha_t *)priv; - if (dev->InOperation == 0) { - if (dev->MailboxCount) { - aha_do_mail(dev); - } else { - dev->Callback += SCSI_DELAY_TM * TIMER_USEC; - return; - } - } else if (dev->InOperation == 1) { - aha_log("%s: Callback: Process SCSI request\n", dev->name); - aha_scsi_cmd(dev); - aha_mbi(dev); - if (dev->Req.CmdBlock.common.Cdb[0] == 0x42) { - /* This is needed since CD Audio inevitably means READ SUBCHANNEL spam. */ - dev->Callback += 1000 * TIMER_USEC; - return; - } - } else if (dev->InOperation == 2) { - aha_log("%s: Callback: Send incoming mailbox\n", dev->name); - aha_mbi(dev); - } else { - fatal("%s: Invalid callback phase: %i\n", dev->name, dev->InOperation); +aha_event_restart: + /* Create a waitable event. */ + dev->evt = thread_create_event(); + +aha_scan_restart: + while (aha_do_mail(dev) != 0) + { } - dev->Callback += SCSI_DELAY_TM * TIMER_USEC; + if (dev->scan_restart) + { + goto aha_scan_restart; + } + + thread_destroy_event(dev->evt); + dev->evt = NULL; + + if (dev->scan_restart) + { + goto aha_event_restart; + } + + poll_tid = NULL; + + aha_log("%s: Callback: polling stopped.\n", dev->name); } @@ -1290,7 +1318,7 @@ aha_read(uint16_t port, void *priv) dev->DataReply++; dev->DataReplyLeft--; if (! dev->DataReplyLeft) - aha_cmd_done(dev); + aha_cmd_done(dev, 0); } break; @@ -1329,6 +1357,7 @@ aha_write(uint16_t port, uint8_t val, void *priv) uint8_t j = 0; BIOSCMD *cmd; uint16_t cyl = 0; + int suppress = 0; aha_log("%s: Write Port 0x%02X, Value %02X\n", dev->name, port, val); @@ -1352,8 +1381,13 @@ aha_write(uint16_t port, uint8_t val, void *priv) (dev->Command == 0xff)) { /* If there are no mailboxes configured, don't even try to do anything. */ if (dev->MailboxCount) { - if (! dev->Callback) { - dev->Callback = SCSI_DELAY_TM * TIMER_USEC; + if (! poll_tid) { + aha_log("%s: starting thread..\n", dev->name); + poll_tid = thread_create(aha_cmd_thread, dev); + dev->scan_restart = 0; + } + else { + dev->scan_restart = 1; } } return; @@ -1479,6 +1513,7 @@ aha_0x01: if (dev->CmdBuf[0] <= 1) { dev->MailboxOutInterrupts = dev->CmdBuf[0]; aha_log("Mailbox out interrupts: %s\n", dev->MailboxOutInterrupts ? "ON" : "OFF"); + suppress = 1; } else { dev->Status |= STAT_INVCMD; } @@ -1648,7 +1683,7 @@ aha_0x01: if (dev->DataReplyLeft) dev->Status |= STAT_DFULL; else if (!dev->CmdParamLeft) - aha_cmd_done(dev); + aha_cmd_done(dev, suppress); break; case 2: @@ -2062,7 +2097,6 @@ aha_init(int type) aha_setnvr(dev); timer_add(aha_reset_poll, &dev->ResetCB, &dev->ResetCB, dev); - timer_add(aha_cmd_cb, &dev->Callback, &dev->Callback, dev); if (dev->Base != 0) { /* Register our address space. */ @@ -2110,11 +2144,22 @@ aha_close(void *priv) { aha_t *dev = (aha_t *)priv; - if (dev->nvr != NULL) - free(dev->nvr); + if (dev) + { + if (dev->evt) { + thread_destroy_event(dev->evt); + dev->evt = NULL; + if (poll_tid) { + poll_tid = NULL; + } + } - free(dev); + if (dev->nvr != NULL) + free(dev->nvr); + free(dev); + dev = NULL; + } } diff --git a/src/scsi/scsi_buslogic.c b/src/scsi/scsi_buslogic.c index 6126df858..d5166766d 100644 --- a/src/scsi/scsi_buslogic.c +++ b/src/scsi/scsi_buslogic.c @@ -10,7 +10,7 @@ * 0 - BT-545C ISA; * 1 - BT-958D PCI (but BT-545C ISA on non-PCI machines) * - * Version: @(#)scsi_buslogic.c 1.0.10 2017/08/26 + * Version: @(#)scsi_buslogic.c 1.0.11 2017/09/01 * * Authors: TheCollector1995, * Miran Grca, @@ -32,6 +32,7 @@ #include "../pci.h" #include "../timer.h" #include "../device.h" +#include "../win/plat_thread.h" #include "scsi.h" #include "scsi_bios_command.h" #include "scsi_device.h" @@ -505,14 +506,17 @@ typedef struct { bios_mask; uint8_t AutoSCSIROM[32768]; uint8_t SCAMData[65536]; + event_t *evt; + int scan_restart; } Buslogic_t; #pragma pack(pop) static int BuslogicResetCallback = 0; -static int BuslogicCallback = 0; -static int BuslogicInOperation = 0; -static Buslogic_t *BuslogicResetDevice; + + +static void BuslogicCommandThread(void *p); +static thread_t *poll_tid; enum { @@ -743,18 +747,6 @@ static void BuslogicInitializeAutoSCSIRam(Buslogic_t *bl) static void BuslogicRaiseInterrupt(Buslogic_t *bl, int suppress, uint8_t Interrupt) { -#if 0 - if (bl->Interrupt & INTR_HACC) { - pclog("Pending IRQ\n"); - bl->PendingInterrupt = Interrupt; - } else { - bl->Interrupt = Interrupt; - pclog("Raising IRQ %i\n", bl->Irq); - if (bl->IrqEnabled) - BuslogicInterrupt(bl, 1); - } -#endif - if (Interrupt & (INTR_MBIF | INTR_MBOA)) { if (!(bl->Interrupt & INTR_HACC)) @@ -807,10 +799,21 @@ BuslogicClearInterrupt(Buslogic_t *bl) static void BuslogicReset(Buslogic_t *bl) { - /* pclog("BuslogicReset()\n"); */ - BuslogicCallback = 0; + /* pclog("BuslogicReset()\n"); */ + if (bl->evt) + { + thread_destroy_event(bl->evt); + bl->evt = NULL; + if (poll_tid) + { + poll_tid = NULL; + } + } + BuslogicResetCallback = 0; - bl->Geometry = 0x80; + bl->scan_restart = 0; + + bl->Geometry = 0x80; bl->Status = STAT_IDLE | STAT_INIT; bl->Command = 0xFF; bl->CmdParam = 0; @@ -822,9 +825,8 @@ BuslogicReset(Buslogic_t *bl) bl->MailboxOutInterrupts = 0; bl->PendingInterrupt = 0; bl->Lock = 0; - BuslogicInOperation = 0; - BuslogicClearInterrupt(bl); + BuslogicClearInterrupt(bl); } @@ -876,8 +878,6 @@ BuslogicMailboxInSetup(Buslogic_t *bl, uint32_t CCBPointer, CCBU *CmdBlock, req->MailboxCompletionCode = MailboxCompletionCode; pclog("Mailbox in setup\n"); - - BuslogicInOperation = 2; } @@ -934,8 +934,6 @@ BuslogicMailboxIn(Buslogic_t *bl) bl->MailboxInPosCur = 0; BuslogicRaiseInterrupt(bl, 0, INTR_MBIF | INTR_ANY); - - BuslogicInOperation = 0; } @@ -1480,8 +1478,13 @@ BuslogicWrite(uint16_t Port, uint8_t Val, void *p) if ((Val == 0x02) && (bl->Command == 0xFF)) { /* If there are no mailboxes configured, don't even try to do anything. */ if (bl->MailboxCount) { - if (!BuslogicCallback) { - BuslogicCallback = 1 * TIMER_USEC; + if (!poll_tid) { + pclog("Buslogic: starting thread..\n"); + poll_tid = thread_create(BuslogicCommandThread, bl); + bl->scan_restart = 0; + } + else { + bl->scan_restart = 1; } } return; @@ -2369,6 +2372,8 @@ BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbox32_t *Mailb fatal("BuslogicSCSIRequestSetup(): Attempting to queue tags\n"); BuslogicMailboxInSetup(bl, CCBPointer, &req->CmdBlock, CCB_INVALID_CCB, SCSI_STATUS_OK, MBI_ERROR); + pclog("BusLogic Callback: Send incoming mailbox\n"); + BuslogicMailboxIn(bl); return; } } @@ -2379,6 +2384,9 @@ BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbox32_t *Mailb BuslogicMailboxInSetup(bl, CCBPointer, &req->CmdBlock, CCB_INVALID_CCB, SCSI_STATUS_OK, MBI_ERROR); return; + + pclog("BusLogic Callback: Send incoming mailbox\n"); + BuslogicMailboxIn(bl); } pclog("BuslogicSCSIRequestSetup(): Scanning SCSI Target ID %i\n", Id); @@ -2394,6 +2402,9 @@ BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbox32_t *Mailb BuslogicSenseBufferFree(req, 0); BuslogicMailboxInSetup(bl, CCBPointer, &req->CmdBlock, CCB_SELECTION_TIMEOUT,SCSI_STATUS_OK,MBI_ERROR); + + pclog("BusLogic Callback: Send incoming mailbox\n"); + BuslogicMailboxIn(bl); } else { pclog("BuslogicSCSIRequestSetup(): SCSI Target ID %i and LUN %i detected and working\n", Id, Lun); @@ -2405,7 +2416,11 @@ BuslogicSCSIRequestSetup(Buslogic_t *bl, uint32_t CCBPointer, Mailbox32_t *Mailb req->CmdBlock.common.ControlByte); } - BuslogicInOperation = 1; + pclog("BusLogic Callback: Process SCSI request\n"); + BuslogicSCSICommand(bl); + + pclog("BusLogic Callback: Send incoming mailbox\n"); + BuslogicMailboxIn(bl); } } @@ -2421,6 +2436,9 @@ BuslogicSCSIRequestAbort(Buslogic_t *bl, uint32_t CCBPointer) /* Only SCSI CD-ROMs are supported at the moment, SCSI hard disk support will come soon. */ BuslogicMailboxInSetup(bl, CCBPointer, &CmdBlock, 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND); + + pclog("BusLogic Callback: Send incoming mailbox\n"); + BuslogicMailboxIn(bl); } @@ -2453,7 +2471,7 @@ BuslogicMailboxOutAdvance(Buslogic_t *bl) } -static void +static uint8_t BuslogicProcessMailbox(Buslogic_t *bl) { Mailbox32_t mb32; @@ -2467,6 +2485,12 @@ BuslogicProcessMailbox(Buslogic_t *bl) pclog("BuslogicProcessMailbox(): Operating in %s mode\n", bl->LocalRAM.structured.autoSCSIData.fAggressiveRoundRobinMode ? "aggressive" : "strict"); #endif + if (bl->Interrupt || bl->PendingInterrupt) + { + /* pclog("Interrupt set, waiting...\n"); */ + return 1; + } + /* 0 = strict, 1 = aggressive */ if (bl->LocalRAM.structured.autoSCSIData.fAggressiveRoundRobinMode) { uint8_t MailboxCur = bl->MailboxOutPosCur; @@ -2488,6 +2512,10 @@ BuslogicProcessMailbox(Buslogic_t *bl) pclog("BuslogicProcessMailbox(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset); DMAPageWrite(Outgoing + CodeOffset, (char *)&CmdStatus, sizeof(CmdStatus)); } + else + { + return 0; + } if (bl->MailboxOutInterrupts) BuslogicRaiseInterrupt(bl, 0, INTR_MBOA | INTR_ANY); @@ -2496,11 +2524,6 @@ BuslogicProcessMailbox(Buslogic_t *bl) pclog("BuslogicProcessMailbox(): Outgoing mailbox action code: %i\n", mb32.u.out.ActionCode); #endif - /* Check if the mailbox is actually loaded. */ - if (mb32.u.out.ActionCode == MBO_FREE) { - return; - } - if (mb32.u.out.ActionCode == MBO_START) { pclog("Start Mailbox Command\n"); BuslogicSCSIRequestSetup(bl, mb32.CCBPointer, &mb32); @@ -2514,6 +2537,8 @@ BuslogicProcessMailbox(Buslogic_t *bl) /* Advance to the next mailbox. */ if (! bl->LocalRAM.structured.autoSCSIData.fAggressiveRoundRobinMode) BuslogicMailboxOutAdvance(bl); + + return 1; } @@ -2530,34 +2555,35 @@ BuslogicResetPoll(void *p) static void -BuslogicCommandCallback(void *p) +BuslogicCommandThread(void *p) { Buslogic_t *bl = (Buslogic_t *)p; - if (BuslogicInOperation == 0) { - if (bl->MailboxCount) { - BuslogicProcessMailbox(bl); - } else { - BuslogicCallback += 1 * TIMER_USEC; - return; - } - } else if (BuslogicInOperation == 1) { - pclog("BusLogic Callback: Process SCSI request\n"); - BuslogicSCSICommand(bl); - if (bl->Req.CmdBlock.common.Cdb[0] == 0x42) - { - /* This is needed since CD Audio inevitably means READ SUBCHANNEL spam. */ - BuslogicCallback += 1000 * TIMER_USEC; - return; - } - } else if (BuslogicInOperation == 2) { - pclog("BusLogic Callback: Send incoming mailbox\n"); - BuslogicMailboxIn(bl); - } else { - fatal("Invalid BusLogic callback phase: %i\n", BuslogicInOperation); +BuslogicEventRestart: + /* Create a waitable event. */ + bl->evt = thread_create_event(); + +BuslogicScanRestart: + while (BuslogicProcessMailbox(bl) != 0) + { } - BuslogicCallback += 1 * TIMER_USEC; + if (bl->scan_restart) + { + goto BuslogicScanRestart; + } + + thread_destroy_event(bl->evt); + bl->evt = NULL; + + if (bl->scan_restart) + { + goto BuslogicEventRestart; + } + + poll_tid = NULL; + + pclog("Buslogic: polling stopped.\n"); } @@ -2825,7 +2851,6 @@ BuslogicInit(int chip) bl = malloc(sizeof(Buslogic_t)); memset(bl, 0x00, sizeof(Buslogic_t)); - BuslogicResetDevice = bl; if (!PCI && (chip == CHIP_BUSLOGIC_PCI)) { chip = CHIP_BUSLOGIC_ISA; @@ -2923,8 +2948,6 @@ BuslogicInit(int chip) timer_add(BuslogicResetPoll, &BuslogicResetCallback, &BuslogicResetCallback, bl); - timer_add(BuslogicCommandCallback, - &BuslogicCallback, &BuslogicCallback, bl); if (bl->chip == CHIP_BUSLOGIC_PCI) { bl->Card = pci_add_card(PCI_ADD_NORMAL, BuslogicPCIRead, BuslogicPCIWrite, bl); @@ -2984,8 +3007,22 @@ static void BuslogicClose(void *p) { Buslogic_t *bl = (Buslogic_t *)p; - free(bl); - BuslogicResetDevice = NULL; + if (bl) + { + if (bl->evt) + { + thread_destroy_event(bl->evt); + bl->evt = NULL; + + if (poll_tid) + { + poll_tid = NULL; + } + } + + free(bl); + bl = NULL; + } }