diff options
Diffstat (limited to '')
-rw-r--r-- | private/ntos/miniport/oliscsi/oliesc2.h | 1400 |
1 files changed, 1400 insertions, 0 deletions
diff --git a/private/ntos/miniport/oliscsi/oliesc2.h b/private/ntos/miniport/oliscsi/oliesc2.h new file mode 100644 index 000000000..0a11a2ee1 --- /dev/null +++ b/private/ntos/miniport/oliscsi/oliesc2.h @@ -0,0 +1,1400 @@ +/*++ + +Copyright (c) Ing. C. Olivetti & C., S.p.A., 1992 + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + oliesc2.h + +Abstract: + + This module contains the structures specific to the Olivetti ESC-2 + host bus adapter. Data structures that are part of standard ANSI + SCSI will be defined in a header file that will be available to all + SCSI device drivers. + +Authors: + + Kris Karnos and Young-Chi Tan, 1-November-1992 + +Revision History: + + 14-Sep-1993: (v-egidis) + - Added support for the EFP-2 mirroring mode. + +--*/ + +#include <scsi.h> + + +// +// To enable the mirroring code set the following define to 1. +// + +#define EFP_MIRRORING_ENABLED 0 +//#define EFP_MIRRORING_ENABLED 1 + +// +// The following define controls the type of error code returned when the +// mirror breaks for the first time. If the define is set to 1, then the +// SrbStatus/ScsiStatus combination is SRB_STATUS_ERROR/SCSISTAT_BUSY, +// else the SrbStatus is set to SRB_STATUS_BUS_RESET. In the first case +// (busy) the request is retried by the scsiport, whereas in the second case +// (bus reset) the request is retried by the class driver. The busy error +// code is the best one but because of a bug in the scsiport's busy logic, +// the current miniport version returns the other one. +// This define is used only if the EFP_MIRRORING_ENABLED is set to 1. +// + +#define EFP_RETURN_BUSY 0 +//#define EFP_RETURN_BUSY 1 + +// +// EISA controller IDs +// + // hi word = card type; lo word = mfg. +#define ESC1_BOARDID 0x2110893D // ESC-1 (which this ADD won't support) +#define ESC2_BOARDID 0x2210893D // ESC-2 (2z10893d, where z > 1, = ESC2) +#define REV_MASK 0xF0FFFFFF // for masking out the revision level (z). + +// +// Maximum number of EISA slots in system +// + +#define MAX_EISA_SLOTS_STD 16 // # of EISA slots possible (per EISA std) +#define MAX_EISA_SLOTS 8 // max # that Oli machines support + +// +// Maximum number of EISA buses. +// +// Note: If you change this define, you need to change also the ScsiInfo +// variable to ... +// +// SCSI_INFO ScsiInfo[MAX_EISA_BUSES][MAX_EISA_SLOTS_STD]; +// +// ... and of course all the code that uses the variable ... +// +// ScsiInfo[ConfigInfo->SystemIoBusNumber][Slot - 1] +// +// It is very uncommon for a system to have 2 buses of the same type +// (especially old buses like ISA and EISA). +// + +#define MAX_EISA_BUSES 1 // # of EISA buses supported. + +// +// Number of devices and EFP queues per host adapter +// +// Note that this miniport assumes that the host adapter uses target ID 7. +// The maximum # of devices that can be attached to a host adapter is therefore +// 7 targets * 8 LUNs = 56. Because the area we reserve for our queues is fixed +// (ScsiPortGetUncachedExtension can only be called once per host adapter), +// we will always create queues for the maximum # of devices that COULD be +// attached to the host adapter -- rather than the actual number of devices +// that are attached. +// + +#define HA_BUSES 2 // EFP2 has 2 buses ( ESC-2 just 1 ) +#define HA_TARGETS 7 // SCSI targets 0 - 7 (but 7 is adapter) +#define HA_LUNS 8 // SCSI LUNs range 0 - 7 +#define HA_DEVICES (HA_TARGETS * HA_LUNS) + // # possible attached devices per Bus +#define HA_QUEUES ( ( HA_DEVICES * HA_BUSES ) + 1 ) + // queue per device + mailbox queue +#define MAX_HAIDS 4 // max number of H.A. Ids + +#define GET_QINDEX(B,T,L) ( B*HA_DEVICES + T*HA_LUNS + L + 1 ) + +// +// Base of the EISA address space +// + +#define EISA_ADDRESS_BASE 0x0C80 + +// +// Define constants for request completion in case of bus reset +// + +#define ALL_TARGET_IDS -1 +#define ALL_LUNS -1 + +// +// Maximum number of scatter/gather descriptors (the ESC-2 limit is 8192, +// because the EFP extended scatter gather command provides 16 bits to +// describe the scatter gather descriptor table length, accessing 64KB, +// and the size of a scatter gather table element is 8 bytes. 64K/8 = 8K) +// + +//#define MAXIMUM_SGL_DESCRIPTORS 8192 +#define MAXIMUM_SGL_DESCRIPTORS 20 + +// +// Maximum data transfer length +// + +#define MAXIMUM_TRANSFER_SIZE 0xffffffff + + +#define NO_BUS_ID 0xFF + +// +// ESC-2 8-bit command codes (for CCB) and configuration commands +// + +#define START_CCB 0x01 // get CCB for this op. Std I/O request. +#define SEND_CONF_INFO 0x02 // send the Host Adapter config info. +#define RESET_TARGET 0x04 // reset a specified SCSI target +#define SET_CONF_INFO 0x40 // set specific configuration bits +#define GET_CONF_INFO 0x41 // get specific configuration bits +#define GET_FW_VERSION 0x42 // read firmware revision number +#define CHECK_DEVICE_PRESENT 0x43 // check presence of a device + +// +// ESC-2 configuration registers +// + +#define CFG_REGS_NUMBER 8 // 8 configuration registers +#define ATCFG_REGISTER 0x1 // AT-compatibility configuration +#define IRQL_REGISTER 0x2 // Interrupt level + +// +// ESC-2 ATCFG_REGISTER AT-compatibility configuration byte flags/masks +// + +#define AT_ENABLED 0x01 // AT-compatibility mode enabled +#define DISK_80_MASK 0x0E // Mask for disk 80's Target ID +#define DISK_81_MASK 0x70 // Mask for disk 81's Target ID + +// +// ESC-2 IRQL-REGISTER definitions +// + +#define IRQ_MASK 0x03 // Mask for IRQ line bits 0 & 1 + +#define IRQ_0B 0x00 // ID values of bits 0 and 1 in +#define IRQ_0A 0x01 // the IRQL-REGISTER +#define IRQ_05 0x02 +#define IRQ_0F 0x03 +#define IRQB 0x0B // The interrupts values themselves. +#define IRQA 0x0A +#define IRQ5 0x05 +#define IRQF 0x0F + +// +// TYPE_SERVICE command IDs and mask (for ESC-2 using EFP interface) +// + +#define S_EFP_SET 0x01 // Request the EFP interface be enabled +#define S_EFP_START 0x02 // Supply physical addr of q descriptor +#define S_EFP_SETDLG 0x04 // Req cntrlr start on-board diagnostics +#define S_EFP_REPNFUL 0x08 // Prev'ly full reply q no longer full +#define S_EFP_WARN 0x10 // For EFP-2 hw, activate auto-recovery + +#define S_EFP_CMD 0x80 // this is OR'd with the queue number + +// +// TYPE MSG messages and masks for messages (EFP interface) +// + +#define M_INIT_DIAG_OK 0x00 // Successful: efp_set|_start|_set_diag +#define M_REPLY_Q_FULL 0x01 // Reply queue is full + +#define M_ERR_INIT 0x40 // Error during efp_set or efp_start +#define M_ERR_CHECKSUM 0x41 // ROM checksum error has been found +#define M_ERR_EEPROM 0x42 // EEPROM error encountered +#define M_ERR_ARBITER 0x45 // Arbiter error exists +#define M_ERR_SYSBUS 0x49 // System bus cntrlr (ie. BMIC) error +#define M_ERR_ATCOMP 0x4A // AT-compat cntrlr has fault/failure +#define M_ERR_UART 0x4C // Failure in the UART +#define M_ERR_CMD_REJ 0x4E // prev cmd issued by sys was rejected +#define M_ERR_CMDQ_NFUL 0x80 // *MASK* 1xxxxxxx (xxxxxxx is queue #) + +// +// EFP interface queue lengths +// +// Due to restrictions of the NT miniport design, we can no longer +// adjust the length of EFP command queues according to the number +// of attached devices. These constants can, and should, be adjusted +// for the best performance in an "average" configuration of attached +// devices. +// + +// Testing values for queue lengths: to force queue full case. +//#define COMMAND_Q_ENTRIES 5 +//#define REPLY_Q_ENTRIES 5 + +#define COMMAND_Q_ENTRIES 0x20 // 32 entries +#define REPLY_Q_ENTRIES 0x80 // 128 entries + +// +// Other queue equates +// + +#define Q_ENTRY_SIZE 32 // a q entry is 32 bytes (LSG = 2 entries) +#define Q_ENTRY_DWORDS 8 // number of dwords in a Q entry (32byte) +#define Q_ENTRY_SHIFT 5 // for shift multiplies + +#define USER_ID_LIMIT 0x0FFFFFFF // wrap around limit for EFP cmd UserID + // MSB (bit 28-31) reserved for slot # + +// +// Olivetti disk geometry translation +// + +#define HPC_SCSI 16 // #heads for capacity up to 504MB +#define THPC_SCSI 64 // #heads for capacity above 504MB +#define SPT_SCSI 63 // #sectors per track +#define HPCxSPT HPC_SCSI*SPT_SCSI // heads x sectors (up to 504MB) +#define THPCxSPT THPC_SCSI*SPT_SCSI // heads x sectors (above 504MB) + + +// YCT I don't think we need the following CCB definition. What you think ? +// +// First byte of the Command Control Block: +// +// Drive Number / Transfer Direction +// +// -------------------------------------- +// | XFER Dir | Target ID | LU Number | +// -------------------------------------- +// 7 6 5 4 3 2 1 0 +// +// +// Subfield constants: +// + +#define CCB_DATA_XFER_ANY_DIR 0 // The adapter decides +#define CCB_DATA_XFER_IN 0x40 // XFER Dir = 01 +#define CCB_DATA_XFER_OUT 0x80 // XFER Dir = 10 +#define CCB_DATA_XFER_NONE 0xC0 // XFER Dir = 11 +#define CCB_TARGET_ID_SHIFT 3 + +// +// Status Register: bit 15-8: adapter status, bits 7-0: target status +// +// Adapter status after a power cycle: + +#define DIAGNOSTICS_RUNNING 0x53 +#define DIAGNOSTICS_OK_CONFIG_RECEIVED 0x01 +#define DIAGNOSTICS_OK_NO_CONFIG_RECEIVED 0x02 + +// +// The ESC-2 controller (and only it) in EFP mode can return some +// error codes that are not present in the specifications. +// + +//#define NO_ERROR 0x00 +//#define INVALID_COMMAND 0x01 +//#define SELECTION_TIMEOUT_EXPIRED 0x11 +//#define DATA_OVERRUN_UNDERRUN 0x12 +//#define UNEXPECTED_BUS_FREE 0x13 +//#define SCSI_PHASE_SEQUENCE_FAILURE 0x14 +//#define COMMAND_ABORTED 0x15 +//#define COMMAND_TO_BE_ABORTED_NOT_FOUND 0x16 +//#define QUEUE_FULL 0x1F +//#define INVALID_CONFIGURATION_COMMAND 0x20 +//#define INVALID_CONFIGURATION_REGISTER 0x21 +//#define NO_REQUEST_SENSE_ISSUED 0x3B + +#define AUTO_REQUEST_SENSE_FAILURE 0x80 +#define PARITY_ERROR 0x81 +#define UNEXPECTED_PHASE_CHANGE 0x82 +#define BUS_RESET_BY_TARGET 0x83 +#define PARITY_ERROR_DURING_DATA_PHASE 0x84 +#define PROTOCOL_ERROR 0x85 + +// Codes to identify logged errors related to H/W malfunction. +// These codes must be shifted left by 16 bits, to distinguish them from +// the adapter status and extended status after a EFP command. +// +// For use with ScsiPortLogError(). + +#define ESCX_BAD_PHYSICAL_ADDRESS (0x01 << 16) +#define SEND_COMMAND_TIMED_OUT (0x02 << 16) +#define ESCX_RESET_FAILED (0x06 << 16) +#define ESCX_INIT_FAILED (0x07 << 16) +#define ESCX_REPLY_DEQUEUE_ERROR (0x08 << 16) + +#if EFP_MIRRORING_ENABLED + +#define EFP_MISSING_SOURCE_ERROR (0x80 << 16) +#define EFP_MISSING_MIRROR_ERROR (0x81 << 16) +#define EFP_SOURCE_OFFLINE_ERROR (0x82 << 16) +#define EFP_MIRROR_OFFLINE_ERROR (0x83 << 16) + +#endif // EFP_MIRRORING_ENABLED + +// +// Define various timeouts: +// +// RESET_REACTION_TIME number of microseconds the adapter takes to +// change the status register on the reset command. +// +// EFP_RESET_DELAY number of microseconds the driver waits for after +// a EFP-2 reset command. For the current 6/3/93 +// revision of the EFP firmware, this is the time +// the board needs to re-initialize itself. +// +// EFP_RESET_LOOPS maximum number of attempts made by the driver to +// get the diagnostics result from the status +// register after a EFP reset command. +// +// EFP_RESET_INTERVAL number of microseconds the driver waits for after +// each read of the status register (on the reset +// command). +// +// ESC_RESET_DELAY number of microseconds the driver waits for after +// a ESC-2 reset command. The minimum value for +// this define is RESET_REACTION_TIME. +// +// ESC_RESET_LOOPS maximum number of attempts made by the driver to +// get the diagnostics result from the status +// register after a ESC reset command. +// +// ESC_RESET_INTERVAL number of microseconds the driver waits for after +// each read of the status register (on the reset +// command). +// +// POST_RESET_DELAY number of microseconds the adapter needs (!) after +// a successful reset in order to accept the first +// command (this should not happen and needs to be +// investigated). +// +// SEMAPHORE_LOOPS maximum number of attempts made by the driver to +// get the semaphore 0 (each attempt is followed +// by a SEMAPHORE_INTERVAL delay. +// +// SEMAPHRE_INTERVAL number of microseconds the driver waits for before +// re-trying to get the semaphore #0. +// +// WAIT_INT_LOOPS maximum number of attempts made by the driver to +// get a reply for a get config info etc. during the +// initialization phase (polling mode). +// +// WAIT_INT_INTERVAL number of microseconds the driver waits for before +// re-checking the interrupt pending status. +// +// TIMER_WAIT_INT_LOOPS maximum number of attempts made by the driver to +// get a reply for a set/start EFP command during the +// reset phase (polling mode with timer). +// +// TIMER_WAIT_INT_INTERVAL number of microseconds the driver waits for before +// re-checking the interrupt pending status. +// + +#define RESET_REACTION_TIME 80 // 80 usec. +#define EFP_RESET_DELAY 1000000 // 1 sec. +#define EFP_RESET_LOOPS 1200 // 2 min. +#define EFP_RESET_INTERVAL 100000 // 100 msec. +#define ESC_RESET_DELAY 200000 // 200 msec. +#define ESC_RESET_LOOPS 140 // 14 sec. +#define ESC_RESET_INTERVAL 100000 // 100 msec. +#define POST_RESET_DELAY 50000 // 50 msec. +#define SEMAPHORE_LOOPS 750 // 75 msec. +#define SEMAPHORE_INTERVAL 100 // 100 usec. +#define WAIT_INT_LOOPS 10000 // 10 sec. +#define WAIT_INT_INTERVAL 1000 // 1 msec. +#define TIMER_WAIT_INT_LOOPS 1000 // 10 sec. +#define TIMER_WAIT_INT_INTERVAL 10000 // 10 msec. + +// +// If the reset is not completed before the next ESC2_RESET_NOTIFICATION usec. +// unit, we call the "ScsiPortNotification(ResetDetected...)" routine. +// After the call the ScsiPort stops the delivery of SRBs for a little bit +// (~4 sec.). The value of this define is lower than 4 sec. because: +// a) it's more implementation indipendent. +// b) we want really really to make sure that the SRBs are held at the ScsiPort +// level during the reset phase. +// + +#define ESC2_RESET_NOTIFICATION 1000000 // 1 sec. (in usec). + +// +// System/Local Interrupt register +// +// bit 3: Adapter reset w/out reconfiguration (Local Interrupt Register only) +// bit 4: Adapter reset w/ reconfiguration (Local Interrupt Register only) +// bit 7: Interrupt pending (read), reset (write) See ESC_INT_BIT +// + +#define ADAPTER_RESET 0x08 +#define ADAPTER_CFG_RESET 0x10 + +// +// Global Configuration Register bits +// +// Bit 3: 1 = edge-triggered interrupts +// 0 = level-triggered interrupts +// + +#define EDGE_SENSITIVE 8 + +// +// EFP interface register bit definitions +// + + // Local Doorbell register bits +#define EFP_INT_BIT 0x02 // driver -> ctrlr that EFP-2 cmd ready + + // System Doorbell register bits +#define EFP_CMD_COMPL 0x01 // ctrlr -> driver: EFP-2 q cmd completed +#define EFP_TYPE_MSG 0x02 // ctrlr wants to send special EFP message +#define EFP_ACK_INT 0x01 // driver -> ctrlr: interrupt serviced. +#define EFP_ACK_MSG 0x02 // driver -> ctrlr: TYPE_MSG int serviced. + + // ESC-1 High Performance -- + // System and Local Doorbell registers +#define ESC_INT_BIT 0x80 // ESC-1 bit for both sys&local doorbells, + // set interrupt, acknowledge int, etc. + // aka INTERRUPT_PENDING + +// +// System/Local Interrupt Mask Register constants +// + +#define INTERRUPTS_DISABLE 0x00 +#define INTERRUPTS_ENABLE (ESC_INT_BIT | EFP_TYPE_MSG | EFP_CMD_COMPL) + + + // Values of the incoming mailbox semaphore (SEM0) +#define SEM_LOCK 0x01 // write 01 to sem port to test if sem free +#define SEM_GAINED 0x01 // get 01 back if it was free, is now yours +#define SEM_IN_USE 0x03 // get 11 (3) back, if sem not available +#define SEM_UNLOCK 0x00 // release the semaphore + +// +// Command Control Block length +// +#define CCB_FIXED_LENGTH 18 + +// +// SystemIntEnable register bit definition(s) +// + +#define SYSTEM_INTS_ENABLE 0x01 // for SystemIntEnable (bellinte) + +// +// EFP interface Mailbox Command Set +// + +#define MB_GET_INFO 0x0 // get_information +#define MB_DOWNLOAD 0x1 // download (DIAGNOSTIC cmd) +#define MB_UPLOAD 0x2 // upload (DIAGNOSTIC cmd) +#define MB_FORCE_EXE 0x3 // force_execution (DIAGNOSTICS) +#define MB_GET_CONF 0x4 // get_configuration +#define MB_RESET_BUS 0x5 // reset_scsi_bus (For EFP-2 board only) +#define MB_SET_COPY 0x6 // set_copy (MAINTENANCE/MIRRORING) +#define MB_SET_VERIFY 0x7 // set_verify (MAINTENANCE/MIRRORING) +#define MB_DOWNLOAD_FW 0x8 // download_firmware + +// +// EFP read/write command type definitions +// + +#define NCMD_READ 0x10 // data xfer from device to sys memory +#define NCMD_WRITE 0x11 // data xfer from sys memory to device +#define NCMD_NODATA 0x12 // no data xfer normal command + +#define SSG_READ 0x20 // short SG read from device to sys memory +#define SSG_WRITE 0x21 // short SG write from sys memory to device + +#define LSG_READ 0x30 // long SG read from device to sys memory +#define LSG_WRITE 0x31 // long SG write from sys memory to device + +#define ESG_READ 0x40 // extended SG read from dev to sys memory +#define ESG_WRITE 0x41 // extended SG write from sys memory to dev + +// +// EFP Reply entry global result values (see also ESC-1 host adapter statuses) +// + +#define EFP_CMD_SUCC 0x00 // command successful +#define EFP_WARN_ERR 0x01 // warning or fatal error +#define EFP_EISA_ERR 0xFF // EISA bus transfer generic error +// Note that the subset below are the same as their ESC-1 counterparts +#define EFP_LINK_COMP 0x0B // linked command complete with flag +#define EFP_SEL_TIMEOUT 0x11 // selection timeout expired +#define EFP_DATA_RUN 0x12 // data overrun/underrun +#define EFP_BUS_FREE 0x13 // unexpected BUS FREE phase detected +#define EFP_PHASE_ERR 0x14 // SCSI phase sequence failure +#define EFP_CMD_ABORT 0x15 // command aborted +#define EFP_ABORT_LOST 0x16 // cmd to be aborted hasn't been found +#define EFP_INT_Q_FULL 0x1F // internal q is full; wait to send cmds +#define EFP_AUTOREC_OK 0x10 // autonomous recovery proc was OK +#define EFP_AUTOREC_KO 0x18 // autonomous recovery proc failed + +// +// EFP Reply entry Extended Status values (compare to SCSI target statuses) +// + +#define EFP_NO_ERROR 0x00 // nothing to report +#define EFP_CHK_COND 0x30 // check condition +#define EFP_COND_MET 0x31 // condition met +#define EFP_DEV_BUSY 0x32 // target busy +#define EFP_INTER_GOOD 0x34 // intermediate/good +#define EFP_INTER_COND 0x35 // intermediate/condition +#define EFP_RESV_CONF 0x36 // reservation conflict +#define EFP_ABORT_CMD 0x3B // abort command + +// +// EFP Reset result values +// + +#define EFP_RESET_OK 0x0000 // SCSI bus reset succeeded. +#define EFP_RESET_ERROR 0x0001 // SCSI bus reset error. + +// +// device LuExtension SRB-CHAIN definition +// + +#define SRB_CHAIN 0x8000 + +// +// High Performance mode command sent flag +// + +#define RESET_TARGET_SENT 0x80 +#define BUS_RESET_SENT 0x70 + +//******************************************************************* +//************************ STRUCTURES ***************************** +//******************************************************************* + +// +// Incoming mailbox format (GetCmdBlock/SendConfInfo requests) +// + +typedef struct _CMDI { + UCHAR mbi_taskid; // task identifier + UCHAR mbi_cmd; // ESC-1 command code + USHORT mbi_cmdlgt; // command length + ULONG mbi_address; // data address +} CMDI, *PCMDI; + +// +// Outgoing mailbox format (GetCmdBlock/SendConfInfo requests) +// + +typedef struct _CMDO { + UCHAR mbo_taskid; // task identifier + UCHAR mbo_pad; + UCHAR mbo_tastat; // target status + UCHAR mbo_hastat; // Host Adapter status + ULONG mbo_address; // data address +} CMDO, *PCMDO; + +// +// Incoming mailbox format for Read Internal Configuration request +// + +typedef struct _RICI { + UCHAR rici_taskid; // task identifier + UCHAR rici_cmd; // ESC-1 command code = 41H + UCHAR rici_reg; // internal register to read (0-7) +} RICI, *PRICI; + +// +// Outgoing mailbox format for Read Internal Configuration request +// + +typedef struct _RICO { + UCHAR rico_taskid; // task identifier + UCHAR rico_pad; + UCHAR rico_tastat; // target status + UCHAR rico_hastat; // Host Adapter status + UCHAR rico_value; // value of requested register +} RICO, *PRICO; + +// +// Incoming mailbox format for Read Firmware Revision request +// + +typedef struct _RFWI { + UCHAR rfwi_taskid; // task identifier + UCHAR rfwi_cmd; // ESC-1 command code = 42H +} RFWI, *PRFWI; + +// +// Outgoing mailbox format for Read Firmware Revision request +// + +typedef struct _RFWO { + UCHAR rfwo_taskid; // task identifier + UCHAR rfwo_pad; + UCHAR rfwo_tastat; // target status + UCHAR rfwo_hastat; // Host Adapter status + UCHAR rfwo_minor; // minor revision, binary + UCHAR rfwo_major; // major revision, binary +} RFWO, *PRFWO; + +// KMK Note: we've never used Check Device Present. +// +// Incoming mailbox format for Check Device Present request +// + +typedef struct _CDPI { + UCHAR cdpi_taskid; // task identifier + UCHAR cdpi_cmd; // ESC-1 command code = 42H + UCHAR cdpi_target; // target ID +} CDPI; + +// +// Outgoing mailbox format for Check Device Present request +// + +typedef struct _CDPO { + UCHAR cdpo_taskid; // task identifier + UCHAR cdpo_pad; + UCHAR cdpo_tastat; // target status + UCHAR cdpo_hastat; // Host Adapter status + UCHAR cdpo_target; // target ID + UCHAR cdpo_status; // 0 = non present, 1 = present +} CDPO; + +// +// MBOX structure (to facilitate MBI and MBO copies (OUTs) +// + +typedef struct _MBOX { + ULONG mblow; + ULONG mbhigh; +} MBOX, *PMBOX; + +// +// Incoming mailbox command +// + +typedef union _MBI { + CMDI cmd; // get CCB or send config info + RICI ric; // read internal configuration + RFWI rfw; // read firmware revision + CDPI cdp; // check device present + MBOX mbcopy; // for copying an MBI +} MBI, *PMBI; + +// +// Outgoing mailbox command +// + +typedef union _MBO { + CMDO cmd; // get CCB or send config info + RICO ric; // read internal configuration + RFWO rfw; // read firmware revision + CDPO cdp; // check device present + MBOX mbcopy; // for copying an MBO +} MBO, *PMBO; + +// +// ESC-2 registers model +// Note that this is designed to begin with EISA_ADDRESS_BASE, 0x0C80. +// ESC-1 high performance names are in lower case; +// EFP interface names are in upper case. +// + +typedef struct _EISA_CONTROLLER { + UCHAR BoardId[4]; // xC80 + UCHAR Unused[4]; // we use no register in XC84 - XC87 range. + UCHAR GlobalConfiguration; // xC88 - Bit 3 of this register indicates + // level- or edge-triggered interrupts + UCHAR SystemIntEnable; // xC89 - system int enab/ctrl reg (bellinte) + UCHAR CommandSemaphore; // xC8A - Semaphore port 0 for the Incoming + // Service Mailbox Regs aka: SEM0, seminc + UCHAR ResultSemaphore; // xC8B - Semaphore port 1 for the Outgoing + // Msg Mailbox Regs aka: SEM1, semout + UCHAR LocalDoorBellMask; // xC8C - Interrupt mask register for the + // Local Doorbell register (maskinc) + UCHAR LocalDoorBell; // xC8D - Local Doorbell register (bellinc) + UCHAR SystemDoorBellMask; // xC8E - Interrupt mask register for the + // System Doorbell register (maskout) + UCHAR SystemDoorBell; // xC8F - System Doorbell register (bellout) + UCHAR InTypeService; // xC90 - 8-bit Incoming Mbox Reg (TYPE_SERV) + // (aka mbi_addr) + // ESC-1: InTaskId + UCHAR InParm1; // xC91 - parameter 1 to TYPE_SERVICE request + // ESC-1: Command + UCHAR InParm2; // xC92 - parameter 2 to TYPE_SERVICE request + // ESC-1: USHORT CommandLength xC92-xC93 + UCHAR InParm3; // xC93 - parameter 3 to TYPE_SERVICE request + UCHAR InParm4; // xC94 - parameter 4 to TYPE_SERVICE request + // ESC-1: ULONG InAddress xC94-xC97 + UCHAR InReserved1; // xC95 - 8-bit mailbox register reserved + UCHAR InReserved2; // xC96 - 8-bit mailbox register reserved + UCHAR InReserved3; // xC97 - 8-bit mailbox register reserved + UCHAR OutTypeMsg; // xC98 - 8-bit Outgoing Mailbox reg (TYPE_MSG) + // (aka mbo_addr) + // ESC-1: OutTaskId + UCHAR OutReserved1; // xC99 - 8-bit mailbox register reserved + UCHAR OutReserved2; // xC9A - 8-bit mailbox register reserved + // ESC-1: USHORT Status xC9A-xC9B + UCHAR OutReserved3; // xC9B - 8-bit mailbox register reserved + UCHAR OutReserved4; // xC9C - 8-bit mailbox register reserved + // ESC-1: ULONG OutAddress xC9C-xC9F + UCHAR OutReserved5; // xC9D - 8-bit mailbox register reserved + UCHAR OutReserved6; // xC9E - 8-bit mailbox register reserved + UCHAR OutReserved7; // xC9F - 8-bit mailbox register reserved + } EISA_CONTROLLER, *PEISA_CONTROLLER; + +// +// EFP QUEUE STRUCTURES section begins -----> +// + +// +// Queues descriptor header. +// + +typedef struct _QD_HEAD { // 16 bytes + USHORT qdh_maint; // 0001h=MAINTENANCE env; 0000h=USER env. + USHORT qdh_n_cmd_q; // num of cmd queues allocated by system. + USHORT qdh_type_reply; // 1=Ctrlr ints @each reply entry; 0=after 1+ + USHORT qdh_reserved1; + ULONG qdh_reply_q_addr; // phys addr of reply q (must be dword aligned) + USHORT qdh_n_ent_reply; // number of entries in the reply queue + USHORT qdh_reserved2; +} QD_HEAD, *PQD_HEAD; + +// +// Queues descriptor body. NOTE: There is one body element for each +// queue, including the mailbox queue. The mailbox queue descriptor +// is the first descriptor body and is always referred to as queue 0. +// + +typedef struct _QD_BODY { // 16 bytes + UCHAR qdb_scsi_level; // SCSI protocol level. 01h=SCSI-1; 02h=SCSI-2. + UCHAR qdb_channel; // SCSI channel. 01h=1st SCSI chan; 02h=2nd. + UCHAR qdb_ID; // SCSI ID of the device. + UCHAR qdb_LUN; // SCSI LUN of the device. + UCHAR qdb_n_entry_cmd; // num of cmd entries in this queue (must be >=4) + UCHAR qdb_notfull_int; // ctrl int if q goes full to not full (01=yes) + UCHAR qdb_no_ars; // 01h=ARS disabled for this device + UCHAR qdb_timeout; // timeout in seconds (0 hex = infinite wait) + ULONG qdb_cmd_q_addr; // physical address of cmd queue. + ULONG qdb_reserved; +} QD_BODY, *PQD_BODY; + +// +// Application field definitions for the EFP Get_Information command. +// + +typedef struct _GET_INFO { // 16 bytes + UCHAR gi_fw_rel[3]; // byte0=minor; byte1=minor*10; byte 2=major + UCHAR gi_scsi_lev; // SCSI level supported by the ctrlr (ESC2: 01) + UCHAR gi_env; // bit packed field defining mirroring environment + UCHAR gi_link; // defining LINKED command constraints + UCHAR gi_maxcmds; // max size of a cmd q; # of 32-byte cmd entries + UCHAR gi_res1; // reserved + UCHAR gi_id1; // controller ID on first SCSI bus + UCHAR gi_id2; // controller ID on second SCSI bus + UCHAR gi_id3; // controller ID on third SCSI bus + UCHAR gi_id4; // controller ID on fourth SCSI bus + ULONG gi_res2; // reserved +} GET_INFO, *PGET_INFO; + +// +// Structure of info returned from the EFP Get_Configuration cmd. +// + +typedef struct _GET_CONF { // 8 bytes per structure, 1 struc per device + UCHAR gc_dev_type; // SCSI device type + UCHAR gc_dev_qual; // SCSI device type qualifier + UCHAR gc_scsi_level; // SCSI protocol level supported by the device + UCHAR gc_env; // EFP interface environment of disk device + UCHAR gc_channel; // SCSI channel to which device is connected + UCHAR gc_id; // SCSI target ID + UCHAR gc_lun; // SCSI Logical Unit Number + UCHAR gc_res; // reserved +} GET_CONF, *PGET_CONF; + + +#if EFP_MIRRORING_ENABLED + +// +// defines for the gc_env of the GET_CONF struct +// + +#define EFP_DUAL_MIRRORING 0x20 // dual bus mirroring +#define EFP_SINGLE_MIRRORING 0x10 // single bus mirroring +#define EFP_DISK_MIRROR 0x02 // mirrored disk presence +#define EFP_DISK_SOURCE 0x01 // source disk presence + +#endif // EFP_MIRRORING_ENABLED + +// +// Flexible structure to specific results for a mailbox command's reply +// + +typedef union _MBAPPL { // see MBRPLY + GET_INFO appgi; // application field for get_information cmd + GET_CONF appgc; // application field for get_configuration cmd +} MBAPPL, *PMBAPPL; + +// +// Mailbox command entry structure (EFP spec) +// + +typedef struct _MAILBOX_CMD { // 32 bytes + ULONG mbc_userid; // command identifier. + UCHAR mbc_sort; // cmd can be sorted (1=yes) + UCHAR mbc_prior; // cmd priority. range 00h (hi) -> FFh (lo). + UCHAR mbc_reserved; // reserved for future use. + UCHAR mbc_cmd_type; // valid mailbox command code (see EFP spec) + ULONG mbc_length; // length of data transfer in bytes. + ULONG mbc_user_data[4]; // generic parameters for the command. + ULONG mbc_addr; // phys addr of buffer in system ram +} MAILBOX_CMD, *PMAILBOX_CMD; // where data is to be transferred to/from. + +// +// Mailbox reply structure (EFP spec) +// + +typedef struct _MAILBOX_REPLY { // 32 bytes + ULONG mbr_userid; // command identifier. + ULONG mbr_length; // length of data xfer successfully completed. + ULONG mbr_reserved; // reserved for future use. + MBAPPL mbr_appl; // specific results for each command. + USHORT mbr_status; // command global result (see spec). + UCHAR mbr_cmd_q; // command queue to which the reply refers. + UCHAR mbr_flag; // if controller sets to 1, response is valid; +} MAILBOX_REPLY, *PMAILBOX_REPLY; // otherwise, response is invalid. + +// +// Normal command structure. (Note: CDB defined in SCSI.H). +// + +typedef struct _NORMAL_CMD { // 32 bytes + ULONG ncmd_userid; // command identifier. + UCHAR ncmd_sort; // cmd can be sorted (1=yes) + UCHAR ncmd_prior; // cmd priority. range 00h (hi) -> FFh (lo). + UCHAR ncmd_mod; // mode. 0=norm/maint on ESC-2 + UCHAR ncmd_cmd_type; // 10h=dev->mem; 11h=mem->dev; 12h=noxfer. + UCHAR ncmd_cdb_l; // length of SCSI cmd block. + UCHAR ncmd_reserved[3]; // reserved + ULONG ncmd_length; // length of the data transfer. + CDB ncmd_cdb; // cmd descriptor block (SCSI CDB - size varies). + ULONG ncmd_address; // physaddr of system mem buf for data xfer. +} NORMAL_CMD, *PNORMAL_CMD; + +// +// Short scatter/gather commands definition. +// + +typedef struct _SHORT_SG { // 32 bytes + ULONG ssg_userid; // cmd id. + UCHAR ssg_sort; // cmd can be sorted (1=YES) + UCHAR ssg_prior; // cmd priority. range 00h (hi) -> FFh (lo). + UCHAR ssg_mod; // mode. 0=norm/maint on ESC-2 + UCHAR ssg_cmd_type; // cmd code. 20h=short read SG. 21h="write. + ULONG ssg_log_blk; // logical block address of the SCSI device. + UCHAR ssg_size_blk; // log. block size of the disk in 256byte units + UCHAR ssg_reserved; // reserved for future use + USHORT ssg_l1; // length of the buffer associated w/ A1 + USHORT ssg_l2; // length of the buffer associated w/ A2 + USHORT ssg_l3; // length of the buffer associated w/ A3 + ULONG ssg_a1; // physical address associated with L1 + ULONG ssg_a2; // physical address associated with L2 + ULONG ssg_a3; // physical address associated with L3 +} SHORT_SG, *PSHORT_SG; + +// +// Long scatter/gather commands definition. +// + +typedef struct _LONG_SG { // 64 bytes + ULONG lsg_userid; // cmd id. + UCHAR lsg_sort; // cmd can be sorted (1=YES) + UCHAR lsg_prior; // cmd priority. range 00h (hi) -> FFh (lo). + UCHAR lsg_mod; // mode. 0=norm/maint on ESC-2 + UCHAR lsg_cmd_type; // cmd code. 30h=long read SG; 31h="write. + ULONG lsg_log_blk; // logical block address of the SCSI device. + UCHAR lsg_size_blk; // log. block size of the disk in 256byte units + UCHAR lsg_reserved; // reserved for future use + USHORT lsg_l1; // length of the buffer associated w/ A1 + USHORT lsg_l2; // length of the buffer associated w/ A2 + USHORT lsg_l3; // length of the buffer associated w/ A3 + ULONG lsg_a1; // physical address assocated with L1 + ULONG lsg_a2; // physical address assocated with L2 + ULONG lsg_a3; // physical address assocated with L3 + USHORT lsg_link; // must be FFFF hex; log link to prev cmd entry. + USHORT lsg_l4; // length of the buffer associated w/ A4 + USHORT lsg_l5; // length of the buffer associated w/ A5 + USHORT lsg_l6; // length of the buffer associated w/ A6 + USHORT lsg_l7; // length of the buffer associated w/ A7 + USHORT lsg_l8; // length of the buffer associated w/ A8 + ULONG lsg_a4; // physical address assocated with L4 + ULONG lsg_a5; // physical address assocated with L5 + ULONG lsg_a6; // physical address assocated with L6 + ULONG lsg_a7; // physical address assocated with L7 + ULONG lsg_a8; // physical address assocated with L8 +} LONG_SG, *PLONG_SG; + +// +// Extended scatter/gather commands definition. +// + +typedef struct _EXTENDED_SG { // 32 bytes + ULONG esg_userid; // cmd id. + UCHAR esg_sort; // cmd can be sorted (1=YES) + UCHAR esg_prior; // cmd priority. range 00h (hi) -> FFh (lo). + UCHAR esg_mod; // mode. 0=norm/maint on ESC-2 + UCHAR esg_cmd_type; // cmd code. 40h=extended read SG; 41h="write. + UCHAR esg_cdb_l; // length of SCSI cmd block. + UCHAR esg_reserved1[3]; + USHORT esg_lb; // length of the scatter gather descriptor table. + USHORT esg_reserved2; + CDB esg_cdb; // cmd descriptor block (SCSI CDB). + ULONG esg_address; // physaddr of scatter gather descriptor table. +} EXTENDED_SG, *PEXTENDED_SG; + +// +// Reply structure for NORMAL/MAINTENANCE environment. (NOTE: There is +// no MIRRORING environment supported by the ESC-2). SENSE_DATA in SCSI.H. +// + +typedef struct _NORMAL_REPLY { // 32 bytes + ULONG nrply_userid; // cmd id. + ULONG nrply_scsi_len; // length of data transfer. + SENSE_DATA nrply_sense; // extended info about error detected + USHORT nrply_reserved; // + UCHAR nrply_status; // cmd global result (0=success;1=warn/err;more) + UCHAR nrply_ex_stat; // extended status (see EFP spec) + UCHAR nrply_cmd_q; // command queue to which the reply refers. + UCHAR nrply_flag; // = 1 means response valid; = 0, resp invalid. +} NORMAL_REPLY, *PNORMAL_REPLY; + + +#if EFP_MIRRORING_ENABLED + +// +// Reply structure for MIRRORING environment. +// + +typedef struct _MIRROR_REPLY { // 32 bytes + + ULONG mrply_userid; // cmd id. + ULONG mrply_scsi_len; // length of data transfer. + UCHAR mrply_valid1; // error source. + UCHAR mrply_sense1; // sense key. + UCHAR mrply_addit1; // additional sense code. + UCHAR mrply_qualif1; // additional sense code qualifier. + ULONG mrply_info1; // information bytes of request sense xdata. + UCHAR mrply_valid2; // error source. + UCHAR mrply_sense2; // sense key. + UCHAR mrply_addit2; // additional sense code. + UCHAR mrply_qualif2; // additional sense code qualifier. + ULONG mrply_info2; // information bytes of request sense xdata. + USHORT mrply_reserved; // + UCHAR mrply_off_attr; // "off line" device attribute. + UCHAR mrply_d_off; // "off line" device SCSI ID. + UCHAR mrply_status; // cmd global result. + UCHAR mrply_ex_stat; // mirroring state (0=OK, 1=KO). + UCHAR mrply_cmd_q; // cmd queue to which the reply refers. + UCHAR mrply_flag; // 3=response is valid, 0=response is invalid. + +} MIRROR_REPLY, *PMIRROR_REPLY; + +// +// "flag" field defines +// + +#define MREPLY_VALID 0x03 // mirroring reply valid +#define NREPLY_VALID 0x01 // normal/maintenance reply valid + +// +// "off_attr" field defines +// + +#define EFP_SOURCE_OFFLINE 0x01 // source disk off line +#define EFP_MIRROR_OFFLINE 0x02 // mirror disk off line + +// +// "valid" field defines (specific to the mirroring environment) +// + +#define EFP_SENSE_NO_INFO 0x70 // info doesn't relate to SCSI device +#define EFP_SENSE_INFO 0xF0 // info relates to SCSI device + +// +// Sense data struct for mirroring replays. +// + +typedef struct _MREPLY_SDATA { + + UCHAR Valid; // error source. + UCHAR Sense; // sense key. + UCHAR Addit; // additional sense code. + UCHAR Qualif; // additional sense code qualifier. + ULONG Info; // information bytes of request sense xdata. + +} MREPLY_SDATA, *PMREPLY_SDATA; + +// +// EFP_FT_TYPE is an enumerated field that describes the FT types. +// + +typedef enum _EFP_FT_TYPE { + + EfpFtNone, + EfpFtSingleBus, + EfpFtDualBus + +} EFP_FT_TYPE, *PEFP_FT_TYPE; + +// +// EFP_FT_MEMBER_STATE is an enumerated field that describes the state of +// one member of the SCSI mirror. +// + +typedef enum _EFP_FT_MEMBER_STATE { + + EfpFtMemberHealthy, + EfpFtMemberMissing, + EfpFtMemberDisabled + +} EFP_FT_MEMBER_STATE, *PEFP_FT_MEMBER_STATE; + +// +// Mirroring macros. +// + +#define D_OFF_TO_LUN(x) (((x) >> 5) & 0x7) +#define D_OFF_TO_TARGET(x) (((x) >> 2) & 0x7) +#define D_OFF_TO_PATH(x) (((x) + 3) & 0x3) + +#endif // EFP_MIRRORING_ENABLED + + +// +// Flexible structure to hold an EFP queue entry (command or reply) +// + +// START NOTE EFP_MIRRORING_ENABLED. +// +// The DequeueEfpReply routine always uses the NORMAL_REPLY struct to +// dequeue a request. This is possible because the "flag" field is at +// the same offset in both structures (NORMAL_REPLY and MIRROR_REPLY). +// +// The DequeueEfpReply routine validates the reply entry checking if the +// "flag" field is different from zero. This is OK because a good reply +// has the "flag" field is set to 1 in NORMAL/MAINTENANCE mode and to 3 +// in MIRRORING mode. A value of zero means reply not good for both +// environments. +// +// The OliEsc2Interrupt routine always uses the "userid" field of the +// NORMAL_REPLY struct to retrieve the SRB. This is OK because the "userid" +// field is at the same offset in both structures (NORMAL_REPLY and +// MIRROR_REPLY). +// +// END NOTE EFP_MIRRORING_ENABLED. + +typedef union _Q_ENTRY { // see ACB's Qbuf, work space for q cmds/replies + MAILBOX_CMD qmbc; + MAILBOX_REPLY qmbr; + NORMAL_CMD qncmd; + SHORT_SG qssg; + EXTENDED_SG qesg; + NORMAL_REPLY qnrply; + +#if EFP_MIRRORING_ENABLED + + MIRROR_REPLY qmrply; + +#endif // EFP_MIRRORING_ENABLED + +} Q_ENTRY, *PQ_ENTRY; + + +// +// EFP Command Queue definition (for both mailbox and device command queues) +// +// Note: this structure need to be ULONG algned! +// + +typedef struct _EFP_COMMAND_QUEUE { + UCHAR Cmd_Q_Get; // get pointer + UCHAR Cmd_Q_Res1; // reserved for future use + UCHAR Cmd_Q_Put; // put pointer + UCHAR Cmd_Q_Res2; // reserved for future use + Q_ENTRY Cmd_Entries[COMMAND_Q_ENTRIES]; +} EFP_COMMAND_QUEUE, *PCOMMAND_QUEUE; + +// +// Used by DevicesPresent array to record which devices are attached, +// and to aid in mapping Target/Lun (TarLun) to queue number. +// + +typedef struct _TAR_Q { + BOOLEAN present; + UCHAR qnumber; + PCOMMAND_QUEUE qPtr; + +#if EFP_MIRRORING_ENABLED + + BOOLEAN KnownError; // TRUE=error already logged + EFP_FT_TYPE Type; // Mirroring type + EFP_FT_MEMBER_STATE SourceDiskState; // Source disk state + EFP_FT_MEMBER_STATE MirrorDiskState; // Mirror disk state + +#endif // EFP_MIRRORING_ENABLED + +} TAR_Q, *PTAR_Q; + + +// +// <----- EFP QUEUE STRUCTURES section ends +// + + +// +// Scatter Gather descriptor +// + +typedef struct _SG_DESCRIPTOR { + ULONG Address; + ULONG Length; +} SG_DESCRIPTOR, *PSG_DESCRIPTOR; + +// +// Scatter Gather descriptor list (SGL) +// +// YCT - we may reduce the size of MAXIMUM_SGL_DESCRITORS, adjust it later. + +typedef struct _SG_LIST { // KMK ?? + SG_DESCRIPTOR Descriptor[MAXIMUM_SGL_DESCRIPTORS]; +} SG_LIST, *PSG_LIST; + +#pragma pack(1) + +typedef struct _CCB { // KMK ?? Compare to our old definition + // We may not need this. Revisit. + // + // This first portion is the structure expected by the ESC-1. + // Its size is CCB_FIXED_LENGTH and does NOT include the variable + // length field Cdb (which can be 6, 10 or 12 bytes long). + // + + UCHAR TaskId; // CCB byte 0 (bits 7-6: xfer dir; + // bits 5-3: target ID; + // bits 2-0: LUN) + UCHAR CdbLength; // CCB byte 1 SCSI Command Descriptor + // Block length + ULONG DataLength; // CCB bytes 2-5 Total data transfer + // length + ULONG DataAddress; // CCB bytes 6-9 Data segment address + ULONG AdditionalRequestBlockLength; // CCB bytes 10-13 Length of the + // scatter/gather list + ULONG LinkedCommandAddress; // CCB bytes 14-17 Not used + UCHAR Cdb[12]; // CCB bytes 18-29 SCSI Command + // Descriptor Block + // + // The following portion is for the miniport driver use only + // + + //PVOID SrbAddress; // Address of the related SRB + //EFP_SGL Sgl; // Scatter/gather data segment list + +} CCB, *PCCB; + +#pragma pack() + + +// +// The first portion is the default EFP 32 byte command structure ( not +// including the LSG command which is 64 bytes). The SrbAddress and Sgl +// are needed for command reference. +// +typedef struct _EFP_SGL { // SRB extension for EFP command and SGL + Q_ENTRY EfpCmd; + PVOID SrbAddress; // address of the associated SRB + SG_LIST Sgl; // Scatter/Gather data segment list + USHORT SGCount; // SG descriptor count + PSCSI_REQUEST_BLOCK NextSrb; // linked unprocessed SRB entry + USHORT QueueControl; // SRB queue control field + + CCB pCCB; // for RESET_TARGET ( Abort) command +} EFP_SGL, *PEFP_SGL; + + +// +// ESC-1 Command Control Block (byte-aligned) +// + +// KMK Here's our old definition, for comparison... +//** Command control block structure (CCB) +//typedef struct _CCB { +// UCHAR CCB_xfer; // targetID/LUN/direction +// UCHAR CCB_scsilgt; // SCSI command length +// ULONG CCB_datalen; // data length +// ULONG CCB_address; // data address +// ULONG CCB_SG_lgt; // scatter/gather block length +// ULONG CCB_nextcmd; // linked command address +// ICDB CCB_cdb; // CDB area +//} CCB; + +// +// This structure is allocated on a per logical unit basis. It is necessary +// for the Abort request handling. +// + +typedef struct _LU_EXTENSION { // KMK ?? + SHORT NumberOfPendingRequests; // Number of SRBs for a logical unit +} LU_EXTENSION, *PLU_EXTENSION; + + +// +// The following structure is allocated from noncached memory, which +// we can only allocate once per adapter, and can not de-allocate. +// We use this area for the EFP command and reply queues, and associated +// overhead. +// + +typedef struct _NONCACHED_EXTENSION { + + // + // EFP Get Configuration returned information; index: 0 to (maxdevs-1) + // + + GET_CONF GetConfigInfo[HA_QUEUES - 1]; // entry #0 = 1st device info + + // + // EFP Queues Descriptor + // + + QD_HEAD QD_Head; // EFP Queues Descriptor head + QD_BODY QD_Bodies[HA_QUEUES]; // EFP Q Desc. body strucs; index:Q# + + // + // EFP Reply Queue (one reply queue per host adapter) + // + + Q_ENTRY Reply_Q[REPLY_Q_ENTRIES]; + + // + // EFP Command Queue + // + + EFP_COMMAND_QUEUE Command_Qs[1]; + +} NONCACHED_EXTENSION, *PNONCACHED_EXTENSION; + + +// +// Device extension +// + +typedef struct _HW_DEVICE_EXTENSION { + + PEISA_CONTROLLER EisaController; // SCSI I/O address + PNONCACHED_EXTENSION NoncachedExt; // address of the uncached extension + // used for EFP cmd and reply queues. + // + // Physical address of the queues descriptor + // + + ULONG QueuesDescriptor_PA; + + // Device Present array: maps which devices are connected to the + // controller, as reported by Get Configuration (this information can + // be extracted from GetConfigInfo, but is more easily accessed in this + // form). The TAR_Q structure also provides a field that maps the device + // to the corresponding device queue. + // + // Entries should be accessed by TarLun . The first entry is therefore + // vacant. + // + + TAR_Q DevicesPresent[HA_QUEUES]; + + // + // General configuration information + // + + BOOLEAN Esc2; // Controller type + UCHAR NumberOfBuses; // number of SCSI buses + BOOLEAN CfgRegsPresent[CFG_REGS_NUMBER]; + UCHAR CfgRegs[CFG_REGS_NUMBER]; + UCHAR IRQ_In_Use; // the IRQ used by this host adapter + + // + // Reset variables. + // + + ULONG ResetInProgress; // >0 if reset is in progress. + ULONG ResetTimerCalls; // # of timer calls before time-out. + ULONG ResetNotification; // Reset notification trigger. + + // + // Enqueue/dequeue information. + // + + Q_ENTRY Q_Buf; // scratch space for building an EFP + // command queue element + UCHAR Q_Full_Map[HA_QUEUES]; // cmd q full (1=full,0=not) index: q # + UCHAR Reply_Q_Full_Flag; + UCHAR Reply_Q_Get; // Get pointer for reply queue + UCHAR RQ_In_Process; // reply queue in process flag + + USHORT TotalAttachedDevices; // number of SCSI devices attached to ctrl + + // + // EFP interface's Get Information returned data + // + + UCHAR FW_Rel[3]; // byte2: major; b1: minor*10; b0:minor + UCHAR SCSI_Level; // SCSI level supported by controller + UCHAR Adapter_ID[MAX_HAIDS]; // controller IDs on SCSI buses + UCHAR Link_Cmd; // ctrl's constraints on linked cmds + UCHAR Max_CmdQ_ents; // the max # 32-byte entries per queue + +#if EFP_MIRRORING_ENABLED + + UCHAR Environment; // define the mirroring environment. + +#endif // EFP_MIRRORING_ENABLED + +} HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION; + + +// +// The following structures are used to pass information between phase #0 +// and phase #1 of the "FindAdapter" process. +// + +typedef struct _SCSI_INFO { + + UCHAR AdapterPresent; // 0 = adapter not found or in error + UCHAR Reserved; // To be defined! + USHORT NumberOfDevices; // # of SCSI devices on the adapter + +} SCSI_INFO, *PSCSI_INFO; + + +typedef struct _ESC2_CONTEXT { + + UCHAR CheckedSlot; // EISA slot number checked + UCHAR Phase; // phase #0 or #1 + + SCSI_INFO ScsiInfo[MAX_EISA_SLOTS_STD]; + +} ESC2_CONTEXT, *PESC2_CONTEXT; + +#if EFP_MIRRORING_ENABLED + +// +// NOTE: the following struct doesn't belong to this file! +// + +// +// Define header for I/O control SRB. +// + +typedef struct _SRB_IO_CONTROL { + ULONG HeaderLength; + UCHAR Signature[8]; + ULONG Timeout; + ULONG ControlCode; + ULONG ReturnCode; + ULONG Length; +} SRB_IO_CONTROL, *PSRB_IO_CONTROL; + +#endif // EFP_MIRRORING_ENABLED |