1 /*
2  * vmscsi-- Miniport driver for the Buslogic BT 958 SCSI Controller
3  *          under Windows 2000/XP/Server 2003
4  *
5  *          Based in parts on the buslogic driver for the same device
6  *          available with the GNU Linux Operating System.
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License along
19  * with this program; if not, write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22 
23 //_________________________________________________________________________________________
24 //
25 // File description :The header file the driver for BusLogic-958 SCSI Host adapter card.
26 // The technical reference for this driver is at :
27 //
28 // Author: Namita Lal, Sirish Raghuram ( Calsoft Pvt Ltd)
29 // Date: 10th June 2002
30 // Status: Released
31 // Revision History: Changed queue depth to 191 - June 2002
32 //
33 //_________________________________________________________________________________________
34 
35 // Prototype for functions
36 
37 #pragma once
38 
39 #include <ntddk.h>
40 #include <srb.h>
41 #include <scsi.h>
42 #include <ntddscsi.h>
43 #include <scsiwmi.h>
44 //#include <ntos/kefuncs.h>
45 
46 
47 //#include "miniport.h"
48 //#include "scsi.h"
49 //#include "scsiwmi.h"
50 //_________________________________________________________________________________________
51 // #defines
52 //_________________________________________________________________________________________
53 
54 // Debug levels
55 #define ERROR   1
56 #define WARNING 2
57 #define TRACE   3
58 #define INFO    4
59 
60 // Max transfer size
61 #define MAX_TRANSFER_SIZE  64 * 1024
62 // flag to turn on Scatter gather support
63 #define SG_SUPPORT 1
64 // flag to turn on tagged command queuing
65 #define TAG_QUEUING 1
66 
67 #define BUSLOGIC_MAXIMUM_TAGS 128
68 
69 //  Define the maximum, maximum automatic, minimum automatic, and default Queue
70 //  Depth to allow for Target Devices depending on whether or not they support
71 //  Tagged Queuing and whether or not ISA Bounce Buffers are required.
72 #define BusLogic_MaxTaggedQueueDepth         128
73 
74 //  Define the default amount of time in seconds to wait between a Host Adapter
75 //  Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI commands.
76 //  Some SCSI devices get confused if they receive SCSI commands too soon after
77 //  a SCSI Bus Reset.
78 #define BusLogic_DefaultBusSettleTime       2
79 
80 //  Define the maximum number of Target Devices supported by this driver.
81 #define BusLogic_MaxTargetDevices       16
82 
83 //  Define the maximum number of Logical unit supported/Target Devices supported by this driver.
84 #define BusLogic_MaxLogicalUnits         32
85 
86 //  Define the maximum number of Mailboxes that should be used for MultiMaster
87 //  Host Adapters.  This number is chosen to be larger than the maximum Host
88 //  Adapter Queue Depth and small enough so that the Host Adapter structure
89 //  does not cross an allocation block size boundary.
90 #define BusLogic_MaxMailboxes           211
91 
92 //  Define the Fetch Host Adapter Local RAM request type.
93 #define BusLogic_BIOS_BaseOffset        0
94 #define BusLogic_AutoSCSI_BaseOffset    64
95 
96 //  Define the SCSI Command Descriptor Block (CDB).
97 #define BusLogic_CDB_MaxLength          12
98 
99 //  Define the maximum number of Scatter/Gather Segments used by this driver.
100 //  For optimal performance, it is important that this limit be at least as
101 //  large as the largest single request generated by the I/O Subsystem.
102 #define BusLogic_ScatterGatherLimit     128
103 #define MAX_SG_LIMIT BusLogic_ScatterGatherLimit
104 
105 #define  BusLogic_AggressiveRoundRobinMode 0
106 #define  BusLogic_StrictRoundRobinMode     1
107 
108 //  Define the Codes for byte 3 (Request sense allocation length) of the CCB structure.
109 #define  BusLogic_Allocate14Bytes       0x00
110 #define  BusLogic_DisableAutoReqSense   0x01
111 //_________________________________________________________________________________________
112 
113 
114 //_________________________________________________________________________________________
115 // typedef
116 //_________________________________________________________________________________________
117 typedef enum
118 {
119   BusLogic_TestCommandCompleteInterrupt = 0x00,
120   BusLogic_InitializeMailbox =            0x01,
121   BusLogic_ExecuteMailboxCommand =        0x02,
122   BusLogic_ExecuteBIOSCommand =           0x03,
123   BusLogic_InquireBoardID =               0x04,
124   BusLogic_EnableOutgoingMailboxAvailableInt =  0x05,
125   BusLogic_SetSCSISelectionTimeout =      0x06,
126   BusLogic_SetPreemptTimeOnBus =          0x07,
127   BusLogic_SetTimeOffBus =                0x08,
128   BusLogic_SetBusTransferRate =           0x09,
129   BusLogic_InquireInstalledDevicesID0to7 =0x0A,
130   BusLogic_InquireConfiguration =         0x0B,
131   BusLogic_EnableTargetMode =             0x0C,
132   BusLogic_InquireSetupInformation =      0x0D,
133   BusLogic_WriteAdapterLocalRAM =         0x1A,
134   BusLogic_ReadAdapterLocalRAM =          0x1B,
135   BusLogic_WriteBusMasterChipFIFO =       0x1C,
136   BusLogic_ReadBusMasterChipFIFO =        0x1D,
137   BusLogic_EchoCommandData =              0x1F,
138   BusLogic_HostAdapterDiagnostic =        0x20,
139   BusLogic_SetAdapterOptions =            0x21,
140   BusLogic_InquireInstalledDevicesID8to15 = 0x23,
141   BusLogic_InquireTargetDevices =         0x24,
142   BusLogic_DisableHostAdapterInterrupt =  0x25,
143   BusLogic_InitializeExtendedMailbox =    0x81,
144   BusLogic_ExecuteSCSICommand =           0x83,
145   BusLogic_InquireFirmwareVersion3rdDigit = 0x84,
146   BusLogic_InquireFirmwareVersionLetter = 0x85,
147   BusLogic_InquirePCIHostAdapterInformation = 0x86,
148   BusLogic_InquireHostAdapterModelNumber =0x8B,
149   BusLogic_InquireSynchronousPeriod =     0x8C,
150   BusLogic_InquireExtendedSetupInformation = 0x8D,
151   BusLogic_EnableStrictRoundRobinMode =   0x8F,
152   BusLogic_StoreHostAdapterLocalRAM =     0x90,
153   BusLogic_FetchHostAdapterLocalRAM =     0x91,
154   BusLogic_StoreLocalDataInEEPROM =       0x92,
155   BusLogic_UploadAutoSCSICode =           0x94,
156   BusLogic_ModifyIOAddress =              0x95,
157   BusLogic_SetCCBFormat =                 0x96,
158   BusLogic_WriteInquiryBuffer =           0x9A,
159   BusLogic_ReadInquiryBuffer =            0x9B,
160   BusLogic_FlashROMUploadDownload =       0xA7,
161   BusLogic_ReadSCAMData =                 0xA8,
162   BusLogic_WriteSCAMData =                0xA9
163 }BusLogic_OperationCode_T;
164 
165 
166 //  Define the Requested Reply Length type used by the Inquire Setup Information,
167 //  Inquire Host Adapter Model Number, Inquire Synchronous Period, and Inquire
168 //  Extended Setup Information commands.
169 typedef UCHAR BusLogic_RequestedReplyLength_T;
170 
171 //  Define a 32 bit Bus Address data type.
172 typedef unsigned int BusLogic_BusAddress_T;
173 
174 //  Define the Inquire Host Adapter Model Number reply type.
175 typedef UCHAR BusLogic_HostAdapterModelNumber_T[5];
176 
177 //  Define the Inquire Firmware Version 3rd Digit reply type.
178 typedef UCHAR BusLogic_FirmwareVersion3rdDigit_T;
179 
180 //  Define the Inquire Firmware Version Letter reply type.
181 typedef UCHAR BusLogic_FirmwareVersionLetter_T;
182 
183 //  Define a 32 bit Byte Count data type.
184 typedef unsigned int BusLogic_ByteCount_T;
185 
186 typedef struct BusLogic_FetchHostAdapterLocalRAMRequest
187 {
188   UCHAR ByteOffset;             // Byte 0
189   UCHAR ByteCount;              // Byte 1
190 }
191 BusLogic_FetchHostAdapterLocalRAMRequest_T;
192 
193 //  Define the Inquire PCI Host Adapter Information reply type.  The ISA
194 //  Compatible I/O Port values are defined here and are also used with
195 //  the Modify I/O Address command.
196 typedef enum BusLogic_ISACompatibleIOPort
197 {
198   BusLogic_IO_330 =             0,
199   BusLogic_IO_334 =             1,
200   BusLogic_IO_230 =             2,
201   BusLogic_IO_234 =             3,
202   BusLogic_IO_130 =             4,
203   BusLogic_IO_134 =             5,
204   BusLogic_IO_Disable =         6,
205   BusLogic_IO_Disable2 =        7
206 }
207 BusLogic_ISACompatibleIOPort_T;
208 
209 #pragma pack (1)
210 typedef struct BusLogic_PCIHostAdapterInformation
211 {
212   UCHAR ISACompatibleIOPort;        /* Byte 0 */
213   UCHAR PCIAssignedIRQChannel;      /* Byte 1 */
214   BOOLEAN LowByteTerminated:1;      /* Byte 2 Bit 0 */
215   BOOLEAN HighByteTerminated:1;     /* Byte 2 Bit 1 */
216   UCHAR :2;                         /* Byte 2 Bits 2-3 */
217   BOOLEAN JP1:1;                    /* Byte 2 Bit 4 */
218   BOOLEAN JP2:1;                    /* Byte 2 Bit 5 */
219   BOOLEAN JP3:1;                    /* Byte 2 Bit 6 */
220   BOOLEAN GenericInfoValid:1;       /* Byte 2 Bit 7 */
221   UCHAR :8;                         /* Byte 3 */
222 }BusLogic_PCIHostAdapterInformation_T;
223 
224 //  Define the Inquire Board ID reply structure.
225 typedef struct BusLogic_BoardID
226 {
227   UCHAR BoardType;                  /* Byte 0 */
228   UCHAR CustomFeatures;             /* Byte 1 */
229   UCHAR FirmwareVersion1stDigit;    /* Byte 2 */
230   UCHAR FirmwareVersion2ndDigit;    /* Byte 3 */
231 } BusLogic_BoardID_T;
232 #pragma pack ()
233 
234 //  Define the Host Adapter Target Flags structure.
235 typedef struct BusLogic_TargetFlags
236 {
237   BOOLEAN TargetExists:1;
238   BOOLEAN TaggedQueuingSupported:1;
239   BOOLEAN WideTransfersSupported:1;
240   BOOLEAN TaggedQueuingActive:1;
241   BOOLEAN WideTransfersActive:1;
242   BOOLEAN CommandSuccessfulFlag:1;
243   BOOLEAN TargetInfoReported:1;
244 }
245 BusLogic_TargetFlags_T;
246 
247 //  Define the Host Adapter Target Statistics structure.
248 #define BusLogic_SizeBuckets            10
249 
250 //  Define a 10^18 Statistics Byte Counter data type.
251 typedef struct BusLogic_ByteCounter
252 {
253   unsigned int Units;
254   unsigned int Billions;
255 }BusLogic_ByteCounter_T;
256 
257 typedef unsigned int BusLogic_CommandSizeBuckets_T[BusLogic_SizeBuckets];
258 
259 typedef struct BusLogic_TargetStatistics
260 {
261   unsigned int CommandsAttempted;
262   unsigned int CommandsCompleted;
263   unsigned int ReadCommands;
264   unsigned int WriteCommands;
265   BusLogic_ByteCounter_T TotalBytesRead;
266   BusLogic_ByteCounter_T TotalBytesWritten;
267   BusLogic_CommandSizeBuckets_T ReadCommandSizeBuckets;
268   BusLogic_CommandSizeBuckets_T WriteCommandSizeBuckets;
269   unsigned short CommandAbortsRequested;
270   unsigned short CommandAbortsAttempted;
271   unsigned short CommandAbortsCompleted;
272   unsigned short BusDeviceResetsRequested;
273   unsigned short BusDeviceResetsAttempted;
274   unsigned short BusDeviceResetsCompleted;
275   unsigned short HostAdapterResetsRequested;
276   unsigned short HostAdapterResetsAttempted;
277   unsigned short HostAdapterResetsCompleted;
278 }
279 BusLogic_TargetStatistics_T;
280 
281 #pragma pack (1)
282 //  Define the Inquire Configuration reply structure.
283 typedef struct BusLogic_Configuration
284 {
285   UCHAR :5;                 /* Byte 0 Bits 0-4 */
286   BOOLEAN DMA_Channel5:1;   /* Byte 0 Bit 5 */
287   BOOLEAN DMA_Channel6:1;   /* Byte 0 Bit 6 */
288   BOOLEAN DMA_Channel7:1;   /* Byte 0 Bit 7 */
289   BOOLEAN IRQ_Channel9:1;   /* Byte 1 Bit 0 */
290   BOOLEAN IRQ_Channel10:1;  /* Byte 1 Bit 1 */
291   BOOLEAN IRQ_Channel11:1;  /* Byte 1 Bit 2 */
292   BOOLEAN IRQ_Channel12:1;  /* Byte 1 Bit 3 */
293   UCHAR :1;                 /* Byte 1 Bit 4 */
294   BOOLEAN IRQ_Channel14:1;  /* Byte 1 Bit 5 */
295   BOOLEAN IRQ_Channel15:1;  /* Byte 1 Bit 6 */
296   UCHAR :1;                 /* Byte 1 Bit 7 */
297   UCHAR HostAdapterID:4;    /* Byte 2 Bits 0-3 */
298   UCHAR :4;                 /* Byte 2 Bits 4-7 */
299 }BusLogic_Configuration_T;
300 
301 //  Define the Inquire Setup Information reply structure.
302 typedef struct BusLogic_SynchronousValue
303 {
304   UCHAR Offset:4;               /* Bits 0-3 */
305   UCHAR TransferPeriod:3;       /* Bits 4-6 */
306   BOOLEAN Synchronous:1;        /* Bit 7    */
307 }BusLogic_SynchronousValue_T;
308 
309 typedef BusLogic_SynchronousValue_T
310   BusLogic_SynchronousValues8_T[8];
311 
312 typedef struct BusLogic_SetupInformation
313 {
314   BOOLEAN SynchronousInitiationEnabled:1;                /* Byte 0 Bit 0 */
315   BOOLEAN ParityCheckingEnabled:1;                       /* Byte 0 Bit 1 */
316   UCHAR :6;                                              /* Byte 0 Bits 2-7 */
317   UCHAR BusTransferRate;                                 /* Byte 1 */
318   UCHAR PreemptTimeOnBus;                                /* Byte 2 */
319   UCHAR TimeOffBus;                                      /* Byte 3 */
320   UCHAR MailboxCount;                                    /* Byte 4 */
321   UCHAR MailboxAddress[3];                               /* Bytes 5-7 */
322   BusLogic_SynchronousValues8_T SynchronousValuesID0to7; /* Bytes 8-15 */
323   UCHAR DisconnectPermittedID0to7;                       /* Byte 16 */
324   UCHAR Signature;                                       /* Byte 17 */
325   UCHAR CharacterD;                                      /* Byte 18 */
326   UCHAR HostBusType;                                     /* Byte 19 */
327   UCHAR WideTransfersPermittedID0to7;                    /* Byte 20 */
328   UCHAR WideTransfersActiveID0to7;                       /* Byte 21 */
329   BusLogic_SynchronousValues8_T SynchronousValuesID8to15;/* Bytes 22-29 */
330   UCHAR DisconnectPermittedID8to15;                      /* Byte 30 */
331   UCHAR :8;                                              /* Byte 31 */
332   UCHAR WideTransfersPermittedID8to15;                   /* Byte 32 */
333   UCHAR WideTransfersActiveID8to15;                      /* Byte 33 */
334 }BusLogic_SetupInformation_T;
335 
336 // Something has to be done about the packing mechanism of these structures - Namita
337 // Define the Inquire Extended Setup Information reply structure.
338 typedef struct BusLogic_ExtendedSetupInformation
339 {
340   UCHAR BusType;                            // Byte 0
341   UCHAR BIOS_Address;                       // Byte 1
342   unsigned short ScatterGatherLimit;        // Bytes 2-3
343   UCHAR MailboxCount;                       // Byte 4
344   BusLogic_BusAddress_T BaseMailboxAddress; // Bytes 5-8
345   struct
346   {
347       UCHAR :2;                             // Byte 9 Bits 0-1
348       BOOLEAN FastOnEISA:1;                 // Byte 9 Bit 2
349       UCHAR :3;                             // Byte 9 Bits 3-5
350       BOOLEAN LevelSensitiveInterrupt:1;    // Byte 9 Bit 6
351       UCHAR :1;
352   } Misc;                                   // Byte 9 Bit 7
353   UCHAR FirmwareRevision[3];                // Bytes 10-12
354   BOOLEAN HostWideSCSI:1;                   // Byte 13 Bit 0
355   BOOLEAN HostDifferentialSCSI:1;           // Byte 13 Bit 1
356   BOOLEAN HostSupportsSCAM:1;               // Byte 13 Bit 2
357   BOOLEAN HostUltraSCSI:1;                  // Byte 13 Bit 3
358   BOOLEAN HostSmartTermination:1;           // Byte 13 Bit 4
359   UCHAR :3;                                 // Byte 13 Bits 5-7
360 }BusLogic_ExtendedSetupInformation_T;
361 
362 //  Define the Host Adapter Local RAM AutoSCSI structure.
363 typedef struct BusLogic_AutoSCSIData
364 {
365   UCHAR InternalFactorySignature[2];/* Bytes 0-1 */
366   UCHAR InformationByteCount;       /* Byte 2 */
367   UCHAR HostAdapterType[6];         /* Bytes 3-8 */
368   UCHAR :8;                         /* Byte 9 */
369   UCHAR FloppyEnabled:1;            /* Byte 10 Bit 0 */
370   UCHAR FloppySecondary:1;          /* Byte 10 Bit 1 */
371   UCHAR LevelSensitiveInterrupt:1;  /* Byte 10 Bit 2 */
372   UCHAR :2;                         /* Byte 10 Bits 3-4 */
373   UCHAR SystemRAMAreaForBIOS:3;     /* Byte 10 Bits 5-7 */
374   UCHAR DMA_Channel:7;              /* Byte 11 Bits 0-6 */
375   UCHAR DMA_AutoConfiguration:1;    /* Byte 11 Bit 7 */
376   UCHAR IRQ_Channel:7;              /* Byte 12 Bits 0-6 */
377   UCHAR IRQ_AutoConfiguration:1;    /* Byte 12 Bit 7 */
378   UCHAR DMA_TransferRate;           /* Byte 13 */
379   UCHAR SCSI_ID;                    /* Byte 14 */
380   UCHAR LowByteTerminated:1;                 /* Byte 15 Bit 0 */
381   UCHAR ParityCheckingEnabled:1;             /* Byte 15 Bit 1 */
382   UCHAR HighByteTerminated:1;                /* Byte 15 Bit 2 */
383   UCHAR NoisyCablingEnvironment:1;           /* Byte 15 Bit 3 */
384   UCHAR FastSynchronousNegotiation:1;        /* Byte 15 Bit 4 */
385   UCHAR BusResetEnabled:1;                   /* Byte 15 Bit 5 */
386   UCHAR :1;                                  /* Byte 15 Bit 6 */
387   UCHAR ActiveNegationEnabled:1;             /* Byte 15 Bit 7 */
388   UCHAR BusOnDelay;                          /* Byte 16 */
389   UCHAR BusOffDelay;                         /* Byte 17 */
390   UCHAR HostAdapterBIOSEnabled:1;            /* Byte 18 Bit 0 */
391   UCHAR BIOSRedirectionOfINT19Enabled:1;     /* Byte 18 Bit 1 */
392   UCHAR ExtendedTranslationEnabled:1;        /* Byte 18 Bit 2 */
393   UCHAR MapRemovableAsFixedEnabled:1;        /* Byte 18 Bit 3 */
394   UCHAR :1;                                  /* Byte 18 Bit 4 */
395   UCHAR BIOSSupportsMoreThan2DrivesEnabled:1;/* Byte 18 Bit 5 */
396   UCHAR BIOSInterruptModeEnabled:1;          /* Byte 18 Bit 6 */
397   UCHAR FlopticalSupportEnabled:1;           /* Byte 19 Bit 7 */
398   unsigned short DeviceEnabled:16;           /* Bytes 19-20 */
399   unsigned short WidePermitted:16;           /* Bytes 21-22 */
400   unsigned short FastPermitted:16;           /* Bytes 23-24 */
401   unsigned short SynchronousPermitted:16;    /* Bytes 25-26 */
402   unsigned short DisconnectPermitted:16;     /* Bytes 27-28 */
403   unsigned short SendStartUnitCommand:16;    /* Bytes 29-30 */
404   unsigned short IgnoreInBIOSScan:16;        /* Bytes 31-32 */
405   UCHAR PCIInterruptPin:2;                   /* Byte 33 Bits 0-1 */
406   UCHAR HostAdapterIOPortAddress:2;          /* Byte 33 Bits 2-3 */
407   UCHAR StrictRoundRobinModeEnabled:1;       /* Byte 33 Bit 4 */
408   UCHAR VESABusSpeedGreaterThan33MHz:1;      /* Byte 33 Bit 5 */
409   UCHAR VESABurstWriteEnabled:1;             /* Byte 33 Bit 6 */
410   UCHAR VESABurstReadEnabled:1;              /* Byte 33 Bit 7 */
411   unsigned short UltraPermitted:16;          /* Bytes 34-35 */
412   unsigned int :32;                          /* Bytes 36-39 */
413   UCHAR :8;                                  /* Byte 40 */
414   UCHAR AutoSCSIMaximumLUN;                  /* Byte 41 */
415   UCHAR :1;                                  /* Byte 42 Bit 0 */
416   UCHAR SCAM_Dominant:1;                     /* Byte 42 Bit 1 */
417   UCHAR SCAM_Enabled:1;                      /* Byte 42 Bit 2 */
418   UCHAR SCAM_Level2:1;                       /* Byte 42 Bit 3 */
419   UCHAR :4;                                  /* Byte 42 Bits 4-7 */
420   UCHAR INT13ExtensionEnabled:1;             /* Byte 43 Bit 0 */
421   UCHAR :1;                                  /* Byte 43 Bit 1 */
422   UCHAR CDROMBootEnabled:1;                  /* Byte 43 Bit 2 */
423   UCHAR :5;                                  /* Byte 43 Bits 3-7 */
424   UCHAR BootTargetID:4;                      /* Byte 44 Bits 0-3 */
425   UCHAR BootChannel:4;                       /* Byte 44 Bits 4-7 */
426   UCHAR ForceBusDeviceScanningOrder:1;       /* Byte 45 Bit 0 */
427   UCHAR :7;                                  /* Byte 45 Bits 1-7 */
428   unsigned short NonTaggedToAlternateLUNPermitted;   /* Bytes 46-47 */
429   unsigned short RenegotiateSyncAfterCheckCondition; /* Bytes 48-49 */
430   UCHAR Reserved[10];                        /* Bytes 50-59 */
431   UCHAR ManufacturingDiagnostic[2];          /* Bytes 60-61 */
432   unsigned short Checksum:16;                /* Bytes 62-63 */
433 }BusLogic_AutoSCSIData_T;
434 #pragma pack()
435 
436 //  Define the Outgoing Mailbox Action Codes.
437 typedef enum
438 {
439   BusLogic_OutgoingMailboxFree =        0x00,
440   BusLogic_MailboxStartCommand =        0x01,
441   BusLogic_MailboxAbortCommand =        0x02
442 }BusLogic_ActionCode_T;
443 
444 
445 //  Define the Incoming Mailbox Completion Codes.  The MultiMaster Firmware
446 //  only uses codes 0 - 4.  The FlashPoint SCCB Manager has no mailboxes, so
447 //  completion codes are stored in the CCB; it only uses codes 1, 2, 4, and 5.
448 typedef enum
449 {
450   BusLogic_IncomingMailboxFree =            0x00,
451   BusLogic_CommandCompletedWithoutError =   0x01,
452   BusLogic_CommandAbortedAtHostRequest =    0x02,
453   BusLogic_AbortedCommandNotFound =         0x03,
454   BusLogic_CommandCompletedWithError =      0x04,
455   BusLogic_InvalidCCB =                     0x05
456 }BusLogic_CompletionCode_T;
457 
458 //  Define the Command Control Block (CCB) Opcodes.
459 typedef enum
460 {
461   BusLogic_InitiatorCCB =                       0x00,
462   BusLogic_TargetCCB =                          0x01,
463   BusLogic_InitiatorCCB_ScatterGather =         0x02,
464   BusLogic_InitiatorCCB_ResidualDataLength =    0x03,
465   BusLogic_InitiatorCCB_ScatterGatherResidual = 0x04,
466   BusLogic_BusDeviceReset =                     0x81
467 }BusLogic_CCB_Opcode_T;
468 
469 
470 //  Define the CCB Data Direction Codes.
471 typedef enum
472 {
473   BusLogic_UncheckedDataTransfer =      0,
474   BusLogic_DataInLengthChecked =        1,
475   BusLogic_DataOutLengthChecked =       2,
476   BusLogic_NoDataTransfer =             3
477 }BusLogic_DataDirection_T;
478 
479 
480 //  Define the Host Adapter Status Codes.  The MultiMaster Firmware does not
481 //  return status code 0x0C; it uses 0x12 for both overruns and underruns.
482 typedef enum
483 {
484   BusLogic_CommandCompletedNormally =       0x00,
485   BusLogic_LinkedCommandCompleted =         0x0A,
486   BusLogic_LinkedCommandCompletedWithFlag = 0x0B,
487   BusLogic_DataUnderRun =                   0x0C,
488   BusLogic_SCSISelectionTimeout =           0x11,
489   BusLogic_DataOverRun =                    0x12,
490   BusLogic_UnexpectedBusFree =              0x13,
491   BusLogic_InvalidBusPhaseRequested =       0x14,
492   BusLogic_InvalidOutgoingMailboxActionCode =   0x15,
493   BusLogic_InvalidCommandOperationCode =    0x16,
494   BusLogic_LinkedCCBhasInvalidLUN =         0x17,
495   BusLogic_InvalidCommandParameter =        0x1A,
496   BusLogic_AutoRequestSenseFailed =         0x1B,
497   BusLogic_TaggedQueuingMessageRejected =   0x1C,
498   BusLogic_UnsupportedMessageReceived =     0x1D,
499   BusLogic_HostAdapterHardwareFailed =      0x20,
500   BusLogic_TargetFailedResponseToATN =      0x21,
501   BusLogic_HostAdapterAssertedRST =         0x22,
502   BusLogic_OtherDeviceAssertedRST =         0x23,
503   BusLogic_TargetDeviceReconnectedImproperly =  0x24,
504   BusLogic_HostAdapterAssertedBusDeviceReset =  0x25,
505   BusLogic_AbortQueueGenerated =            0x26,
506   BusLogic_HostAdapterSoftwareError =       0x27,
507   BusLogic_HostAdapterHardwareTimeoutError= 0x30,
508   BusLogic_SCSIParityErrorDetected =        0x34
509 }BusLogic_HostAdapterStatus_T;
510 
511 //  Define the SCSI Target Device Status Codes.
512 typedef enum
513 {
514   BusLogic_OperationGood =          0x00,
515   BusLogic_CheckCondition =         0x02,
516   BusLogic_DeviceBusy =             0x08
517 }BusLogic_TargetDeviceStatus_T;
518 
519 //  Define the Queue Tag Codes.
520 typedef enum
521 {
522   BusLogic_SimpleQueueTag =         0,
523   BusLogic_HeadOfQueueTag =         1,
524   BusLogic_OrderedQueueTag =        2,
525   BusLogic_ReservedQT =             3
526 }BusLogic_QueueTag_T;
527 
528 //  Define the Scatter/Gather Segment structure required by the MultiMaster
529 //  Firmware Interface and the FlashPoint SCCB Manager.
530 typedef struct BusLogic_ScatterGatherSegment
531 {
532   BusLogic_ByteCount_T SegmentByteCount;        /* Bytes 0-3 */
533   BusLogic_BusAddress_T SegmentDataPointer;     /* Bytes 4-7 */
534 }BusLogic_ScatterGatherSegment_T;
535 
536 
537 typedef UCHAR SCSI_CDB_T[BusLogic_CDB_MaxLength];
538 
539 //  Define the Driver CCB Status Codes.
540 typedef enum
541 {
542   BusLogic_CCB_Free =               0,
543   BusLogic_CCB_Active =             1,
544   BusLogic_CCB_Completed =          2,
545   BusLogic_CCB_Reset =              3
546 }BusLogic_CCB_Status_T;
547 
548 //  Define the 32 Bit Mode Command Control Block (CCB) structure.  The first 40
549 //  bytes are defined by the MultiMaster Firmware The remaining components are
550 //  defined by the Scsi MiniportDriver.
551 //  Extended LUN Format CCBs differ from Legacy LUN Format 32 Bit Mode
552 //  CCBs only in having the TagEnable and QueueTag fields moved from byte 17 to
553 //  byte 1, and the Logical Unit field in byte 17 expanded to 6 bits.  In theory,
554 //  Extended LUN Format CCBs can support up to 64 Logical Units, but in practice
555 //  many devices will respond improperly to Logical Units between 32 and 63, and
556 //  the SCSI-2 specification defines Bit 5 as LUNTAR.  Extended LUN Format CCBs
557 //  are used by recent versions of the MultiMaster Firmware.
558 //  Since 64 Logical Units are unlikely to be needed in practice, and
559 //  since they are problematic for the above reasons, and since limiting them to
560 //  5 bits simplifies the CCB structure definition, this driver only supports
561 //  32 Logical Units per Target Device.
562 typedef struct BusLogic_CCB
563 {
564   UCHAR Opcode;                 /* Byte 0 */
565   UCHAR :3;                     /* Byte 1 Bits 0-2 */
566   UCHAR DataDirection:2;        /* Byte 1 Bits 3-4 */
567   UCHAR TagEnable:1;            /* Byte 1 Bit 5 */
568   UCHAR QueueTag:2;             /* Byte 1 Bits 6-7 */
569   UCHAR CDB_Length;             /* Byte 2 */
570   UCHAR SenseDataLength;        /* Byte 3 */
571   BusLogic_ByteCount_T DataLength;  /* Bytes 4-7 */
572   BusLogic_BusAddress_T DataPointer;/* Bytes 8-11 */
573   UCHAR :8;                         /* Byte 12 */
574   UCHAR :8;                         /* Byte 13 */
575   UCHAR HostAdapterStatus;          /* Byte 14 */
576   UCHAR TargetDeviceStatus;         /* Byte 15 */
577   UCHAR TargetID;                   /* Byte 16 */
578   UCHAR LogicalUnit:5;              /* Byte 17 Bits 0-4 */
579   UCHAR LegacyTagEnable:1;          /* Byte 17 Bit 5 */
580   UCHAR LegacyQueueTag:2;           /* Byte 17 Bits 6-7 */
581   SCSI_CDB_T CDB;                   /* Bytes 18-29 */
582   UCHAR :8;                         /* Byte 30 */
583   UCHAR :8;                         /* Byte 31 */
584   unsigned int :32;                 /* Bytes 32-35 */
585   BusLogic_BusAddress_T SenseDataPointer;/* Bytes 36-39 */
586 
587   // BusLogic Driver Defined Portion.
588   BusLogic_CCB_Status_T Status;
589   unsigned long SerialNumber;
590   struct BusLogic_HostAdapter *HostAdapter;
591   struct BusLogic_CCB *Next;
592     BusLogic_ScatterGatherSegment_T ScatterGatherList[BusLogic_ScatterGatherLimit];
593 
594   BusLogic_CompletionCode_T CompletionCode;
595   // Pointer to the CCB
596   PVOID SrbAddress;
597   PVOID AbortSrb;
598 }BusLogic_CCB_T, *PBuslogic_CCB_T;
599 
600 #pragma pack(1)
601 //  Define the 32 Bit Mode Outgoing Mailbox structure.
602 typedef struct BusLogic_OutgoingMailbox
603 {
604   BusLogic_BusAddress_T CCB;/* Bytes 0-3 */
605   UCHAR :8;                 /* Bytes 4 */
606   UCHAR :8;                 /* Bytes 5 */
607   UCHAR :8;                 /* Bytes 6 */
608   UCHAR ActionCode;         /* Byte 7 */
609 }BusLogic_OutgoingMailbox_T;
610 
611 //  Define the 32 Bit Mode Incoming Mailbox structure.
612 typedef struct BusLogic_IncomingMailbox
613 {
614   BusLogic_BusAddress_T CCB;    /* Bytes 0-3 */
615   UCHAR HostAdapterStatus;      /* Byte 4 */
616   UCHAR TargetDeviceStatus;     /* Byte 5 */
617   UCHAR :8;                     /* Byte 6 */
618   UCHAR CompletionCode;         /* Byte 7 */
619 }BusLogic_IncomingMailbox_T;
620 #pragma pack ()
621 
622 //
623 // The following structure is allocated
624 // from noncached memory as data will be DMA'd to
625 // and from it.
626 typedef struct _NONCACHED_EXTENSION
627 {
628     // Physical base address of mailboxes
629     ULONG MailboxPA;
630 
631     // Mailboxes
632     UCHAR MailboxOut[BusLogic_MaxMailboxes * sizeof(BusLogic_OutgoingMailbox_T)];
633     UCHAR MailboxIn[BusLogic_MaxMailboxes * sizeof(BusLogic_IncomingMailbox_T)];
634 } NONCACHED_EXTENSION, *PNONCACHED_EXTENSION;
635 
636 //  Define the types of BusLogic Host Adapters that are supported and the number
637 //  of I/O Addresses required by each type.
638 typedef enum
639 {
640   BusLogic_MultiMaster =            1,
641   BusLogic_FlashPoint =             2
642 }BusLogic_HostAdapterType_T;
643 
644 //  Define the possible Host Adapter Bus Types.
645 typedef enum
646 {
647   BusLogic_Unknown_Bus =            0,
648   BusLogic_ISA_Bus =                1,
649   BusLogic_EISA_Bus =               2,
650   BusLogic_PCI_Bus =                3,
651   BusLogic_VESA_Bus =               4,
652   BusLogic_MCA_Bus =                5
653 }BusLogic_HostAdapterBusType_T;
654 
655 #if 0
656 static char *BusLogic_HostAdapterBusNames[] = { "Unknown", "ISA", "EISA", "PCI", "VESA", "MCA" };
657 #endif
658 static BusLogic_HostAdapterBusType_T
659   BusLogic_HostAdapterBusTypes[] ={ BusLogic_VESA_Bus,     /* BT-4xx */
660                                     BusLogic_ISA_Bus,      /* BT-5xx */
661                                     BusLogic_MCA_Bus,      /* BT-6xx */
662                                     BusLogic_EISA_Bus,     /* BT-7xx */
663                                     BusLogic_Unknown_Bus,  /* BT-8xx */
664                                     BusLogic_PCI_Bus       /* BT-9xx */
665                                   };
666 
667 //  Define the BusLogic Driver Host Adapter structure
668 typedef struct BusLogic_HostAdapter
669 {
670 
671   BusLogic_HostAdapterType_T HostAdapterType;
672   BusLogic_HostAdapterBusType_T HostAdapterBusType;
673 
674   UCHAR ModelName[9];
675   UCHAR FirmwareVersion[6];
676   UCHAR FullModelName[18];
677   UCHAR Bus;
678 
679   PUCHAR IO_Address;
680   UCHAR IRQ_Channel;
681   UCHAR SCSI_ID;
682 
683   BOOLEAN ExtendedTranslationEnabled:1;
684   BOOLEAN ParityCheckingEnabled:1;
685   BOOLEAN BusResetEnabled:1;
686   BOOLEAN LevelSensitiveInterrupt:1;
687   BOOLEAN HostWideSCSI:1;
688   BOOLEAN HostDifferentialSCSI:1;
689   BOOLEAN HostSupportsSCAM:1;
690   BOOLEAN HostUltraSCSI:1;
691   BOOLEAN ExtendedLUNSupport:1;
692   BOOLEAN TerminationInfoValid:1;
693   BOOLEAN LowByteTerminated:1;
694   BOOLEAN HighByteTerminated:1;
695   BOOLEAN BounceBuffersRequired:1;
696   BOOLEAN StrictRoundRobinModeSupport:1;
697   BOOLEAN SCAM_Enabled:1;
698   BOOLEAN SCAM_Level2:1;
699   BOOLEAN HostAdapterInitialized:1;
700   BOOLEAN HostAdapterExternalReset:1;
701   BOOLEAN HostAdapterInternalError:1;
702 
703   BOOLEAN ProcessCompletedCCBsActive;
704   volatile BOOLEAN HostAdapterCommandCompleted;
705   unsigned short HostAdapterScatterGatherLimit;
706   unsigned short DriverScatterGatherLimit;
707 
708   UCHAR MaxTargetDevices;
709   UCHAR MaxLogicalUnits;
710 
711   unsigned short DriverQueueDepth;
712   unsigned short HostAdapterQueueDepth;
713   unsigned short UntaggedQueueDepth;
714   unsigned short CommonQueueDepth;
715   unsigned short BusSettleTime;
716   unsigned short SynchronousPermitted;
717   unsigned short FastPermitted;
718   unsigned short UltraPermitted;
719   unsigned short WidePermitted;
720   unsigned short DisconnectPermitted;
721   unsigned short TaggedQueuingPermitted;
722   unsigned short ExternalHostAdapterResets;
723   unsigned short HostAdapterInternalErrors;
724   unsigned short TargetDeviceCount;
725 
726   BusLogic_BusAddress_T BIOS_Address;
727 
728   BusLogic_CCB_T *FirstCompletedCCB;
729   BusLogic_CCB_T *LastCompletedCCB;
730   BusLogic_CCB_T *BusDeviceResetPendingCCB[BusLogic_MaxTargetDevices];
731 
732   BusLogic_TargetFlags_T TargetFlags[BusLogic_MaxTargetDevices];
733   UCHAR SynchronousPeriod[BusLogic_MaxTargetDevices];
734   UCHAR SynchronousOffset[BusLogic_MaxTargetDevices];
735   UCHAR ActiveCommandsPerTarget[BusLogic_MaxTargetDevices];
736   UCHAR ActiveCommandsPerLun[BusLogic_MaxTargetDevices][BusLogic_MaxLogicalUnits];
737   unsigned int CommandsSinceReset[BusLogic_MaxTargetDevices];
738   unsigned long LastSequencePoint[BusLogic_MaxTargetDevices];
739   unsigned long LastResetAttempted[BusLogic_MaxTargetDevices];
740   unsigned long LastResetCompleted[BusLogic_MaxTargetDevices];
741 
742   UCHAR MailboxCount;
743   BusLogic_OutgoingMailbox_T *FirstOutgoingMailbox;
744   BusLogic_OutgoingMailbox_T *LastOutgoingMailbox;
745   BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
746   BusLogic_IncomingMailbox_T *FirstIncomingMailbox;
747   BusLogic_IncomingMailbox_T *LastIncomingMailbox;
748   BusLogic_IncomingMailbox_T *NextIncomingMailbox;
749   BusLogic_TargetStatistics_T TargetStatistics[BusLogic_MaxTargetDevices];
750 }BusLogic_HostAdapter_T;
751 
752 
753 // Buslogic specific port driver device object extension.
754 typedef struct
755 _HW_DEVICE_EXTENSION
756 {
757   BusLogic_HostAdapter_T   hcs;
758   PNONCACHED_EXTENSION NoncachedExtension;
759   SCSI_WMILIB_CONTEXT WmiLibContext;
760 
761 } HW_DEVICE_EXTENSION, *PHW_DEVICE_EXTENSION;
762 
763 
764 //  Define a structure for the SCSI Inquiry command results.
765 #pragma pack (1)
766 typedef struct SCSI_Inquiry
767 {
768   UCHAR PeripheralDeviceType:5; /* Byte 0 Bits 0-4 */
769   UCHAR PeripheralQualifier:3;  /* Byte 0 Bits 5-7 */
770   UCHAR DeviceTypeModifier:7;   /* Byte 1 Bits 0-6 */
771   BOOLEAN RMB:1;                /* Byte 1 Bit 7 */
772   UCHAR ANSI_ApprovedVersion:3; /* Byte 2 Bits 0-2 */
773   UCHAR ECMA_Version:3;         /* Byte 2 Bits 3-5 */
774   UCHAR ISO_Version:2;          /* Byte 2 Bits 6-7 */
775   UCHAR ResponseDataFormat:4;   /* Byte 3 Bits 0-3 */
776   UCHAR :2;                     /* Byte 3 Bits 4-5 */
777   BOOLEAN TrmIOP:1;             /* Byte 3 Bit 6 */
778   BOOLEAN AENC:1;               /* Byte 3 Bit 7 */
779   UCHAR AdditionalLength;       /* Byte 4 */
780   UCHAR :8;                     /* Byte 5 */
781   UCHAR :8;                     /* Byte 6 */
782   BOOLEAN SftRe:1;              /* Byte 7 Bit 0 */
783   BOOLEAN CmdQue:1;             /* Byte 7 Bit 1 */
784   BOOLEAN :1;                   /* Byte 7 Bit 2 */
785   BOOLEAN Linked:1;             /* Byte 7 Bit 3 */
786   BOOLEAN Sync:1;               /* Byte 7 Bit 4 */
787   BOOLEAN WBus16:1;             /* Byte 7 Bit 5 */
788   BOOLEAN WBus32:1;             /* Byte 7 Bit 6 */
789   BOOLEAN RelAdr:1;             /* Byte 7 Bit 7 */
790   UCHAR VendorIdentification[8];/* Bytes 8-15 */
791   UCHAR ProductIdentification[16];/* Bytes 16-31 */
792   UCHAR ProductRevisionLevel[4];/* Bytes 32-35 */
793 }SCSI_Inquiry_T;
794 
795 typedef struct BusLogic_WmiExtendedSetupInformation
796 {
797   UCHAR BusType;                            // Byte 0
798   UCHAR BIOS_Address;                       // Byte 1
799   unsigned short ScatterGatherLimit;        // Bytes 2-3
800   UCHAR MailboxCount;                       // Byte 4
801   BusLogic_BusAddress_T BaseMailboxAddress; // Bytes 5-8
802   BOOLEAN FastOnEISA;                   // Byte 9
803   BOOLEAN LevelSensitiveInterrupt;      // Byte 10
804   UCHAR FirmwareRevision[3];            // Bytes 11-14
805   BOOLEAN HostWideSCSI;                 // Byte 15
806   BOOLEAN HostDifferentialSCSI;         // Byte 16
807   BOOLEAN HostSupportsSCAM;             // Byte 17
808   BOOLEAN HostUltraSCSI;                // Byte 18
809   BOOLEAN HostSmartTermination;         // Byte 19
810 }BusLogic_WmiExtendedSetupInformation_T, *PBusLogic_WmiExtendedSetupInformation_T;
811 
812 #pragma pack ()
813 
814 //_________________________________________________________________________________________
815 // function declarations
816 //_________________________________________________________________________________________
817 ULONG
818 NTAPI
819 DriverEntry(IN PVOID DriverObject,
820             IN PVOID Argument2
821             );
822 
823 ULONG
824 NTAPI
825 BT958HwFindAdapter(IN PVOID HwDeviceExtension,
826                    IN PVOID Context,
827                    IN PVOID BusInformation,
828                    IN PCHAR ArgumentString,
829                    IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
830                    OUT PBOOLEAN Again
831                   );
832 
833 BOOLEAN
834 NTAPI
835 BT958HwInitialize(IN PVOID HwDeviceExtension);
836 
837 BOOLEAN
838 NTAPI
839 BT958HwStartIO(IN PVOID HwDeviceExtension,
840                IN PSCSI_REQUEST_BLOCK Srb
841               );
842 
843 BOOLEAN
844 NTAPI
845 BT958HwInterrupt(IN PVOID HwDeviceExtension);
846 
847 BOOLEAN
848 NTAPI
849 BT958HwResetBus(IN PVOID HwDeviceExtension,
850                 IN ULONG PathId
851                );
852 
853 SCSI_ADAPTER_CONTROL_STATUS
854 NTAPI
855 BT958HwAdapterControl(IN PVOID HwDeviceExtension,
856                       IN SCSI_ADAPTER_CONTROL_TYPE ControlType,
857                       IN PVOID Parameters
858                       );
859 #if 0
860 BOOLEAN
861 BT958WmiSrb(IN     PHW_DEVICE_EXTENSION    HwDeviceExtension,
862             IN OUT PSCSI_WMI_REQUEST_BLOCK Srb);
863 #endif
864 void
865 BT958WmiInitialize( IN PHW_DEVICE_EXTENSION HwDeviceExtension);
866 
867 
868 BOOLEAN
869 Buslogic_InitBT958(PHW_DEVICE_EXTENSION deviceExtension,
870                    PPORT_CONFIGURATION_INFORMATION ConfigInfo);
871 
872 BOOLEAN
873 BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter);
874 
875 BOOLEAN
876 BusLogic_HardwareResetHostAdapter(BusLogic_HostAdapter_T  *HostAdapter,
877                                   BOOLEAN HardReset);
878 
879 BOOLEAN
880 BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter);
881 
882 int
883 BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,
884                  BusLogic_OperationCode_T OperationCode,
885                  void *ParameterData,
886                  int ParameterLength,
887                  void *ReplyData,
888                  int ReplyLength);
889 
890 BOOLEAN
891 BusLogic_ReadHostAdapterConfiguration( BusLogic_HostAdapter_T  *HostAdapter);
892 
893 BOOLEAN
894 BusLogic_InitializeHostAdapter(PHW_DEVICE_EXTENSION deviceExtension,
895                                PPORT_CONFIGURATION_INFORMATION ConfigInfo);
896 
897 BOOLEAN
898 BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T *HostAdapter);
899 
900 int
901 BusLogic_QueueCommand(IN PVOID HwDeviceExtension,
902                       IN PSCSI_REQUEST_BLOCK Srb,
903                       IN PBuslogic_CCB_T ccb);
904 
905 BOOLEAN
906 BusLogic_WriteOutgoingMailbox(PHW_DEVICE_EXTENSION deviceExtension ,
907                               BusLogic_ActionCode_T ActionCode,
908                               BusLogic_CCB_T *CCB);
909 
910 void
911 BusLogic_ScanIncomingMailboxes(PHW_DEVICE_EXTENSION deviceExtension);
912 
913 void
914 BusLogic_QueueCompletedCCB(PHW_DEVICE_EXTENSION deviceExtension, BusLogic_CCB_T *CCB);
915 
916 void
917 BusLogic_ProcessCompletedCCBs(PHW_DEVICE_EXTENSION deviceExtension);
918 
919 UCHAR
920 BusLogic_ComputeResultCode(BusLogic_HostAdapter_T        *HostAdapter,
921                            BusLogic_HostAdapterStatus_T  HostAdapterStatus,
922                            BusLogic_TargetDeviceStatus_T TargetDeviceStatus,
923                            UCHAR SenseDataLength);
924 
925 BOOLEAN
926 BusLogic_SendBusDeviceReset(IN PVOID HwDeviceExtension,
927                             PSCSI_REQUEST_BLOCK Srb);
928 
929 static UCHAR
ReadBusLogicPort(PUCHAR adr)930 ReadBusLogicPort(PUCHAR adr )
931 {
932     return ScsiPortReadPortUchar( adr );
933 }
934 
935 static VOID
WriteBusLogicPort(UCHAR data,PUCHAR adr)936 WriteBusLogicPort(UCHAR data,
937                   PUCHAR adr)
938 {
939     ScsiPortWritePortUchar(adr, data);
940 }
941 
942 //_________________________________________________________________________________________
943 // Declarations for the device registers and reading and writing to them
944 //_________________________________________________________________________________________
945 
946 //  Define the BusLogic SCSI Host Adapter I/O Register Offsets.
947 #define BusLogic_ControlRegisterOffset          0   // WO register
948 #define BusLogic_StatusRegisterOffset           0   // RO register
949 #define BusLogic_CommandParameterRegisterOffset 1   // WO register
950 #define BusLogic_DataInRegisterOffset           1   // RO register
951 #define BusLogic_InterruptRegisterOffset        2   // RO register
952 #define BusLogic_GeometryRegisterOffset         3   // RO register
953 
954 
955 //  Define the structure of the write-only Control Register.
956 typedef union BusLogic_ControlRegister
957 {
958   UCHAR All;
959   struct
960   {
961     UCHAR :4;                   // Bits 0-3
962     BOOLEAN SCSIBusReset:1;     // Bit 4
963     BOOLEAN InterruptReset:1;   // Bit 5
964     BOOLEAN SoftReset:1;        // Bit 6
965     BOOLEAN HardReset:1;        // Bit 7
966   } Bits;
967 }BusLogic_ControlRegister_T;
968 
969 
970 //  Define the structure of the read-only Status Register.
971 typedef union BusLogic_StatusRegister
972 {
973   UCHAR All;
974   struct
975   {
976     BOOLEAN CommandInvalid:1;               // Bit 0
977     BOOLEAN Reserved:1;                     // Bit 1
978     BOOLEAN DataInRegisterReady:1;          // Bit 2
979     BOOLEAN CommandParameterRegisterBusy:1; // Bit 3
980     BOOLEAN HostAdapterReady:1;             // Bit 4
981     BOOLEAN InitializationRequired:1;       // Bit 5
982     BOOLEAN DiagnosticFailure:1;            // Bit 6
983     BOOLEAN DiagnosticActive:1;             // Bit 7
984   } Bits;
985 }BusLogic_StatusRegister_T;
986 
987 
988 
989 //  Define the structure of the read-only Interrupt Register.
990 typedef union BusLogic_InterruptRegister
991 {
992   UCHAR All;
993   struct
994   {
995     BOOLEAN IncomingMailboxLoaded:1;    // Bit 0
996     BOOLEAN OutgoingMailboxAvailable:1; // Bit 1
997     BOOLEAN CommandComplete:1;          // Bit 2
998     BOOLEAN ExternalBusReset:1;         // Bit 3
999     UCHAR Reserved:3;                   // Bits 4-6
1000     BOOLEAN InterruptValid:1;           // Bit 7
1001   } Bits;
1002 }BusLogic_InterruptRegister_T;
1003 
1004 //  Define the possible Host Adapter BIOS Disk Geometry Translations.
1005 typedef enum BusLogic_BIOS_DiskGeometryTranslation
1006 {
1007   BusLogic_BIOS_Disk_Not_Installed =        0,
1008   BusLogic_BIOS_Disk_Installed_64x32 =      1,
1009   BusLogic_BIOS_Disk_Installed_128x32 =     2,
1010   BusLogic_BIOS_Disk_Installed_255x63 =     3
1011 }BusLogic_BIOS_DiskGeometryTranslation_T;
1012 
1013 //  Define the structure of the read-only Geometry Register
1014 typedef union BusLogic_GeometryRegister
1015 {
1016   UCHAR All;
1017   struct
1018   {
1019     BusLogic_BIOS_DiskGeometryTranslation_T Drive0Geometry:2; // Bits 0-1
1020     BusLogic_BIOS_DiskGeometryTranslation_T Drive1Geometry:2; // Bits 2-3
1021     UCHAR :3;                                                 // Bits 4-6
1022     BOOLEAN ExtendedTranslationEnabled:1;                     // Bit 7
1023   } Bits;
1024 }
1025 BusLogic_GeometryRegister_T;
1026 
1027 static void
BusLogic_InterruptReset(BusLogic_HostAdapter_T * HostAdapter)1028 BusLogic_InterruptReset(BusLogic_HostAdapter_T *HostAdapter)
1029 {
1030   BusLogic_ControlRegister_T ControlRegister;
1031   ControlRegister.All = 0;
1032   ControlRegister.Bits.InterruptReset = TRUE;
1033 
1034   WriteBusLogicPort(ControlRegister.All,
1035        HostAdapter->IO_Address + BusLogic_ControlRegisterOffset);
1036 }
1037 
1038 static void
BusLogic_SoftReset(BusLogic_HostAdapter_T * HostAdapter)1039 BusLogic_SoftReset(BusLogic_HostAdapter_T *HostAdapter)
1040 {
1041   BusLogic_ControlRegister_T ControlRegister;
1042   ControlRegister.All = 0;
1043   ControlRegister.Bits.SoftReset = TRUE;
1044   WriteBusLogicPort(ControlRegister.All,
1045        HostAdapter->IO_Address + BusLogic_ControlRegisterOffset);
1046 }
1047 
1048 static void
BusLogic_HardReset(BusLogic_HostAdapter_T * HostAdapter)1049 BusLogic_HardReset(BusLogic_HostAdapter_T *HostAdapter)
1050 {
1051   BusLogic_ControlRegister_T ControlRegister;
1052   ControlRegister.All = 0;
1053   ControlRegister.Bits.HardReset = TRUE;
1054   WriteBusLogicPort(ControlRegister.All,
1055        HostAdapter->IO_Address + BusLogic_ControlRegisterOffset);
1056 }
1057 
1058 static UCHAR
BusLogic_ReadStatusRegister(BusLogic_HostAdapter_T * HostAdapter)1059 BusLogic_ReadStatusRegister(BusLogic_HostAdapter_T *HostAdapter)
1060 {
1061   return ReadBusLogicPort(HostAdapter->IO_Address + BusLogic_StatusRegisterOffset);
1062 }
1063 
1064 static UCHAR
BusLogic_ReadInterruptRegister(BusLogic_HostAdapter_T * HostAdapter)1065 BusLogic_ReadInterruptRegister(BusLogic_HostAdapter_T *HostAdapter)
1066 {
1067   return ReadBusLogicPort(HostAdapter->IO_Address + BusLogic_InterruptRegisterOffset);
1068 }
1069 
1070 static UCHAR
BusLogic_ReadGeometryRegister(BusLogic_HostAdapter_T * HostAdapter)1071 BusLogic_ReadGeometryRegister(BusLogic_HostAdapter_T *HostAdapter)
1072 {
1073   return ReadBusLogicPort(HostAdapter->IO_Address + BusLogic_GeometryRegisterOffset);
1074 }
1075 
1076 static UCHAR
BusLogic_ReadDataInRegister(BusLogic_HostAdapter_T * HostAdapter)1077 BusLogic_ReadDataInRegister(BusLogic_HostAdapter_T *HostAdapter)
1078 {
1079   return ReadBusLogicPort(HostAdapter->IO_Address + BusLogic_DataInRegisterOffset);
1080 }
1081 
1082 static void
BusLogic_WriteCommandParameterRegister(BusLogic_HostAdapter_T * HostAdapter,UCHAR Value)1083 BusLogic_WriteCommandParameterRegister(BusLogic_HostAdapter_T *HostAdapter,
1084                                        UCHAR Value)
1085 {
1086   WriteBusLogicPort(Value,
1087                     HostAdapter->IO_Address + BusLogic_CommandParameterRegisterOffset);
1088 }
1089 
1090 //  BusLogic_StartMailboxCommand issues an Execute Mailbox Command, which
1091 //  notifies the Host Adapter that an entry has been made in an Outgoing
1092 //  Mailbox.
1093 static void
BusLogic_StartMailboxCommand(BusLogic_HostAdapter_T * HostAdapter)1094 BusLogic_StartMailboxCommand(BusLogic_HostAdapter_T *HostAdapter)
1095 {
1096   BusLogic_WriteCommandParameterRegister(HostAdapter,
1097                                          BusLogic_ExecuteMailboxCommand);
1098 }
1099 
1100 //  Define the Inquire Synchronous Period reply type.  For each Target Device,
1101 //  a byte is returned which represents the Synchronous Transfer Period in units
1102 //  of 10 nanoseconds.
1103 typedef UCHAR BusLogic_SynchronousPeriod_T[BusLogic_MaxTargetDevices];
1104 
1105 //  Define the Inquire Installed Devices ID 0 to 7 and Inquire Installed
1106 //  Devices ID 8 to 15 reply type.  For each Target Device, a byte is returned
1107 //  where bit 0 set indicates that Logical Unit 0 exists, bit 1 set indicates
1108 //  that Logical Unit 1 exists, and so on.
1109 typedef UCHAR BusLogic_InstalledDevices8_T[8];
1110 
1111 //  Define the Inquire Target Devices reply type.  Inquire Target Devices only
1112 //  tests Logical Unit 0 of each Target Device unlike the Inquire Installed
1113 //  Devices commands which test Logical Units 0 - 7.  Two bytes are returned,
1114 //  where byte 0 bit 0 set indicates that Target Device 0 exists, and so on.
1115 typedef unsigned short BusLogic_InstalledDevices_T;
1116 
1117 //  Define the Initialize Extended Mailbox request structure.
1118 #pragma pack (1)
1119 typedef struct BusLogic_ExtendedMailboxRequest
1120 {
1121     UCHAR MailboxCount;         /* Byte 0 */
1122     ULONG BaseMailboxAddress;   /* Bytes 1-4 */
1123 }BusLogic_ExtendedMailboxRequest_T;
1124 #pragma pack ()
1125 
1126 //  Define the Set CCB Format request type.  Extended LUN Format CCBs are
1127 //  necessary to support more than 8 Logical Units per Target Device.
1128 typedef enum BusLogic_SetCCBFormatRequest
1129 {
1130   BusLogic_LegacyLUNFormatCCB =         0,
1131   BusLogic_ExtendedLUNFormatCCB =       1
1132 }BusLogic_SetCCBFormatRequest_T;
1133 
1134 //______________________________________________________________________________________
1135 // Statistics
1136 //______________________________________________________________________________________
1137 //  BusLogic_IncrementByteCounter increments Byte Counter by Amount.
1138 static void
BusLogic_IncrementByteCounter(BusLogic_ByteCounter_T * ByteCounter,unsigned int Amount)1139 BusLogic_IncrementByteCounter(BusLogic_ByteCounter_T *ByteCounter,
1140                               unsigned int Amount)
1141 {
1142   ByteCounter->Units += Amount;
1143   if (ByteCounter->Units > 999999999)
1144   {
1145       ByteCounter->Units -= 1000000000;
1146       ByteCounter->Billions++;
1147   }
1148 }
1149 
1150 //  BusLogic_IncrementSizeBucket increments the Bucket for Amount.
1151 static void
BusLogic_IncrementSizeBucket(BusLogic_CommandSizeBuckets_T CommandSizeBuckets,unsigned int Amount)1152 BusLogic_IncrementSizeBucket(BusLogic_CommandSizeBuckets_T CommandSizeBuckets,
1153                              unsigned int Amount)
1154 {
1155   int Index = 0;
1156   if (Amount < 8*1024)
1157   {
1158     if (Amount < 2*1024)
1159         Index = (Amount < 1*1024 ? 0 : 1);
1160     else
1161         Index = (Amount < 4*1024 ? 2 : 3);
1162   }
1163   else if (Amount < 128*1024)
1164   {
1165     if (Amount < 32*1024)
1166         Index = (Amount < 16*1024 ? 4 : 5);
1167     else
1168         Index = (Amount < 64*1024 ? 6 : 7);
1169   }
1170   else
1171       Index = (Amount < 256*1024 ? 8 : 9);
1172   CommandSizeBuckets[Index]++;
1173 }
1174 
1175 
1176 //  BusLogic_IncrementErrorCounter increments Error Counter by 1, stopping at
1177 //  65535 rather than wrapping around to 0.
1178 static void
BusLogic_IncrementErrorCounter(unsigned short * ErrorCounter)1179 BusLogic_IncrementErrorCounter(unsigned short *ErrorCounter)
1180 {
1181   if (*ErrorCounter < 65535) (*ErrorCounter)++;
1182 }
1183 //____________________________________________________________________________________________
1184