/*++ 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 // // 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