2017-05-30 03:38:38 +02:00
/*
* 86 Box A hypervisor and IBM PC system emulator that specializes in
* running old operating systems and software designed for IBM
* PC systems and compatibles from 1981 through fairly recent
* system designs based on the PCI bus .
*
2017-06-02 14:11:53 -04:00
* Emulation of BusLogic ISA and PCI SCSI controllers . Boards
* supported :
2017-05-30 03:38:38 +02:00
*
2017-10-14 07:03:19 +02:00
* 0 - BT - 542 BH ISA ;
* 1 - BT - 545 S ISA ;
* 2 - BT - 958 D PCI
2017-06-02 14:11:53 -04:00
*
2017-10-16 18:40:34 +02:00
* Version : @ ( # ) scsi_buslogic . c 1.0 .24 2017 / 10 / 16
2017-05-30 03:38:38 +02:00
*
2017-06-04 02:11:19 -04:00
* Authors : TheCollector1995 , < mariogplayer @ gmail . com >
2017-05-30 03:38:38 +02:00
* Miran Grca , < mgrca8 @ gmail . com >
* Fred N . van Kempen , < decwiz @ yahoo . com >
2017-10-11 05:40:44 -04:00
*
2017-08-24 01:14:39 -04:00
* Copyright 2016 , 2017 Miran Grca .
* Copyright 2017 Fred N . van Kempen .
2017-05-30 03:38:38 +02:00
*/
2017-05-05 01:49:42 +02:00
# include <stdio.h>
2017-09-25 04:31:20 -04:00
# include <stdint.h>
2017-05-05 01:49:42 +02:00
# include <string.h>
2017-09-25 04:31:20 -04:00
# include <stdlib.h>
2017-05-05 01:49:42 +02:00
# include <stdarg.h>
2017-09-25 04:31:20 -04:00
# include <wchar.h>
2017-08-27 00:58:44 +02:00
# include "../ibm.h"
# include "../io.h"
2017-10-14 07:03:19 +02:00
# include "../mca.h"
2017-08-27 00:58:44 +02:00
# include "../mem.h"
2017-10-14 07:03:19 +02:00
# include "../mca.h"
2017-08-27 00:58:44 +02:00
# include "../rom.h"
2017-09-23 21:12:26 -04:00
# include "../nvr.h"
2017-08-27 00:58:44 +02:00
# include "../dma.h"
# include "../pic.h"
# include "../pci.h"
# include "../timer.h"
# include "../device.h"
2017-10-11 05:40:44 -04:00
# include "../plat.h"
2017-05-05 01:49:42 +02:00
# include "scsi.h"
# include "scsi_buslogic.h"
2017-10-14 07:03:19 +02:00
# include "scsi_device.h"
# include "scsi_x54x.h"
2017-05-05 01:49:42 +02:00
/*
* Auto SCSI structure which is located
* in host adapter RAM and contains several
* configuration parameters .
*/
# pragma pack(push,1)
typedef struct {
uint8_t aInternalSignature [ 2 ] ;
uint8_t cbInformation ;
uint8_t aHostAdaptertype [ 6 ] ;
uint8_t uReserved1 ;
uint8_t fFloppyEnabled : 1 ,
fFloppySecondary : 1 ,
fLevelSensitiveInterrupt : 1 ,
uReserved2 : 2 ,
uSystemRAMAreForBIOS : 3 ;
uint8_t uDMAChannel : 7 ,
fDMAAutoConfiguration : 1 ,
uIrqChannel : 7 ,
fIrqAutoConfiguration : 1 ;
uint8_t uDMATransferRate ;
uint8_t uSCSIId ;
2017-08-25 23:03:15 +02:00
uint8_t uSCSIConfiguration ;
2017-05-05 01:49:42 +02:00
uint8_t uBusOnDelay ;
uint8_t uBusOffDelay ;
2017-08-25 23:03:15 +02:00
uint8_t uBIOSConfiguration ;
2017-05-05 01:49:42 +02:00
uint16_t u16DeviceEnabledMask ;
uint16_t u16WidePermittedMask ;
uint16_t u16FastPermittedMask ;
uint16_t u16SynchronousPermittedMask ;
uint16_t u16DisconnectPermittedMask ;
uint16_t u16SendStartUnitCommandMask ;
uint16_t u16IgnoreInBIOSScanMask ;
unsigned char uPCIInterruptPin : 2 ;
unsigned char uHostAdapterIoPortAddress : 2 ;
2017-08-27 23:57:47 +02:00
uint8_t fAggressiveRoundRobinMode : 1 ;
2017-05-05 01:49:42 +02:00
uint8_t fVesaBusSpeedGreaterThan33MHz : 1 ;
uint8_t fVesaBurstWrite : 1 ;
uint8_t fVesaBurstRead : 1 ;
uint16_t u16UltraPermittedMask ;
uint32_t uReserved5 ;
uint8_t uReserved6 ;
uint8_t uAutoSCSIMaximumLUN ;
uint8_t fReserved7 : 1 ;
uint8_t fSCAMDominant : 1 ;
uint8_t fSCAMenabled : 1 ;
uint8_t fSCAMLevel2 : 1 ;
unsigned char uReserved8 : 4 ;
uint8_t fInt13Extension : 1 ;
uint8_t fReserved9 : 1 ;
uint8_t fCDROMBoot : 1 ;
2017-08-26 04:38:12 +02:00
unsigned char uReserved10 : 2 ;
uint8_t fMultiBoot : 1 ;
unsigned char uReserved11 : 2 ;
2017-05-05 01:49:42 +02:00
unsigned char uBootTargetId : 4 ;
unsigned char uBootChannel : 4 ;
uint8_t fForceBusDeviceScanningOrder : 1 ;
2017-08-26 04:38:12 +02:00
unsigned char uReserved12 : 7 ;
2017-05-05 01:49:42 +02:00
uint16_t u16NonTaggedToAlternateLunPermittedMask ;
uint16_t u16RenegotiateSyncAfterCheckConditionMask ;
2017-08-26 04:38:12 +02:00
uint8_t aReserved14 [ 10 ] ;
2017-05-05 01:49:42 +02:00
uint8_t aManufacturingDiagnostic [ 2 ] ;
uint16_t u16Checksum ;
} AutoSCSIRam ;
# pragma pack(pop)
/* 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 */
AutoSCSIRam autoSCSIData ; /* Auto SCSI structure */
} structured ;
} HALocalRAM ;
# pragma pack(pop)
/** Structure for the INQUIRE_SETUP_INFORMATION reply. */
# pragma pack(push,1)
typedef struct {
uint8_t uSignature ;
uint8_t uCharacterD ;
uint8_t uHostBusType ;
uint8_t uWideTransferPermittedId0To7 ;
uint8_t uWideTransfersActiveId0To7 ;
ReplyInquireSetupInformationSynchronousValue SynchronousValuesId8To15 [ 8 ] ;
uint8_t uDisconnectPermittedId8To15 ;
uint8_t uReserved2 ;
uint8_t uWideTransferPermittedId8To15 ;
uint8_t uWideTransfersActiveId8To15 ;
2017-10-14 07:03:19 +02:00
} buslogic_setup_t ;
2017-05-05 01:49:42 +02:00
# pragma pack(pop)
/* Structure for the INQUIRE_EXTENDED_SETUP_INFORMATION. */
# pragma pack(push,1)
typedef struct {
uint8_t uBusType ;
uint8_t uBiosAddress ;
uint16_t u16ScatterGatherLimit ;
uint8_t cMailbox ;
uint32_t uMailboxAddressBase ;
uint8_t uReserved1 : 2 ,
fFastEISA : 1 ,
uReserved2 : 3 ,
fLevelSensitiveInterrupt : 1 ,
uReserved3 : 1 ;
uint8_t aFirmwareRevision [ 3 ] ;
uint8_t fHostWideSCSI : 1 ,
fHostDifferentialSCSI : 1 ,
fHostSupportsSCAM : 1 ,
fHostUltraSCSI : 1 ,
fHostSmartTermination : 1 ,
uReserved4 : 3 ;
} ReplyInquireExtendedSetupInformation ;
# pragma pack(pop)
/* Structure for the INQUIRE_PCI_HOST_ADAPTER_INFORMATION reply. */
# pragma pack(push,1)
typedef struct {
uint8_t IsaIOPort ;
uint8_t IRQ ;
uint8_t LowByteTerminated : 1 ,
HighByteTerminated : 1 ,
uReserved : 2 , /* Reserved. */
JP1 : 1 , /* Whatever that means. */
JP2 : 1 , /* Whatever that means. */
JP3 : 1 , /* Whatever that means. */
InformationIsValid : 1 ;
uint8_t uReserved2 ; /* Reserved. */
} BuslogicPCIInformation_t ;
# pragma pack(pop)
2017-08-15 19:49:25 +02:00
# pragma pack(push,1)
typedef struct
{
/** Data length. */
uint32_t DataLength ;
/** Data pointer. */
uint32_t DataPointer ;
/** The device the request is sent to. */
uint8_t TargetId ;
/** The LUN in the device. */
uint8_t LogicalUnit ;
/** Reserved */
unsigned char Reserved1 : 3 ;
/** Data direction for the request. */
unsigned char DataDirection : 2 ;
/** Reserved */
unsigned char Reserved2 : 3 ;
/** Length of the SCSI CDB. */
uint8_t CDBLength ;
/** The SCSI CDB. (A CDB can be 12 bytes long.) */
uint8_t CDB [ 12 ] ;
} ESCMD ;
# pragma pack(pop)
2017-05-05 01:49:42 +02:00
# pragma pack(push,1)
typedef struct {
2017-10-14 07:03:19 +02:00
uint8_t Count ;
uint32_t Address ;
} MailboxInitExtended_t ;
2017-05-05 01:49:42 +02:00
# pragma pack(pop)
2017-10-17 00:49:32 +02:00
# pragma pack(push,1)
2017-05-05 01:49:42 +02:00
typedef struct {
rom_t bios ;
int ExtendedLUNCCBFormat ;
2017-10-14 07:03:19 +02:00
int fAggressiveRoundRobinMode ;
2017-05-05 01:49:42 +02:00
HALocalRAM LocalRAM ;
int PCIBase ;
int MMIOBase ;
int chip ;
2017-08-17 23:16:26 +02:00
int has_bios ;
uint32_t bios_addr ,
bios_size ,
bios_mask ;
2017-08-25 23:03:15 +02:00
uint8_t AutoSCSIROM [ 32768 ] ;
2017-08-27 00:58:44 +02:00
uint8_t SCAMData [ 65536 ] ;
2017-10-14 07:03:19 +02:00
} buslogic_data_t ;
2017-10-17 00:49:32 +02:00
# pragma pack(pop)
2017-05-05 01:49:42 +02:00
2017-05-07 23:42:05 -04:00
enum {
2017-10-14 07:03:19 +02:00
CHIP_BUSLOGIC_ISA_542 ,
2017-05-07 23:42:05 -04:00
CHIP_BUSLOGIC_ISA ,
2017-08-25 23:03:15 +02:00
CHIP_BUSLOGIC_MCA ,
2017-10-14 07:03:19 +02:00
CHIP_BUSLOGIC_EISA ,
2017-08-26 05:36:43 +02:00
CHIP_BUSLOGIC_VLB ,
2017-05-07 23:42:05 -04:00
CHIP_BUSLOGIC_PCI
2017-05-05 01:49:42 +02:00
} ;
2017-10-11 05:40:44 -04:00
# ifdef ENABLE_BUSLOGIC_LOG
2017-10-11 01:17:41 +02:00
int buslogic_do_log = ENABLE_BUSLOGIC_LOG ;
# endif
2017-05-05 01:49:42 +02:00
2017-05-07 23:42:05 -04:00
static void
2017-10-14 07:03:19 +02:00
buslogic_log ( const char * format , . . . )
2017-05-05 01:49:42 +02:00
{
# ifdef ENABLE_BUSLOGIC_LOG
va_list ap ;
if ( buslogic_do_log ) {
va_start ( ap , format ) ;
vprintf ( format , ap ) ;
va_end ( ap ) ;
fflush ( stdout ) ;
}
# endif
}
2017-06-02 02:22:38 +02:00
2017-08-25 23:03:15 +02:00
static wchar_t *
2017-10-14 07:03:19 +02:00
BuslogicGetNVRFileName ( buslogic_data_t * bl )
2017-08-25 23:03:15 +02:00
{
switch ( bl - > chip )
{
2017-10-14 07:03:19 +02:00
case CHIP_BUSLOGIC_ISA_542 :
return L " bt542bh.nvr " ;
2017-08-25 23:03:15 +02:00
case CHIP_BUSLOGIC_ISA :
2017-10-14 07:03:19 +02:00
return L " bt545s.nvr " ;
# ifdef BUSLOGIC_NOT_WORKING
2017-08-25 23:03:15 +02:00
case CHIP_BUSLOGIC_MCA :
2017-08-27 00:58:44 +02:00
return L " bt640a.nvr " ;
2017-08-26 05:36:43 +02:00
case CHIP_BUSLOGIC_VLB :
return L " bt445s.nvr " ;
2017-10-14 07:03:19 +02:00
# endif
2017-08-25 23:03:15 +02:00
case CHIP_BUSLOGIC_PCI :
2017-08-27 00:58:44 +02:00
return L " bt958d.nvr " ;
2017-08-25 23:03:15 +02:00
default :
fatal ( " Unrecognized BusLogic chip: %i \n " , bl - > chip ) ;
return NULL ;
}
}
static void
2017-10-14 07:03:19 +02:00
BuslogicAutoSCSIRamSetDefaults ( x54x_t * dev , uint8_t safe )
2017-08-25 23:03:15 +02:00
{
2017-10-14 07:03:19 +02:00
buslogic_data_t * bl = ( buslogic_data_t * ) dev - > ven_data ;
HALocalRAM * HALR = & bl - > LocalRAM ;
2017-08-25 23:03:15 +02:00
2017-10-14 07:03:19 +02:00
memset ( & ( HALR - > structured . autoSCSIData ) , 0 , sizeof ( AutoSCSIRam ) ) ;
2017-08-25 23:03:15 +02:00
2017-10-14 07:03:19 +02:00
HALR - > structured . autoSCSIData . aInternalSignature [ 0 ] = ' F ' ;
HALR - > structured . autoSCSIData . aInternalSignature [ 1 ] = ' A ' ;
2017-08-25 23:03:15 +02:00
2017-10-14 07:03:19 +02:00
HALR - > structured . autoSCSIData . cbInformation = 64 ;
2017-08-25 23:03:15 +02:00
2017-10-14 07:03:19 +02:00
HALR - > structured . autoSCSIData . aHostAdaptertype [ 0 ] = ' ' ;
HALR - > structured . autoSCSIData . aHostAdaptertype [ 5 ] = ' ' ;
switch ( bl - > chip ) {
case CHIP_BUSLOGIC_ISA_542 :
memcpy ( & ( HALR - > structured . autoSCSIData . aHostAdaptertype [ 1 ] ) , " 542BH " , 5 ) ;
break ;
case CHIP_BUSLOGIC_ISA :
memcpy ( & ( HALR - > structured . autoSCSIData . aHostAdaptertype [ 1 ] ) , " 545S " , 4 ) ;
break ;
# ifdef BUSLOGIC_NOT_WORKING
case CHIP_BUSLOGIC_VLB :
memcpy ( & ( HALR - > structured . autoSCSIData . aHostAdaptertype [ 1 ] ) , " 445S " , 4 ) ;
break ;
case CHIP_BUSLOGIC_MCA :
memcpy ( & ( HALR - > structured . autoSCSIData . aHostAdaptertype [ 1 ] ) , " 640A " , 4 ) ;
break ;
# endif
case CHIP_BUSLOGIC_PCI :
memcpy ( & ( HALR - > structured . autoSCSIData . aHostAdaptertype [ 1 ] ) , " 958D " , 4 ) ;
break ;
}
HALR - > structured . autoSCSIData . fLevelSensitiveInterrupt = ( bl - > chip = = CHIP_BUSLOGIC_PCI ) ? 1 : 0 ;
HALR - > structured . autoSCSIData . uSystemRAMAreForBIOS = 6 ;
if ( bl - > chip ! = CHIP_BUSLOGIC_PCI ) {
switch ( dev - > DmaChannel ) {
case 5 :
HALR - > structured . autoSCSIData . uDMAChannel = 1 ;
2017-08-26 05:36:43 +02:00
break ;
2017-10-14 07:03:19 +02:00
case 6 :
HALR - > structured . autoSCSIData . uDMAChannel = 2 ;
2017-08-26 05:36:43 +02:00
break ;
2017-10-14 07:03:19 +02:00
case 7 :
HALR - > structured . autoSCSIData . uDMAChannel = 3 ;
2017-08-26 05:36:43 +02:00
break ;
2017-10-14 07:03:19 +02:00
default :
HALR - > structured . autoSCSIData . uDMAChannel = 0 ;
2017-08-26 05:36:43 +02:00
break ;
}
2017-10-14 07:03:19 +02:00
}
HALR - > structured . autoSCSIData . fDMAAutoConfiguration = ( bl - > chip = = CHIP_BUSLOGIC_PCI ) ? 0 : 1 ;
2017-08-25 23:03:15 +02:00
2017-10-14 07:03:19 +02:00
if ( bl - > chip ! = CHIP_BUSLOGIC_PCI ) {
switch ( dev - > Irq ) {
case 9 :
HALR - > structured . autoSCSIData . uIrqChannel = 1 ;
break ;
case 10 :
HALR - > structured . autoSCSIData . uIrqChannel = 2 ;
break ;
case 11 :
HALR - > structured . autoSCSIData . uIrqChannel = 3 ;
break ;
case 12 :
HALR - > structured . autoSCSIData . uIrqChannel = 4 ;
break ;
case 14 :
HALR - > structured . autoSCSIData . uIrqChannel = 5 ;
break ;
case 15 :
HALR - > structured . autoSCSIData . uIrqChannel = 6 ;
break ;
default :
HALR - > structured . autoSCSIData . uIrqChannel = 0 ;
break ;
2017-08-25 23:03:15 +02:00
}
2017-10-14 07:03:19 +02:00
}
HALR - > structured . autoSCSIData . fIrqAutoConfiguration = ( bl - > chip = = CHIP_BUSLOGIC_PCI ) ? 0 : 1 ;
2017-08-25 23:03:15 +02:00
2017-10-14 07:03:19 +02:00
HALR - > structured . autoSCSIData . uDMATransferRate = ( ( bl - > chip = = CHIP_BUSLOGIC_ISA_542 ) | | ( bl - > chip = = CHIP_BUSLOGIC_ISA ) ) ? 1 : 0 ;
2017-08-25 23:03:15 +02:00
2017-10-14 07:03:19 +02:00
HALR - > structured . autoSCSIData . uSCSIId = 7 ;
HALR - > structured . autoSCSIData . uSCSIConfiguration = 0x3F ;
HALR - > structured . autoSCSIData . uBusOnDelay = ( bl - > chip = = CHIP_BUSLOGIC_PCI ) ? 0 : 7 ;
HALR - > structured . autoSCSIData . uBusOffDelay = ( bl - > chip = = CHIP_BUSLOGIC_PCI ) ? 0 : 4 ;
HALR - > structured . autoSCSIData . uBIOSConfiguration = ( bl - > has_bios ) ? 0x33 : 0x32 ;
if ( ! safe )
HALR - > structured . autoSCSIData . uBIOSConfiguration | = 0x04 ;
2017-08-25 23:03:15 +02:00
2017-10-14 07:03:19 +02:00
HALR - > structured . autoSCSIData . u16DeviceEnabledMask = 0xffff ;
HALR - > structured . autoSCSIData . u16WidePermittedMask = 0xffff ;
HALR - > structured . autoSCSIData . u16FastPermittedMask = 0xffff ;
HALR - > structured . autoSCSIData . u16DisconnectPermittedMask = 0xffff ;
2017-08-25 23:03:15 +02:00
2017-10-14 07:03:19 +02:00
HALR - > structured . autoSCSIData . uPCIInterruptPin = PCI_INTA ;
HALR - > structured . autoSCSIData . fVesaBusSpeedGreaterThan33MHz = 1 ;
2017-08-25 23:03:15 +02:00
2017-10-14 07:03:19 +02:00
HALR - > structured . autoSCSIData . uAutoSCSIMaximumLUN = 7 ;
2017-08-25 23:03:15 +02:00
2017-10-14 07:03:19 +02:00
HALR - > structured . autoSCSIData . fForceBusDeviceScanningOrder = 1 ;
HALR - > structured . autoSCSIData . fInt13Extension = safe ? 0 : 1 ;
HALR - > structured . autoSCSIData . fCDROMBoot = safe ? 0 : 1 ;
HALR - > structured . autoSCSIData . fMultiBoot = safe ? 0 : 1 ;
HALR - > structured . autoSCSIData . fAggressiveRoundRobinMode = safe ? 0 : 1 ; /* 1 = aggressive, 0 = strict */
2017-08-27 23:57:47 +02:00
}
2017-10-14 07:03:19 +02:00
static void
BuslogicInitializeAutoSCSIRam ( x54x_t * dev )
2017-08-27 23:57:47 +02:00
{
2017-10-14 07:03:19 +02:00
buslogic_data_t * bl = ( buslogic_data_t * ) dev - > ven_data ;
2017-08-27 23:57:47 +02:00
FILE * f ;
2017-10-03 16:26:55 -04:00
f = nvr_fopen ( BuslogicGetNVRFileName ( bl ) , L " rb " ) ;
2017-08-27 23:57:47 +02:00
if ( f )
{
fread ( & ( bl - > LocalRAM . structured . autoSCSIData ) , 1 , 64 , f ) ;
fclose ( f ) ;
f = NULL ;
}
else
{
2017-10-14 07:03:19 +02:00
BuslogicAutoSCSIRamSetDefaults ( dev , 0 ) ;
2017-08-27 23:57:47 +02:00
}
}
static void
2017-10-14 07:03:19 +02:00
buslogic_cmd_phase1 ( void * p )
2017-08-27 23:57:47 +02:00
{
2017-10-14 07:03:19 +02:00
x54x_t * dev = ( x54x_t * ) p ;
2017-08-25 23:03:15 +02:00
2017-10-14 07:03:19 +02:00
if ( ( dev - > CmdParam = = 2 ) & & ( dev - > Command = = 0x90 ) ) {
dev - > CmdParamLeft = dev - > CmdBuf [ 1 ] ;
2017-05-05 01:49:42 +02:00
}
2017-10-14 07:03:19 +02:00
if ( ( dev - > CmdParam = = 10 ) & & ( ( dev - > Command = = 0x97 ) | | ( dev - > Command = = 0xA7 ) ) ) {
dev - > CmdParamLeft = dev - > CmdBuf [ 6 ] ;
dev - > CmdParamLeft < < = 8 ;
dev - > CmdParamLeft | = dev - > CmdBuf [ 7 ] ;
dev - > CmdParamLeft < < = 8 ;
dev - > CmdParamLeft | = dev - > CmdBuf [ 8 ] ;
2017-09-01 19:36:08 +02:00
}
2017-10-14 07:03:19 +02:00
if ( ( dev - > CmdParam = = 4 ) & & ( dev - > Command = = 0xA9 ) ) {
dev - > CmdParamLeft = dev - > CmdBuf [ 3 ] ;
dev - > CmdParamLeft < < = 8 ;
dev - > CmdParamLeft | = dev - > CmdBuf [ 2 ] ;
2017-05-05 01:49:42 +02:00
}
}
2017-10-14 07:03:19 +02:00
static uint8_t
buslogic_get_host_id ( void * p )
2017-05-05 01:49:42 +02:00
{
2017-10-14 07:03:19 +02:00
x54x_t * dev = ( x54x_t * ) p ;
buslogic_data_t * bl = ( buslogic_data_t * ) dev - > ven_data ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
HALocalRAM * HALR = & bl - > LocalRAM ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
if ( bl - > chip = = CHIP_BUSLOGIC_ISA_542 )
return dev - > HostID ;
else
return HALR - > structured . autoSCSIData . uSCSIId ;
2017-05-05 01:49:42 +02:00
}
2017-10-14 07:03:19 +02:00
static uint8_t
buslogic_get_irq ( void * p )
2017-05-05 01:49:42 +02:00
{
2017-10-14 07:03:19 +02:00
x54x_t * dev = ( x54x_t * ) p ;
buslogic_data_t * bl = ( buslogic_data_t * ) dev - > ven_data ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
uint8_t bl_irq [ 7 ] = { 0 , 9 , 10 , 11 , 12 , 14 , 15 } ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
HALocalRAM * HALR = & bl - > LocalRAM ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
if ( bl - > chip = = CHIP_BUSLOGIC_PCI )
return dev - > Irq ;
else
return bl_irq [ HALR - > structured . autoSCSIData . uIrqChannel ] ;
}
2017-10-11 01:17:41 +02:00
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
static uint8_t
buslogic_get_dma ( void * p )
{
x54x_t * dev = ( x54x_t * ) p ;
buslogic_data_t * bl = ( buslogic_data_t * ) dev - > ven_data ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
uint8_t bl_dma [ 4 ] = { 0 , 5 , 6 , 7 } ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
HALocalRAM * HALR = & bl - > LocalRAM ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
if ( bl - > chip = = CHIP_BUSLOGIC_PCI )
return dev - > DmaChannel ;
else
return bl_dma [ HALR - > structured . autoSCSIData . uDMAChannel ] ;
2017-05-05 01:49:42 +02:00
}
2017-10-14 07:03:19 +02:00
static uint8_t
buslogic_param_len ( void * p )
2017-05-05 01:49:42 +02:00
{
2017-10-14 07:03:19 +02:00
x54x_t * dev = ( x54x_t * ) p ;
buslogic_data_t * bl = ( buslogic_data_t * ) dev - > ven_data ;
switch ( dev - > Command ) {
case 0x21 :
return 5 ;
case 0x25 :
case 0x8B :
case 0x8C :
case 0x8D :
case 0x8F :
case 0x92 :
case 0x96 :
return 1 ;
case 0x81 :
return sizeof ( MailboxInitExtended_t ) ;
case 0x83 :
return 12 ;
case 0x90 :
case 0x91 :
return 2 ;
case 0x94 :
return 3 ;
case 0x95 : /* Valid only for PCI */
return ( bl - > chip = = CHIP_BUSLOGIC_PCI ) ? 1 : 0 ;
case 0x97 : /* Valid only for PCI */
case 0xA7 : /* Valid only for PCI */
return ( bl - > chip = = CHIP_BUSLOGIC_PCI ) ? 10 : 0 ;
case 0xA8 : /* Valid only for PCI */
case 0xA9 : /* Valid only for PCI */
return ( bl - > chip = = CHIP_BUSLOGIC_PCI ) ? 4 : 0 ;
default :
return 0 ;
2017-05-05 01:49:42 +02:00
}
}
2017-10-14 07:03:19 +02:00
static void
BuslogicSCSIBIOSDMATransfer ( ESCMD * ESCSICmd , uint8_t TargetID , uint8_t LUN , int dir )
2017-05-05 01:49:42 +02:00
{
2017-10-14 07:03:19 +02:00
uint32_t DataPointer = ESCSICmd - > DataPointer ;
uint32_t DataLength = ESCSICmd - > DataLength ;
2017-10-11 01:17:41 +02:00
uint32_t Address ;
2017-10-14 07:03:19 +02:00
uint32_t TransferLength ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
if ( ESCSICmd - > DataDirection = = 0x03 ) {
/* Non-data command. */
buslogic_log ( " BuslogicSCSIBIOSDMATransfer(): Non-data control byte \n " ) ;
return ;
2017-05-29 01:18:32 +02:00
}
2017-10-14 07:03:19 +02:00
buslogic_log ( " BuslogicSCSIBIOSDMATransfer(): BIOS Data Buffer read: length %d, pointer 0x%04X \n " , DataLength , DataPointer ) ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
/* If the control byte is 0x00, it means that the transfer direction is set up by the SCSI command without
checking its length , so do this procedure for both read / write commands . */
if ( ( DataLength > 0 ) & & ( SCSIDevices [ TargetID ] [ LUN ] . BufferLength > 0 ) ) {
Address = DataPointer ;
TransferLength = MIN ( DataLength , SCSIDevices [ TargetID ] [ LUN ] . BufferLength ) ;
if ( dir & & ( ( ESCSICmd - > DataDirection = = CCB_DATA_XFER_OUT ) | | ( ESCSICmd - > DataDirection = = 0x00 ) ) ) {
buslogic_log ( " BusLogic BIOS DMA: Reading %i bytes from %08X \n " , TransferLength , Address ) ;
DMAPageRead ( Address , ( char * ) SCSIDevices [ TargetID ] [ LUN ] . CmdBuffer , TransferLength ) ;
} else if ( ! dir & & ( ( ESCSICmd - > DataDirection = = CCB_DATA_XFER_IN ) | | ( ESCSICmd - > DataDirection = = 0x00 ) ) ) {
buslogic_log ( " BusLogic BIOS DMA: Writing %i bytes at %08X \n " , TransferLength , Address ) ;
DMAPageWrite ( Address , ( char * ) SCSIDevices [ TargetID ] [ LUN ] . CmdBuffer , TransferLength ) ;
2017-10-11 01:17:41 +02:00
}
}
}
2017-05-05 01:49:42 +02:00
2017-05-29 06:17:13 +02:00
2017-10-11 01:17:41 +02:00
static void
2017-10-14 07:03:19 +02:00
BuslogicSCSIBIOSRequestSetup ( x54x_t * dev , uint8_t * CmdBuf , uint8_t * DataInBuf , uint8_t DataReply )
{
ESCMD * ESCSICmd = ( ESCMD * ) CmdBuf ;
uint32_t i ;
uint8_t temp_cdb [ 12 ] ;
int target_cdb_len = 12 ;
uint8_t target_id = 0 ;
int phase ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
DataInBuf [ 0 ] = DataInBuf [ 1 ] = 0 ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
if ( ( ESCSICmd - > TargetId > 15 ) | | ( ESCSICmd - > LogicalUnit > 7 ) ) {
DataInBuf [ 2 ] = CCB_INVALID_CCB ;
DataInBuf [ 3 ] = SCSI_STATUS_OK ;
return ;
}
buslogic_log ( " Scanning SCSI Target ID %i \n " , ESCSICmd - > TargetId ) ;
SCSIStatus = SCSI_STATUS_OK ;
2017-05-05 01:49:42 +02:00
2017-10-16 20:58:43 +02:00
if ( ! scsi_device_present ( ESCSICmd - > TargetId , 0 ) ) {
buslogic_log ( " SCSI Target ID %i has no device attached \n " , ESCSICmd - > TargetId , ESCSICmd - > LogicalUnit ) ;
2017-10-14 07:03:19 +02:00
DataInBuf [ 2 ] = CCB_SELECTION_TIMEOUT ;
DataInBuf [ 3 ] = SCSI_STATUS_OK ;
2017-05-05 01:49:42 +02:00
} else {
2017-10-16 20:58:43 +02:00
buslogic_log ( " SCSI Target ID %i detected and working \n " , ESCSICmd - > TargetId , ESCSICmd - > LogicalUnit ) ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
buslogic_log ( " Transfer Control %02X \n " , ESCSICmd - > DataDirection ) ;
buslogic_log ( " CDB Length %i \n " , ESCSICmd - > CDBLength ) ;
if ( ESCSICmd - > DataDirection > 0x03 ) {
buslogic_log ( " Invalid control byte: %02X \n " ,
ESCSICmd - > DataDirection ) ;
2017-05-05 01:49:42 +02:00
}
}
2017-10-14 07:03:19 +02:00
x54x_buf_alloc ( ESCSICmd - > TargetId , ESCSICmd - > LogicalUnit , ESCSICmd - > DataLength ) ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
target_cdb_len = scsi_device_cdb_length ( ESCSICmd - > TargetId , ESCSICmd - > LogicalUnit ) ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
if ( ! scsi_device_valid ( ESCSICmd - > TargetId , ESCSICmd - > LogicalUnit ) ) fatal ( " SCSI target on %02i:%02i has disappeared \n " , ESCSICmd - > TargetId , ESCSICmd - > LogicalUnit ) ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
buslogic_log ( " SCSI target command being executed on: SCSI ID %i, SCSI LUN %i, Target %i \n " , ESCSICmd - > TargetId , ESCSICmd - > LogicalUnit , target_id ) ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
buslogic_log ( " SCSI Cdb[0]=0x%02X \n " , ESCSICmd - > CDB [ 0 ] ) ;
for ( i = 1 ; i < ESCSICmd - > CDBLength ; i + + ) {
buslogic_log ( " SCSI Cdb[%i]=%i \n " , i , ESCSICmd - > CDB [ i ] ) ;
}
2017-05-07 23:42:05 -04:00
2017-10-14 07:03:19 +02:00
memset ( temp_cdb , 0 , target_cdb_len ) ;
if ( ESCSICmd - > CDBLength < = target_cdb_len ) {
memcpy ( temp_cdb , ESCSICmd - > CDB , ESCSICmd - > CDBLength ) ;
} else {
memcpy ( temp_cdb , ESCSICmd - > CDB , target_cdb_len ) ;
}
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
SCSIDevices [ ESCSICmd - > TargetId ] [ ESCSICmd - > LogicalUnit ] . BufferLength = ESCSICmd - > DataLength ;
scsi_device_command_phase0 ( ESCSICmd - > TargetId , ESCSICmd - > LogicalUnit , ESCSICmd - > CDBLength , temp_cdb ) ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
phase = SCSIPhase ;
if ( phase ! = SCSI_PHASE_STATUS ) {
if ( phase = = SCSI_PHASE_DATA_IN )
scsi_device_command_phase1 ( ESCSICmd - > TargetId , ESCSICmd - > LogicalUnit ) ;
BuslogicSCSIBIOSDMATransfer ( ESCSICmd , ESCSICmd - > TargetId , ESCSICmd - > LogicalUnit , ( phase = = SCSI_PHASE_DATA_OUT ) ) ;
if ( phase = = SCSI_PHASE_DATA_OUT )
scsi_device_command_phase1 ( ESCSICmd - > TargetId , ESCSICmd - > LogicalUnit ) ;
}
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
x54x_buf_free ( ESCSICmd - > TargetId , ESCSICmd - > LogicalUnit ) ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
buslogic_log ( " BIOS Request complete \n " ) ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
if ( SCSIStatus = = SCSI_STATUS_OK ) {
DataInBuf [ 2 ] = CCB_COMPLETE ;
DataInBuf [ 3 ] = SCSI_STATUS_OK ;
} else if ( SCSIStatus = = SCSI_STATUS_CHECK_CONDITION ) {
DataInBuf [ 2 ] = CCB_COMPLETE ;
DataInBuf [ 3 ] = SCSI_STATUS_CHECK_CONDITION ;
}
2017-08-15 19:49:25 +02:00
2017-10-14 07:03:19 +02:00
dev - > DataReplyLeft = DataReply ;
}
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
static uint8_t
buslogic_cmds ( void * p )
{
x54x_t * dev = ( x54x_t * ) p ;
buslogic_data_t * bl = ( buslogic_data_t * ) dev - > ven_data ;
2017-05-07 23:42:05 -04:00
2017-10-14 07:03:19 +02:00
FILE * f ;
uint16_t TargetsPresentMask = 0 ;
uint8_t Offset ;
int i = 0 ;
int j = 0 ;
MailboxInitExtended_t * MailboxInitE ;
ReplyInquireExtendedSetupInformation * ReplyIESI ;
BuslogicPCIInformation_t * ReplyPI ;
int cCharsToTransfer ;
switch ( dev - > Command ) {
case 0x20 :
dev - > DataReplyLeft = 0 ;
x54x_reset_ctrl ( dev , 1 ) ;
break ;
case 0x21 :
if ( dev - > CmdParam = = 1 )
dev - > CmdParamLeft = dev - > CmdBuf [ 0 ] ;
dev - > DataReplyLeft = 0 ;
break ;
case 0x23 :
memset ( dev - > DataBuf , 0 , 8 ) ;
for ( i = 8 ; i < 15 ; i + + ) {
dev - > DataBuf [ i - 8 ] = 0 ;
for ( j = 0 ; j < 8 ; j + + ) {
if ( scsi_device_present ( i , j ) & & ( i ! = buslogic_get_host_id ( dev ) ) )
dev - > DataBuf [ i - 8 ] | = ( 1 < < j ) ;
}
}
dev - > DataReplyLeft = 8 ;
break ;
case 0x24 :
for ( i = 0 ; i < 15 ; i + + ) {
if ( scsi_device_present ( i , 0 ) & & ( i ! = buslogic_get_host_id ( dev ) ) )
TargetsPresentMask | = ( 1 < < i ) ;
}
dev - > DataBuf [ 0 ] = TargetsPresentMask & 0xFF ;
dev - > DataBuf [ 1 ] = TargetsPresentMask > > 8 ;
dev - > DataReplyLeft = 2 ;
break ;
case 0x25 :
if ( dev - > CmdBuf [ 0 ] = = 0 )
dev - > IrqEnabled = 0 ;
else
dev - > IrqEnabled = 1 ;
return 1 ;
case 0x81 :
x54x_busy_set ( ) ;
dev - > Mbx24bit = 0 ;
MailboxInitE = ( MailboxInitExtended_t * ) dev - > CmdBuf ;
dev - > MailboxInit = 1 ;
dev - > MailboxCount = MailboxInitE - > Count ;
dev - > MailboxOutAddr = MailboxInitE - > Address ;
dev - > MailboxInAddr = MailboxInitE - > Address + ( dev - > MailboxCount * sizeof ( Mailbox32_t ) ) ;
buslogic_log ( " Buslogic Extended Initialize Mailbox Command \n " ) ;
buslogic_log ( " Mailbox Out Address=0x%08X \n " , dev - > MailboxOutAddr ) ;
buslogic_log ( " Mailbox In Address=0x%08X \n " , dev - > MailboxInAddr ) ;
buslogic_log ( " Initialized Extended Mailbox, %d entries at 0x%08X \n " , MailboxInitE - > Count , MailboxInitE - > Address ) ;
dev - > Status & = ~ STAT_INIT ;
dev - > DataReplyLeft = 0 ;
x54x_busy_clear ( ) ;
break ;
case 0x83 :
if ( dev - > CmdParam = = 12 ) {
dev - > CmdParamLeft = dev - > CmdBuf [ 11 ] ;
buslogic_log ( " Execute SCSI BIOS Command: %u more bytes follow \n " , dev - > CmdParamLeft ) ;
} else {
buslogic_log ( " Execute SCSI BIOS Command: received %u bytes \n " , dev - > CmdBuf [ 0 ] ) ;
BuslogicSCSIBIOSRequestSetup ( dev , dev - > CmdBuf , dev - > DataBuf , 4 ) ;
}
break ;
case 0x84 :
dev - > DataBuf [ 0 ] = dev - > fw_rev [ 4 ] ;
dev - > DataReplyLeft = 1 ;
break ;
case 0x85 :
if ( strlen ( dev - > fw_rev ) = = 6 )
dev - > DataBuf [ 0 ] = dev - > fw_rev [ 5 ] ;
else
dev - > DataBuf [ 0 ] = ' ' ;
dev - > DataReplyLeft = 1 ;
break ;
case 0x86 :
if ( bl - > chip = = CHIP_BUSLOGIC_PCI ) {
ReplyPI = ( BuslogicPCIInformation_t * ) dev - > DataBuf ;
memset ( ReplyPI , 0 , sizeof ( BuslogicPCIInformation_t ) ) ;
ReplyPI - > InformationIsValid = 0 ;
switch ( dev - > Base ) {
case 0x330 :
ReplyPI - > IsaIOPort = 0 ;
2017-08-15 19:49:25 +02:00
break ;
2017-10-14 07:03:19 +02:00
case 0x334 :
ReplyPI - > IsaIOPort = 1 ;
2017-05-07 23:42:05 -04:00
break ;
2017-10-14 07:03:19 +02:00
case 0x230 :
ReplyPI - > IsaIOPort = 2 ;
2017-08-25 23:03:15 +02:00
break ;
2017-10-14 07:03:19 +02:00
case 0x234 :
ReplyPI - > IsaIOPort = 3 ;
2017-08-25 23:03:15 +02:00
break ;
2017-10-14 07:03:19 +02:00
case 0x130 :
ReplyPI - > IsaIOPort = 4 ;
2017-05-07 23:42:05 -04:00
break ;
2017-10-14 07:03:19 +02:00
case 0x134 :
ReplyPI - > IsaIOPort = 5 ;
2017-08-27 00:58:44 +02:00
break ;
2017-10-14 07:03:19 +02:00
default :
ReplyPI - > IsaIOPort = 0xFF ;
2017-08-27 00:58:44 +02:00
break ;
2017-10-14 07:03:19 +02:00
}
ReplyPI - > IRQ = dev - > Irq ;
dev - > DataReplyLeft = sizeof ( BuslogicPCIInformation_t ) ;
} else {
dev - > DataReplyLeft = 0 ;
dev - > Status | = STAT_INVCMD ;
}
break ;
case 0x8B :
/* The reply length is set by the guest and is found in the first byte of the command buffer. */
dev - > DataReplyLeft = dev - > CmdBuf [ 0 ] ;
memset ( dev - > DataBuf , 0 , dev - > DataReplyLeft ) ;
if ( bl - > chip = = CHIP_BUSLOGIC_ISA_542 )
i = 5 ;
else
i = 4 ;
cCharsToTransfer = MIN ( dev - > DataReplyLeft , i ) ;
2017-08-27 00:58:44 +02:00
2017-10-14 07:03:19 +02:00
memcpy ( dev - > DataBuf , & ( bl - > LocalRAM . structured . autoSCSIData . aHostAdaptertype [ 1 ] ) , cCharsToTransfer ) ;
break ;
case 0x8C :
dev - > DataReplyLeft = dev - > CmdBuf [ 0 ] ;
memset ( dev - > DataBuf , 0 , dev - > DataReplyLeft ) ;
break ;
case 0x8D :
dev - > DataReplyLeft = dev - > CmdBuf [ 0 ] ;
ReplyIESI = ( ReplyInquireExtendedSetupInformation * ) dev - > DataBuf ;
memset ( ReplyIESI , 0 , sizeof ( ReplyInquireExtendedSetupInformation ) ) ;
switch ( bl - > chip ) {
case CHIP_BUSLOGIC_ISA_542 :
case CHIP_BUSLOGIC_ISA :
case CHIP_BUSLOGIC_VLB :
ReplyIESI - > uBusType = ' A ' ; /* ISA style */
break ;
case CHIP_BUSLOGIC_MCA :
ReplyIESI - > uBusType = ' M ' ; /* MCA style */
break ;
case CHIP_BUSLOGIC_PCI :
ReplyIESI - > uBusType = ' E ' ; /* PCI style */
break ;
}
ReplyIESI - > uBiosAddress = 0xd8 ;
ReplyIESI - > u16ScatterGatherLimit = 8192 ;
ReplyIESI - > cMailbox = dev - > MailboxCount ;
ReplyIESI - > uMailboxAddressBase = dev - > MailboxOutAddr ;
ReplyIESI - > fHostWideSCSI = 1 ; /* This should be set for the BT-542B as well. */
if ( bl - > chip ! = CHIP_BUSLOGIC_ISA_542 )
ReplyIESI - > fLevelSensitiveInterrupt = bl - > LocalRAM . structured . autoSCSIData . fLevelSensitiveInterrupt ;
if ( bl - > chip = = CHIP_BUSLOGIC_PCI )
ReplyIESI - > fHostUltraSCSI = 1 ;
memcpy ( ReplyIESI - > aFirmwareRevision , & ( dev - > fw_rev [ strlen ( dev - > fw_rev ) - 3 ] ) , sizeof ( ReplyIESI - > aFirmwareRevision ) ) ;
buslogic_log ( " Return Extended Setup Information: %d \n " , dev - > CmdBuf [ 0 ] ) ;
break ;
case 0x8F :
if ( bl - > chip = = CHIP_BUSLOGIC_ISA_542 )
bl - > fAggressiveRoundRobinMode = dev - > CmdBuf [ 0 ] & 1 ;
else
bl - > LocalRAM . structured . autoSCSIData . fAggressiveRoundRobinMode = dev - > CmdBuf [ 0 ] & 1 ;
2017-08-27 00:58:44 +02:00
2017-10-14 07:03:19 +02:00
dev - > DataReplyLeft = 0 ;
break ;
case 0x90 :
buslogic_log ( " Store Local RAM \n " ) ;
Offset = dev - > CmdBuf [ 0 ] ;
dev - > DataReplyLeft = 0 ;
memcpy ( & ( bl - > LocalRAM . u8View [ Offset ] ) , & ( dev - > CmdBuf [ 2 ] ) , dev - > CmdBuf [ 1 ] ) ;
dev - > DataReply = 0 ;
break ;
case 0x91 :
buslogic_log ( " Fetch Local RAM \n " ) ;
Offset = dev - > CmdBuf [ 0 ] ;
dev - > DataReplyLeft = dev - > CmdBuf [ 1 ] ;
memcpy ( dev - > DataBuf , & ( bl - > LocalRAM . u8View [ Offset ] ) , dev - > CmdBuf [ 1 ] ) ;
2017-08-27 00:58:44 +02:00
2017-10-14 07:03:19 +02:00
dev - > DataReply = 0 ;
break ;
case 0x92 :
if ( bl - > chip = = CHIP_BUSLOGIC_ISA_542 ) {
dev - > DataReplyLeft = 0 ;
dev - > Status | = STAT_INVCMD ;
break ;
}
2017-08-27 00:58:44 +02:00
2017-10-14 07:03:19 +02:00
dev - > DataReplyLeft = 0 ;
2017-08-27 00:58:44 +02:00
2017-10-14 07:03:19 +02:00
switch ( dev - > CmdBuf [ 0 ] ) {
case 0 :
case 2 :
BuslogicAutoSCSIRamSetDefaults ( dev , 0 ) ;
break ;
case 3 :
BuslogicAutoSCSIRamSetDefaults ( dev , 3 ) ;
break ;
case 1 :
f = nvr_fopen ( BuslogicGetNVRFileName ( bl ) , L " wb " ) ;
if ( f ) {
fwrite ( & ( bl - > LocalRAM . structured . autoSCSIData ) , 1 , 64 , f ) ;
fclose ( f ) ;
f = NULL ;
}
break ;
default :
dev - > Status | = STAT_INVCMD ;
break ;
}
break ;
case 0x94 :
if ( bl - > chip = = CHIP_BUSLOGIC_ISA_542 ) {
dev - > DataReplyLeft = 0 ;
dev - > Status | = STAT_INVCMD ;
break ;
2017-05-05 01:49:42 +02:00
}
2017-08-15 19:49:25 +02:00
2017-10-14 07:03:19 +02:00
if ( dev - > CmdBuf [ 0 ] ) {
buslogic_log ( " Invalid AutoSCSI command mode %x \n " , dev - > CmdBuf [ 0 ] ) ;
dev - > DataReplyLeft = 0 ;
dev - > Status | = STAT_INVCMD ;
} else {
dev - > DataReplyLeft = dev - > CmdBuf [ 2 ] ;
dev - > DataReplyLeft < < = 8 ;
dev - > DataReplyLeft | = dev - > CmdBuf [ 1 ] ;
memcpy ( dev - > DataBuf , bl - > AutoSCSIROM , dev - > DataReplyLeft ) ;
buslogic_log ( " Returning AutoSCSI ROM (%04X %04X %04X %04X) \n " , dev - > DataBuf [ 0 ] , dev - > DataBuf [ 1 ] , dev - > DataBuf [ 2 ] , dev - > DataBuf [ 3 ] ) ;
2017-08-15 19:49:25 +02:00
}
2017-10-14 07:03:19 +02:00
break ;
case 0x95 :
if ( bl - > chip = = CHIP_BUSLOGIC_PCI ) {
if ( dev - > Base ! = 0 )
x54x_io_remove ( dev , dev - > Base ) ;
if ( dev - > CmdBuf [ 0 ] < 6 ) {
dev - > Base = ( ( 3 - ( dev - > CmdBuf [ 0 ] > > 1 ) ) < < 8 ) | ( ( dev - > CmdBuf [ 0 ] & 1 ) ? 0x34 : 0x30 ) ;
x54x_io_set ( dev , dev - > Base ) ;
} else
dev - > Base = 0 ;
dev - > DataReplyLeft = 0 ;
return 1 ;
} else {
dev - > DataReplyLeft = 0 ;
dev - > Status | = STAT_INVCMD ;
2017-08-15 19:49:25 +02:00
}
2017-05-05 01:49:42 +02:00
break ;
2017-10-14 07:03:19 +02:00
case 0x96 :
if ( dev - > CmdBuf [ 0 ] = = 0 )
bl - > ExtendedLUNCCBFormat = 0 ;
else if ( dev - > CmdBuf [ 0 ] = = 1 )
bl - > ExtendedLUNCCBFormat = 1 ;
dev - > DataReplyLeft = 0 ;
break ;
case 0x97 :
case 0xA7 :
/* TODO: Actually correctly implement this whole SCSI BIOS Flash stuff. */
dev - > DataReplyLeft = 0 ;
break ;
case 0xA8 :
if ( bl - > chip ! = CHIP_BUSLOGIC_PCI ) {
dev - > DataReplyLeft = 0 ;
dev - > Status | = STAT_INVCMD ;
2017-05-05 01:49:42 +02:00
break ;
2017-10-14 07:03:19 +02:00
}
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
Offset = dev - > CmdBuf [ 1 ] ;
Offset < < = 8 ;
Offset | = dev - > CmdBuf [ 0 ] ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
dev - > DataReplyLeft = dev - > CmdBuf [ 3 ] ;
dev - > DataReplyLeft < < = 8 ;
dev - > DataReplyLeft | = dev - > CmdBuf [ 2 ] ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
memcpy ( dev - > DataBuf , & ( bl - > SCAMData [ Offset ] ) , dev - > DataReplyLeft ) ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
dev - > DataReply = 0 ;
break ;
case 0xA9 :
if ( bl - > chip ! = CHIP_BUSLOGIC_PCI ) {
dev - > DataReplyLeft = 0 ;
dev - > Status | = STAT_INVCMD ;
break ;
}
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
Offset = dev - > CmdBuf [ 1 ] ;
Offset < < = 8 ;
Offset | = dev - > CmdBuf [ 0 ] ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
dev - > DataReplyLeft = dev - > CmdBuf [ 3 ] ;
dev - > DataReplyLeft < < = 8 ;
dev - > DataReplyLeft | = dev - > CmdBuf [ 2 ] ;
2017-08-25 23:03:15 +02:00
2017-10-14 07:03:19 +02:00
memcpy ( & ( bl - > SCAMData [ Offset ] ) , & ( dev - > CmdBuf [ 4 ] ) , dev - > DataReplyLeft ) ;
dev - > DataReplyLeft = 0 ;
2017-08-25 23:03:15 +02:00
2017-10-14 07:03:19 +02:00
dev - > DataReply = 0 ;
break ;
}
return 0 ;
2017-08-25 23:03:15 +02:00
}
static void
2017-10-14 07:03:19 +02:00
buslogic_setup_data ( void * p )
2017-08-25 23:03:15 +02:00
{
2017-10-14 07:03:19 +02:00
x54x_t * dev = ( x54x_t * ) p ;
ReplyInquireSetupInformation * ReplyISI ;
buslogic_setup_t * bl_setup ;
buslogic_data_t * bl = ( buslogic_data_t * ) dev - > ven_data ;
ReplyISI = ( ReplyInquireSetupInformation * ) dev - > DataBuf ;
bl_setup = ( buslogic_setup_t * ) ReplyISI - > VendorSpecificData ;
bl_setup - > uSignature = ' B ' ;
/* The 'D' signature prevents Buslogic's OS/2 drivers from getting too
* friendly with Adaptec hardware and upsetting the HBA state .
*/
bl_setup - > uCharacterD = ' D ' ; /* BusLogic model. */
switch ( bl - > chip )
{
case CHIP_BUSLOGIC_ISA_542 :
case CHIP_BUSLOGIC_ISA :
bl_setup - > uHostBusType = ' A ' ;
break ;
# ifdef BUSLOGIC_NOT_WORKING
case CHIP_BUSLOGIC_MCA :
bl_setup - > uHostBusType = ' B ' ;
break ;
case CHIP_BUSLOGIC_VLB :
bl_setup - > uHostBusType = ' E ' ;
break ;
# endif
case CHIP_BUSLOGIC_PCI :
bl_setup - > uHostBusType = ' F ' ;
break ;
}
2017-08-25 23:03:15 +02:00
}
2017-10-14 07:03:19 +02:00
static uint8_t
buslogic_is_aggressive_mode ( void * p )
2017-05-05 01:49:42 +02:00
{
2017-10-14 07:03:19 +02:00
x54x_t * dev = ( x54x_t * ) p ;
buslogic_data_t * bl = ( buslogic_data_t * ) dev - > ven_data ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
HALocalRAM * HALR = & bl - > LocalRAM ;
if ( bl - > chip = = CHIP_BUSLOGIC_ISA_542 )
return bl - > fAggressiveRoundRobinMode ;
else
return HALR - > structured . autoSCSIData . fAggressiveRoundRobinMode ;
2017-05-05 01:49:42 +02:00
}
2017-10-14 07:03:19 +02:00
static uint8_t
buslogic_interrupt_type ( void * p )
2017-05-05 01:49:42 +02:00
{
2017-10-14 07:03:19 +02:00
x54x_t * dev = ( x54x_t * ) p ;
buslogic_data_t * bl = ( buslogic_data_t * ) dev - > ven_data ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
if ( bl - > chip = = CHIP_BUSLOGIC_ISA_542 )
return 0 ;
2017-09-08 00:17:49 +02:00
else
2017-10-14 07:03:19 +02:00
return ! ! bl - > LocalRAM . structured . autoSCSIData . fLevelSensitiveInterrupt ;
}
2017-09-01 19:36:08 +02:00
2017-10-14 07:03:19 +02:00
static void
buslogic_reset ( void * p )
{
x54x_t * dev = ( x54x_t * ) p ;
buslogic_data_t * bl = ( buslogic_data_t * ) dev - > ven_data ;
2017-09-01 19:36:08 +02:00
2017-10-14 07:03:19 +02:00
bl - > ExtendedLUNCCBFormat = 0 ;
2017-05-05 01:49:42 +02:00
}
uint8_t buslogic_pci_regs [ 256 ] ;
bar_t buslogic_pci_bar [ 3 ] ;
2017-08-17 23:16:26 +02:00
static void
2017-10-14 07:03:19 +02:00
BuslogicBIOSUpdate ( buslogic_data_t * bl )
2017-08-17 23:16:26 +02:00
{
int bios_enabled = buslogic_pci_bar [ 2 ] . addr_regs [ 0 ] & 0x01 ;
if ( ! bl - > has_bios ) {
return ;
}
/* PCI BIOS stuff, just enable_disable. */
if ( ( bl - > bios_addr > 0 ) & & bios_enabled ) {
mem_mapping_enable ( & bl - > bios . mapping ) ;
mem_mapping_set_addr ( & bl - > bios . mapping ,
bl - > bios_addr , bl - > bios_size ) ;
2017-10-14 07:03:19 +02:00
buslogic_log ( " BT-958D: BIOS now at: %06X \n " , bl - > bios_addr ) ;
2017-08-17 23:16:26 +02:00
} else {
2017-10-14 07:03:19 +02:00
buslogic_log ( " BT-958D: BIOS disabled \n " ) ;
2017-08-17 23:16:26 +02:00
mem_mapping_disable ( & bl - > bios . mapping ) ;
}
}
2017-05-07 23:42:05 -04:00
static uint8_t
BuslogicPCIRead ( int func , int addr , void * p )
2017-05-05 01:49:42 +02:00
{
2017-10-14 07:03:19 +02:00
x54x_t * dev = ( x54x_t * ) p ;
buslogic_data_t * bl = ( buslogic_data_t * ) dev - > ven_data ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
buslogic_log ( " BT-958D: Reading register %02X \n " , addr & 0xff ) ;
2017-08-25 23:03:15 +02:00
2017-05-05 01:49:42 +02:00
switch ( addr ) {
case 0x00 :
return 0x4b ;
case 0x01 :
return 0x10 ;
case 0x02 :
return 0x40 ;
case 0x03 :
return 0x10 ;
case 0x04 :
2017-08-17 23:16:26 +02:00
return buslogic_pci_regs [ 0x04 ] & 0x03 ; /*Respond to IO and memory accesses*/
2017-05-05 01:49:42 +02:00
case 0x05 :
2017-08-17 23:16:26 +02:00
return 0 ;
2017-05-05 01:49:42 +02:00
case 0x07 :
return 2 ;
case 0x08 :
return 1 ; /*Revision ID*/
case 0x09 :
return 0 ; /*Programming interface*/
case 0x0A :
return 0 ; /*Subclass*/
case 0x0B :
2017-08-25 23:03:15 +02:00
return 1 ; /*Class code*/
case 0x0E :
return 0 ; /*Header type */
2017-05-05 01:49:42 +02:00
case 0x10 :
return ( buslogic_pci_bar [ 0 ] . addr_regs [ 0 ] & 0xe0 ) | 1 ; /*I/O space*/
case 0x11 :
return buslogic_pci_bar [ 0 ] . addr_regs [ 1 ] ;
case 0x12 :
return buslogic_pci_bar [ 0 ] . addr_regs [ 2 ] ;
case 0x13 :
return buslogic_pci_bar [ 0 ] . addr_regs [ 3 ] ;
case 0x14 :
return ( buslogic_pci_bar [ 1 ] . addr_regs [ 0 ] & 0xe0 ) ; /*Memory space*/
case 0x15 :
return buslogic_pci_bar [ 1 ] . addr_regs [ 1 ] ;
case 0x16 :
return buslogic_pci_bar [ 1 ] . addr_regs [ 2 ] ;
case 0x17 :
return buslogic_pci_bar [ 1 ] . addr_regs [ 3 ] ;
case 0x2C :
return 0x4b ;
case 0x2D :
return 0x10 ;
case 0x2E :
return 0x40 ;
case 0x2F :
return 0x10 ;
2017-08-17 23:16:26 +02:00
case 0x30 : /* PCI_ROMBAR */
2017-10-14 07:03:19 +02:00
buslogic_log ( " BT-958D: BIOS BAR 00 = %02X \n " , buslogic_pci_bar [ 2 ] . addr_regs [ 0 ] & 0x01 ) ;
2017-08-17 23:16:26 +02:00
return buslogic_pci_bar [ 2 ] . addr_regs [ 0 ] & 0x01 ;
case 0x31 : /* PCI_ROMBAR 15:11 */
2017-10-14 07:03:19 +02:00
buslogic_log ( " BT-958D: BIOS BAR 01 = %02X \n " , ( buslogic_pci_bar [ 2 ] . addr_regs [ 1 ] & bl - > bios_mask ) ) ;
2017-08-27 06:20:38 +02:00
return buslogic_pci_bar [ 2 ] . addr_regs [ 1 ] ;
2017-08-17 23:16:26 +02:00
break ;
case 0x32 : /* PCI_ROMBAR 23:16 */
2017-10-14 07:03:19 +02:00
buslogic_log ( " BT-958D: BIOS BAR 02 = %02X \n " , buslogic_pci_bar [ 2 ] . addr_regs [ 2 ] ) ;
2017-05-05 01:49:42 +02:00
return buslogic_pci_bar [ 2 ] . addr_regs [ 2 ] ;
2017-08-17 23:16:26 +02:00
break ;
case 0x33 : /* PCI_ROMBAR 31:24 */
2017-10-14 07:03:19 +02:00
buslogic_log ( " BT-958D: BIOS BAR 03 = %02X \n " , buslogic_pci_bar [ 2 ] . addr_regs [ 3 ] ) ;
2017-05-05 01:49:42 +02:00
return buslogic_pci_bar [ 2 ] . addr_regs [ 3 ] ;
2017-08-17 23:16:26 +02:00
break ;
2017-05-05 01:49:42 +02:00
case 0x3C :
2017-10-14 07:03:19 +02:00
return dev - > Irq ;
2017-05-05 01:49:42 +02:00
case 0x3D :
2017-09-04 05:15:12 +02:00
return PCI_INTA ;
2017-05-05 01:49:42 +02:00
}
return ( 0 ) ;
}
2017-05-07 23:42:05 -04:00
static void
BuslogicPCIWrite ( int func , int addr , uint8_t val , void * p )
2017-05-05 01:49:42 +02:00
{
2017-10-14 07:03:19 +02:00
x54x_t * dev = ( x54x_t * ) p ;
buslogic_data_t * bl = ( buslogic_data_t * ) dev - > ven_data ;
2017-06-02 17:56:14 +02:00
uint8_t valxor ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
buslogic_log ( " BT-958D: Write value %02X to register %02X \n " , val , addr & 0xff ) ;
2017-08-25 23:03:15 +02:00
2017-05-05 01:49:42 +02:00
switch ( addr ) {
case 0x04 :
2017-06-02 17:56:14 +02:00
valxor = ( val & 0x27 ) ^ buslogic_pci_regs [ addr ] ;
if ( valxor & PCI_COMMAND_IO ) {
2017-10-14 07:03:19 +02:00
x54x_io_remove ( dev , bl - > PCIBase ) ;
2017-06-02 17:56:14 +02:00
if ( ( bl - > PCIBase ! = 0 ) & & ( val & PCI_COMMAND_IO ) ) {
2017-10-14 07:03:19 +02:00
x54x_io_set ( dev , bl - > PCIBase ) ;
2017-05-05 01:49:42 +02:00
}
}
2017-06-02 17:56:14 +02:00
if ( valxor & PCI_COMMAND_MEM ) {
2017-10-14 07:03:19 +02:00
x54x_mem_disable ( dev ) ;
2017-06-02 17:56:14 +02:00
if ( ( bl - > MMIOBase ! = 0 ) & ( val & PCI_COMMAND_MEM ) ) {
2017-10-14 07:03:19 +02:00
x54x_mem_set_addr ( dev , bl - > MMIOBase ) ;
2017-05-05 01:49:42 +02:00
}
}
2017-06-02 17:56:14 +02:00
buslogic_pci_regs [ addr ] = val & 0x27 ;
2017-05-05 01:49:42 +02:00
break ;
case 0x10 :
val & = 0xe0 ;
val | = 1 ;
case 0x11 : case 0x12 : case 0x13 :
/* I/O Base set. */
/* First, remove the old I/O. */
2017-10-14 07:03:19 +02:00
x54x_io_remove ( dev , bl - > PCIBase ) ;
2017-05-05 01:49:42 +02:00
/* Then let's set the PCI regs. */
buslogic_pci_bar [ 0 ] . addr_regs [ addr & 3 ] = val ;
/* Then let's calculate the new I/O base. */
bl - > PCIBase = buslogic_pci_bar [ 0 ] . addr & 0xffe0 ;
/* Log the new base. */
2017-10-14 07:03:19 +02:00
buslogic_log ( " BusLogic PCI: New I/O base is %04X \n " , bl - > PCIBase ) ;
2017-05-05 01:49:42 +02:00
/* We're done, so get out of the here. */
if ( buslogic_pci_regs [ 4 ] & PCI_COMMAND_IO ) {
if ( bl - > PCIBase ! = 0 ) {
2017-10-14 07:03:19 +02:00
x54x_io_set ( dev , bl - > PCIBase ) ;
2017-05-05 01:49:42 +02:00
}
}
return ;
case 0x14 :
val & = 0xe0 ;
case 0x15 : case 0x16 : case 0x17 :
2017-10-14 07:03:19 +02:00
/* MMIO Base set. */
2017-05-05 01:49:42 +02:00
/* First, remove the old I/O. */
2017-10-14 07:03:19 +02:00
x54x_mem_disable ( dev ) ;
2017-05-05 01:49:42 +02:00
/* Then let's set the PCI regs. */
buslogic_pci_bar [ 1 ] . addr_regs [ addr & 3 ] = val ;
/* Then let's calculate the new I/O base. */
bl - > MMIOBase = buslogic_pci_bar [ 1 ] . addr & 0xffffffe0 ;
/* Log the new base. */
2017-10-14 07:03:19 +02:00
buslogic_log ( " BusLogic PCI: New MMIO base is %04X \n " , bl - > MMIOBase ) ;
2017-05-05 01:49:42 +02:00
/* We're done, so get out of the here. */
if ( buslogic_pci_regs [ 4 ] & PCI_COMMAND_MEM ) {
2017-08-25 23:03:15 +02:00
if ( bl - > MMIOBase ! = 0 ) {
2017-10-14 07:03:19 +02:00
x54x_mem_set_addr ( dev , bl - > MMIOBase ) ;
2017-05-05 01:49:42 +02:00
}
}
2017-08-15 19:49:25 +02:00
return ;
2017-08-27 06:20:38 +02:00
2017-08-17 23:16:26 +02:00
case 0x30 : /* PCI_ROMBAR */
case 0x31 : /* PCI_ROMBAR */
case 0x32 : /* PCI_ROMBAR */
case 0x33 : /* PCI_ROMBAR */
buslogic_pci_bar [ 2 ] . addr_regs [ addr & 3 ] = val ;
2017-08-27 06:20:38 +02:00
buslogic_pci_bar [ 2 ] . addr & = 0xffffc001 ;
bl - > bios_addr = buslogic_pci_bar [ 2 ] . addr & 0xffffc000 ;
2017-10-14 07:03:19 +02:00
buslogic_log ( " BT-958D: BIOS BAR %02X = NOW %02X (%02X) \n " , addr & 3 , buslogic_pci_bar [ 2 ] . addr_regs [ addr & 3 ] , val ) ;
2017-08-17 23:16:26 +02:00
BuslogicBIOSUpdate ( bl ) ;
return ;
2017-05-05 01:49:42 +02:00
case 0x3C :
buslogic_pci_regs [ addr ] = val ;
if ( val ! = 0xFF ) {
2017-10-14 07:03:19 +02:00
buslogic_log ( " BusLogic IRQ now: %i \n " , val ) ;
dev - > Irq = val ;
2017-05-05 01:49:42 +02:00
}
return ;
}
}
2017-08-17 23:16:26 +02:00
static void
2017-10-14 07:03:19 +02:00
BuslogicInitializeLocalRAM ( buslogic_data_t * bl )
2017-08-17 23:16:26 +02:00
{
2017-10-14 07:03:19 +02:00
memset ( bl - > LocalRAM . u8View , 0 , sizeof ( HALocalRAM ) ) ;
if ( bl - > chip = = CHIP_BUSLOGIC_PCI ) {
bl - > LocalRAM . structured . autoSCSIData . fLevelSensitiveInterrupt = 1 ;
} else {
bl - > LocalRAM . structured . autoSCSIData . fLevelSensitiveInterrupt = 0 ;
}
bl - > LocalRAM . structured . autoSCSIData . u16DeviceEnabledMask = ~ 0 ;
bl - > LocalRAM . structured . autoSCSIData . u16WidePermittedMask = ~ 0 ;
bl - > LocalRAM . structured . autoSCSIData . u16FastPermittedMask = ~ 0 ;
bl - > LocalRAM . structured . autoSCSIData . u16SynchronousPermittedMask = ~ 0 ;
bl - > LocalRAM . structured . autoSCSIData . u16DisconnectPermittedMask = ~ 0 ;
bl - > LocalRAM . structured . autoSCSIData . fAggressiveRoundRobinMode = 0 ;
bl - > LocalRAM . structured . autoSCSIData . u16UltraPermittedMask = ~ 0 ;
2017-08-17 23:16:26 +02:00
}
2017-08-27 23:57:47 +02:00
void
BuslogicDeviceReset ( void * p )
{
2017-10-14 07:03:19 +02:00
x54x_t * dev = ( x54x_t * ) p ;
buslogic_data_t * bl = ( buslogic_data_t * ) dev - > ven_data ;
2017-08-27 23:57:47 +02:00
2017-10-14 07:03:19 +02:00
x54x_reset_ctrl ( dev , 1 ) ;
BuslogicInitializeLocalRAM ( bl ) ;
BuslogicInitializeAutoSCSIRam ( dev ) ;
2017-08-27 23:57:47 +02:00
}
2017-05-07 23:42:05 -04:00
static void *
2017-10-14 07:03:19 +02:00
buslogic_init ( device_t * info )
2017-05-05 01:49:42 +02:00
{
2017-10-14 07:03:19 +02:00
x54x_t * dev ;
2017-08-27 00:58:44 +02:00
wchar_t * bios_rom_name ;
uint16_t bios_rom_size ;
uint16_t bios_rom_mask ;
uint8_t has_autoscsi_rom ;
wchar_t * autoscsi_rom_name ;
uint16_t autoscsi_rom_size ;
uint8_t has_scam_rom ;
wchar_t * scam_rom_name ;
uint16_t scam_rom_size ;
2017-08-25 23:03:15 +02:00
FILE * f ;
2017-10-14 07:03:19 +02:00
buslogic_data_t * bl ;
2017-10-15 02:43:13 +02:00
uint32_t bios_rom_addr ;
2017-10-14 07:03:19 +02:00
/* Call common initializer. */
dev = x54x_init ( info ) ;
dev - > ven_data = malloc ( sizeof ( buslogic_data_t ) ) ;
memset ( dev - > ven_data , 0x00 , sizeof ( buslogic_data_t ) ) ;
bl = ( buslogic_data_t * ) dev - > ven_data ;
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
dev - > bus = info - > flags ;
dev - > Base = device_get_config_hex16 ( " base " ) ;
dev - > Irq = device_get_config_int ( " irq " ) ;
dev - > DmaChannel = device_get_config_int ( " dma " ) ;
dev - > HostID = 7 ; /* default HA ID */
dev - > setup_info_len = sizeof ( buslogic_setup_t ) ;
dev - > max_id = 7 ;
dev - > int_geom_writable = 1 ;
2017-10-14 18:52:25 +02:00
dev - > cdrom_boot = 0 ;
2017-10-08 05:04:38 +02:00
2017-10-07 22:18:30 -04:00
bl - > chip = info - > local ;
2017-05-05 01:49:42 +02:00
bl - > PCIBase = 0 ;
bl - > MMIOBase = 0 ;
2017-10-15 02:43:13 +02:00
if ( info - > flags & DEVICE_PCI ) {
bios_rom_addr = 0xd8000 ;
bl - > has_bios = device_get_config_int ( " bios " ) ;
} else {
bios_rom_addr = device_get_config_hex20 ( " bios_addr " ) ;
bl - > has_bios = ! ! bios_rom_addr ;
}
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
dev - > ven_cmd_phase1 = buslogic_cmd_phase1 ;
dev - > ven_get_host_id = buslogic_get_host_id ;
dev - > ven_get_irq = buslogic_get_irq ;
dev - > ven_get_dma = buslogic_get_dma ;
dev - > get_ven_param_len = buslogic_param_len ;
dev - > ven_cmds = buslogic_cmds ;
dev - > interrupt_type = buslogic_interrupt_type ;
dev - > is_aggressive_mode = buslogic_is_aggressive_mode ;
dev - > get_ven_data = buslogic_setup_data ;
dev - > ven_reset = buslogic_reset ;
strcpy ( dev - > vendor , " BusLogic " ) ;
if ( ( dev - > Base ! = 0 ) & & ! ( dev - > bus & DEVICE_MCA ) ) {
x54x_io_set ( dev , dev - > Base ) ;
2017-05-05 01:49:42 +02:00
}
2017-10-14 07:03:19 +02:00
switch ( bl - > chip )
{
case CHIP_BUSLOGIC_ISA_542 :
strcpy ( dev - > name , " BT-542BH " ) ;
bios_rom_name = L " roms/scsi/buslogic/BT-542BH_BIOS.rom " ;
bios_rom_size = 0x4000 ;
bios_rom_mask = 0x3fff ;
has_autoscsi_rom = 0 ;
has_scam_rom = 0 ;
dev - > fw_rev = " AA335 " ;
bl - > fAggressiveRoundRobinMode = 1 ;
break ;
case CHIP_BUSLOGIC_ISA :
default :
strcpy ( dev - > name , " BT-545S " ) ;
bios_rom_name = L " roms/scsi/buslogic/BT-545S_BIOS.rom " ;
bios_rom_size = 0x4000 ;
bios_rom_mask = 0x3fff ;
has_autoscsi_rom = 1 ;
autoscsi_rom_name = L " roms/scsi/buslogic/BT-545S_AutoSCSI.rom " ;
autoscsi_rom_size = 0x4000 ;
has_scam_rom = 0 ;
dev - > fw_rev = " AA421E " ;
break ;
# ifdef BUSLOGIC_NOT_WORKING
case CHIP_BUSLOGIC_MCA :
strcpy ( dev - > name , " BT-640A " ) ;
bios_rom_name = L " roms/scsi/buslogic/BT-640_BIOS.rom " ;
bios_rom_size = 0x4000 ;
bios_rom_mask = 0x3fff ;
has_autoscsi_rom = 1 ;
autoscsi_rom_name = L " roms/scsi/buslogic/BT-640_AutoSCSI.rom " ;
autoscsi_rom_size = 0x4000 ;
has_scam_rom = 0 ;
dev - > fw_rev = " BA421E " ;
break ;
# endif
case CHIP_BUSLOGIC_PCI :
strcpy ( dev - > name , " BT-958D " ) ;
bios_rom_name = L " roms/scsi/buslogic/BT-958D_BIOS.rom " ;
bios_rom_size = 0x4000 ;
bios_rom_mask = 0x3fff ;
has_autoscsi_rom = 1 ;
autoscsi_rom_name = L " roms/scsi/buslogic/BT-958D_AutoSCSI.rom " ;
autoscsi_rom_size = 0x8000 ;
has_scam_rom = 1 ;
scam_rom_name = L " roms/scsi/buslogic/BT-958D_SCAM.rom " ;
scam_rom_size = 0x0200 ;
dev - > fw_rev = " AA507B " ;
2017-10-14 18:52:25 +02:00
dev - > cdrom_boot = 1 ;
2017-10-14 07:03:19 +02:00
break ;
}
2017-08-27 00:58:44 +02:00
2017-10-14 07:03:19 +02:00
memset ( bl - > AutoSCSIROM , 0xff , 32768 ) ;
2017-08-27 00:58:44 +02:00
2017-10-14 07:03:19 +02:00
memset ( bl - > SCAMData , 0x00 , 65536 ) ;
2017-08-17 23:16:26 +02:00
2017-10-14 07:03:19 +02:00
if ( bl - > has_bios )
{
bl - > bios_size = bios_rom_size ;
2017-08-17 23:16:26 +02:00
2017-10-14 07:03:19 +02:00
bl - > bios_mask = 0xffffc000 ;
2017-08-27 00:58:44 +02:00
2017-10-15 02:43:13 +02:00
rom_init ( & bl - > bios , bios_rom_name , bios_rom_addr , bios_rom_size , bios_rom_mask , 0 , MEM_MAPPING_EXTERNAL ) ;
2017-08-25 23:03:15 +02:00
2017-10-14 07:03:19 +02:00
if ( has_autoscsi_rom ) {
f = rom_fopen ( autoscsi_rom_name , L " rb " ) ;
if ( f ) {
fread ( bl - > AutoSCSIROM , 1 , autoscsi_rom_size , f ) ;
fclose ( f ) ;
f = NULL ;
2017-08-17 23:16:26 +02:00
}
}
2017-10-14 07:03:19 +02:00
if ( has_scam_rom ) {
f = rom_fopen ( scam_rom_name , L " rb " ) ;
if ( f ) {
fread ( bl - > SCAMData , 1 , scam_rom_size , f ) ;
fclose ( f ) ;
f = NULL ;
}
2017-08-17 23:16:26 +02:00
}
2017-10-14 07:03:19 +02:00
}
else {
bl - > bios_size = 0 ;
2017-08-25 23:03:15 +02:00
2017-10-14 07:03:19 +02:00
bl - > bios_mask = 0 ;
}
2017-05-05 01:49:42 +02:00
if ( bl - > chip = = CHIP_BUSLOGIC_PCI ) {
2017-10-14 07:03:19 +02:00
dev - > pci_slot = pci_add_card ( PCI_ADD_NORMAL , BuslogicPCIRead , BuslogicPCIWrite , dev ) ;
2017-05-05 01:49:42 +02:00
buslogic_pci_bar [ 0 ] . addr_regs [ 0 ] = 1 ;
buslogic_pci_bar [ 1 ] . addr_regs [ 0 ] = 0 ;
2017-06-02 17:56:14 +02:00
buslogic_pci_regs [ 0x04 ] = 3 ;
2017-08-17 23:16:26 +02:00
/* Enable our BIOS space in PCI, if needed. */
2017-10-14 07:03:19 +02:00
if ( bl - > has_bios ) {
2017-08-27 06:20:38 +02:00
buslogic_pci_bar [ 2 ] . addr = 0xFFFFC000 ;
2017-10-14 07:03:19 +02:00
} else {
2017-08-17 23:16:26 +02:00
buslogic_pci_bar [ 2 ] . addr = 0 ;
}
2017-05-05 01:49:42 +02:00
2017-10-14 07:03:19 +02:00
x54x_mem_init ( dev , 0xfffd0000 ) ;
x54x_mem_disable ( dev ) ;
2017-08-17 23:16:26 +02:00
mem_mapping_disable ( & bl - > bios . mapping ) ;
2017-05-05 01:49:42 +02:00
}
2017-10-14 07:03:19 +02:00
buslogic_log ( " Buslogic on port 0x%04X \n " , dev - > Base ) ;
2017-05-05 01:49:42 +02:00
2017-10-16 18:40:34 +02:00
x54x_device_reset ( dev ) ;
2017-09-01 19:36:08 +02:00
2017-10-14 07:03:19 +02:00
if ( bl - > chip ! = CHIP_BUSLOGIC_ISA_542 ) {
BuslogicInitializeLocalRAM ( bl ) ;
BuslogicInitializeAutoSCSIRam ( dev ) ;
2017-09-01 19:36:08 +02:00
}
2017-10-14 07:03:19 +02:00
return ( dev ) ;
2017-05-05 01:49:42 +02:00
}
2017-10-14 07:03:19 +02:00
static device_config_t BT_ISA_Config [ ] = {
2017-05-05 01:49:42 +02:00
{
2017-05-27 03:53:32 +02:00
" base " , " Address " , CONFIG_HEX16 , " " , 0x334 ,
2017-05-05 01:49:42 +02:00
{
{
" 0x330 " , 0x330
} ,
{
" 0x334 " , 0x334
} ,
{
" 0x230 " , 0x230
} ,
{
" 0x234 " , 0x234
} ,
{
" 0x130 " , 0x130
} ,
{
" 0x134 " , 0x134
} ,
{
" "
}
} ,
} ,
{
" irq " , " IRQ " , CONFIG_SELECTION , " " , 9 ,
{
{
" IRQ 9 " , 9
} ,
{
" IRQ 10 " , 10
} ,
{
" IRQ 11 " , 11
} ,
{
" IRQ 12 " , 12
} ,
{
" IRQ 14 " , 14
} ,
{
" IRQ 15 " , 15
} ,
{
" "
}
} ,
} ,
{
" dma " , " DMA channel " , CONFIG_SELECTION , " " , 6 ,
{
{
" DMA 5 " , 5
} ,
{
" DMA 6 " , 6
} ,
{
" DMA 7 " , 7
} ,
{
" "
}
} ,
} ,
2017-10-15 02:43:13 +02:00
{
" bios_addr " , " BIOS Address " , CONFIG_HEX20 , " " , 0 ,
{
{
" Disabled " , 0
} ,
{
" C800H " , 0xc8000
} ,
{
" D000H " , 0xd0000
} ,
{
" D800H " , 0xd8000
} ,
{
" "
}
} ,
} ,
2017-05-05 01:49:42 +02:00
{
" " , " " , - 1
}
} ;
2017-10-08 05:38:45 +02:00
static device_config_t BT958D_Config [ ] = {
{
" base " , " Legacy Address " , CONFIG_HEX16 , " " , 0x334 ,
{
{
" None " , 0
} ,
{
" 0x330 " , 0x330
} ,
{
" 0x334 " , 0x334
} ,
{
" 0x230 " , 0x230
} ,
{
" 0x234 " , 0x234
} ,
{
" 0x130 " , 0x130
} ,
{
" 0x134 " , 0x134
} ,
{
" "
}
} ,
} ,
{
" bios " , " Enable BIOS " , CONFIG_BINARY , " " , 0
} ,
{
" " , " " , - 1
}
} ;
2017-05-07 23:42:05 -04:00
device_t buslogic_device = {
2017-10-14 07:03:19 +02:00
" Buslogic BT-542BH ISA " ,
DEVICE_ISA | DEVICE_AT ,
CHIP_BUSLOGIC_ISA_542 ,
buslogic_init , x54x_close , NULL ,
NULL , NULL , NULL , NULL ,
BT_ISA_Config
} ;
device_t buslogic_545s_device = {
" Buslogic BT-545S ISA " ,
2017-10-10 00:14:15 +02:00
DEVICE_ISA | DEVICE_AT ,
2017-10-07 22:18:30 -04:00
CHIP_BUSLOGIC_ISA ,
2017-10-14 07:03:19 +02:00
buslogic_init , x54x_close , NULL ,
2017-10-10 03:07:29 -04:00
NULL , NULL , NULL , NULL ,
2017-10-14 07:03:19 +02:00
BT_ISA_Config
2017-05-05 01:49:42 +02:00
} ;
2017-05-07 23:42:05 -04:00
device_t buslogic_pci_device = {
2017-08-27 00:58:44 +02:00
" Buslogic BT-958D PCI " ,
2017-10-08 05:38:45 +02:00
DEVICE_PCI ,
2017-10-07 22:18:30 -04:00
CHIP_BUSLOGIC_PCI ,
2017-10-14 07:03:19 +02:00
buslogic_init , x54x_close , NULL ,
2017-10-10 03:07:29 -04:00
NULL , NULL , NULL , NULL ,
2017-10-08 05:38:45 +02:00
BT958D_Config
2017-05-05 01:49:42 +02:00
} ;