diff --git a/src/Makefile.mingw b/src/Makefile.mingw index 868a23e30..af5c4e83b 100644 --- a/src/Makefile.mingw +++ b/src/Makefile.mingw @@ -8,7 +8,7 @@ # # Modified Makefile for Win32 (MinGW32) environment. # -# Version: @(#)Makefile.mingw 1.0.39 2017/08/26 +# Version: @(#)Makefile.mingw 1.0.40 2017/08/27 # # Authors: Miran Grca, # Fred N. van Kempen, @@ -28,7 +28,9 @@ STUFF = # -DANSI_CFG forces the config file to ANSI encoding. # -DENABLE_VRAM_DUMP enables Video Ram dumping. # -DENABLE_LOG_BREAKPOINT enables extra logging. -# -DENABLE_BUSLOGIC_LOG enables extra logging. +# -DENABLE_SCSI_BIOS_COMMAND_LOG=n enables extra logging. +# -DENABLE_AHA154X_LOG=n enables extra logging. +# -DENABLE_BUSLOGIC_LOG=n enables extra logging. # -DENABLE_CDROM_LOG enables extra logging. # -DENABLE_D86F_LOG enables extra logging. # -DENABLE_FDC_LOG enables extra logging. diff --git a/src/scsi/scsi.c b/src/scsi/scsi.c index 492e42db3..429088520 100644 --- a/src/scsi/scsi.c +++ b/src/scsi/scsi.c @@ -8,12 +8,11 @@ * * Handling of the SCSI controllers. * - * Version: @(#)scsi.c 1.0.2 2017/08/23 + * Version: @(#)scsi.c 1.0.3 2017/08/27 * * Authors: TheCollector1995, * Miran Grca, * Fred N. van Kempen, - * Copyright 2008-2017 TheCollector1995. * Copyright 2016,2017 Miran Grca. * Copyright 2017 Fred N. van Kempen. */ @@ -29,6 +28,7 @@ #include "scsi_buslogic.h" +scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX]; uint8_t SCSIPhase = SCSI_PHASE_BUS_FREE; uint8_t SCSIStatus = SCSI_STATUS_OK; uint8_t scsi_cdrom_id = 3; /*common setting*/ @@ -116,18 +116,13 @@ void scsi_card_init(void) pclog("Building SCSI CD-ROM map...\n"); build_scsi_cdrom_map(); - for (i=0; i<16; i++) - { - for (j=0; j<8; j++) - { + for (i=0; i * Miran Grca, @@ -28,73 +28,78 @@ #endif +/* Configuration. */ +#define SCSI_ID_MAX 8 /* 16 on wide buses */ +#define SCSI_LUN_MAX 8 /* always 8 */ + + /* SCSI commands. */ -#define GPCMD_TEST_UNIT_READY 0x00 -#define GPCMD_REZERO_UNIT 0x01 -#define GPCMD_REQUEST_SENSE 0x03 -#define GPCMD_FORMAT_UNIT 0x04 -#define GPCMD_READ_6 0x08 -#define GPCMD_WRITE_6 0x0a -#define GPCMD_SEEK_6 0x0b -#define GPCMD_INQUIRY 0x12 -#define GPCMD_VERIFY_6 0x13 -#define GPCMD_MODE_SELECT_6 0x15 -#define GPCMD_MODE_SENSE_6 0x1a -#define GPCMD_START_STOP_UNIT 0x1b -#define GPCMD_PREVENT_REMOVAL 0x1e -#define GPCMD_READ_CDROM_CAPACITY 0x25 -#define GPCMD_READ_10 0x28 -#define GPCMD_WRITE_10 0x2a -#define GPCMD_SEEK_10 0x2b -#define GPCMD_VERIFY_10 0x2f -#define GPCMD_READ_SUBCHANNEL 0x42 -#define GPCMD_READ_TOC_PMA_ATIP 0x43 -#define GPCMD_READ_HEADER 0x44 -#define GPCMD_PLAY_AUDIO_10 0x45 -#define GPCMD_GET_CONFIGURATION 0x46 -#define GPCMD_PLAY_AUDIO_MSF 0x47 -#define GPCMD_PLAY_AUDIO_TRACK_INDEX 0x48 -#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a -#define GPCMD_PAUSE_RESUME 0x4b -#define GPCMD_STOP_PLAY_SCAN 0x4e -#define GPCMD_READ_DISC_INFORMATION 0x51 +#define GPCMD_TEST_UNIT_READY 0x00 +#define GPCMD_REZERO_UNIT 0x01 +#define GPCMD_REQUEST_SENSE 0x03 +#define GPCMD_FORMAT_UNIT 0x04 +#define GPCMD_READ_6 0x08 +#define GPCMD_WRITE_6 0x0a +#define GPCMD_SEEK_6 0x0b +#define GPCMD_INQUIRY 0x12 +#define GPCMD_VERIFY_6 0x13 +#define GPCMD_MODE_SELECT_6 0x15 +#define GPCMD_MODE_SENSE_6 0x1a +#define GPCMD_START_STOP_UNIT 0x1b +#define GPCMD_PREVENT_REMOVAL 0x1e +#define GPCMD_READ_CDROM_CAPACITY 0x25 +#define GPCMD_READ_10 0x28 +#define GPCMD_WRITE_10 0x2a +#define GPCMD_SEEK_10 0x2b +#define GPCMD_VERIFY_10 0x2f +#define GPCMD_READ_SUBCHANNEL 0x42 +#define GPCMD_READ_TOC_PMA_ATIP 0x43 +#define GPCMD_READ_HEADER 0x44 +#define GPCMD_PLAY_AUDIO_10 0x45 +#define GPCMD_GET_CONFIGURATION 0x46 +#define GPCMD_PLAY_AUDIO_MSF 0x47 +#define GPCMD_PLAY_AUDIO_TRACK_INDEX 0x48 +#define GPCMD_GET_EVENT_STATUS_NOTIFICATION 0x4a +#define GPCMD_PAUSE_RESUME 0x4b +#define GPCMD_STOP_PLAY_SCAN 0x4e +#define GPCMD_READ_DISC_INFORMATION 0x51 #define GPCMD_READ_TRACK_INFORMATION 0x52 -#define GPCMD_MODE_SELECT_10 0x55 -#define GPCMD_MODE_SENSE_10 0x5a -#define GPCMD_PLAY_AUDIO_12 0xa5 -#define GPCMD_READ_12 0xa8 -#define GPCMD_WRITE_12 0xaa -#define GPCMD_READ_DVD_STRUCTURE 0xad /* For reading. */ -#define GPCMD_VERIFY_12 0xaf -#define GPCMD_PLAY_CD_OLD 0xb4 -#define GPCMD_READ_CD_OLD 0xb8 -#define GPCMD_READ_CD_MSF 0xb9 -#define GPCMD_SCAN 0xba -#define GPCMD_SET_SPEED 0xbb -#define GPCMD_PLAY_CD 0xbc -#define GPCMD_MECHANISM_STATUS 0xbd -#define GPCMD_READ_CD 0xbe -#define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to PCem. */ -#define GPCMD_PAUSE_RESUME_ALT 0xc2 -#define GPCMD_SCAN_ALT 0xcd /* Should be equivalent to 0xba */ -#define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */ +#define GPCMD_MODE_SELECT_10 0x55 +#define GPCMD_MODE_SENSE_10 0x5a +#define GPCMD_PLAY_AUDIO_12 0xa5 +#define GPCMD_READ_12 0xa8 +#define GPCMD_WRITE_12 0xaa +#define GPCMD_READ_DVD_STRUCTURE 0xad /* For reading. */ +#define GPCMD_VERIFY_12 0xaf +#define GPCMD_PLAY_CD_OLD 0xb4 +#define GPCMD_READ_CD_OLD 0xb8 +#define GPCMD_READ_CD_MSF 0xb9 +#define GPCMD_SCAN 0xba +#define GPCMD_SET_SPEED 0xbb +#define GPCMD_PLAY_CD 0xbc +#define GPCMD_MECHANISM_STATUS 0xbd +#define GPCMD_READ_CD 0xbe +#define GPCMD_SEND_DVD_STRUCTURE 0xbf /* This is for writing only, irrelevant to PCem. */ +#define GPCMD_PAUSE_RESUME_ALT 0xc2 +#define GPCMD_SCAN_ALT 0xcd /* Should be equivalent to 0xba */ +#define GPCMD_SET_SPEED_ALT 0xda /* Should be equivalent to 0xbb */ /* Mode page codes for mode sense/set */ -#define GPMODE_R_W_ERROR_PAGE 0x01 -#define GPMODE_CDROM_PAGE 0x0d -#define GPMODE_CDROM_AUDIO_PAGE 0x0e -#define GPMODE_CAPABILITIES_PAGE 0x2a -#define GPMODE_ALL_PAGES 0x3f +#define GPMODE_R_W_ERROR_PAGE 0x01 +#define GPMODE_CDROM_PAGE 0x0d +#define GPMODE_CDROM_AUDIO_PAGE 0x0e +#define GPMODE_CAPABILITIES_PAGE 0x2a +#define GPMODE_ALL_PAGES 0x3f /* SCSI Status Codes */ -#define SCSI_STATUS_OK 0 +#define SCSI_STATUS_OK 0 #define SCSI_STATUS_CHECK_CONDITION 2 /* SCSI Sense Keys */ -#define SENSE_NONE 0 -#define SENSE_NOT_READY 2 -#define SENSE_ILLEGAL_REQUEST 5 -#define SENSE_UNIT_ATTENTION 6 +#define SENSE_NONE 0 +#define SENSE_NOT_READY 2 +#define SENSE_ILLEGAL_REQUEST 5 +#define SENSE_UNIT_ATTENTION 6 /* SCSI Additional Sense Codes */ #define ASC_AUDIO_PLAY_OPERATION 0x00 @@ -193,45 +198,43 @@ #define CHECK_READY 2 #define ALLOW_UA 1 -extern uint8_t SCSICommandTable[0x100]; -extern uint8_t mode_sense_pages[0x40]; - -extern int readcdmode; +extern uint8_t SCSICommandTable[0x100]; +extern uint8_t mode_sense_pages[0x40]; +extern int readcdmode; /* Mode sense/select stuff. */ -extern uint8_t mode_pages_in[256][256]; +extern uint8_t mode_pages_in[256][256]; +extern uint8_t page_flags[256]; +extern uint8_t prefix_len; +extern uint8_t page_current; #define PAGE_CHANGEABLE 1 #define PAGE_CHANGED 2 -extern uint8_t page_flags[256]; -extern uint8_t prefix_len; -extern uint8_t page_current; -extern uint32_t DataLength; -extern uint32_t DataPointer; +extern uint32_t DataLength; +extern uint32_t DataPointer; -extern int SectorLBA; -extern int SectorLen; +extern int SectorLBA; +extern int SectorLen; -extern int MediaPresent; +extern int MediaPresent; -extern uint8_t SCSIStatus; -extern uint8_t SCSIPhase; -extern uint8_t scsi_cdrom_id; +extern uint8_t SCSIStatus; +extern uint8_t SCSIPhase; +extern uint8_t scsi_cdrom_id; -struct -{ - uint8_t SenseBuffer[18]; - uint8_t SenseLength; - uint8_t UnitAttention; - uint8_t SenseKey; - uint8_t Asc; - uint8_t Ascq; +struct { + uint8_t SenseBuffer[18]; + uint8_t SenseLength; + uint8_t UnitAttention; + uint8_t SenseKey; + uint8_t Asc; + uint8_t Ascq; } SCSISense; -extern int cd_status; -extern int prev_status; +extern int cd_status; +extern int prev_status; #define SCSI_NONE 0 #define SCSI_DISK 1 @@ -248,13 +251,16 @@ extern int prev_status; #define SCSI_PHASE_BUS_FREE ( 8 ) #define SCSI_PHASE_SELECT ( 9 ) -struct -{ - uint8_t *CmdBuffer; - uint32_t CmdBufferLength; - int LunType; - uint32_t InitLength; -} SCSIDevices[16][8]; + +typedef struct { + uint8_t *CmdBuffer; + uint32_t CmdBufferLength; + int LunType; + uint32_t InitLength; +} scsi_device_t; + + +extern scsi_device_t SCSIDevices[SCSI_ID_MAX][SCSI_LUN_MAX]; extern void SCSIReset(uint8_t id, uint8_t lun); diff --git a/src/scsi/scsi_aha154x.c b/src/scsi/scsi_aha154x.c index d3efa96b0..b03fd108e 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/26 + * Version: @(#)scsi_aha154x.c 1.0.14 2017/08/27 * * Authors: Fred N. van Kempen, * Original Buslogic version by SA1988 and Miran Grca. @@ -150,16 +150,6 @@ enum { }; -/* The local RAM. */ -#pragma pack(push,1) -typedef union { - uint8_t u8View[256]; /* byte view */ - struct { /* structured view */ - uint8_t u8Bios[64]; /* offset 0 - 63 is for BIOS */ - } structured; -} HALocalRAM; -#pragma pack(pop) - /* Structure for the INQUIRE_SETUP_INFORMATION reply. */ #pragma pack(push,1) typedef struct { @@ -383,11 +373,10 @@ typedef struct { int8_t Irq; int8_t DmaChannel; - int8_t IrqEnabled; + int8_t HostID; uint32_t Base; uint8_t pos_regs[8]; /* MCA */ - uint8_t flags; /* local flags */ uint8_t bid; /* board ID */ char fwl, fwh; /* firmware info */ @@ -398,14 +387,19 @@ typedef struct { uint16_t rom_shramsz; /* size of shared RAM */ uint16_t rom_fwhigh; /* offset in BIOS of ver ID */ rom_t bios; /* BIOS memory descriptor */ + uint8_t *rom1; /* main BIOS image */ + uint8_t *rom2; /* SCSI-Select image */ wchar_t *nvr_path; /* path to NVR image file */ uint8_t *nvr; /* EEPROM buffer */ - int UseLocalRAM; + int Callback; + int InOperation; + int ResetCB; + + int8_t IrqEnabled; int StrictRoundRobinMode; int ExtendedLUNCCBFormat; - HALocalRAM LocalRAM; Req_t Req; uint8_t Status; uint8_t Interrupt; @@ -432,41 +426,30 @@ typedef struct { #pragma pack(pop) -static int ResetCB = 0; -static int AHA_Callback = 0; -static int AHA_InOperation = 0; -static aha_t *ResetDev; -static rom_t aha_bios; /* active ROM */ -static uint8_t *aha_rom1; /* main BIOS */ -static uint8_t *aha_rom2; /* SCSI-Select */ static uint16_t aha_ports[] = { 0x0330, 0x0334, 0x0230, 0x0234, 0x0130, 0x0134, 0x0000, 0x0000 }; -#ifdef WALTJE -int aha_do_log = 1; -# define ENABLE_AHA154X_LOG -#else -int aha_do_log = 0; +#if ENABLE_AHA154X_LOG +int aha_do_log = ENABLE_AHA154X_LOG; #endif static void -aha_log(const char *format, ...) +aha_log(const char *fmt, ...) { -#ifdef ENABLE_AHA154X_LOG +#if ENABLE_AHA154X_LOG va_list ap; if (aha_do_log) { - va_start(ap, format); - vprintf(format, ap); + va_start(ap, fmt); + vprintf(fmt, ap); va_end(ap); fflush(stdout); } #endif } -#define pclog aha_log /* @@ -524,15 +507,15 @@ aha154x_shram(aha_t *dev, uint8_t cmd) switch(cmd) { case 0x00: /* disable, make it look like ROM */ - memset(&aha_bios.rom[dev->rom_shram], 0xFF, dev->rom_shramsz); + memset(&dev->bios.rom[dev->rom_shram], 0xFF, dev->rom_shramsz); break; case 0x02: /* clear it */ - memset(&aha_bios.rom[dev->rom_shram], 0x00, dev->rom_shramsz); + memset(&dev->bios.rom[dev->rom_shram], 0x00, dev->rom_shramsz); break; case 0x03: /* enable, clear for use */ - memset(&aha_bios.rom[dev->rom_shram], 0x00, dev->rom_shramsz); + memset(&dev->bios.rom[dev->rom_shram], 0x00, dev->rom_shramsz); break; } @@ -546,7 +529,7 @@ aha154x_eeprom(aha_t *dev, uint8_t cmd,uint8_t arg,uint8_t len,uint8_t off,uint8 { uint8_t r = 0xff; - pclog("%s: EEPROM cmd=%02x, arg=%02x len=%d, off=%02x\n", + aha_log("%s: EEPROM cmd=%02x, arg=%02x len=%d, off=%02x\n", dev->name, cmd, arg, len, off); /* Only if we can handle it.. */ @@ -572,19 +555,19 @@ aha154x_eeprom(aha_t *dev, uint8_t cmd,uint8_t arg,uint8_t len,uint8_t off,uint8 /* Mess with the AHA-154xCF's Shadow RAM. */ static uint8_t -aha154x_memory(aha_t *dev, uint8_t cmd) +aha154x_mmap(aha_t *dev, uint8_t cmd) { - pclog("%s: MEMORY cmd=%02x\n", dev->name, cmd); + aha_log("%s: MEMORY cmd=%02x\n", dev->name, cmd); switch(cmd) { case 0x26: /* Disable the mapper, so, set ROM1 active. */ - aha_bios.rom = aha_rom1; + dev->bios.rom = dev->rom1; break; case 0x27: /* Enable the mapper, so, set ROM2 active. */ - aha_bios.rom = aha_rom2; + dev->bios.rom = dev->rom2; break; } @@ -596,12 +579,12 @@ static void ClearIntr(aha_t *dev) { dev->Interrupt = 0; - pclog("%s: lowering IRQ %i (stat 0x%02x)\n", + aha_log("%s: lowering IRQ %i (stat 0x%02x)\n", dev->name, dev->Irq, dev->Interrupt); picintc(1 << dev->Irq); if (dev->PendingInterrupt) { dev->Interrupt = dev->PendingInterrupt; - pclog("%s: Raising Interrupt 0x%02X (Pending)\n", + 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); @@ -615,11 +598,11 @@ static void RaiseIntr(aha_t *dev, uint8_t Interrupt) { if (dev->Interrupt & INTR_HACC) { - pclog("%s: Pending IRQ\n", dev->name); + aha_log("%s: Pending IRQ\n", dev->name); dev->PendingInterrupt = Interrupt; } else { dev->Interrupt = Interrupt; - pclog("%s: Raising IRQ %i\n", dev->name, dev->Irq); + aha_log("%s: Raising IRQ %i\n", dev->name, dev->Irq); if (dev->IrqEnabled) picint(1 << dev->Irq); } @@ -629,8 +612,9 @@ RaiseIntr(aha_t *dev, uint8_t Interrupt) static void aha_reset(aha_t *dev) { - AHA_Callback = 0; - ResetCB = 0; + dev->ResetCB = 0; + dev->Callback = 0; + dev->Status = STAT_IDLE | STAT_INIT; dev->Geometry = 0x80; dev->Command = 0xFF; @@ -644,7 +628,7 @@ aha_reset(aha_t *dev) dev->MailboxOutInterrupts = 0; dev->PendingInterrupt = 0; dev->Lock = 0; - AHA_InOperation = 0; + dev->InOperation = 0; ClearIntr(dev); } @@ -653,16 +637,32 @@ aha_reset(aha_t *dev) static void aha_reset_ctrl(aha_t *dev, uint8_t Reset) { + /* Only if configured.. */ + if (dev->Base == 0x0000) return; + /* Say hello! */ - pclog("Adaptec %s (IO=0x%04X, IRQ=%d, DMA=%d) BIOS @ %06lX\n", - dev->name, dev->Base, dev->Irq, dev->DmaChannel, dev->rom_addr); + pclog("Adaptec %s (IO=0x%04X, IRQ=%d, DMA=%d, BIOS @%05lX) ID=%d\n", + dev->name, dev->Base, dev->Irq, dev->DmaChannel, + dev->rom_addr, dev->HostID); aha_reset(dev); if (Reset) { dev->Status |= STAT_STST; dev->Status &= ~STAT_IDLE; } - ResetCB = AHA_RESET_DURATION_US * TIMER_USEC; + dev->ResetCB = AHA_RESET_DURATION_US * TIMER_USEC; +} + + +static void +aha_reset_poll(void *priv) +{ + aha_t *dev = (aha_t *)priv; + + dev->Status &= ~STAT_STST; + dev->Status |= STAT_IDLE; + + dev->ResetCB = 0; } @@ -671,16 +671,16 @@ aha_cmd_done(aha_t *dev) { 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); - pclog("%s: Raising IRQ %i\n", dev->name, dev->Irq); + aha_log("%s: Raising IRQ %i\n", dev->name, dev->Irq); if (dev->IrqEnabled) picint(1 << dev->Irq); } - dev->Command = 0xFF; + dev->Command = 0xff; dev->CmdParam = 0; } @@ -698,9 +698,9 @@ aha_mbi_setup(aha_t *dev, uint32_t CCBPointer, CCBU *CmdBlock, req->TargetStatus = TargetStatus; req->MailboxCompletionCode = mbcc; - pclog("Mailbox in setup\n"); + aha_log("Mailbox in setup\n"); - AHA_InOperation = 2; + dev->InOperation = 2; } @@ -729,26 +729,26 @@ aha_mbi(aha_t *dev) CmdBlock->common.TargetStatus = TargetStatus; /* Rewrite the CCB up to the CDB. */ - pclog("CCB rewritten to the CDB (pointer %08X)\n", CCBPointer); + aha_log("CCB rewritten to the CDB (pointer %08X)\n", CCBPointer); DMAPageWrite(CCBPointer, (char *)CmdBlock, 18); } else { - pclog("Mailbox not found!\n"); + aha_log("Mailbox not found!\n"); } - pclog("Host Status 0x%02X, Target Status 0x%02X\n",HostStatus,TargetStatus); + aha_log("Host Status 0x%02X, Target Status 0x%02X\n",HostStatus,TargetStatus); if (dev->Mbx24bit) { MailboxIn.CmdStatus = Mailbox32.u.in.CompletionCode; U32_TO_ADDR(MailboxIn.CCBPointer, Mailbox32.CCBPointer); - pclog("Mailbox 24-bit: Status=0x%02X, CCB at 0x%04X\n", MailboxIn.CmdStatus, ADDR_TO_U32(MailboxIn.CCBPointer)); + aha_log("Mailbox 24-bit: Status=0x%02X, CCB at 0x%04X\n", MailboxIn.CmdStatus, ADDR_TO_U32(MailboxIn.CCBPointer)); DMAPageWrite(Incoming, (char *)&MailboxIn, sizeof(Mailbox_t)); - pclog("%i bytes of 24-bit mailbox written to: %08X\n", sizeof(Mailbox_t), Incoming); + aha_log("%i bytes of 24-bit mailbox written to: %08X\n", sizeof(Mailbox_t), Incoming); } else { - pclog("Mailbox 32-bit: Status=0x%02X, CCB at 0x%04X\n", Mailbox32.u.in.CompletionCode, Mailbox32.CCBPointer); + aha_log("Mailbox 32-bit: Status=0x%02X, CCB at 0x%04X\n", Mailbox32.u.in.CompletionCode, Mailbox32.CCBPointer); DMAPageWrite(Incoming, (char *)&Mailbox32, sizeof(Mailbox32_t)); - pclog("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming); + aha_log("%i bytes of 32-bit mailbox written to: %08X\n", sizeof(Mailbox32_t), Incoming); } dev->MailboxInPosCur++; @@ -757,7 +757,7 @@ aha_mbi(aha_t *dev) RaiseIntr(dev, INTR_MBIF | INTR_ANY); - AHA_InOperation = 0; + dev->InOperation = 0; } @@ -796,11 +796,10 @@ aha_buf_alloc(Req_t *req, int Is24bit) DataPointer = req->CmdBlock.new.DataPointer; DataLength = req->CmdBlock.new.DataLength; } - pclog("Data Buffer write: length %d, pointer 0x%04X\n", + aha_log("Data Buffer write: length %d, pointer 0x%04X\n", DataLength, DataPointer); - if (SCSIDevices[req->TargetID][req->LUN].CmdBuffer != NULL) - { + if (SCSIDevices[req->TargetID][req->LUN].CmdBuffer != NULL) { free(SCSIDevices[req->TargetID][req->LUN].CmdBuffer); SCSIDevices[req->TargetID][req->LUN].CmdBuffer = NULL; } @@ -821,23 +820,23 @@ aha_buf_alloc(Req_t *req, int Is24bit) aha_rd_sge(Is24bit, SGAddrCurrent, SGRead, SGBuffer); - for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { - pclog("S/G Write: ScatterEntry=%u\n", ScatterEntry); + for (ScatterEntry=0; ScatterEntry 0); - pclog("Data to transfer (S/G) %d\n", DataToTransfer); + aha_log("Data to transfer (S/G) %d\n", DataToTransfer); SCSIDevices[req->TargetID][req->LUN].InitLength = DataToTransfer; - pclog("Allocating buffer for Scatter/Gather (%i bytes)\n", DataToTransfer); + aha_log("Allocating buffer for Scatter/Gather (%i bytes)\n", DataToTransfer); SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataToTransfer); memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataToTransfer); @@ -855,13 +854,13 @@ aha_buf_alloc(Req_t *req, int Is24bit) aha_rd_sge(Is24bit, SGAddrCurrent, SGRead, SGBuffer); - for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { - pclog("S/G Write: ScatterEntry=%u\n", ScatterEntry); + for (ScatterEntry=0; ScatterEntryTargetID][req->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer); sg_buffer_pos += DataToTransfer; @@ -876,7 +875,7 @@ aha_buf_alloc(Req_t *req, int Is24bit) SCSIDevices[req->TargetID][req->LUN].InitLength = DataLength; - pclog("Allocating buffer for direct transfer (%i bytes)\n", DataLength); + aha_log("Allocating buffer for direct transfer (%i bytes)\n", DataLength); SCSIDevices[req->TargetID][req->LUN].CmdBuffer = (uint8_t *) malloc(DataLength); memset(SCSIDevices[req->TargetID][req->LUN].CmdBuffer, 0, DataLength); @@ -915,7 +914,7 @@ aha_buf_free(Req_t *req) } if ((DataLength != 0) && (req->CmdBlock.common.Cdb[0] == GPCMD_TEST_UNIT_READY)) { - pclog("Data length not 0 with TEST UNIT READY: %i (%i)\n", + aha_log("Data length not 0 with TEST UNIT READY: %i (%i)\n", DataLength, SCSIDevices[req->TargetID][req->LUN].InitLength); } @@ -923,7 +922,7 @@ aha_buf_free(Req_t *req) DataLength = 0; } - pclog("Data Buffer read: length %d, pointer 0x%04X\n", + aha_log("Data Buffer read: length %d, pointer 0x%04X\n", DataLength, DataPointer); /* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without @@ -944,13 +943,13 @@ aha_buf_free(Req_t *req) aha_rd_sge(req->Is24bit, SGAddrCurrent, SGRead, SGBuffer); - for (ScatterEntry = 0; ScatterEntry < SGRead; ScatterEntry++) { - pclog("S/G: ScatterEntry=%u\n", ScatterEntry); + for (ScatterEntry=0; ScatterEntryTargetID][req->LUN].CmdBuffer + sg_buffer_pos, DataToTransfer); sg_buffer_pos += DataToTransfer; @@ -962,8 +961,8 @@ aha_buf_free(Req_t *req) req->CmdBlock.common.Opcode == SCSI_INITIATOR_COMMAND_RES) { Address = DataPointer; - pclog("DMA: Writing %i bytes at %08X\n", - DataLength, Address); + aha_log("DMA: Writing %i bytes at %08X\n", + DataLength, Address); DMAPageWrite(Address, (char *)SCSIDevices[req->TargetID][req->LUN].CmdBuffer, DataLength); } } @@ -980,23 +979,299 @@ aha_buf_free(Req_t *req) if (req->Is24bit) { U32_TO_ADDR(req->CmdBlock.old.DataLength, Residual); - pclog("24-bit Residual data length for reading: %d\n", + aha_log("24-bit Residual data length for reading: %d\n", ADDR_TO_U32(req->CmdBlock.old.DataLength)); } else { req->CmdBlock.new.DataLength = Residual; - pclog("32-bit Residual data length for reading: %d\n", + aha_log("32-bit Residual data length for reading: %d\n", req->CmdBlock.new.DataLength); } } - if (SCSIDevices[req->TargetID][req->LUN].CmdBuffer != NULL) - { + if (SCSIDevices[req->TargetID][req->LUN].CmdBuffer != NULL) { free(SCSIDevices[req->TargetID][req->LUN].CmdBuffer); SCSIDevices[req->TargetID][req->LUN].CmdBuffer = NULL; } } +static uint8_t +ConvertSenseLength(uint8_t RequestSenseLength) +{ + aha_log("Unconverted Request Sense length %i\n", RequestSenseLength); + + if (RequestSenseLength == 0) + RequestSenseLength = 14; + else if (RequestSenseLength == 1) + RequestSenseLength = 0; + + aha_log("Request Sense length %i\n", RequestSenseLength); + + return(RequestSenseLength); +} + + +static void +SenseBufferFree(Req_t *req, int Copy) +{ + uint8_t SenseLength = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength); + uint32_t SenseBufferAddress; + uint8_t temp_sense[256]; + + if (SenseLength && Copy) { + scsi_device_request_sense(req->TargetID, req->LUN, temp_sense, SenseLength); + + /* + * The sense address, in 32-bit mode, is located in the + * Sense Pointer of the CCB, but in 24-bit mode, it is + * located at the end of the Command Descriptor Block. + */ + if (req->Is24bit) { + SenseBufferAddress = req->CCBPointer; + SenseBufferAddress += req->CmdBlock.common.CdbLength + 18; + } else { + SenseBufferAddress = req->CmdBlock.new.SensePointer; + } + + aha_log("Request Sense address: %02X\n", SenseBufferAddress); + + aha_log("SenseBufferFree(): Writing %i bytes at %08X\n", + SenseLength, SenseBufferAddress); + DMAPageWrite(SenseBufferAddress, (char *)temp_sense, SenseLength); + aha_log("Sense data written to buffer: %02X %02X %02X\n", + temp_sense[2], temp_sense[12], temp_sense[13]); + } +} + + +static void +aha_scsi_cmd(aha_t *dev) +{ + Req_t *req = &dev->Req; + uint8_t id, lun; + uint8_t temp_cdb[12]; + uint32_t i; + int target_cdb_len = 12; + + id = req->TargetID; + lun = req->LUN; + + target_cdb_len = scsi_device_cdb_length(id, lun); + + if (!scsi_device_valid(id, lun)) + fatal("SCSI target on %02i:%02i has disappeared\n", id, lun); + + aha_log("SCSI command being executed on ID %i, LUN %i\n", id, lun); + + aha_log("SCSI CDB[0]=0x%02X\n", req->CmdBlock.common.Cdb[0]); + for (i=1; iCmdBlock.common.CdbLength; i++) + aha_log("SCSI CDB[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]); + + memset(temp_cdb, 0x00, target_cdb_len); + if (req->CmdBlock.common.CdbLength <= target_cdb_len) { + memcpy(temp_cdb, req->CmdBlock.common.Cdb, + req->CmdBlock.common.CdbLength); + } else { + memcpy(temp_cdb, req->CmdBlock.common.Cdb, target_cdb_len); + } + + scsi_device_command(id, lun, req->CmdBlock.common.CdbLength, temp_cdb); + + aha_buf_free(req); + + SenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK)); + + aha_log("Request complete\n"); + + if (SCSIStatus == SCSI_STATUS_OK) { + aha_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); + } else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) { + aha_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, + CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); + } +} + + +static void +aha_req_setup(aha_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) +{ + Req_t *req = &dev->Req; + uint8_t id, lun; + uint8_t max_id = SCSI_ID_MAX-1; + + /* Fetch data from the Command Control Block. */ + DMAPageRead(CCBPointer, (char *)&req->CmdBlock, sizeof(CCB32)); + + req->Is24bit = dev->Mbx24bit; + req->CCBPointer = CCBPointer; + req->TargetID = dev->Mbx24bit ? req->CmdBlock.old.Id : req->CmdBlock.new.Id; + req->LUN = dev->Mbx24bit ? req->CmdBlock.old.Lun : req->CmdBlock.new.Lun; + + id = req->TargetID; + lun = req->LUN; + if ((id > max_id) || (lun > 7)) { + aha_mbi_setup(dev, CCBPointer, &req->CmdBlock, + CCB_INVALID_CCB, SCSI_STATUS_OK, MBI_ERROR); + return; + } + + aha_log("Scanning SCSI Target ID %i\n", id); + + SCSIStatus = SCSI_STATUS_OK; + SCSIDevices[id][lun].InitLength = 0; + + aha_buf_alloc(req, req->Is24bit); + + if (! scsi_device_present(id, lun)) { + aha_log("SCSI Target ID %i and LUN %i have no device attached\n",id,lun); + aha_buf_free(req); + SenseBufferFree(req, 0); + aha_mbi_setup(dev, CCBPointer, &req->CmdBlock, + CCB_SELECTION_TIMEOUT,SCSI_STATUS_OK,MBI_ERROR); + } else { + aha_log("SCSI Target ID %i and LUN %i detected and working\n", id, lun); + + aha_log("Transfer Control %02X\n", req->CmdBlock.common.ControlByte); + aha_log("CDB Length %i\n", req->CmdBlock.common.CdbLength); + aha_log("CCB Opcode %x\n", req->CmdBlock.common.Opcode); + if (req->CmdBlock.common.ControlByte > 0x03) { + aha_log("Invalid control byte: %02X\n", + req->CmdBlock.common.ControlByte); + } + + dev->InOperation = 1; + } +} + + +static void +aha_req_abort(aha_t *dev, uint32_t CCBPointer) +{ + CCBU CmdBlock; + + /* Fetch data from the Command Control Block. */ + DMAPageRead(CCBPointer, (char *)&CmdBlock, sizeof(CCB32)); + + aha_mbi_setup(dev, CCBPointer, &CmdBlock, + 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND); +} + + +static uint32_t +aha_mbo(aha_t *dev, Mailbox32_t *Mailbox32) +{ + Mailbox_t MailboxOut; + uint32_t Outgoing; + + if (dev->Mbx24bit) { + Outgoing = dev->MailboxOutAddr + (dev->MailboxOutPosCur * sizeof(Mailbox_t)); + DMAPageRead(Outgoing, (char *)&MailboxOut, sizeof(Mailbox_t)); + + Mailbox32->CCBPointer = ADDR_TO_U32(MailboxOut.CCBPointer); + Mailbox32->u.out.ActionCode = MailboxOut.CmdStatus; + } else { + Outgoing = dev->MailboxOutAddr + (dev->MailboxOutPosCur * sizeof(Mailbox32_t)); + + DMAPageRead(Outgoing, (char *)Mailbox32, sizeof(Mailbox32_t)); + } + + return(Outgoing); +} + + +static void +aha_mbo_adv(aha_t *dev) +{ + dev->MailboxOutPosCur = (dev->MailboxOutPosCur + 1) % dev->MailboxCount; +} + + +static void +aha_do_mail(aha_t *dev) +{ + Mailbox32_t mb32; + uint32_t Outgoing; + uint8_t CmdStatus = MBO_FREE; + uint32_t CodeOffset = 0; + + 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 (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)); + } + + if (dev->MailboxOutInterrupts) + RaiseIntr(dev, INTR_MBOA | INTR_ANY); + + /* Check if the mailbox is actually loaded. */ + if (mb32.u.out.ActionCode == MBO_FREE) return; + + if (mb32.u.out.ActionCode == MBO_START) { + aha_log("Start Mailbox Command\n"); + aha_req_setup(dev, mb32.CCBPointer, &mb32); + } else if (mb32.u.out.ActionCode == MBO_ABORT) { + aha_log("Abort Mailbox Command\n"); + aha_req_abort(dev, mb32.CCBPointer); + } else { + aha_log("Invalid action code: %02X\n", mb32.u.out.ActionCode); + } + + /* Advance to the next mailbox. */ + if (dev->StrictRoundRobinMode) + aha_mbo_adv(dev); +} + + +static void +aha_cmd_cb(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); + } + + dev->Callback += SCSI_DELAY_TM * TIMER_USEC; +} + + static uint8_t aha_read(uint16_t port, void *priv) { @@ -1029,10 +1304,8 @@ aha_read(uint16_t port, void *priv) } #ifndef WALTJE - if (port < 0x1000) { - pclog("%s: Read Port 0x%02X, Returned Value %02X\n", + aha_log("%s: Read Port 0x%02X, Returned Value %02X\n", dev->name, port, ret); - } #endif return(ret); @@ -1049,21 +1322,21 @@ aha_readw(uint16_t port, void *priv) static void aha_write(uint16_t port, uint8_t val, void *priv) { + ReplyInquireSetupInformation *ReplyISI; + aha_t *dev = (aha_t *)priv; + MailboxInit_t *mbi; int i = 0; uint8_t j = 0; - aha_t *dev = (aha_t *)priv; - MailboxInit_t *MailboxInit; - BIOSCMD *BiosCmd; - ReplyInquireSetupInformation *ReplyISI; + BIOSCMD *cmd; uint16_t cyl = 0; - pclog("%s: Write Port 0x%02X, Value %02X\n", dev->name, port, val); + aha_log("%s: Write Port 0x%02X, Value %02X\n", dev->name, port, val); switch (port & 3) { case 0: if ((val & CTRL_HRST) || (val & CTRL_SRST)) { uint8_t Reset = (val & CTRL_HRST); - pclog("Reset completed = %x\n", Reset); + aha_log("Reset completed = %x\n", Reset); aha_reset_ctrl(dev, Reset); break; } @@ -1076,23 +1349,23 @@ aha_write(uint16_t port, uint8_t val, void *priv) case 1: /* Fast path for the mailbox execution command. */ if (((val == CMD_START_SCSI) || (val == CMD_BIOS_SCSI)) && - (dev->Command == 0xFF)) { + (dev->Command == 0xff)) { /* If there are no mailboxes configured, don't even try to do anything. */ if (dev->MailboxCount) { - if (!AHA_Callback) { - AHA_Callback = SCSI_DELAY_TM * TIMER_USEC; + if (! dev->Callback) { + dev->Callback = SCSI_DELAY_TM * TIMER_USEC; } } return; } - if (dev->Command == 0xFF) { + if (dev->Command == 0xff) { dev->Command = val; dev->CmdParam = 0; dev->CmdParamLeft = 0; dev->Status &= ~(STAT_INVCMD | STAT_IDLE); - pclog("%s: Operation Code 0x%02X\n", dev->name, val); + aha_log("%s: Operation Code 0x%02X\n", dev->name, val); switch (dev->Command) { case CMD_MBINIT: dev->CmdParamLeft = sizeof(MailboxInit_t); @@ -1141,69 +1414,71 @@ aha_write(uint16_t port, uint8_t val, void *priv) } if (! dev->CmdParamLeft) { - pclog("Running Operation Code 0x%02X\n", dev->Command); + aha_log("Running Operation Code 0x%02X\n", dev->Command); switch (dev->Command) { - case CMD_NOP: /* No Operation Command */ + case CMD_NOP: /* No Operation */ dev->DataReplyLeft = 0; break; - case CMD_MBINIT: /* Mailbox Initialitation */ + case CMD_MBINIT: /* mailbox initialization */ aha_0x01: { dev->Mbx24bit = 1; - MailboxInit = (MailboxInit_t *)dev->CmdBuf; + mbi = (MailboxInit_t *)dev->CmdBuf; - dev->MailboxCount = MailboxInit->Count; - dev->MailboxOutAddr = ADDR_TO_U32(MailboxInit->Address); + dev->MailboxCount = mbi->Count; + dev->MailboxOutAddr = ADDR_TO_U32(mbi->Address); dev->MailboxInAddr = dev->MailboxOutAddr + (dev->MailboxCount * sizeof(Mailbox_t)); - pclog("Initialize Mailbox: MBI=0x%08lx, MBO=0x%08lx, %d entries at 0x%08lx\n", + aha_log("Initialize Mailbox: MBI=0x%08lx, MBO=0x%08lx, %d entries at 0x%08lx\n", dev->MailboxOutAddr, dev->MailboxInAddr, - MailboxInit->Count, - ADDR_TO_U32(MailboxInit->Address)); + mbi->Count, + ADDR_TO_U32(mbi->Address)); dev->Status &= ~STAT_INIT; dev->DataReplyLeft = 0; } break; - case CMD_BIOSCMD: /* Execute BIOS Command */ - BiosCmd = (BIOSCMD *)dev->CmdBuf; + case CMD_BIOSCMD: /* execute BIOS */ + cmd = (BIOSCMD *)dev->CmdBuf; if (dev->type != AHA_1640) { - cyl = ((BiosCmd->u.chs.cyl & 0xff) << 8) | ((BiosCmd->u.chs.cyl >> 8) & 0xff); - BiosCmd->u.chs.cyl = cyl; + /* 1640 uses LBA. */ + cyl = ((cmd->u.chs.cyl & 0xff) << 8) | ((cmd->u.chs.cyl >> 8) & 0xff); + cmd->u.chs.cyl = cyl; } if (dev->type == AHA_1640) { - pclog("BIOS LBA=%06lx (%lu)\n", - lba32_blk(BiosCmd), - lba32_blk(BiosCmd)); + /* 1640 uses LBA. */ + aha_log("BIOS LBA=%06lx (%lu)\n", + lba32_blk(cmd), + lba32_blk(cmd)); } else { - BiosCmd->u.chs.head &= 0xf; - BiosCmd->u.chs.sec &= 0x1f; - pclog("BIOS CHS=%04X/%02X%02X\n", - BiosCmd->u.chs.cyl, - BiosCmd->u.chs.head, - BiosCmd->u.chs.sec); + cmd->u.chs.head &= 0xf; + cmd->u.chs.sec &= 0x1f; + aha_log("BIOS CHS=%04X/%02X%02X\n", + cmd->u.chs.cyl, + cmd->u.chs.head, + cmd->u.chs.sec); } - dev->DataBuf[0] = scsi_bios_command(7, BiosCmd, (dev->type==AHA_1640)?1:0); - pclog("BIOS Completion/Status Code %x\n", dev->DataBuf[0]); + dev->DataBuf[0] = scsi_bios_command(7, cmd, (dev->type==AHA_1640)?1:0); + aha_log("BIOS Completion/Status Code %x\n", dev->DataBuf[0]); dev->DataReplyLeft = 1; break; - case CMD_INQUIRY: /* Inquiry Command */ - dev->DataBuf[0] = (dev->type != AHA_1640) ? dev->bid : 0x42; + case CMD_INQUIRY: /* Inquiry */ + dev->DataBuf[0] = dev->bid; dev->DataBuf[1] = (dev->type != AHA_1640) ? 0x30 : 0x42; dev->DataBuf[2] = dev->fwh; dev->DataBuf[3] = dev->fwl; dev->DataReplyLeft = 4; break; - case CMD_EMBOI: /* Enable Mailbox Out Interrupt */ + case CMD_EMBOI: /* enable MBO Interrupt */ if (dev->CmdBuf[0] <= 1) { dev->MailboxOutInterrupts = dev->CmdBuf[0]; - pclog("Mailbox out interrupts: %s\n", dev->MailboxOutInterrupts ? "ON" : "OFF"); + aha_log("Mailbox out interrupts: %s\n", dev->MailboxOutInterrupts ? "ON" : "OFF"); } else { dev->Status |= STAT_INVCMD; } @@ -1214,45 +1489,48 @@ aha_0x01: dev->DataReplyLeft = 0; break; - case CMD_BUSON_TIME: /* Bus-on time */ + case CMD_BUSON_TIME: /* bus-on time */ dev->DataReplyLeft = 0; - pclog("Bus-on time: %d\n", dev->CmdBuf[0]); + aha_log("Bus-on time: %d\n", dev->CmdBuf[0]); break; - case CMD_BUSOFF_TIME: /* Bus-off time */ + case CMD_BUSOFF_TIME: /* bus-off time */ dev->DataReplyLeft = 0; - pclog("Bus-off time: %d\n", dev->CmdBuf[0]); + aha_log("Bus-off time: %d\n", dev->CmdBuf[0]); break; - case CMD_DMASPEED: /* DMA Transfer Rate Command */ + case CMD_DMASPEED: /* DMA Transfer Rate */ dev->DataReplyLeft = 0; - pclog("DMA transfer rate: %02X\n", dev->CmdBuf[0]); + aha_log("DMA transfer rate: %02X\n", dev->CmdBuf[0]); break; - case CMD_RETDEVS: /* Return Installed Devices */ + case CMD_RETDEVS: /* return Installed Devices */ memset(dev->DataBuf, 0x00, 8); - for (i=0; i<7; i++) { + for (i=0; iDataBuf[i] = 0x00; - for (j=0; j<8; j++) { + + /* Skip the HA .. */ + if (i == dev->HostID) continue; + + for (j=0; jDataBuf[i] |= (1<DataBuf[7] = 0x00; - dev->DataReplyLeft = 8; + dev->DataReplyLeft = i; break; - case CMD_RETCONF: /* Return Configuration Command */ + case CMD_RETCONF: /* return Configuration */ dev->DataBuf[0] = (1<DmaChannel); if (dev->Irq >= 8) dev->DataBuf[1]=(1<<(dev->Irq-9)); else dev->DataBuf[1]=(1<Irq); - dev->DataBuf[2] = 7; /* HOST ID */ + dev->DataBuf[2] = dev->HostID; dev->DataReplyLeft = 3; break; - case CMD_RETSETUP: /* Return Setup Command */ + case CMD_RETSETUP: /* return Setup */ { dev->DataReplyLeft = dev->CmdBuf[0]; @@ -1263,11 +1541,11 @@ aha_0x01: ReplyISI->fParityCheckingEnabled = 1; ReplyISI->cMailbox = dev->MailboxCount; U32_TO_ADDR(ReplyISI->MailboxAddress, dev->MailboxOutAddr); - pclog("Return Setup Information: %d\n", dev->CmdBuf[0]); + aha_log("Return Setup Information: %d\n", dev->CmdBuf[0]); } break; - case CMD_ECHO: /* ECHO data Command */ + case CMD_ECHO: /* ECHO data */ dev->DataBuf[0] = dev->CmdBuf[0]; dev->DataReplyLeft = 1; break; @@ -1319,7 +1597,7 @@ aha_0x01: dev->Interrupt = aha154x_shram(dev,val); break; - case CMD_BIOS_MBINIT: /* BIOS Mailbox Initialitation Command */ + case CMD_BIOS_MBINIT: /* BIOS Mailbox Initialization */ /* Sent by CF BIOS. */ goto aha_0x01; @@ -1327,7 +1605,7 @@ aha_0x01: case CMD_MEMORY_MAP_2: /* AHA memory mapper */ /* Sent by CF BIOS. */ dev->DataReplyLeft = - aha154x_memory(dev, dev->Command); + aha154x_mmap(dev, dev->Command); break; case CMD_EXTBIOS: /* Return extended BIOS information */ @@ -1389,297 +1667,6 @@ aha_writew(uint16_t Port, uint16_t Val, void *p) } -static uint8_t -ConvertSenseLength(uint8_t RequestSenseLength) -{ - pclog("Unconverted Request Sense length %i\n", RequestSenseLength); - - if (RequestSenseLength == 0) - RequestSenseLength = 14; - else if (RequestSenseLength == 1) - RequestSenseLength = 0; - - pclog("Request Sense length %i\n", RequestSenseLength); - - return(RequestSenseLength); -} - - -static void -SenseBufferFree(Req_t *req, int Copy) -{ - uint8_t SenseLength = ConvertSenseLength(req->CmdBlock.common.RequestSenseLength); - uint32_t SenseBufferAddress; - uint8_t temp_sense[256]; - - if (SenseLength && Copy) { - scsi_device_request_sense(req->TargetID, req->LUN, temp_sense, SenseLength); - - /* - * The sense address, in 32-bit mode, is located in the - * Sense Pointer of the CCB, but in 24-bit mode, it is - * located at the end of the Command Descriptor Block. - */ - if (req->Is24bit) { - SenseBufferAddress = req->CCBPointer; - SenseBufferAddress += req->CmdBlock.common.CdbLength + 18; - } else { - SenseBufferAddress = req->CmdBlock.new.SensePointer; - } - - pclog("Request Sense address: %02X\n", SenseBufferAddress); - - pclog("SenseBufferFree(): Writing %i bytes at %08X\n", - SenseLength, SenseBufferAddress); - DMAPageWrite(SenseBufferAddress, (char *)temp_sense, SenseLength); - pclog("Sense data written to buffer: %02X %02X %02X\n", - temp_sense[2], temp_sense[12], temp_sense[13]); - } -} - - -static void -aha_scsi_cmd(aha_t *dev) -{ - Req_t *req = &dev->Req; - uint8_t Id, Lun; - uint8_t temp_cdb[12]; - uint32_t i; - int target_cdb_len = 12; - - Id = req->TargetID; - Lun = req->LUN; - - target_cdb_len = scsi_device_cdb_length(Id, Lun); - - if (!scsi_device_valid(Id, Lun)) - fatal("SCSI target on %02i:%02i has disappeared\n", Id, Lun); - - pclog("SCSI command being executed on ID %i, LUN %i\n", Id, Lun); - - pclog("SCSI CDB[0]=0x%02X\n", req->CmdBlock.common.Cdb[0]); - for (i=1; iCmdBlock.common.CdbLength; i++) - pclog("SCSI CDB[%i]=%i\n", i, req->CmdBlock.common.Cdb[i]); - - memset(temp_cdb, 0x00, target_cdb_len); - if (req->CmdBlock.common.CdbLength <= target_cdb_len) { - memcpy(temp_cdb, req->CmdBlock.common.Cdb, - req->CmdBlock.common.CdbLength); - } else { - memcpy(temp_cdb, req->CmdBlock.common.Cdb, target_cdb_len); - } - - scsi_device_command(Id, Lun, req->CmdBlock.common.CdbLength, temp_cdb); - - aha_buf_free(req); - - SenseBufferFree(req, (SCSIStatus != SCSI_STATUS_OK)); - - pclog("Request complete\n"); - - if (SCSIStatus == SCSI_STATUS_OK) { - aha_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, - CCB_COMPLETE, SCSI_STATUS_OK, MBI_SUCCESS); - } else if (SCSIStatus == SCSI_STATUS_CHECK_CONDITION) { - aha_mbi_setup(dev, req->CCBPointer, &req->CmdBlock, - CCB_COMPLETE, SCSI_STATUS_CHECK_CONDITION, MBI_ERROR); - } -} - - -static void -aha_req_setup(aha_t *dev, uint32_t CCBPointer, Mailbox32_t *Mailbox32) -{ - Req_t *req = &dev->Req; - uint8_t Id, Lun; - uint8_t last_id = 7; - - /* Fetch data from the Command Control Block. */ - DMAPageRead(CCBPointer, (char *)&req->CmdBlock, sizeof(CCB32)); - - req->Is24bit = dev->Mbx24bit; - req->CCBPointer = CCBPointer; - req->TargetID = dev->Mbx24bit ? req->CmdBlock.old.Id : req->CmdBlock.new.Id; - req->LUN = dev->Mbx24bit ? req->CmdBlock.old.Lun : req->CmdBlock.new.Lun; - - Id = req->TargetID; - Lun = req->LUN; - if ((Id > last_id) || (Lun > 7)) { - aha_mbi_setup(dev, CCBPointer, &req->CmdBlock, - CCB_INVALID_CCB, SCSI_STATUS_OK, MBI_ERROR); - return; - } - - pclog("Scanning SCSI Target ID %i\n", Id); - - SCSIStatus = SCSI_STATUS_OK; - SCSIDevices[Id][Lun].InitLength = 0; - - aha_buf_alloc(req, req->Is24bit); - - if (!scsi_device_present(Id, Lun)) { - pclog("SCSI Target ID %i and LUN %i have no device attached\n",Id,Lun); - aha_buf_free(req); - SenseBufferFree(req, 0); - aha_mbi_setup(dev, CCBPointer, &req->CmdBlock, - CCB_SELECTION_TIMEOUT,SCSI_STATUS_OK,MBI_ERROR); - } else { - pclog("SCSI Target ID %i and LUN %i detected and working\n", Id, Lun); - - pclog("Transfer Control %02X\n", req->CmdBlock.common.ControlByte); - pclog("CDB Length %i\n", req->CmdBlock.common.CdbLength); - pclog("CCB Opcode %x\n", req->CmdBlock.common.Opcode); - if (req->CmdBlock.common.ControlByte > 0x03) { - pclog("Invalid control byte: %02X\n", - req->CmdBlock.common.ControlByte); - } - - AHA_InOperation = 1; - } -} - - -static void -aha_req_abort(aha_t *dev, uint32_t CCBPointer) -{ - CCBU CmdBlock; - - /* Fetch data from the Command Control Block. */ - DMAPageRead(CCBPointer, (char *)&CmdBlock, sizeof(CCB32)); - - aha_mbi_setup(dev, CCBPointer, &CmdBlock, - 0x26, SCSI_STATUS_OK, MBI_NOT_FOUND); -} - - -static uint32_t -aha_mbo(aha_t *dev, Mailbox32_t *Mailbox32) -{ - Mailbox_t MailboxOut; - uint32_t Outgoing; - - if (dev->Mbx24bit) { - Outgoing = dev->MailboxOutAddr + (dev->MailboxOutPosCur * sizeof(Mailbox_t)); - DMAPageRead(Outgoing, (char *)&MailboxOut, sizeof(Mailbox_t)); - - Mailbox32->CCBPointer = ADDR_TO_U32(MailboxOut.CCBPointer); - Mailbox32->u.out.ActionCode = MailboxOut.CmdStatus; - } else { - Outgoing = dev->MailboxOutAddr + (dev->MailboxOutPosCur * sizeof(Mailbox32_t)); - - DMAPageRead(Outgoing, (char *)Mailbox32, sizeof(Mailbox32_t)); - } - - return Outgoing; -} - - -static void -aha_mbo_adv(aha_t *dev) -{ - dev->MailboxOutPosCur = (dev->MailboxOutPosCur + 1) % dev->MailboxCount; -} - - -static void -aha_do_mail(aha_t *dev) -{ - Mailbox32_t mb32; - uint32_t Outgoing; - uint8_t CmdStatus = MBO_FREE; - uint32_t CodeOffset = 0; - - 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 (mb32.u.out.ActionCode != MBO_FREE) { - /* We got the mailbox, mark it as free in the guest. */ - pclog("aha_do_mail(): Writing %i bytes at %08X\n", sizeof(CmdStatus), Outgoing + CodeOffset); - DMAPageWrite(Outgoing + CodeOffset, (char *)&CmdStatus, sizeof(CmdStatus)); - } - - if (dev->MailboxOutInterrupts) - RaiseIntr(dev, INTR_MBOA | INTR_ANY); - - /* 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"); - aha_req_setup(dev, mb32.CCBPointer, &mb32); - } else if (mb32.u.out.ActionCode == MBO_ABORT) { - pclog("Abort Mailbox Command\n"); - aha_req_abort(dev, mb32.CCBPointer); - } else { - pclog("Invalid action code: %02X\n", mb32.u.out.ActionCode); - } - - /* Advance to the next mailbox. */ - if (dev->StrictRoundRobinMode) - aha_mbo_adv(dev); -} - - -static void -aha_reset_poll(void *priv) -{ - aha_t *dev = (aha_t *)priv; - - dev->Status &= ~STAT_STST; - dev->Status |= STAT_IDLE; - - ResetCB = 0; -} - - -static void -aha_cmd_cb(void *priv) -{ - aha_t *dev = (aha_t *)priv; - - if (AHA_InOperation == 0) { - if (dev->MailboxCount) { - aha_do_mail(dev); - } else { - AHA_Callback += SCSI_DELAY_TM * TIMER_USEC; - return; - } - } else if (AHA_InOperation == 1) { - pclog("%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. */ - AHA_Callback += 1000 * TIMER_USEC; - return; - } - } else if (AHA_InOperation == 2) { - pclog("%s: Callback: Send incoming mailbox\n", dev->name); - aha_mbi(dev); - } else { - fatal("%s: Invalid callback phase: %i\n", dev->name, AHA_InOperation); - } - - AHA_Callback += SCSI_DELAY_TM * TIMER_USEC; -} - - static uint8_t aha_mca_read(int port, void *priv) { @@ -1693,116 +1680,117 @@ static void aha_mca_write(int port, uint8_t val, void *priv) { aha_t *dev = (aha_t *)priv; - uint16_t addr; - - if (port < 0x0102) return; - /* Remove the current I/O handler. */ - io_removehandler(dev->Base, 4, - aha_read, aha_readw, NULL, - aha_write, aha_writew, NULL, dev); + /* MCA does not write registers below 0x0100. */ + if (port < 0x0102) return; /* Save the MCA register value. */ dev->pos_regs[port & 7] = val; -pclog("MCA: 1640 [%02x] [%02x] [%02x]\n", dev->pos_regs[2], dev->pos_regs[3], dev->pos_regs[4]); /* Get the new assigned I/O base address. */ - if (dev->pos_regs[2] & 1) { - addr = 0x0000; - switch(dev->pos_regs[3] & 0xc7) { - case 0x01: - addr = 0x0130; - break; + switch(dev->pos_regs[3] & 0xc7) { + case 0x01: /* [1]=00xx x001 */ + dev->Base = 0x0130; + break; - case 0x02: - addr = 0x0230; - break; + case 0x02: /* [1]=00xx x010 */ + dev->Base = 0x0230; + break; - case 0x03: - addr = 0x0330; - break; + case 0x03: /* [1]=00xx x011 */ + dev->Base = 0x0330; + break; - case 0x41: - addr = 0x0134; - break; + case 0x41: + dev->Base = 0x0134; + break; - case 0x42: - addr = 0x0234; - break; + case 0x42: /* [1]=01xx x010 */ + dev->Base = 0x0234; + break; - case 0x43: - addr = 0x0334; - break; - } - dev->Base = addr; + case 0x43: /* [1]=01xx x011 */ + dev->Base = 0x0334; + break; + } + + /* Save the new IRQ and DMA channel values. */ + dev->Irq = (dev->pos_regs[4] & 0x07) + 8; + dev->DmaChannel = dev->pos_regs[5] & 0x0f; + + /* Extract the BIOS ROM address info. */ + if (! (dev->pos_regs[2] & 0x80)) switch(dev->pos_regs[3] & 0x38) { + case 0x38: /* [1]=xx11 1xxx */ + dev->rom_addr = 0xDC000; + break; + + case 0x30: /* [1]=xx11 0xxx */ + dev->rom_addr = 0xD8000; + break; + + case 0x28: /* [1]=xx10 1xxx */ + dev->rom_addr = 0xD4000; + break; + + case 0x20: /* [1]=xx10 0xxx */ + dev->rom_addr = 0xD0000; + break; + + case 0x18: /* [1]=xx01 1xxx */ + dev->rom_addr = 0xCC000; + break; + + case 0x10: /* [1]=xx01 0xxx */ + dev->rom_addr = 0xC8000; + break; + } else { + /* Disabled. */ + dev->rom_addr = 0x000000; + } + + /* + * Get misc SCSI config stuff. For now, we are only + * interested in the configured HA target ID: + * + * pos[2]=111xxxxx = 7 + * pos[2]=000xxxxx = 0 + */ + dev->HostID = (dev->pos_regs[4] >> 5) & 0x07; + + /* + * SYNC mode is pos[2]=xxxx1xxx. + * + * SCSI Parity is pos[2]=xxx1xxxx. + */ + + /* Initialize the device if fully configured. */ + if (dev->pos_regs[2] & 0x01) { + /* Card has been enabled! First, remove the current I/O handler. */ + io_removehandler(dev->Base, 4, + aha_read, aha_readw, NULL, + aha_write, aha_writew, NULL, dev); + mem_mapping_disable(&dev->bios.mapping); /* Register the new I/O range. */ - io_sethandler(addr, 4, + io_sethandler(dev->Base, 4, aha_read, aha_readw, NULL, aha_write, aha_writew, NULL, dev); - /* Save the new IRQ and DMA channel values. */ - dev->Irq = (dev->pos_regs[4] & 0x07) + 8; - dev->DmaChannel = dev->pos_regs[5] & 0x0f; - - /* Extract the BIOS ROM address info. */ - if (! (dev->pos_regs[2] & 0x80)) { - switch(dev->pos_regs[3] & 0x38) { - case 0x38: /* [1]=xx11 1xxx */ - dev->rom_addr = 0xDC000; - break; - - case 0x30: /* [1]=xx11 0xxx */ - dev->rom_addr = 0xD8000; - break; - - case 0x28: /* [1]=xx10 1xxx */ - dev->rom_addr = 0xD4000; - break; - - case 0x20: /* [1]=xx10 0xxx */ - dev->rom_addr = 0xD0000; - break; - - case 0x18: /* [1]=xx01 1xxx */ - dev->rom_addr = 0xCC000; - break; - - case 0x10: /* [1]=xx01 0xxx */ - dev->rom_addr = 0xC8000; - break; - } - } else { - /* Disabled. */ - dev->rom_addr = 0x000000; - } - } - - /* Initialize the device if fully configured. */ - if (dev->Base != 0 && dev->Irq != 0 && dev->DmaChannel != 0) { + /* Reset the device. */ aha_reset_ctrl(dev, CTRL_HRST); /* Enable the memory. */ if (dev->rom_addr != 0x000000) { - mem_mapping_enable(&aha_bios.mapping); - mem_mapping_set_addr(&aha_bios.mapping, dev->rom_addr, 0x4000); + mem_mapping_enable(&dev->bios.mapping); + mem_mapping_set_addr(&dev->bios.mapping, dev->rom_addr, ROM_SIZE); } } } -void -aha_device_reset(void *p) -{ - aha_t *dev = (aha_t *) p; - - aha_reset_ctrl(dev, 1); -} - - /* Initialize the board's ROM BIOS. */ static void -aha_setbios(aha_t *dev, uint32_t memaddr) +aha_setbios(aha_t *dev) { uint32_t size; uint32_t mask; @@ -1832,21 +1820,21 @@ aha_setbios(aha_t *dev, uint32_t memaddr) (void)fseek(f, 0L, SEEK_SET); /* Load first chunk of BIOS (which is the main BIOS, aka ROM1.) */ - aha_rom1 = malloc(ROM_SIZE); - (void)fread(aha_rom1, ROM_SIZE, 1, f); + dev->rom1 = malloc(ROM_SIZE); + (void)fread(dev->rom1, ROM_SIZE, 1, f); temp -= ROM_SIZE; if (temp > 0) { - aha_rom2 = malloc(ROM_SIZE); - (void)fread(aha_rom2, ROM_SIZE, 1, f); + dev->rom2 = malloc(ROM_SIZE); + (void)fread(dev->rom2, ROM_SIZE, 1, f); temp -= ROM_SIZE; } else { - aha_rom2 = NULL; + dev->rom2 = NULL; } if (temp != 0) { pclog("%s: BIOS ROM size invalid!\n", dev->name); - free(aha_rom1); - if (aha_rom2 != NULL) - free(aha_rom2); + free(dev->rom1); + if (dev->rom2 != NULL) + free(dev->rom2); (void)fclose(f); return; } @@ -1865,22 +1853,23 @@ aha_setbios(aha_t *dev, uint32_t memaddr) size = 0x2000; mask = (size - 1); pclog("%s: BIOS at 0x%06lX, size %lu, mask %08lx\n", - dev->name, memaddr, size, mask); + dev->name, dev->rom_addr, size, mask); /* Initialize the ROM entry for this BIOS. */ - memset(&aha_bios, 0x00, sizeof(rom_t)); + memset(&dev->bios, 0x00, sizeof(rom_t)); /* Enable ROM1 into the memory map. */ - aha_bios.rom = aha_rom1; + dev->bios.rom = dev->rom1; /* Set up an address mask for this memory. */ - aha_bios.mask = mask; + dev->bios.mask = mask; /* Map this system into the memory map. */ - mem_mapping_add(&aha_bios.mapping, memaddr, size, + mem_mapping_add(&dev->bios.mapping, dev->rom_addr, size, aha_mem_read, aha_mem_readw, aha_mem_readl, aha_mem_write, NULL, NULL, - aha_bios.rom, MEM_MAPPING_EXTERNAL, &aha_bios); + dev->bios.rom, MEM_MAPPING_EXTERNAL, &dev->bios); + mem_mapping_disable(&dev->bios.mapping); /* * Patch the ROM BIOS image for stuff Adaptec deliberately @@ -1900,7 +1889,7 @@ aha_setbios(aha_t *dev, uint32_t memaddr) dev->name, dev->Base); return; } - aha_bios.rom[dev->rom_ioaddr] = (uint8_t)i; + dev->bios.rom[dev->rom_ioaddr] = (uint8_t)i; } /* @@ -1914,8 +1903,8 @@ aha_setbios(aha_t *dev, uint32_t memaddr) dev->fwl = '0'; if (dev->rom_fwhigh != 0x0000) { /* Read firmware version from the BIOS. */ - dev->fwh = aha_bios.rom[dev->rom_fwhigh]; - dev->fwl = aha_bios.rom[dev->rom_fwhigh+1]; + dev->fwh = dev->bios.rom[dev->rom_fwhigh]; + dev->fwl = dev->bios.rom[dev->rom_fwhigh+1]; } /* @@ -1935,16 +1924,12 @@ aha_setbios(aha_t *dev, uint32_t memaddr) again: mask = 0; for (temp=0; tempbios.rom[temp]; mask &= 0xff; if (mask != 0x00) { - pclog("%s: fixing BIOS checksum (%02x) ..\n", dev->name, mask); - aha_bios.rom[temp-1] += (256 - mask); + dev->bios.rom[temp-1] += (256 - mask); goto again; } - - /* Save the BIOS address. */ - dev->rom_addr = memaddr; } @@ -1960,7 +1945,7 @@ aha_setnvr(aha_t *dev) memset(dev->nvr, 0x00, NVR_SIZE); /* Initialize the on-board EEPROM. */ - dev->nvr[0] = 7; /* SCSI ID 7 */ + dev->nvr[0] = dev->HostID; /* SCSI ID 7 */ dev->nvr[0] |= (0x10 | 0x20 | 0x40); dev->nvr[1] = dev->Irq-9; /* IRQ15 */ dev->nvr[1] |= (dev->DmaChannel<<4); /* DMA6 */ @@ -1978,7 +1963,6 @@ static void * aha_init(int type) { aha_t *dev; - uint32_t bios; /* Allocate control block and set up basic stuff. */ dev = malloc(sizeof(aha_t)); @@ -1996,8 +1980,14 @@ aha_init(int type) dev->Base = device_get_config_hex16("base"); dev->Irq = device_get_config_int("irq"); dev->DmaChannel = device_get_config_int("dma"); - bios = device_get_config_hex20("bios_addr"); + dev->rom_addr = device_get_config_hex20("bios_addr"); +#if NOT_YET_USED + dev->HostID = device_get_config_int("hostid"); +#else + dev->HostID = 7; /* default HA ID */ +#endif + /* Perform per-board initialization. */ switch(type) { case AHA_154xB: strcpy(dev->name, "AHA-154xB"); @@ -2050,25 +2040,23 @@ aha_init(int type) case AHA_1640: strcpy(dev->name, "AHA-1640"); dev->bios_path = L"roms/scsi/adaptec/aha1640.bin"; + dev->bid = 'B'; /* Enable MCA. */ dev->pos_regs[0] = 0x1F; /* MCA board ID */ dev->pos_regs[1] = 0x0F; - dev->pos_regs[2] = 0x01; /* as per ADF */ - dev->pos_regs[5] = 0x20; /* as per ADF */ mca_add(aha_mca_read, aha_mca_write, dev); break; } - ResetDev = dev; /* Initialize ROM BIOS if needed. */ - aha_setbios(dev, bios); + aha_setbios(dev); /* Initialize EEPROM (NVR) if needed. */ aha_setnvr(dev); - timer_add(aha_reset_poll, &ResetCB, &ResetCB, dev); - timer_add(aha_cmd_cb, &AHA_Callback, &AHA_Callback, 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. */ @@ -2078,12 +2066,12 @@ aha_init(int type) /* Initialize the device. */ aha_reset_ctrl(dev, CTRL_HRST); - } - /* Enable the memory. */ - if (dev->rom_addr != 0x000000) { - mem_mapping_enable(&aha_bios.mapping); - mem_mapping_set_addr(&aha_bios.mapping, dev->rom_addr, 0x4000); + /* Enable the memory. */ + if (dev->rom_addr != 0x000000) { + mem_mapping_enable(&dev->bios.mapping); + mem_mapping_set_addr(&dev->bios.mapping, dev->rom_addr, ROM_SIZE); + } } return(dev); @@ -2116,9 +2104,6 @@ aha_close(void *priv) { aha_t *dev = (aha_t *)priv; - /* Make sure it won't get called anymore.. */ - ResetDev = NULL; - if (dev->nvr != NULL) free(dev->nvr); @@ -2127,6 +2112,15 @@ aha_close(void *priv) } +void +aha_device_reset(void *priv) +{ + aha_t *dev = (aha_t *)priv; + + aha_reset_ctrl(dev, 1); +} + + static device_config_t aha_154x_config[] = { { "base", "Address", CONFIG_HEX16, "", 0x334, diff --git a/src/scsi/scsi_bios_command.c b/src/scsi/scsi_bios_command.c index 3dc1a674d..d085e2532 100644 --- a/src/scsi/scsi_bios_command.c +++ b/src/scsi/scsi_bios_command.c @@ -8,445 +8,443 @@ * * The shared AHA and Buslogic SCSI BIOS command handler. * - * Version: @(#)scsi_bios_command.c 1.0.0 2017/08/26 + * Version: @(#)scsi_bios_command.c 1.0.1 2017/08/27 * * Authors: TheCollector1995, * Miran Grca, * Fred N. van Kempen, - * Copyright 2016,2017 Miran Grca. + * Copyright 2017 Miran Grca. * Copyright 2017 Fred N. van Kempen. */ #include #include - #include "../ibm.h" #include "../dma.h" #include "scsi.h" #include "scsi_bios_command.h" #include "scsi_device.h" -/* #define ENABLE_SCSI_BIOS_COMMAND_LOG 0 */ -int scsi_bios_command_do_log = 0; + +#if ENABLE_SCSI_BIOS_COMMAND_LOG +int scsi_bios_command_do_log = ENABLE_SCSI_BIOS_COMMAND_LOG; +#endif + static void -scsi_bios_command_log(const char *format, ...) +cmd_log(const char *fmt, ...) { -#ifdef ENABLE_SCSI_BIOS_COMMAND_LOG - if (scsi_bios_command_do_log) - { - va_list ap; +#if ENABLE_SCSI_BIOS_COMMAND_LOG + va_list ap; - va_start(ap, format); - vprintf(format, ap); - va_end(ap); - fflush(stdout); - } + if (scsi_bios_command_do_log) { + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + fflush(stdout); + } #endif } -static uint8_t scsi_bios_completion_code(uint8_t *sense) + +static void +target_check(uint8_t id, uint8_t lun) { - switch (sense[12]) - { - case 0x00: - return 0x00; - case 0x20: - return 0x01; - case 0x12: - case 0x21: - return 0x02; - case 0x27: - return 0x03; - case 0x14: case 0x16: - return 0x04; - case 0x10: case 0x11: - return 0x10; - case 0x17: case 0x18: - return 0x11; - case 0x01: case 0x03: case 0x05: case 0x06: case 0x07: case 0x08: case 0x09: - case 0x1B: case 0x1C: case 0x1D: - case 0x40: case 0x41: case 0x42: case 0x43: case 0x44: case 0x45: case 0x46: - case 0x47: case 0x48: case 0x49: - return 0x20; - case 0x15: - case 0x02: - return 0x40; - case 0x04: - case 0x28: case 0x29: case 0x2A: - return 0xAA; - default: - return 0xFF; - } + if (! scsi_device_valid(id, lun)) { + fatal("BIOS INT13 device on %02i:%02i has disappeared\n", id, lun); + } } -uint8_t scsi_bios_command_08(uint8_t id, uint8_t lun, uint8_t *buffer) + +static uint8_t +completion_code(uint8_t *sense) { - uint32_t len = 0; - uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - uint8_t rcbuf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - int ret = 0; - int i = 0; - uint8_t sc = 0; + switch (sense[12]) { + case 0x00: + return(0x00); - ret = scsi_device_read_capacity(id, lun, cdb, rcbuf, &len); - sc = scsi_bios_completion_code(scsi_device_sense(id, lun)); + case 0x20: + return(0x01); - if (ret == 0) - { - return sc; - } + case 0x12: + case 0x21: + return(0x02); - memset(buffer, 0, 6); + case 0x27: + return(0x03); - for (i = 0; i < 4; i++) - { - buffer[i] = rcbuf[i]; - } + case 0x14: + case 0x16: + return(0x04); - for (i = 4; i < 6; i++) - { - buffer[i] = rcbuf[(i + 2) ^ 1]; - } + case 0x10: + case 0x11: + return(0x10); - scsi_bios_command_log("BIOS Command 0x08: %02X %02X %02X %02X %02X %02X\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); - - return 0; + case 0x17: + case 0x18: + return(0x11); + + case 0x01: + case 0x03: + case 0x05: + case 0x06: + case 0x07: + case 0x08: + case 0x09: + case 0x1B: + case 0x1C: + case 0x1D: + case 0x40: + case 0x41: + case 0x42: + case 0x43: + case 0x44: + case 0x45: + case 0x46: + case 0x47: + case 0x48: + case 0x49: + return(0x20); + + case 0x15: + case 0x02: + return(0x40); + + case 0x04: + case 0x28: + case 0x29: + case 0x2a: + return(0xaa); + + default: + break; + }; + + return(0xff); } -int scsi_bios_command_15(uint8_t id, uint8_t lun, uint8_t *buffer) + +uint8_t +scsi_bios_command_08(uint8_t id, uint8_t lun, uint8_t *buffer) { - uint32_t len = 0; - uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - uint8_t rcbuf[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - int ret = 0; - int i = 0; - uint8_t sc = 0; + uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0,0,0,0,0,0,0,0,0,0,0 }; + uint8_t rcbuf[8] = { 0,0,0,0,0,0,0,0 }; + uint32_t len = 0; + int i, ret, sc; - ret = scsi_device_read_capacity(id, lun, cdb, rcbuf, &len); - sc = scsi_bios_completion_code(scsi_device_sense(id, lun)); + ret = scsi_device_read_capacity(id, lun, cdb, rcbuf, &len); + sc = completion_code(scsi_device_sense(id, lun)); + if (ret == 0) return(sc); - memset(buffer, 0, 6); + memset(buffer, 0x00, 6); + for (i=0; i<4; i++) + buffer[i] = rcbuf[i]; + for (i=4; i<6; i++) + buffer[i] = rcbuf[(i + 2) ^ 1]; + cmd_log("BIOS Command 0x08: %02X %02X %02X %02X %02X %02X\n", + buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); - for (i = 0; i < 4; i++) - { - buffer[i] = (ret == 0) ? 0 : rcbuf[i]; - } - - scsi_device_type_data(id, lun, &(buffer[4]), &(buffer[5])); - - scsi_bios_command_log("BIOS Command 0x15: %02X %02X %02X %02X %02X %02X\n", buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); - - return sc; + return(0); } -static void scsi_bios_command_id_check(uint8_t id, uint8_t lun) + +int +scsi_bios_command_15(uint8_t id, uint8_t lun, uint8_t *buffer) { - if (!scsi_device_valid(id, lun)) - { - fatal("BIOS INT13 CD-ROM on %02i:%02i has disappeared\n", id, lun); - } + uint8_t cdb[12] = { GPCMD_READ_CDROM_CAPACITY, 0,0,0,0,0,0,0,0,0,0,0 }; + uint8_t rcbuf[8] = { 0,0,0,0,0,0,0,0 }; + uint32_t len = 0; + int i, ret, sc; + + ret = scsi_device_read_capacity(id, lun, cdb, rcbuf, &len); + sc = completion_code(scsi_device_sense(id, lun)); + + memset(buffer, 0x00, 6); + for (i=0; i<4; i++) + buffer[i] = (ret == 0) ? 0 : rcbuf[i]; + + scsi_device_type_data(id, lun, &(buffer[4]), &(buffer[5])); + + cmd_log("BIOS Command 0x15: %02X %02X %02X %02X %02X %02X\n", + buffer[0], buffer[1], buffer[2], buffer[3], buffer[4], buffer[5]); + + return(sc); } /* This returns the completion code. */ -uint8_t scsi_bios_command(uint8_t last_id, BIOSCMD *BiosCmd, int8_t islba) +uint8_t +scsi_bios_command(uint8_t max_id, BIOSCMD *cmd, int8_t islba) { - uint32_t dma_address; - uint32_t lba; - int sector_len = BiosCmd->secount; - int block_shift = 9; - uint8_t ret = 0; - uint8_t cdb[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + uint8_t cdb[12] = { 0,0,0,0,0,0,0,0,0,0,0,0 }; + scsi_device_t *dev; + uint32_t dma_address; + uint32_t lba; + int sector_len = cmd->secount; + int block_shift; + uint8_t ret; - if (islba) - lba = lba32_blk(BiosCmd); - else - lba = (BiosCmd->u.chs.cyl << 9) + (BiosCmd->u.chs.head << 5) + BiosCmd->u.chs.sec; + if (islba) + lba = lba32_blk(cmd); + else + lba = (cmd->u.chs.cyl << 9) + (cmd->u.chs.head << 5) + cmd->u.chs.sec; - scsi_bios_command_log("BIOS Command = 0x%02X\n", BiosCmd->command); + cmd_log("BIOS Command = 0x%02X\n", cmd->command); - if ((BiosCmd->id > last_id) || (BiosCmd->lun > 7)) { - return 0x80; - } + if ((cmd->id > max_id) || (cmd->lun > 7)) return(0x80); - SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = 0; + /* Get pointer to selected device. */ + dev = &SCSIDevices[cmd->id][cmd->lun]; + dev->InitLength = 0; - if (!scsi_device_present(BiosCmd->id, BiosCmd->lun)) - { - scsi_bios_command_log("BIOS Target ID %i and LUN %i have no device attached\n",BiosCmd->id,BiosCmd->lun); - return 0x80; - } + if (! scsi_device_present(cmd->id, cmd->lun)) { + cmd_log("BIOS Target ID %i and LUN %i have no device attached\n", + cmd->id, cmd->lun); + return(0x80); + } - dma_address = ADDR_TO_U32(BiosCmd->dma_address); + dma_address = ADDR_TO_U32(cmd->dma_address); - scsi_bios_command_log("BIOS Data Buffer write: length %d, pointer 0x%04X\n", sector_len, dma_address); + cmd_log("BIOS Data Buffer write: length %d, pointer 0x%04X\n", + sector_len, dma_address); - if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL) - { - free(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer); - SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL; - } + if (dev->CmdBuffer != NULL) { + free(dev->CmdBuffer); + dev->CmdBuffer = NULL; + } - block_shift = scsi_device_block_shift(BiosCmd->id, BiosCmd->lun); + block_shift = scsi_device_block_shift(cmd->id, cmd->lun); - switch(BiosCmd->command) - { - case 0x00: /* Reset Disk System, in practice it's a nop */ - return 0; + switch(cmd->command) { + case 0x00: /* Reset Disk System, in practice it's a nop */ + return(0); - case 0x01: /* Read Status of Last Operation */ - scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); + case 0x01: /* Read Status of Last Operation */ + target_check(cmd->id, cmd->lun); - /* Assuming 14 bytes because that's the default length for SCSI sense, and no command-specific - indication is given. */ - SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = 14; + /* + * Assuming 14 bytes because that is the default + * length for SCSI sense, and no command-specific + * indication is given. + */ + dev->InitLength = 14; + dev->CmdBuffer = (uint8_t *)malloc(14); + memset(dev->CmdBuffer, 0x00, 14); - SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = (uint8_t *) malloc(14); - memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, 14); - - /* SCSIStatus = scsi_bios_command_08(BiosCmd->id, BiosCmd->lun, SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer) ? SCSI_STATUS_OK : SCSI_STATUS_CHECK_CONDITION; */ - - if (sector_len > 0) - { - scsi_bios_command_log("BusLogic BIOS DMA: Reading 14 bytes at %08X\n", dma_address); - DMAPageWrite(dma_address, (char *)scsi_device_sense(BiosCmd->id, BiosCmd->lun), 14); - } - - if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL) - { - free(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer); - SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL; - } - - return 0; - - break; - - case 0x02: /* Read Desired Sectors to Memory */ - scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); - - SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = sector_len << block_shift; - - SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = (uint8_t *) malloc(sector_len << block_shift); - memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, sector_len << block_shift); - - cdb[0] = GPCMD_READ_10; - cdb[1] = (BiosCmd->lun & 7) << 5; - cdb[2] = (lba >> 24) & 0xff; - cdb[3] = (lba >> 16) & 0xff; - cdb[4] = (lba >> 8) & 0xff; - cdb[5] = lba & 0xff; - cdb[7] = (sector_len >> 8) & 0xff; - cdb[8] = sector_len & 0xff; #if 0 -pclog("BIOS CMD(READ, %08lx, %d)\n", lba, BiosCmd->secount); + SCSIStatus = scsi_bios_command_08(cmd->id, cmd->lun, dev->CmdBuffer) ? SCSI_STATUS_OK : SCSI_STATUS_CHECK_CONDITION; #endif - scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb); + if (sector_len > 0) { + cmd_log("BIOS DMA: Reading 14 bytes at %08X\n", + dma_address); + DMAPageWrite(dma_address, + (char *)scsi_device_sense(cmd->id, cmd->lun), 14); + } - if (sector_len > 0) - { - scsi_bios_command_log("BIOS DMA: Reading %i bytes at %08X\n", sector_len << block_shift, dma_address); - DMAPageWrite(dma_address, (char *)SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, sector_len << block_shift); - } + if (dev->CmdBuffer != NULL) { + free(dev->CmdBuffer); + dev->CmdBuffer = NULL; + } - if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL) - { - free(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer); - SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL; - } + return(0); - return scsi_bios_completion_code(scsi_device_sense(BiosCmd->id, BiosCmd->lun)); + case 0x02: /* Read Desired Sectors to Memory */ + target_check(cmd->id, cmd->lun); - break; + dev->InitLength = sector_len << block_shift; + dev->CmdBuffer = (uint8_t *)malloc(dev->InitLength); + memset(dev->CmdBuffer, 0x00, dev->InitLength); - case 0x03: /* Write Desired Sectors from Memory */ - scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); - - SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = sector_len << block_shift; - - SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = (uint8_t *) malloc(sector_len << block_shift); - memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, sector_len << block_shift); - - if (sector_len > 0) - { - scsi_bios_command_log("BIOS DMA: Reading %i bytes at %08X\n", sector_len << block_shift, dma_address); - DMAPageRead(dma_address, (char *)SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, sector_len << block_shift); - } - - cdb[0] = GPCMD_WRITE_10; - cdb[1] = (BiosCmd->lun & 7) << 5; - cdb[2] = (lba >> 24) & 0xff; - cdb[3] = (lba >> 16) & 0xff; - cdb[4] = (lba >> 8) & 0xff; - cdb[5] = lba & 0xff; - cdb[7] = (sector_len >> 8) & 0xff; - cdb[8] = sector_len & 0xff; + cdb[0] = GPCMD_READ_10; + cdb[1] = (cmd->lun & 7) << 5; + cdb[2] = (lba >> 24) & 0xff; + cdb[3] = (lba >> 16) & 0xff; + cdb[4] = (lba >> 8) & 0xff; + cdb[5] = lba & 0xff; + cdb[7] = (sector_len >> 8) & 0xff; + cdb[8] = sector_len & 0xff; #if 0 -pclog("BIOS CMD(WRITE, %08lx, %d)\n", lba, BiosCmd->secount); + cmd_log("BIOS CMD(READ, %08lx, %d)\n", lba, cmd->secount); #endif - scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb); + scsi_device_command(cmd->id, cmd->lun, 12, cdb); + if (sector_len > 0) { + cmd_log("BIOS DMA: Reading %i bytes at %08X\n", + dev->InitLength, dma_address); + DMAPageWrite(dma_address, + (char *)dev->CmdBuffer, dev->InitLength); + } - if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL) - { - free(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer); - SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL; - } + if (dev->CmdBuffer != NULL) { + free(dev->CmdBuffer); + dev->CmdBuffer = NULL; + } - return scsi_bios_completion_code(scsi_device_sense(BiosCmd->id, BiosCmd->lun)); + return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); - break; + case 0x03: /* Write Desired Sectors from Memory */ + target_check(cmd->id, cmd->lun); - case 0x04: /* Verify Desired Sectors */ - scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); + dev->InitLength = sector_len << block_shift; + dev->CmdBuffer = (uint8_t *)malloc(dev->InitLength); + memset(dev->CmdBuffer, 0x00, dev->InitLength); - cdb[0] = GPCMD_VERIFY_10; - cdb[1] = (BiosCmd->lun & 7) << 5; - cdb[2] = (lba >> 24) & 0xff; - cdb[3] = (lba >> 16) & 0xff; - cdb[4] = (lba >> 8) & 0xff; - cdb[5] = lba & 0xff; - cdb[7] = (sector_len >> 8) & 0xff; - cdb[8] = sector_len & 0xff; + if (sector_len > 0) { + cmd_log("BIOS DMA: Reading %i bytes at %08X\n", + dev->InitLength, dma_address); + DMAPageRead(dma_address, + (char *)dev->CmdBuffer, dev->InitLength); + } - scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb); + cdb[0] = GPCMD_WRITE_10; + cdb[1] = (cmd->lun & 7) << 5; + cdb[2] = (lba >> 24) & 0xff; + cdb[3] = (lba >> 16) & 0xff; + cdb[4] = (lba >> 8) & 0xff; + cdb[5] = lba & 0xff; + cdb[7] = (sector_len >> 8) & 0xff; + cdb[8] = sector_len & 0xff; +#if 0 + cmd_log("BIOS CMD(WRITE, %08lx, %d)\n", lba, cmd->secount); +#endif - return scsi_bios_completion_code(scsi_device_sense(BiosCmd->id, BiosCmd->lun)); + scsi_device_command(cmd->id, cmd->lun, 12, cdb); - break; + if (dev->CmdBuffer != NULL) { + free(dev->CmdBuffer); + dev->CmdBuffer = NULL; + } - case 0x05: /* Format Track, invalid since SCSI has no tracks */ - return 1; + return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); - break; + case 0x04: /* Verify Desired Sectors */ + target_check(cmd->id, cmd->lun); - case 0x06: /* Identify SCSI Devices, in practice it's a nop */ - return 0; + cdb[0] = GPCMD_VERIFY_10; + cdb[1] = (cmd->lun & 7) << 5; + cdb[2] = (lba >> 24) & 0xff; + cdb[3] = (lba >> 16) & 0xff; + cdb[4] = (lba >> 8) & 0xff; + cdb[5] = lba & 0xff; + cdb[7] = (sector_len >> 8) & 0xff; + cdb[8] = sector_len & 0xff; - break; + scsi_device_command(cmd->id, cmd->lun, 12, cdb); - case 0x07: /* Format Unit */ - scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); + return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); - cdb[0] = GPCMD_FORMAT_UNIT; - cdb[1] = (BiosCmd->lun & 7) << 5; + case 0x05: /* Format Track, invalid since SCSI has no tracks */ +//FIXME: add a longer delay here --FvK + return(1); - scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb); + case 0x06: /* Identify SCSI Devices, in practice it's a nop */ +//FIXME: add a longer delay here --FvK + return(0); - return scsi_bios_completion_code(scsi_device_sense(BiosCmd->id, BiosCmd->lun)); + case 0x07: /* Format Unit */ + target_check(cmd->id, cmd->lun); - break; + cdb[0] = GPCMD_FORMAT_UNIT; + cdb[1] = (cmd->lun & 7) << 5; - case 0x08: /* Read Drive Parameters */ - scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); + scsi_device_command(cmd->id, cmd->lun, 12, cdb); - SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = 6; + return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); - SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = (uint8_t *) malloc(6); - memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, 6); + case 0x08: /* Read Drive Parameters */ + target_check(cmd->id, cmd->lun); - ret = scsi_bios_command_08(BiosCmd->id, BiosCmd->lun, SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer); + dev->InitLength = 6; + dev->CmdBuffer = (uint8_t *)malloc(dev->InitLength); + memset(dev->CmdBuffer, 0x00, dev->InitLength); - scsi_bios_command_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address); - DMAPageWrite(dma_address, (char *)SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 6); + ret = scsi_bios_command_08(cmd->id, cmd->lun, dev->CmdBuffer); - if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL) - { - free(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer); - SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL; - } + cmd_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address); + DMAPageWrite(dma_address, + (char *)dev->CmdBuffer, dev->InitLength); - return ret; + if (dev->CmdBuffer != NULL) { + free(dev->CmdBuffer); + dev->CmdBuffer = NULL; + } - break; + return(ret); - case 0x09: /* Initialize Drive Pair Characteristics, in practice it's a nop */ - return 0; + case 0x09: /* Initialize Drive Pair Characteristics, in practice it's a nop */ +//FIXME: add a longer delay here --FvK + return(0); - break; + case 0x0c: /* Seek */ + target_check(cmd->id, cmd->lun); - case 0x0C: /* Seek */ - scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); +//FIXME: is this needed? Looks like a copy-paste leftover.. --FvK + dev->InitLength = sector_len << block_shift; - SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = sector_len << block_shift; + cdb[0] = GPCMD_SEEK_10; + cdb[1] = (cmd->lun & 7) << 5; + cdb[2] = (lba >> 24) & 0xff; + cdb[3] = (lba >> 16) & 0xff; + cdb[4] = (lba >> 8) & 0xff; + cdb[5] = lba & 0xff; - cdb[0] = GPCMD_SEEK_10; - cdb[1] = (BiosCmd->lun & 7) << 5; - cdb[2] = (lba >> 24) & 0xff; - cdb[3] = (lba >> 16) & 0xff; - cdb[4] = (lba >> 8) & 0xff; - cdb[5] = lba & 0xff; + scsi_device_command(cmd->id, cmd->lun, 12, cdb); - scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb); + return((SCSIStatus == SCSI_STATUS_OK) ? 1 : 0); - return (SCSIStatus == SCSI_STATUS_OK) ? 1 : 0; + case 0x0d: /* Alternate Disk Reset, in practice it's a nop */ +//FIXME: add a longer delay here --FvK + return(0); - break; + case 0x10: /* Test Drive Ready */ + target_check(cmd->id, cmd->lun); - case 0x0D: /* Alternate Disk Reset, in practice it's a nop */ - return 0; + cdb[0] = GPCMD_TEST_UNIT_READY; + cdb[1] = (cmd->lun & 7) << 5; - break; + scsi_device_command(cmd->id, cmd->lun, 12, cdb); - case 0x10: /* Test Drive Ready */ - scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); + return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); - cdb[0] = GPCMD_TEST_UNIT_READY; - cdb[1] = (BiosCmd->lun & 7) << 5; + case 0x11: /* Recalibrate */ + target_check(cmd->id, cmd->lun); - scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb); + cdb[0] = GPCMD_REZERO_UNIT; + cdb[1] = (cmd->lun & 7) << 5; - return scsi_bios_completion_code(scsi_device_sense(BiosCmd->id, BiosCmd->lun)); + scsi_device_command(cmd->id, cmd->lun, 12, cdb); - break; + return(completion_code(scsi_device_sense(cmd->id, cmd->lun))); - case 0x11: /* Recalibrate */ - scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); + case 0x14: /* Controller Diagnostic */ +//FIXME: add a longer delay here --FvK + return(0); - cdb[0] = GPCMD_REZERO_UNIT; - cdb[1] = (BiosCmd->lun & 7) << 5; + case 0x15: /* Read DASD Type */ + target_check(cmd->id, cmd->lun); - scsi_device_command(BiosCmd->id, BiosCmd->lun, 12, cdb); + dev->InitLength = 6; + dev->CmdBuffer = (uint8_t *)malloc(dev->InitLength); + memset(dev->CmdBuffer, 0x00, dev->InitLength); - return scsi_bios_completion_code(scsi_device_sense(BiosCmd->id, BiosCmd->lun)); + ret = scsi_bios_command_15(cmd->id, cmd->lun, dev->CmdBuffer); - break; + cmd_log("BIOS DMA: Reading 6 bytes at %08X\n", dma_address); + DMAPageWrite(dma_address, + (char *)dev->CmdBuffer, dev->InitLength); - case 0x14: /* Controller Diagnostic */ - return 0; + if (dev->CmdBuffer != NULL) { + free(dev->CmdBuffer); + dev->CmdBuffer = NULL; + } - break; + return(ret); - case 0x15: /* Read DASD Type */ - scsi_bios_command_id_check(BiosCmd->id, BiosCmd->lun); - - SCSIDevices[BiosCmd->id][BiosCmd->lun].InitLength = 6; - - SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = (uint8_t *) malloc(6); - memset(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 0, 6); - - ret = scsi_bios_command_15(BiosCmd->id, BiosCmd->lun, SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer); - - scsi_bios_command_log("BusLogic BIOS DMA: Reading 6 bytes at %08X\n", dma_address); - DMAPageWrite(dma_address, (char *)SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer, 6); - - if (SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer != NULL) - { - free(SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer); - SCSIDevices[BiosCmd->id][BiosCmd->lun].CmdBuffer = NULL; - } - - return ret; - - break; - - default: - scsi_bios_command_log("BusLogic BIOS: Unimplemented command: %02X\n", BiosCmd->command); - return 1; - - break; - } + default: + cmd_log("BIOS: Unimplemented command: %02X\n", cmd->command); + return(1); + } - pclog("BIOS Request complete\n"); + cmd_log("BIOS Request complete\n"); }