summaryrefslogtreecommitdiffstats
path: root/private/ntos/miniport/oliscsi/oliesc2.h
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/ntos/miniport/oliscsi/oliesc2.h1400
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