ia64/xen-unstable

changeset 908:8d4b127849bd

bitkeeper revision 1.572.1.1 (3facce1c9dWmFo8RXZ7u-UnRmx-g_A)

BusLogic.h, BusLogic.c, FlashPoint.c.inc:
new file
config.h, Makefile:
Ported BusLogic SCSI driver. Note that is is UNTESTED.
author kaf24@scramble.cl.cam.ac.uk
date Sat Nov 08 11:06:04 2003 +0000 (2003-11-08)
parents 90ae2bc0ebee
children 3f85eabfe053
files .rootkeys xen/drivers/scsi/BusLogic.c xen/drivers/scsi/BusLogic.h xen/drivers/scsi/FlashPoint.c.inc xen/drivers/scsi/Makefile xen/include/xeno/config.h
line diff
     1.1 --- a/.rootkeys	Fri Nov 07 16:37:15 2003 +0000
     1.2 +++ b/.rootkeys	Sat Nov 08 11:06:04 2003 +0000
     1.3 @@ -334,6 +334,9 @@ 3ddb79bfkVLMq5CWjZLACPDivqxq_w xen/drive
     1.4  3ddb79bfl1H1arbB0pzAEC2uPmY_3g xen/drivers/pci/setup-irq.c
     1.5  3ddb79bfJaf0bkE1Y67bnll8-kjEPg xen/drivers/pci/setup-res.c
     1.6  3ddb79bfIcCWJsBDNcQQE3ok2Azn-Q xen/drivers/pci/syscall.c
     1.7 +3facce119oL2_kMylnMRUQlTsUw-OA xen/drivers/scsi/BusLogic.c
     1.8 +3facce12hrTrkdXJQR0MjOG3ud0K0A xen/drivers/scsi/BusLogic.h
     1.9 +3facce0dDkxv278IqO4gxypPDiw3Ow xen/drivers/scsi/FlashPoint.c.inc
    1.10  3ddb79be3kwzyKagpMHGoXZFdan7dg xen/drivers/scsi/Makefile
    1.11  3e564137sVLmo7rTnKLNzLSCvuUz8g xen/drivers/scsi/aacraid/Makefile
    1.12  3e5641379FXvLDjV-0OrRNOBTwL_Lw xen/drivers/scsi/aacraid/README
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/xen/drivers/scsi/BusLogic.c	Sat Nov 08 11:06:04 2003 +0000
     2.3 @@ -0,0 +1,5010 @@
     2.4 +/*
     2.5 +
     2.6 +  Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters
     2.7 +
     2.8 +  Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>
     2.9 +
    2.10 +  This program is free software; you may redistribute and/or modify it under
    2.11 +  the terms of the GNU General Public License Version 2 as published by the
    2.12 +  Free Software Foundation.
    2.13 +
    2.14 +  This program is distributed in the hope that it will be useful, but
    2.15 +  WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
    2.16 +  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    2.17 +  for complete details.
    2.18 +
    2.19 +  The author respectfully requests that any modifications to this software be
    2.20 +  sent directly to him for evaluation and testing.
    2.21 +
    2.22 +  Special thanks to Wayne Yen, Jin-Lon Hon, and Alex Win of BusLogic, whose
    2.23 +  advice has been invaluable, to David Gentzel, for writing the original Linux
    2.24 +  BusLogic driver, and to Paul Gortmaker, for being such a dedicated test site.
    2.25 +
    2.26 +  Finally, special thanks to Mylex/BusLogic for making the FlashPoint SCCB
    2.27 +  Manager available as freely redistributable source code.
    2.28 +
    2.29 +*/
    2.30 +
    2.31 +
    2.32 +#define BusLogic_DriverVersion		"2.1.15"
    2.33 +#define BusLogic_DriverDate		"17 August 1998"
    2.34 +
    2.35 +
    2.36 +#include <linux/version.h>
    2.37 +#include <linux/module.h>
    2.38 +#include <linux/config.h>
    2.39 +#include <linux/init.h>
    2.40 +#include <linux/types.h>
    2.41 +#include <linux/blk.h>
    2.42 +#include <linux/blkdev.h>
    2.43 +#include <linux/delay.h>
    2.44 +#include <linux/ioport.h>
    2.45 +#include <linux/mm.h>
    2.46 +#include <linux/sched.h>
    2.47 +/*#include <linux/stat.h>*/
    2.48 +#include <linux/pci.h>
    2.49 +#include <linux/spinlock.h>
    2.50 +#include <asm/dma.h>
    2.51 +#include <asm/io.h>
    2.52 +#include <asm/system.h>
    2.53 +#include "scsi.h"
    2.54 +#include "hosts.h"
    2.55 +#include "sd.h"
    2.56 +#include "BusLogic.h"
    2.57 +#include "FlashPoint.c.inc"
    2.58 +
    2.59 +
    2.60 +/*
    2.61 +  BusLogic_DriverOptionsCount is a count of the number of BusLogic Driver
    2.62 +  Options specifications provided via the Linux Kernel Command Line or via
    2.63 +  the Loadable Kernel Module Installation Facility.
    2.64 +*/
    2.65 +
    2.66 +static int
    2.67 +  BusLogic_DriverOptionsCount;
    2.68 +
    2.69 +
    2.70 +/*
    2.71 +  BusLogic_DriverOptions is an array of Driver Options structures representing
    2.72 +  BusLogic Driver Options specifications provided via the Linux Kernel Command
    2.73 +  Line or via the Loadable Kernel Module Installation Facility.
    2.74 +*/
    2.75 +
    2.76 +static BusLogic_DriverOptions_T
    2.77 +  BusLogic_DriverOptions[BusLogic_MaxHostAdapters];
    2.78 +
    2.79 +
    2.80 +/*
    2.81 +  BusLogic can be assigned a string by insmod.
    2.82 +*/
    2.83 +
    2.84 +#ifdef MODULE
    2.85 +static char *BusLogic;
    2.86 +MODULE_PARM(BusLogic, "s");
    2.87 +#endif
    2.88 +
    2.89 +
    2.90 +/*
    2.91 +  BusLogic_ProbeOptions is a set of Probe Options to be applied across
    2.92 +  all BusLogic Host Adapters.
    2.93 +*/
    2.94 +
    2.95 +static BusLogic_ProbeOptions_T
    2.96 +  BusLogic_ProbeOptions;
    2.97 +
    2.98 +
    2.99 +/*
   2.100 +  BusLogic_GlobalOptions is a set of Global Options to be applied across
   2.101 +  all BusLogic Host Adapters.
   2.102 +*/
   2.103 +
   2.104 +static BusLogic_GlobalOptions_T
   2.105 +  BusLogic_GlobalOptions;
   2.106 +
   2.107 +
   2.108 +/*
   2.109 +  BusLogic_FirstRegisteredHostAdapter and BusLogic_LastRegisteredHostAdapter
   2.110 +  are pointers to the first and last registered BusLogic Host Adapters.
   2.111 +*/
   2.112 +
   2.113 +static BusLogic_HostAdapter_T
   2.114 +  *BusLogic_FirstRegisteredHostAdapter,
   2.115 +  *BusLogic_LastRegisteredHostAdapter;
   2.116 +
   2.117 +
   2.118 +/*
   2.119 +  BusLogic_ProbeInfoCount is the number of entries in BusLogic_ProbeInfoList.
   2.120 +*/
   2.121 +
   2.122 +static int
   2.123 +  BusLogic_ProbeInfoCount;
   2.124 +
   2.125 +
   2.126 +/*
   2.127 +  BusLogic_ProbeInfoList is the list of I/O Addresses and Bus Probe Information
   2.128 +  to be checked for potential BusLogic Host Adapters.  It is initialized by
   2.129 +  interrogating the PCI Configuration Space on PCI machines as well as from the
   2.130 +  list of standard BusLogic I/O Addresses.
   2.131 +*/
   2.132 +
   2.133 +static BusLogic_ProbeInfo_T
   2.134 +  *BusLogic_ProbeInfoList;
   2.135 +
   2.136 +
   2.137 +/*
   2.138 +  BusLogic_CommandFailureReason holds a string identifying the reason why a
   2.139 +  call to BusLogic_Command failed.  It is only non-NULL when BusLogic_Command
   2.140 +  returns a failure code.
   2.141 +*/
   2.142 +
   2.143 +static char
   2.144 +  *BusLogic_CommandFailureReason;
   2.145 +
   2.146 +/*
   2.147 +  BusLogic_AnnounceDriver announces the Driver Version and Date, Author's
   2.148 +  Name, Copyright Notice, and Electronic Mail Address.
   2.149 +*/
   2.150 +
   2.151 +static void BusLogic_AnnounceDriver(BusLogic_HostAdapter_T *HostAdapter)
   2.152 +{
   2.153 +  BusLogic_Announce("***** BusLogic SCSI Driver Version "
   2.154 +		    BusLogic_DriverVersion " of "
   2.155 +		    BusLogic_DriverDate " *****\n", HostAdapter);
   2.156 +  BusLogic_Announce("Copyright 1995-1998 by Leonard N. Zubkoff "
   2.157 +		    "<lnz@dandelion.com>\n", HostAdapter);
   2.158 +}
   2.159 +
   2.160 +
   2.161 +/*
   2.162 +  BusLogic_DriverInfo returns the Host Adapter Name to identify this SCSI
   2.163 +  Driver and Host Adapter.
   2.164 +*/
   2.165 +
   2.166 +const char *BusLogic_DriverInfo(SCSI_Host_T *Host)
   2.167 +{
   2.168 +  BusLogic_HostAdapter_T *HostAdapter =
   2.169 +    (BusLogic_HostAdapter_T *) Host->hostdata;
   2.170 +  return HostAdapter->FullModelName;
   2.171 +}
   2.172 +
   2.173 +
   2.174 +/*
   2.175 +  BusLogic_RegisterHostAdapter adds Host Adapter to the list of registered
   2.176 +  BusLogic Host Adapters.
   2.177 +*/
   2.178 +
   2.179 +static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
   2.180 +{
   2.181 +  HostAdapter->Next = NULL;
   2.182 +  if (BusLogic_FirstRegisteredHostAdapter == NULL)
   2.183 +    {
   2.184 +      BusLogic_FirstRegisteredHostAdapter = HostAdapter;
   2.185 +      BusLogic_LastRegisteredHostAdapter = HostAdapter;
   2.186 +    }
   2.187 +  else
   2.188 +    {
   2.189 +      BusLogic_LastRegisteredHostAdapter->Next = HostAdapter;
   2.190 +      BusLogic_LastRegisteredHostAdapter = HostAdapter;
   2.191 +    }
   2.192 +}
   2.193 +
   2.194 +
   2.195 +/*
   2.196 +  BusLogic_UnregisterHostAdapter removes Host Adapter from the list of
   2.197 +  registered BusLogic Host Adapters.
   2.198 +*/
   2.199 +
   2.200 +static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
   2.201 +{
   2.202 +  if (HostAdapter == BusLogic_FirstRegisteredHostAdapter)
   2.203 +    {
   2.204 +      BusLogic_FirstRegisteredHostAdapter =
   2.205 +	BusLogic_FirstRegisteredHostAdapter->Next;
   2.206 +      if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
   2.207 +	BusLogic_LastRegisteredHostAdapter = NULL;
   2.208 +    }
   2.209 +  else
   2.210 +    {
   2.211 +      BusLogic_HostAdapter_T *PreviousHostAdapter =
   2.212 +	BusLogic_FirstRegisteredHostAdapter;
   2.213 +      while (PreviousHostAdapter != NULL &&
   2.214 +	     PreviousHostAdapter->Next != HostAdapter)
   2.215 +	PreviousHostAdapter = PreviousHostAdapter->Next;
   2.216 +      if (PreviousHostAdapter != NULL)
   2.217 +	PreviousHostAdapter->Next = HostAdapter->Next;
   2.218 +    }
   2.219 +  HostAdapter->Next = NULL;
   2.220 +}
   2.221 +
   2.222 +
   2.223 +/*
   2.224 +  BusLogic_InitializeCCBs initializes a group of Command Control Blocks (CCBs)
   2.225 +  for Host Adapter from the BlockSize bytes located at BlockPointer.  The newly
   2.226 +  created CCBs are added to Host Adapter's free list.
   2.227 +*/
   2.228 +
   2.229 +static void BusLogic_InitializeCCBs(BusLogic_HostAdapter_T *HostAdapter,
   2.230 +				    void *BlockPointer, int BlockSize)
   2.231 +{
   2.232 +  BusLogic_CCB_T *CCB = (BusLogic_CCB_T *) BlockPointer;
   2.233 +  memset(BlockPointer, 0, BlockSize);
   2.234 +  CCB->AllocationGroupHead = true;
   2.235 +  while ((BlockSize -= sizeof(BusLogic_CCB_T)) >= 0)
   2.236 +    {
   2.237 +      CCB->Status = BusLogic_CCB_Free;
   2.238 +      CCB->HostAdapter = HostAdapter;
   2.239 +      if (BusLogic_FlashPointHostAdapterP(HostAdapter))
   2.240 +	{
   2.241 +	  CCB->CallbackFunction = BusLogic_QueueCompletedCCB;
   2.242 +	  CCB->BaseAddress = HostAdapter->FlashPointInfo.BaseAddress;
   2.243 +	}
   2.244 +      CCB->Next = HostAdapter->Free_CCBs;
   2.245 +      CCB->NextAll = HostAdapter->All_CCBs;
   2.246 +      HostAdapter->Free_CCBs = CCB;
   2.247 +      HostAdapter->All_CCBs = CCB;
   2.248 +      HostAdapter->AllocatedCCBs++;
   2.249 +      CCB++;
   2.250 +    }
   2.251 +}
   2.252 +
   2.253 +
   2.254 +/*
   2.255 +  BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter.
   2.256 +*/
   2.257 +
   2.258 +static boolean BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *HostAdapter)
   2.259 +{
   2.260 +  int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(BusLogic_CCB_T);
   2.261 +  while (HostAdapter->AllocatedCCBs < HostAdapter->InitialCCBs)
   2.262 +    {
   2.263 +      void *BlockPointer = kmalloc(BlockSize,
   2.264 +				   (HostAdapter->BounceBuffersRequired
   2.265 +				    ? GFP_ATOMIC | GFP_DMA
   2.266 +				    : GFP_ATOMIC));
   2.267 +      if (BlockPointer == NULL)
   2.268 +	{
   2.269 +	  BusLogic_Error("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n",
   2.270 +			 HostAdapter);
   2.271 +	  return false;
   2.272 +	}
   2.273 +      BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize);
   2.274 +    }
   2.275 +  return true;
   2.276 +}
   2.277 +
   2.278 +
   2.279 +/*
   2.280 +  BusLogic_DestroyCCBs deallocates the CCBs for Host Adapter.
   2.281 +*/
   2.282 +
   2.283 +static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *HostAdapter)
   2.284 +{
   2.285 +  BusLogic_CCB_T *NextCCB = HostAdapter->All_CCBs, *CCB;
   2.286 +  HostAdapter->All_CCBs = NULL;
   2.287 +  HostAdapter->Free_CCBs = NULL;
   2.288 +  while ((CCB = NextCCB) != NULL)
   2.289 +    {
   2.290 +      NextCCB = CCB->NextAll;
   2.291 +      if (CCB->AllocationGroupHead)
   2.292 +	kfree(CCB);
   2.293 +    }
   2.294 +}
   2.295 +
   2.296 +
   2.297 +/*
   2.298 +  BusLogic_CreateAdditionalCCBs allocates Additional CCBs for Host Adapter.  If
   2.299 +  allocation fails and there are no remaining CCBs available, the Driver Queue
   2.300 +  Depth is decreased to a known safe value to avoid potential deadlocks when
   2.301 +  multiple host adapters share the same IRQ Channel.
   2.302 +*/
   2.303 +
   2.304 +static void BusLogic_CreateAdditionalCCBs(BusLogic_HostAdapter_T *HostAdapter,
   2.305 +					  int AdditionalCCBs,
   2.306 +					  boolean SuccessMessageP)
   2.307 +{
   2.308 +  int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(BusLogic_CCB_T);
   2.309 +  int PreviouslyAllocated = HostAdapter->AllocatedCCBs;
   2.310 +  if (AdditionalCCBs <= 0) return;
   2.311 +  while (HostAdapter->AllocatedCCBs - PreviouslyAllocated < AdditionalCCBs)
   2.312 +    {
   2.313 +      void *BlockPointer = kmalloc(BlockSize,
   2.314 +				   (HostAdapter->BounceBuffersRequired
   2.315 +				    ? GFP_ATOMIC | GFP_DMA
   2.316 +				    : GFP_ATOMIC));
   2.317 +      if (BlockPointer == NULL) break;
   2.318 +      BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize);
   2.319 +    }
   2.320 +  if (HostAdapter->AllocatedCCBs > PreviouslyAllocated)
   2.321 +    {
   2.322 +      if (SuccessMessageP)
   2.323 +	BusLogic_Notice("Allocated %d additional CCBs (total now %d)\n",
   2.324 +			HostAdapter,
   2.325 +			HostAdapter->AllocatedCCBs - PreviouslyAllocated,
   2.326 +			HostAdapter->AllocatedCCBs);
   2.327 +      return;
   2.328 +    }
   2.329 +  BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter);
   2.330 +  if (HostAdapter->DriverQueueDepth >
   2.331 +      HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount)
   2.332 +    {
   2.333 +      HostAdapter->DriverQueueDepth =
   2.334 +	HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount;
   2.335 +      HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth;
   2.336 +    }
   2.337 +}
   2.338 +
   2.339 +
   2.340 +/*
   2.341 +  BusLogic_AllocateCCB allocates a CCB from Host Adapter's free list,
   2.342 +  allocating more memory from the Kernel if necessary.  The Host Adapter's
   2.343 +  Lock should already have been acquired by the caller.
   2.344 +*/
   2.345 +
   2.346 +static BusLogic_CCB_T *BusLogic_AllocateCCB(BusLogic_HostAdapter_T
   2.347 +					    *HostAdapter)
   2.348 +{
   2.349 +  static unsigned long SerialNumber = 0;
   2.350 +  BusLogic_CCB_T *CCB;
   2.351 +  CCB = HostAdapter->Free_CCBs;
   2.352 +  if (CCB != NULL)
   2.353 +    {
   2.354 +      CCB->SerialNumber = ++SerialNumber;
   2.355 +      HostAdapter->Free_CCBs = CCB->Next;
   2.356 +      CCB->Next = NULL;
   2.357 +      if (HostAdapter->Free_CCBs == NULL)
   2.358 +	BusLogic_CreateAdditionalCCBs(HostAdapter,
   2.359 +				      HostAdapter->IncrementalCCBs,
   2.360 +				      true);
   2.361 +      return CCB;
   2.362 +    }
   2.363 +  BusLogic_CreateAdditionalCCBs(HostAdapter,
   2.364 +				HostAdapter->IncrementalCCBs,
   2.365 +				true);
   2.366 +  CCB = HostAdapter->Free_CCBs;
   2.367 +  if (CCB == NULL) return NULL;
   2.368 +  CCB->SerialNumber = ++SerialNumber;
   2.369 +  HostAdapter->Free_CCBs = CCB->Next;
   2.370 +  CCB->Next = NULL;
   2.371 +  return CCB;
   2.372 +}
   2.373 +
   2.374 +
   2.375 +/*
   2.376 +  BusLogic_DeallocateCCB deallocates a CCB, returning it to the Host Adapter's
   2.377 +  free list.  The Host Adapter's Lock should already have been acquired by the
   2.378 +  caller.
   2.379 +*/
   2.380 +
   2.381 +static void BusLogic_DeallocateCCB(BusLogic_CCB_T *CCB)
   2.382 +{
   2.383 +  BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
   2.384 +  CCB->Command = NULL;
   2.385 +  CCB->Status = BusLogic_CCB_Free;
   2.386 +  CCB->Next = HostAdapter->Free_CCBs;
   2.387 +  HostAdapter->Free_CCBs = CCB;
   2.388 +}
   2.389 +
   2.390 +
   2.391 +/*
   2.392 +  BusLogic_Command sends the command OperationCode to HostAdapter, optionally
   2.393 +  providing ParameterLength bytes of ParameterData and receiving at most
   2.394 +  ReplyLength bytes of ReplyData; any excess reply data is received but
   2.395 +  discarded.
   2.396 +
   2.397 +  On success, this function returns the number of reply bytes read from
   2.398 +  the Host Adapter (including any discarded data); on failure, it returns
   2.399 +  -1 if the command was invalid, or -2 if a timeout occurred.
   2.400 +
   2.401 +  BusLogic_Command is called exclusively during host adapter detection and
   2.402 +  initialization, so performance and latency are not critical, and exclusive
   2.403 +  access to the Host Adapter hardware is assumed.  Once the host adapter and
   2.404 +  driver are initialized, the only Host Adapter command that is issued is the
   2.405 +  single byte Execute Mailbox Command operation code, which does not require
   2.406 +  waiting for the Host Adapter Ready bit to be set in the Status Register.
   2.407 +*/
   2.408 +
   2.409 +static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,
   2.410 +			    BusLogic_OperationCode_T OperationCode,
   2.411 +			    void *ParameterData,
   2.412 +			    int ParameterLength,
   2.413 +			    void *ReplyData,
   2.414 +			    int ReplyLength)
   2.415 +{
   2.416 +  unsigned char *ParameterPointer = (unsigned char *) ParameterData;
   2.417 +  unsigned char *ReplyPointer = (unsigned char *) ReplyData;
   2.418 +  BusLogic_StatusRegister_T StatusRegister;
   2.419 +  BusLogic_InterruptRegister_T InterruptRegister;
   2.420 +  ProcessorFlags_T ProcessorFlags = 0;
   2.421 +  int ReplyBytes = 0, Result;
   2.422 +  long TimeoutCounter;
   2.423 +  /*
   2.424 +    Clear out the Reply Data if provided.
   2.425 +  */
   2.426 +  if (ReplyLength > 0)
   2.427 +    memset(ReplyData, 0, ReplyLength);
   2.428 +  /*
   2.429 +    If the IRQ Channel has not yet been acquired, then interrupts must be
   2.430 +    disabled while issuing host adapter commands since a Command Complete
   2.431 +    interrupt could occur if the IRQ Channel was previously enabled by another
   2.432 +    BusLogic Host Adapter or another driver sharing the same IRQ Channel.
   2.433 +  */
   2.434 +  if (!HostAdapter->IRQ_ChannelAcquired)
   2.435 +    {
   2.436 +      save_flags(ProcessorFlags);
   2.437 +      cli();
   2.438 +    }
   2.439 +  /*
   2.440 +    Wait for the Host Adapter Ready bit to be set and the Command/Parameter
   2.441 +    Register Busy bit to be reset in the Status Register.
   2.442 +  */
   2.443 +  TimeoutCounter = 10000;
   2.444 +  while (--TimeoutCounter >= 0)
   2.445 +    {
   2.446 +      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
   2.447 +      if (StatusRegister.Bits.HostAdapterReady &&
   2.448 +	  !StatusRegister.Bits.CommandParameterRegisterBusy)
   2.449 +	break;
   2.450 +      udelay(100);
   2.451 +    }
   2.452 +  if (TimeoutCounter < 0)
   2.453 +    {
   2.454 +      BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
   2.455 +      Result = -2;
   2.456 +      goto Done;
   2.457 +    }
   2.458 +  /*
   2.459 +    Write the OperationCode to the Command/Parameter Register.
   2.460 +  */
   2.461 +  HostAdapter->HostAdapterCommandCompleted = false;
   2.462 +  BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
   2.463 +  /*
   2.464 +    Write any additional Parameter Bytes.
   2.465 +  */
   2.466 +  TimeoutCounter = 10000;
   2.467 +  while (ParameterLength > 0 && --TimeoutCounter >= 0)
   2.468 +    {
   2.469 +      /*
   2.470 +	Wait 100 microseconds to give the Host Adapter enough time to determine
   2.471 +	whether the last value written to the Command/Parameter Register was
   2.472 +	valid or not.  If the Command Complete bit is set in the Interrupt
   2.473 +	Register, then the Command Invalid bit in the Status Register will be
   2.474 +	reset if the Operation Code or Parameter was valid and the command
   2.475 +	has completed, or set if the Operation Code or Parameter was invalid.
   2.476 +	If the Data In Register Ready bit is set in the Status Register, then
   2.477 +	the Operation Code was valid, and data is waiting to be read back
   2.478 +	from the Host Adapter.  Otherwise, wait for the Command/Parameter
   2.479 +	Register Busy bit in the Status Register to be reset.
   2.480 +      */
   2.481 +      udelay(100);
   2.482 +      InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
   2.483 +      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
   2.484 +      if (InterruptRegister.Bits.CommandComplete) break;
   2.485 +      if (HostAdapter->HostAdapterCommandCompleted) break;
   2.486 +      if (StatusRegister.Bits.DataInRegisterReady) break;
   2.487 +      if (StatusRegister.Bits.CommandParameterRegisterBusy) continue;
   2.488 +      BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
   2.489 +      ParameterLength--;
   2.490 +    }
   2.491 +  if (TimeoutCounter < 0)
   2.492 +    {
   2.493 +      BusLogic_CommandFailureReason =
   2.494 +	"Timeout waiting for Parameter Acceptance";
   2.495 +      Result = -2;
   2.496 +      goto Done;
   2.497 +    }
   2.498 +  /*
   2.499 +    The Modify I/O Address command does not cause a Command Complete Interrupt.
   2.500 +  */
   2.501 +  if (OperationCode == BusLogic_ModifyIOAddress)
   2.502 +    {
   2.503 +      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
   2.504 +      if (StatusRegister.Bits.CommandInvalid)
   2.505 +	{
   2.506 +	  BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
   2.507 +	  Result = -1;
   2.508 +	  goto Done;
   2.509 +	}
   2.510 +      if (BusLogic_GlobalOptions.TraceConfiguration)
   2.511 +	BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: "
   2.512 +			"(Modify I/O Address)\n", HostAdapter,
   2.513 +			OperationCode, StatusRegister.All);
   2.514 +      Result = 0;
   2.515 +      goto Done;
   2.516 +    }
   2.517 +  /*
   2.518 +    Select an appropriate timeout value for awaiting command completion.
   2.519 +  */
   2.520 +  switch (OperationCode)
   2.521 +    {
   2.522 +    case BusLogic_InquireInstalledDevicesID0to7:
   2.523 +    case BusLogic_InquireInstalledDevicesID8to15:
   2.524 +    case BusLogic_InquireTargetDevices:
   2.525 +      /* Approximately 60 seconds. */
   2.526 +      TimeoutCounter = 60*10000;
   2.527 +      break;
   2.528 +    default:
   2.529 +      /* Approximately 1 second. */
   2.530 +      TimeoutCounter = 10000;
   2.531 +      break;
   2.532 +    }
   2.533 +  /*
   2.534 +    Receive any Reply Bytes, waiting for either the Command Complete bit to
   2.535 +    be set in the Interrupt Register, or for the Interrupt Handler to set the
   2.536 +    Host Adapter Command Completed bit in the Host Adapter structure.
   2.537 +  */
   2.538 +  while (--TimeoutCounter >= 0)
   2.539 +    {
   2.540 +      InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
   2.541 +      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
   2.542 +      if (InterruptRegister.Bits.CommandComplete) break;
   2.543 +      if (HostAdapter->HostAdapterCommandCompleted) break;
   2.544 +      if (StatusRegister.Bits.DataInRegisterReady)
   2.545 +	{
   2.546 +	  if (++ReplyBytes <= ReplyLength)
   2.547 +	    *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
   2.548 +	  else BusLogic_ReadDataInRegister(HostAdapter);
   2.549 +	}
   2.550 +      if (OperationCode == BusLogic_FetchHostAdapterLocalRAM &&
   2.551 +	  StatusRegister.Bits.HostAdapterReady) break;
   2.552 +      udelay(100);
   2.553 +    }
   2.554 +  if (TimeoutCounter < 0)
   2.555 +    {
   2.556 +      BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
   2.557 +      Result = -2;
   2.558 +      goto Done;
   2.559 +    }
   2.560 +  /*
   2.561 +    Clear any pending Command Complete Interrupt.
   2.562 +  */
   2.563 +  BusLogic_InterruptReset(HostAdapter);
   2.564 +  /*
   2.565 +    Provide tracing information if requested.
   2.566 +  */
   2.567 +  if (BusLogic_GlobalOptions.TraceConfiguration)
   2.568 +    {
   2.569 +      int i;
   2.570 +      BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:",
   2.571 +		      HostAdapter, OperationCode,
   2.572 +		      StatusRegister.All, ReplyLength, ReplyBytes);
   2.573 +      if (ReplyLength > ReplyBytes) ReplyLength = ReplyBytes;
   2.574 +      for (i = 0; i < ReplyLength; i++)
   2.575 +	BusLogic_Notice(" %02X", HostAdapter,
   2.576 +			((unsigned char *) ReplyData)[i]);
   2.577 +      BusLogic_Notice("\n", HostAdapter);
   2.578 +    }
   2.579 +  /*
   2.580 +    Process Command Invalid conditions.
   2.581 +  */
   2.582 +  if (StatusRegister.Bits.CommandInvalid)
   2.583 +    {
   2.584 +      /*
   2.585 +	Some early BusLogic Host Adapters may not recover properly from
   2.586 +	a Command Invalid condition, so if this appears to be the case,
   2.587 +	a Soft Reset is issued to the Host Adapter.  Potentially invalid
   2.588 +	commands are never attempted after Mailbox Initialization is
   2.589 +	performed, so there should be no Host Adapter state lost by a
   2.590 +	Soft Reset in response to a Command Invalid condition.
   2.591 +      */
   2.592 +      udelay(1000);
   2.593 +      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
   2.594 +      if (StatusRegister.Bits.CommandInvalid ||
   2.595 +	  StatusRegister.Bits.Reserved ||
   2.596 +	  StatusRegister.Bits.DataInRegisterReady ||
   2.597 +	  StatusRegister.Bits.CommandParameterRegisterBusy ||
   2.598 +	  !StatusRegister.Bits.HostAdapterReady ||
   2.599 +	  !StatusRegister.Bits.InitializationRequired ||
   2.600 +	  StatusRegister.Bits.DiagnosticActive ||
   2.601 +	  StatusRegister.Bits.DiagnosticFailure)
   2.602 +	{
   2.603 +	  BusLogic_SoftReset(HostAdapter);
   2.604 +	  udelay(1000);
   2.605 +	}
   2.606 +      BusLogic_CommandFailureReason = "Command Invalid";
   2.607 +      Result = -1;
   2.608 +      goto Done;
   2.609 +    }
   2.610 +  /*
   2.611 +    Handle Excess Parameters Supplied conditions.
   2.612 +  */
   2.613 +  if (ParameterLength > 0)
   2.614 +    {
   2.615 +      BusLogic_CommandFailureReason = "Excess Parameters Supplied";
   2.616 +      Result = -1;
   2.617 +      goto Done;
   2.618 +    }
   2.619 +  /*
   2.620 +    Indicate the command completed successfully.
   2.621 +  */
   2.622 +  BusLogic_CommandFailureReason = NULL;
   2.623 +  Result = ReplyBytes;
   2.624 +  /*
   2.625 +    Restore the interrupt status if necessary and return.
   2.626 +  */
   2.627 +Done:
   2.628 +  if (!HostAdapter->IRQ_ChannelAcquired)
   2.629 +    restore_flags(ProcessorFlags);
   2.630 +  return Result;
   2.631 +}
   2.632 +
   2.633 +
   2.634 +/*
   2.635 +  BusLogic_AppendProbeAddressISA appends a single ISA I/O Address to the list
   2.636 +  of I/O Address and Bus Probe Information to be checked for potential BusLogic
   2.637 +  Host Adapters.
   2.638 +*/
   2.639 +
   2.640 +static void BusLogic_AppendProbeAddressISA(BusLogic_IO_Address_T IO_Address)
   2.641 +{
   2.642 +  BusLogic_ProbeInfo_T *ProbeInfo;
   2.643 +  if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return;
   2.644 +  ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
   2.645 +  ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
   2.646 +  ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
   2.647 +  ProbeInfo->IO_Address = IO_Address;
   2.648 +}
   2.649 +
   2.650 +
   2.651 +/*
   2.652 +  BusLogic_InitializeProbeInfoListISA initializes the list of I/O Address and
   2.653 +  Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters
   2.654 +  only from the list of standard BusLogic MultiMaster ISA I/O Addresses.
   2.655 +*/
   2.656 +
   2.657 +static void BusLogic_InitializeProbeInfoListISA(BusLogic_HostAdapter_T
   2.658 +						*PrototypeHostAdapter)
   2.659 +{
   2.660 +  /*
   2.661 +    If BusLogic Driver Options specifications requested that ISA Bus Probes
   2.662 +    be inhibited, do not proceed further.
   2.663 +  */
   2.664 +  if (BusLogic_ProbeOptions.NoProbeISA) return;
   2.665 +  /*
   2.666 +    Append the list of standard BusLogic MultiMaster ISA I/O Addresses.
   2.667 +  */
   2.668 +  if (BusLogic_ProbeOptions.LimitedProbeISA
   2.669 +      ? BusLogic_ProbeOptions.Probe330
   2.670 +      : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)
   2.671 +    BusLogic_AppendProbeAddressISA(0x330);
   2.672 +  if (BusLogic_ProbeOptions.LimitedProbeISA
   2.673 +      ? BusLogic_ProbeOptions.Probe334
   2.674 +      : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0)
   2.675 +    BusLogic_AppendProbeAddressISA(0x334);
   2.676 +  if (BusLogic_ProbeOptions.LimitedProbeISA
   2.677 +      ? BusLogic_ProbeOptions.Probe230
   2.678 +      : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0)
   2.679 +    BusLogic_AppendProbeAddressISA(0x230);
   2.680 +  if (BusLogic_ProbeOptions.LimitedProbeISA
   2.681 +      ? BusLogic_ProbeOptions.Probe234
   2.682 +      : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0)
   2.683 +    BusLogic_AppendProbeAddressISA(0x234);
   2.684 +  if (BusLogic_ProbeOptions.LimitedProbeISA
   2.685 +      ? BusLogic_ProbeOptions.Probe130
   2.686 +      : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0)
   2.687 +    BusLogic_AppendProbeAddressISA(0x130);
   2.688 +  if (BusLogic_ProbeOptions.LimitedProbeISA
   2.689 +      ? BusLogic_ProbeOptions.Probe134
   2.690 +      : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0)
   2.691 +    BusLogic_AppendProbeAddressISA(0x134);
   2.692 +}
   2.693 +
   2.694 +
   2.695 +#ifdef CONFIG_PCI
   2.696 +
   2.697 +
   2.698 +/*
   2.699 +  BusLogic_SortProbeInfo sorts a section of BusLogic_ProbeInfoList in order
   2.700 +  of increasing PCI Bus and Device Number.
   2.701 +*/
   2.702 +
   2.703 +static void BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *ProbeInfoList,
   2.704 +				   int ProbeInfoCount)
   2.705 +{
   2.706 +  int LastInterchange = ProbeInfoCount-1, Bound, j;
   2.707 +  while (LastInterchange > 0)
   2.708 +    {
   2.709 +      Bound = LastInterchange;
   2.710 +      LastInterchange = 0;
   2.711 +      for (j = 0; j < Bound; j++)
   2.712 +	{
   2.713 +	  BusLogic_ProbeInfo_T *ProbeInfo1 = &ProbeInfoList[j];
   2.714 +	  BusLogic_ProbeInfo_T *ProbeInfo2 = &ProbeInfoList[j+1];
   2.715 +	  if (ProbeInfo1->Bus > ProbeInfo2->Bus ||
   2.716 +	      (ProbeInfo1->Bus == ProbeInfo2->Bus &&
   2.717 +	       (ProbeInfo1->Device > ProbeInfo2->Device)))
   2.718 +	    {
   2.719 +	      BusLogic_ProbeInfo_T TempProbeInfo;
   2.720 +	      memcpy(&TempProbeInfo, ProbeInfo1, sizeof(BusLogic_ProbeInfo_T));
   2.721 +	      memcpy(ProbeInfo1, ProbeInfo2, sizeof(BusLogic_ProbeInfo_T));
   2.722 +	      memcpy(ProbeInfo2, &TempProbeInfo, sizeof(BusLogic_ProbeInfo_T));
   2.723 +	      LastInterchange = j;
   2.724 +	    }
   2.725 +	}
   2.726 +    }
   2.727 +}
   2.728 +
   2.729 +
   2.730 +/*
   2.731 +  BusLogic_InitializeMultiMasterProbeInfo initializes the list of I/O Address
   2.732 +  and Bus Probe Information to be checked for potential BusLogic MultiMaster
   2.733 +  SCSI Host Adapters by interrogating the PCI Configuration Space on PCI
   2.734 +  machines as well as from the list of standard BusLogic MultiMaster ISA
   2.735 +  I/O Addresses.  It returns the number of PCI MultiMaster Host Adapters found.
   2.736 +*/
   2.737 +
   2.738 +static int BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T
   2.739 +						   *PrototypeHostAdapter)
   2.740 +{
   2.741 +  BusLogic_ProbeInfo_T *PrimaryProbeInfo =
   2.742 +    &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount];
   2.743 +  int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1;
   2.744 +  int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0;
   2.745 +  boolean ForceBusDeviceScanningOrder = false;
   2.746 +  boolean ForceBusDeviceScanningOrderChecked = false;
   2.747 +  boolean StandardAddressSeen[6];
   2.748 +  PCI_Device_T *PCI_Device = NULL;
   2.749 +  int i;
   2.750 +  if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return 0;
   2.751 +  BusLogic_ProbeInfoCount++;
   2.752 +  for (i = 0; i < 6; i++)
   2.753 +    StandardAddressSeen[i] = false;
   2.754 +  /*
   2.755 +    Iterate over the MultiMaster PCI Host Adapters.  For each enumerated host
   2.756 +    adapter, determine whether its ISA Compatible I/O Port is enabled and if
   2.757 +    so, whether it is assigned the Primary I/O Address.  A host adapter that is
   2.758 +    assigned the Primary I/O Address will always be the preferred boot device.
   2.759 +    The MultiMaster BIOS will first recognize a host adapter at the Primary I/O
   2.760 +    Address, then any other PCI host adapters, and finally any host adapters
   2.761 +    located at the remaining standard ISA I/O Addresses.  When a PCI host
   2.762 +    adapter is found with its ISA Compatible I/O Port enabled, a command is
   2.763 +    issued to disable the ISA Compatible I/O Port, and it is noted that the
   2.764 +    particular standard ISA I/O Address need not be probed.
   2.765 +  */
   2.766 +  PrimaryProbeInfo->IO_Address = 0;
   2.767 +  while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
   2.768 +				       PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
   2.769 +				       PCI_Device)) != NULL)
   2.770 +    {
   2.771 +      BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
   2.772 +      BusLogic_PCIHostAdapterInformation_T PCIHostAdapterInformation;
   2.773 +      BusLogic_ModifyIOAddressRequest_T ModifyIOAddressRequest;
   2.774 +      unsigned char Bus = PCI_Device->bus->number;
   2.775 +      unsigned char Device = PCI_Device->devfn >> 3;
   2.776 +      unsigned int IRQ_Channel;
   2.777 +      unsigned long BaseAddress0;
   2.778 +      unsigned long BaseAddress1;
   2.779 +      BusLogic_IO_Address_T IO_Address;
   2.780 +      BusLogic_PCI_Address_T PCI_Address;
   2.781 +
   2.782 +      if (pci_enable_device(PCI_Device))
   2.783 +      	continue;
   2.784 +      
   2.785 +      IRQ_Channel = PCI_Device->irq;
   2.786 +      IO_Address  = BaseAddress0 = pci_resource_start(PCI_Device, 0);
   2.787 +      PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
   2.788 +
   2.789 +      if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM)
   2.790 +	{
   2.791 +	  BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
   2.792 +			 "MultiMaster Host Adapter\n", NULL, BaseAddress0);
   2.793 +	  BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
   2.794 +			 NULL, Bus, Device, IO_Address);
   2.795 +	  continue;
   2.796 +	}
   2.797 +      if (pci_resource_flags(PCI_Device,1) & IORESOURCE_IO)
   2.798 +	{
   2.799 +	  BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
   2.800 +			 "MultiMaster Host Adapter\n", NULL, BaseAddress1);
   2.801 +	  BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n",
   2.802 +			 NULL, Bus, Device, PCI_Address);
   2.803 +	  continue;
   2.804 +	}
   2.805 +      if (IRQ_Channel == 0)
   2.806 +	{
   2.807 +	  BusLogic_Error("BusLogic: IRQ Channel %d illegal for "
   2.808 +			 "MultiMaster Host Adapter\n", NULL, IRQ_Channel);
   2.809 +	  BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
   2.810 +			 NULL, Bus, Device, IO_Address);
   2.811 +	  continue;
   2.812 +	}
   2.813 +      if (BusLogic_GlobalOptions.TraceProbe)
   2.814 +	{
   2.815 +	  BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter "
   2.816 +			  "detected at\n", NULL);
   2.817 +	  BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address "
   2.818 +			  "0x%X PCI Address 0x%X\n", NULL,
   2.819 +			  Bus, Device, IO_Address, PCI_Address);
   2.820 +	}
   2.821 +      /*
   2.822 +	Issue the Inquire PCI Host Adapter Information command to determine
   2.823 +	the ISA Compatible I/O Port.  If the ISA Compatible I/O Port is
   2.824 +	known and enabled, note that the particular Standard ISA I/O
   2.825 +	Address should not be probed.
   2.826 +      */
   2.827 +      HostAdapter->IO_Address = IO_Address;
   2.828 +      BusLogic_InterruptReset(HostAdapter);
   2.829 +      if (BusLogic_Command(HostAdapter,
   2.830 +			   BusLogic_InquirePCIHostAdapterInformation,
   2.831 +			   NULL, 0, &PCIHostAdapterInformation,
   2.832 +			   sizeof(PCIHostAdapterInformation))
   2.833 +	  == sizeof(PCIHostAdapterInformation))
   2.834 +	{
   2.835 +	  if (PCIHostAdapterInformation.ISACompatibleIOPort < 6)
   2.836 +	    StandardAddressSeen[PCIHostAdapterInformation
   2.837 +				.ISACompatibleIOPort] = true;
   2.838 +	}
   2.839 +      else PCIHostAdapterInformation.ISACompatibleIOPort =
   2.840 +	     BusLogic_IO_Disable;
   2.841 +      /*
   2.842 +	Issue the Modify I/O Address command to disable the ISA Compatible
   2.843 +	I/O Port.
   2.844 +      */
   2.845 +      ModifyIOAddressRequest = BusLogic_IO_Disable;
   2.846 +      BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress,
   2.847 +		       &ModifyIOAddressRequest,
   2.848 +		       sizeof(ModifyIOAddressRequest), NULL, 0);
   2.849 +      /*
   2.850 +	For the first MultiMaster Host Adapter enumerated, issue the Fetch
   2.851 +	Host Adapter Local RAM command to read byte 45 of the AutoSCSI area,
   2.852 +	for the setting of the "Use Bus And Device # For PCI Scanning Seq."
   2.853 +	option.  Issue the Inquire Board ID command since this option is
   2.854 +	only valid for the BT-948/958/958D.
   2.855 +      */
   2.856 +      if (!ForceBusDeviceScanningOrderChecked)
   2.857 +	{
   2.858 +	  BusLogic_FetchHostAdapterLocalRAMRequest_T
   2.859 +	    FetchHostAdapterLocalRAMRequest;
   2.860 +	  BusLogic_AutoSCSIByte45_T AutoSCSIByte45;
   2.861 +	  BusLogic_BoardID_T BoardID;
   2.862 +	  FetchHostAdapterLocalRAMRequest.ByteOffset =
   2.863 +	    BusLogic_AutoSCSI_BaseOffset + 45;
   2.864 +	  FetchHostAdapterLocalRAMRequest.ByteCount =
   2.865 +	    sizeof(AutoSCSIByte45);
   2.866 +	  BusLogic_Command(HostAdapter,
   2.867 +			   BusLogic_FetchHostAdapterLocalRAM,
   2.868 +			   &FetchHostAdapterLocalRAMRequest,
   2.869 +			   sizeof(FetchHostAdapterLocalRAMRequest),
   2.870 +			   &AutoSCSIByte45, sizeof(AutoSCSIByte45));
   2.871 +	  BusLogic_Command(HostAdapter, BusLogic_InquireBoardID,
   2.872 +			   NULL, 0, &BoardID, sizeof(BoardID));
   2.873 +	  if (BoardID.FirmwareVersion1stDigit == '5')
   2.874 +	    ForceBusDeviceScanningOrder =
   2.875 +	      AutoSCSIByte45.ForceBusDeviceScanningOrder;
   2.876 +	  ForceBusDeviceScanningOrderChecked = true;
   2.877 +	}
   2.878 +      /*
   2.879 +	Determine whether this MultiMaster Host Adapter has its ISA
   2.880 +	Compatible I/O Port enabled and is assigned the Primary I/O Address.
   2.881 +	If it does, then it is the Primary MultiMaster Host Adapter and must
   2.882 +	be recognized first.  If it does not, then it is added to the list
   2.883 +	for probing after any Primary MultiMaster Host Adapter is probed.
   2.884 +      */
   2.885 +      if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330)
   2.886 +	{
   2.887 +	  PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
   2.888 +	  PrimaryProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
   2.889 +	  PrimaryProbeInfo->IO_Address = IO_Address;
   2.890 +	  PrimaryProbeInfo->PCI_Address = PCI_Address;
   2.891 +	  PrimaryProbeInfo->Bus = Bus;
   2.892 +	  PrimaryProbeInfo->Device = Device;
   2.893 +	  PrimaryProbeInfo->IRQ_Channel = IRQ_Channel;
   2.894 +	  PCIMultiMasterCount++;
   2.895 +	}
   2.896 +      else if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
   2.897 +	{
   2.898 +	  BusLogic_ProbeInfo_T *ProbeInfo =
   2.899 +	    &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
   2.900 +	  ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
   2.901 +	  ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
   2.902 +	  ProbeInfo->IO_Address = IO_Address;
   2.903 +	  ProbeInfo->PCI_Address = PCI_Address;
   2.904 +	  ProbeInfo->Bus = Bus;
   2.905 +	  ProbeInfo->Device = Device;
   2.906 +	  ProbeInfo->IRQ_Channel = IRQ_Channel;
   2.907 +	  NonPrimaryPCIMultiMasterCount++;
   2.908 +	  PCIMultiMasterCount++;
   2.909 +	}
   2.910 +      else BusLogic_Warning("BusLogic: Too many Host Adapters "
   2.911 +			    "detected\n", NULL);
   2.912 +    }
   2.913 +  /*
   2.914 +    If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option is ON
   2.915 +    for the first enumerated MultiMaster Host Adapter, and if that host adapter
   2.916 +    is a BT-948/958/958D, then the MultiMaster BIOS will recognize MultiMaster
   2.917 +    Host Adapters in the order of increasing PCI Bus and Device Number.  In
   2.918 +    that case, sort the probe information into the same order the BIOS uses.
   2.919 +    If this option is OFF, then the MultiMaster BIOS will recognize MultiMaster
   2.920 +    Host Adapters in the order they are enumerated by the PCI BIOS, and hence
   2.921 +    no sorting is necessary.
   2.922 +  */
   2.923 +  if (ForceBusDeviceScanningOrder)
   2.924 +    BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[
   2.925 +			      NonPrimaryPCIMultiMasterIndex],
   2.926 +			   NonPrimaryPCIMultiMasterCount);
   2.927 +  /*
   2.928 +    If no PCI MultiMaster Host Adapter is assigned the Primary I/O Address,
   2.929 +    then the Primary I/O Address must be probed explicitly before any PCI
   2.930 +    host adapters are probed.
   2.931 +  */
   2.932 +  if (!BusLogic_ProbeOptions.NoProbeISA)
   2.933 +    if (PrimaryProbeInfo->IO_Address == 0 &&
   2.934 +	(BusLogic_ProbeOptions.LimitedProbeISA
   2.935 +	 ? BusLogic_ProbeOptions.Probe330
   2.936 +	 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0))
   2.937 +      {
   2.938 +	PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
   2.939 +	PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
   2.940 +	PrimaryProbeInfo->IO_Address = 0x330;
   2.941 +      }
   2.942 +  /*
   2.943 +    Append the list of standard BusLogic MultiMaster ISA I/O Addresses,
   2.944 +    omitting the Primary I/O Address which has already been handled.
   2.945 +  */
   2.946 +  if (!BusLogic_ProbeOptions.NoProbeISA)
   2.947 +    {
   2.948 +      if (!StandardAddressSeen[1] &&
   2.949 +	  (BusLogic_ProbeOptions.LimitedProbeISA
   2.950 +	   ? BusLogic_ProbeOptions.Probe334
   2.951 +	   : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0))
   2.952 +	BusLogic_AppendProbeAddressISA(0x334);
   2.953 +      if (!StandardAddressSeen[2] &&
   2.954 +	  (BusLogic_ProbeOptions.LimitedProbeISA
   2.955 +	   ? BusLogic_ProbeOptions.Probe230
   2.956 +	   : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0))
   2.957 +	BusLogic_AppendProbeAddressISA(0x230);
   2.958 +      if (!StandardAddressSeen[3] &&
   2.959 +	  (BusLogic_ProbeOptions.LimitedProbeISA
   2.960 +	   ? BusLogic_ProbeOptions.Probe234
   2.961 +	   : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0))
   2.962 +	BusLogic_AppendProbeAddressISA(0x234);
   2.963 +      if (!StandardAddressSeen[4] &&
   2.964 +	  (BusLogic_ProbeOptions.LimitedProbeISA
   2.965 +	   ? BusLogic_ProbeOptions.Probe130
   2.966 +	   : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0))
   2.967 +	BusLogic_AppendProbeAddressISA(0x130);
   2.968 +      if (!StandardAddressSeen[5] &&
   2.969 +	  (BusLogic_ProbeOptions.LimitedProbeISA
   2.970 +	   ? BusLogic_ProbeOptions.Probe134
   2.971 +	   : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0))
   2.972 +	BusLogic_AppendProbeAddressISA(0x134);
   2.973 +    }
   2.974 +  /*
   2.975 +    Iterate over the older non-compliant MultiMaster PCI Host Adapters,
   2.976 +    noting the PCI bus location and assigned IRQ Channel.
   2.977 +  */
   2.978 +  PCI_Device = NULL;
   2.979 +  while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
   2.980 +				       PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
   2.981 +				       PCI_Device)) != NULL)
   2.982 +    {
   2.983 +      unsigned char Bus = PCI_Device->bus->number;
   2.984 +      unsigned char Device = PCI_Device->devfn >> 3;
   2.985 +      unsigned int IRQ_Channel = PCI_Device->irq;
   2.986 +      BusLogic_IO_Address_T IO_Address = pci_resource_start(PCI_Device, 0);
   2.987 +
   2.988 +      if (pci_enable_device(PCI_Device))
   2.989 +		continue;
   2.990 +
   2.991 +      if (IO_Address == 0 || IRQ_Channel == 0) continue;
   2.992 +      for (i = 0; i < BusLogic_ProbeInfoCount; i++)
   2.993 +	{
   2.994 +	  BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[i];
   2.995 +	  if (ProbeInfo->IO_Address == IO_Address &&
   2.996 +	      ProbeInfo->HostAdapterType == BusLogic_MultiMaster)
   2.997 +	    {
   2.998 +	      ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
   2.999 +	      ProbeInfo->PCI_Address = 0;
  2.1000 +	      ProbeInfo->Bus = Bus;
  2.1001 +	      ProbeInfo->Device = Device;
  2.1002 +	      ProbeInfo->IRQ_Channel = IRQ_Channel;
  2.1003 +	      break;
  2.1004 +	    }
  2.1005 +	}
  2.1006 +    }
  2.1007 +  return PCIMultiMasterCount;
  2.1008 +}
  2.1009 +
  2.1010 +
  2.1011 +/*
  2.1012 +  BusLogic_InitializeFlashPointProbeInfo initializes the list of I/O Address
  2.1013 +  and Bus Probe Information to be checked for potential BusLogic FlashPoint
  2.1014 +  Host Adapters by interrogating the PCI Configuration Space.  It returns the
  2.1015 +  number of FlashPoint Host Adapters found.
  2.1016 +*/
  2.1017 +
  2.1018 +static int BusLogic_InitializeFlashPointProbeInfo(BusLogic_HostAdapter_T
  2.1019 +						  *PrototypeHostAdapter)
  2.1020 +{
  2.1021 +  int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0;
  2.1022 +  PCI_Device_T *PCI_Device = NULL;
  2.1023 +  /*
  2.1024 +    Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
  2.1025 +  */
  2.1026 +  while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
  2.1027 +				       PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
  2.1028 +				       PCI_Device)) != NULL)
  2.1029 +    {
  2.1030 +      unsigned char Bus = PCI_Device->bus->number;
  2.1031 +      unsigned char Device = PCI_Device->devfn >> 3;
  2.1032 +      unsigned int IRQ_Channel = PCI_Device->irq;
  2.1033 +      unsigned long BaseAddress0 = pci_resource_start(PCI_Device, 0);
  2.1034 +      unsigned long BaseAddress1 = pci_resource_start(PCI_Device, 1);
  2.1035 +      BusLogic_IO_Address_T IO_Address = BaseAddress0;
  2.1036 +      BusLogic_PCI_Address_T PCI_Address = BaseAddress1;
  2.1037 +
  2.1038 +      if (pci_enable_device(PCI_Device))
  2.1039 +		continue;
  2.1040 +
  2.1041 +#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
  2.1042 +      if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM)
  2.1043 +	{
  2.1044 +	  BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
  2.1045 +			 "FlashPoint Host Adapter\n", NULL, BaseAddress0);
  2.1046 +	  BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
  2.1047 +			 NULL, Bus, Device, IO_Address);
  2.1048 +	  continue;
  2.1049 +	}
  2.1050 +      if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO)
  2.1051 +	{
  2.1052 +	  BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
  2.1053 +			 "FlashPoint Host Adapter\n", NULL, BaseAddress1);
  2.1054 +	  BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n",
  2.1055 +			 NULL, Bus, Device, PCI_Address);
  2.1056 +	  continue;
  2.1057 +	}
  2.1058 +      if (IRQ_Channel == 0)
  2.1059 +	{
  2.1060 +	  BusLogic_Error("BusLogic: IRQ Channel %d illegal for "
  2.1061 +			 "FlashPoint Host Adapter\n", NULL, IRQ_Channel);
  2.1062 +	  BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
  2.1063 +			 NULL, Bus, Device, IO_Address);
  2.1064 +	  continue;
  2.1065 +	}
  2.1066 +      if (BusLogic_GlobalOptions.TraceProbe)
  2.1067 +	{
  2.1068 +	  BusLogic_Notice("BusLogic: FlashPoint Host Adapter "
  2.1069 +			  "detected at\n", NULL);
  2.1070 +	  BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address "
  2.1071 +			  "0x%X PCI Address 0x%X\n", NULL,
  2.1072 +			  Bus, Device, IO_Address, PCI_Address);
  2.1073 +	}
  2.1074 +      if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
  2.1075 +	{
  2.1076 +	  BusLogic_ProbeInfo_T *ProbeInfo =
  2.1077 +	    &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
  2.1078 +	  ProbeInfo->HostAdapterType = BusLogic_FlashPoint;
  2.1079 +	  ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
  2.1080 +	  ProbeInfo->IO_Address = IO_Address;
  2.1081 +	  ProbeInfo->PCI_Address = PCI_Address;
  2.1082 +	  ProbeInfo->Bus = Bus;
  2.1083 +	  ProbeInfo->Device = Device;
  2.1084 +	  ProbeInfo->IRQ_Channel = IRQ_Channel;
  2.1085 +	  FlashPointCount++;
  2.1086 +	}
  2.1087 +      else BusLogic_Warning("BusLogic: Too many Host Adapters "
  2.1088 +			    "detected\n", NULL);
  2.1089 +#else
  2.1090 +      BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
  2.1091 +		     "PCI Bus %d Device %d\n", NULL, Bus, Device);
  2.1092 +      BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, "
  2.1093 +		     "but FlashPoint\n", NULL, IO_Address, PCI_Address, IRQ_Channel);
  2.1094 +      BusLogic_Error("BusLogic: support was omitted in this kernel "
  2.1095 +		     "configuration.\n", NULL);
  2.1096 +#endif
  2.1097 +    }
  2.1098 +  /*
  2.1099 +    The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of
  2.1100 +    increasing PCI Bus and Device Number, so sort the probe information into
  2.1101 +    the same order the BIOS uses.
  2.1102 +  */
  2.1103 +  BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[FlashPointIndex],
  2.1104 +			 FlashPointCount);
  2.1105 +  return FlashPointCount;
  2.1106 +}
  2.1107 +
  2.1108 +
  2.1109 +/*
  2.1110 +  BusLogic_InitializeProbeInfoList initializes the list of I/O Address and Bus
  2.1111 +  Probe Information to be checked for potential BusLogic SCSI Host Adapters by
  2.1112 +  interrogating the PCI Configuration Space on PCI machines as well as from the
  2.1113 +  list of standard BusLogic MultiMaster ISA I/O Addresses.  By default, if both
  2.1114 +  FlashPoint and PCI MultiMaster Host Adapters are present, this driver will
  2.1115 +  probe for FlashPoint Host Adapters first unless the BIOS primary disk is
  2.1116 +  controlled by the first PCI MultiMaster Host Adapter, in which case
  2.1117 +  MultiMaster Host Adapters will be probed first.  The BusLogic Driver Options
  2.1118 +  specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force
  2.1119 +  a particular probe order.
  2.1120 +*/
  2.1121 +
  2.1122 +static void BusLogic_InitializeProbeInfoList(BusLogic_HostAdapter_T
  2.1123 +					     *PrototypeHostAdapter)
  2.1124 +{
  2.1125 +  /*
  2.1126 +    If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint
  2.1127 +    Host Adapters; otherwise, default to the standard ISA MultiMaster probe.
  2.1128 +  */
  2.1129 +  if (!BusLogic_ProbeOptions.NoProbePCI && pci_present())
  2.1130 +    {
  2.1131 +      if (BusLogic_ProbeOptions.MultiMasterFirst)
  2.1132 +	{
  2.1133 +	  BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
  2.1134 +	  BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
  2.1135 +	}
  2.1136 +      else if (BusLogic_ProbeOptions.FlashPointFirst)
  2.1137 +	{
  2.1138 +	  BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
  2.1139 +	  BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
  2.1140 +	}
  2.1141 +      else
  2.1142 +	{
  2.1143 +	  int FlashPointCount =
  2.1144 +	    BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
  2.1145 +	  int PCIMultiMasterCount =
  2.1146 +	    BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
  2.1147 +	  if (FlashPointCount > 0 && PCIMultiMasterCount > 0)
  2.1148 +	    {
  2.1149 +	      BusLogic_ProbeInfo_T *ProbeInfo =
  2.1150 +		&BusLogic_ProbeInfoList[FlashPointCount];
  2.1151 +	      BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
  2.1152 +	      BusLogic_FetchHostAdapterLocalRAMRequest_T
  2.1153 +		FetchHostAdapterLocalRAMRequest;
  2.1154 +	      BusLogic_BIOSDriveMapByte_T Drive0MapByte;
  2.1155 +	      while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus)
  2.1156 +		ProbeInfo++;
  2.1157 +	      HostAdapter->IO_Address = ProbeInfo->IO_Address;
  2.1158 +	      FetchHostAdapterLocalRAMRequest.ByteOffset =
  2.1159 +		BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0;
  2.1160 +	      FetchHostAdapterLocalRAMRequest.ByteCount =
  2.1161 +		sizeof(Drive0MapByte);
  2.1162 +	      BusLogic_Command(HostAdapter,
  2.1163 +			       BusLogic_FetchHostAdapterLocalRAM,
  2.1164 +			       &FetchHostAdapterLocalRAMRequest,
  2.1165 +			       sizeof(FetchHostAdapterLocalRAMRequest),
  2.1166 +			       &Drive0MapByte, sizeof(Drive0MapByte));
  2.1167 +	      /*
  2.1168 +		If the Map Byte for BIOS Drive 0 indicates that BIOS Drive 0
  2.1169 +		is controlled by this PCI MultiMaster Host Adapter, then
  2.1170 +		reverse the probe order so that MultiMaster Host Adapters are
  2.1171 +		probed before FlashPoint Host Adapters.
  2.1172 +	      */
  2.1173 +	      if (Drive0MapByte.DiskGeometry !=
  2.1174 +		  BusLogic_BIOS_Disk_Not_Installed)
  2.1175 +		{
  2.1176 +		  BusLogic_ProbeInfo_T
  2.1177 +		    SavedProbeInfo[BusLogic_MaxHostAdapters];
  2.1178 +		  int MultiMasterCount =
  2.1179 +		    BusLogic_ProbeInfoCount - FlashPointCount;
  2.1180 +		  memcpy(SavedProbeInfo,
  2.1181 +			 BusLogic_ProbeInfoList,
  2.1182 +			 BusLogic_ProbeInfoCount
  2.1183 +			 * sizeof(BusLogic_ProbeInfo_T));
  2.1184 +		  memcpy(&BusLogic_ProbeInfoList[0],
  2.1185 +			 &SavedProbeInfo[FlashPointCount],
  2.1186 +			 MultiMasterCount * sizeof(BusLogic_ProbeInfo_T));
  2.1187 +		  memcpy(&BusLogic_ProbeInfoList[MultiMasterCount],
  2.1188 +			 &SavedProbeInfo[0],
  2.1189 +			 FlashPointCount * sizeof(BusLogic_ProbeInfo_T));
  2.1190 +		}
  2.1191 +	    }
  2.1192 +	}
  2.1193 +    }
  2.1194 +  else BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter);
  2.1195 +}
  2.1196 +
  2.1197 +
  2.1198 +#endif  /* CONFIG_PCI */
  2.1199 +
  2.1200 +
  2.1201 +/*
  2.1202 +  BusLogic_Failure prints a standardized error message, and then returns false.
  2.1203 +*/
  2.1204 +
  2.1205 +static boolean BusLogic_Failure(BusLogic_HostAdapter_T *HostAdapter,
  2.1206 +				char *ErrorMessage)
  2.1207 +{
  2.1208 +  BusLogic_AnnounceDriver(HostAdapter);
  2.1209 +  if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus)
  2.1210 +    {
  2.1211 +      BusLogic_Error("While configuring BusLogic PCI Host Adapter at\n",
  2.1212 +		     HostAdapter);
  2.1213 +      BusLogic_Error("Bus %d Device %d I/O Address 0x%X PCI Address 0x%X:\n",
  2.1214 +		     HostAdapter, HostAdapter->Bus, HostAdapter->Device,
  2.1215 +		     HostAdapter->IO_Address, HostAdapter->PCI_Address);
  2.1216 +    }
  2.1217 +  else BusLogic_Error("While configuring BusLogic Host Adapter at "
  2.1218 +		      "I/O Address 0x%X:\n", HostAdapter,
  2.1219 +		      HostAdapter->IO_Address);
  2.1220 +  BusLogic_Error("%s FAILED - DETACHING\n", HostAdapter, ErrorMessage);
  2.1221 +  if (BusLogic_CommandFailureReason != NULL)
  2.1222 +    BusLogic_Error("ADDITIONAL FAILURE INFO - %s\n", HostAdapter,
  2.1223 +		   BusLogic_CommandFailureReason);
  2.1224 +  return false;
  2.1225 +}
  2.1226 +
  2.1227 +
  2.1228 +/*
  2.1229 +  BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
  2.1230 +*/
  2.1231 +
  2.1232 +static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
  2.1233 +{
  2.1234 +  BusLogic_StatusRegister_T StatusRegister;
  2.1235 +  BusLogic_InterruptRegister_T InterruptRegister;
  2.1236 +  BusLogic_GeometryRegister_T GeometryRegister;
  2.1237 +  /*
  2.1238 +    FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
  2.1239 +  */
  2.1240 +  if (BusLogic_FlashPointHostAdapterP(HostAdapter))
  2.1241 +    {
  2.1242 +      FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
  2.1243 +      FlashPointInfo->BaseAddress =
  2.1244 +	(BusLogic_Base_Address_T) HostAdapter->IO_Address;
  2.1245 +      FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel;
  2.1246 +      FlashPointInfo->Present = false;
  2.1247 +      if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 &&
  2.1248 +	    FlashPointInfo->Present))
  2.1249 +	{
  2.1250 +	  BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
  2.1251 +			 "PCI Bus %d Device %d\n", HostAdapter,
  2.1252 +			 HostAdapter->Bus, HostAdapter->Device);
  2.1253 +	  BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, "
  2.1254 +			 "but FlashPoint\n", HostAdapter,
  2.1255 +			 HostAdapter->IO_Address, HostAdapter->PCI_Address);
  2.1256 +	  BusLogic_Error("BusLogic: Probe Function failed to validate it.\n",
  2.1257 +			 HostAdapter);
  2.1258 +	  return false;
  2.1259 +	}
  2.1260 +      if (BusLogic_GlobalOptions.TraceProbe)
  2.1261 +	BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n",
  2.1262 +			HostAdapter, HostAdapter->IO_Address);
  2.1263 +      /*
  2.1264 +	Indicate the Host Adapter Probe completed successfully.
  2.1265 +      */
  2.1266 +      return true;
  2.1267 +    }
  2.1268 +  /*
  2.1269 +    Read the Status, Interrupt, and Geometry Registers to test if there are I/O
  2.1270 +    ports that respond, and to check the values to determine if they are from a
  2.1271 +    BusLogic Host Adapter.  A nonexistent I/O port will return 0xFF, in which
  2.1272 +    case there is definitely no BusLogic Host Adapter at this base I/O Address.
  2.1273 +    The test here is a subset of that used by the BusLogic Host Adapter BIOS.
  2.1274 +  */
  2.1275 +  StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
  2.1276 +  InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
  2.1277 +  GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
  2.1278 +  if (BusLogic_GlobalOptions.TraceProbe)
  2.1279 +    BusLogic_Notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, "
  2.1280 +		    "Geometry 0x%02X\n", HostAdapter,
  2.1281 +		    HostAdapter->IO_Address, StatusRegister.All,
  2.1282 +		    InterruptRegister.All, GeometryRegister.All);
  2.1283 +  if (StatusRegister.All == 0 ||
  2.1284 +      StatusRegister.Bits.DiagnosticActive ||
  2.1285 +      StatusRegister.Bits.CommandParameterRegisterBusy ||
  2.1286 +      StatusRegister.Bits.Reserved ||
  2.1287 +      StatusRegister.Bits.CommandInvalid ||
  2.1288 +      InterruptRegister.Bits.Reserved != 0)
  2.1289 +    return false;
  2.1290 +  /*
  2.1291 +    Check the undocumented Geometry Register to test if there is an I/O port
  2.1292 +    that responded.  Adaptec Host Adapters do not implement the Geometry
  2.1293 +    Register, so this test helps serve to avoid incorrectly recognizing an
  2.1294 +    Adaptec 1542A or 1542B as a BusLogic.  Unfortunately, the Adaptec 1542C
  2.1295 +    series does respond to the Geometry Register I/O port, but it will be
  2.1296 +    rejected later when the Inquire Extended Setup Information command is
  2.1297 +    issued in BusLogic_CheckHostAdapter.  The AMI FastDisk Host Adapter is a
  2.1298 +    BusLogic clone that implements the same interface as earlier BusLogic
  2.1299 +    Host Adapters, including the undocumented commands, and is therefore
  2.1300 +    supported by this driver.  However, the AMI FastDisk always returns 0x00
  2.1301 +    upon reading the Geometry Register, so the extended translation option
  2.1302 +    should always be left disabled on the AMI FastDisk.
  2.1303 +  */
  2.1304 +  if (GeometryRegister.All == 0xFF) return false;
  2.1305 +  /*
  2.1306 +    Indicate the Host Adapter Probe completed successfully.
  2.1307 +  */
  2.1308 +  return true;
  2.1309 +}
  2.1310 +
  2.1311 +
  2.1312 +/*
  2.1313 +  BusLogic_HardwareResetHostAdapter issues a Hardware Reset to the Host Adapter
  2.1314 +  and waits for Host Adapter Diagnostics to complete.  If HardReset is true, a
  2.1315 +  Hard Reset is performed which also initiates a SCSI Bus Reset.  Otherwise, a
  2.1316 +  Soft Reset is performed which only resets the Host Adapter without forcing a
  2.1317 +  SCSI Bus Reset.
  2.1318 +*/
  2.1319 +
  2.1320 +static boolean BusLogic_HardwareResetHostAdapter(BusLogic_HostAdapter_T
  2.1321 +						   *HostAdapter,
  2.1322 +						 boolean HardReset)
  2.1323 +{
  2.1324 +  BusLogic_StatusRegister_T StatusRegister;
  2.1325 +  int TimeoutCounter;
  2.1326 +  /*
  2.1327 +    FlashPoint Host Adapters are Hard Reset by the FlashPoint SCCB Manager.
  2.1328 +  */
  2.1329 +  if (BusLogic_FlashPointHostAdapterP(HostAdapter))
  2.1330 +    {
  2.1331 +      FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
  2.1332 +      FlashPointInfo->HostSoftReset = !HardReset;
  2.1333 +      FlashPointInfo->ReportDataUnderrun = true;
  2.1334 +      HostAdapter->CardHandle =
  2.1335 +	FlashPoint_HardwareResetHostAdapter(FlashPointInfo);
  2.1336 +      if (HostAdapter->CardHandle == FlashPoint_BadCardHandle) return false;
  2.1337 +      /*
  2.1338 +	Indicate the Host Adapter Hard Reset completed successfully.
  2.1339 +      */
  2.1340 +      return true;
  2.1341 +    }
  2.1342 +  /*
  2.1343 +    Issue a Hard Reset or Soft Reset Command to the Host Adapter.  The Host
  2.1344 +    Adapter should respond by setting Diagnostic Active in the Status Register.
  2.1345 +  */
  2.1346 +  if (HardReset)
  2.1347 +    BusLogic_HardReset(HostAdapter);
  2.1348 +  else BusLogic_SoftReset(HostAdapter);
  2.1349 +  /*
  2.1350 +    Wait until Diagnostic Active is set in the Status Register.
  2.1351 +  */
  2.1352 +  TimeoutCounter = 5*10000;
  2.1353 +  while (--TimeoutCounter >= 0)
  2.1354 +    {
  2.1355 +      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
  2.1356 +      if (StatusRegister.Bits.DiagnosticActive) break;
  2.1357 +      udelay(100);
  2.1358 +    }
  2.1359 +  if (BusLogic_GlobalOptions.TraceHardwareReset)
  2.1360 +    BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, "
  2.1361 +		    "Status 0x%02X\n", HostAdapter,
  2.1362 +		    HostAdapter->IO_Address, StatusRegister.All);
  2.1363 +  if (TimeoutCounter < 0) return false;
  2.1364 +  /*
  2.1365 +    Wait 100 microseconds to allow completion of any initial diagnostic
  2.1366 +    activity which might leave the contents of the Status Register
  2.1367 +    unpredictable.
  2.1368 +  */
  2.1369 +  udelay(100);
  2.1370 +  /*
  2.1371 +    Wait until Diagnostic Active is reset in the Status Register.
  2.1372 +  */
  2.1373 +  TimeoutCounter = 10*10000;
  2.1374 +  while (--TimeoutCounter >= 0)
  2.1375 +    {
  2.1376 +      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
  2.1377 +      if (!StatusRegister.Bits.DiagnosticActive) break;
  2.1378 +      udelay(100);
  2.1379 +    }
  2.1380 +  if (BusLogic_GlobalOptions.TraceHardwareReset)
  2.1381 +    BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, "
  2.1382 +		    "Status 0x%02X\n", HostAdapter,
  2.1383 +		    HostAdapter->IO_Address, StatusRegister.All);
  2.1384 +  if (TimeoutCounter < 0) return false;
  2.1385 +  /*
  2.1386 +    Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
  2.1387 +    or Data In Register Ready bits is set in the Status Register.
  2.1388 +  */
  2.1389 +  TimeoutCounter = 10000;
  2.1390 +  while (--TimeoutCounter >= 0)
  2.1391 +    {
  2.1392 +      StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
  2.1393 +      if (StatusRegister.Bits.DiagnosticFailure ||
  2.1394 +	  StatusRegister.Bits.HostAdapterReady ||
  2.1395 +	  StatusRegister.Bits.DataInRegisterReady)
  2.1396 +	break;
  2.1397 +      udelay(100);
  2.1398 +    }
  2.1399 +  if (BusLogic_GlobalOptions.TraceHardwareReset)
  2.1400 +    BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, "
  2.1401 +		    "Status 0x%02X\n", HostAdapter,
  2.1402 +		    HostAdapter->IO_Address, StatusRegister.All);
  2.1403 +  if (TimeoutCounter < 0) return false;
  2.1404 +  /*
  2.1405 +    If Diagnostic Failure is set or Host Adapter Ready is reset, then an
  2.1406 +    error occurred during the Host Adapter diagnostics.  If Data In Register
  2.1407 +    Ready is set, then there is an Error Code available.
  2.1408 +  */
  2.1409 +  if (StatusRegister.Bits.DiagnosticFailure ||
  2.1410 +      !StatusRegister.Bits.HostAdapterReady)
  2.1411 +    {
  2.1412 +      BusLogic_CommandFailureReason = NULL;
  2.1413 +      BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
  2.1414 +      BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n",
  2.1415 +		     HostAdapter, StatusRegister.All);
  2.1416 +      if (StatusRegister.Bits.DataInRegisterReady)
  2.1417 +	{
  2.1418 +	  unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
  2.1419 +	  BusLogic_Error("HOST ADAPTER ERROR CODE = %d\n",
  2.1420 +			 HostAdapter, ErrorCode);
  2.1421 +	}
  2.1422 +      return false;
  2.1423 +    }
  2.1424 +  /*
  2.1425 +    Indicate the Host Adapter Hard Reset completed successfully.
  2.1426 +  */
  2.1427 +  return true;
  2.1428 +}
  2.1429 +
  2.1430 +
  2.1431 +/*
  2.1432 +  BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
  2.1433 +  Host Adapter.
  2.1434 +*/
  2.1435 +
  2.1436 +static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
  2.1437 +{
  2.1438 +  BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
  2.1439 +  BusLogic_RequestedReplyLength_T RequestedReplyLength;
  2.1440 +  boolean Result = true;
  2.1441 +  /*
  2.1442 +    FlashPoint Host Adapters do not require this protection.
  2.1443 +  */
  2.1444 +  if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
  2.1445 +  /*
  2.1446 +    Issue the Inquire Extended Setup Information command.  Only genuine
  2.1447 +    BusLogic Host Adapters and true clones support this command.  Adaptec 1542C
  2.1448 +    series Host Adapters that respond to the Geometry Register I/O port will
  2.1449 +    fail this command.
  2.1450 +  */
  2.1451 +  RequestedReplyLength = sizeof(ExtendedSetupInformation);
  2.1452 +  if (BusLogic_Command(HostAdapter,
  2.1453 +		       BusLogic_InquireExtendedSetupInformation,
  2.1454 +		       &RequestedReplyLength,
  2.1455 +		       sizeof(RequestedReplyLength),
  2.1456 +		       &ExtendedSetupInformation,
  2.1457 +		       sizeof(ExtendedSetupInformation))
  2.1458 +      != sizeof(ExtendedSetupInformation))
  2.1459 +    Result = false;
  2.1460 +  /*
  2.1461 +    Provide tracing information if requested and return.
  2.1462 +  */
  2.1463 +  if (BusLogic_GlobalOptions.TraceProbe)
  2.1464 +    BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter,
  2.1465 +		    HostAdapter->IO_Address, (Result ? "Found" : "Not Found"));
  2.1466 +  return Result;
  2.1467 +}
  2.1468 +
  2.1469 +
  2.1470 +/*
  2.1471 +  BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
  2.1472 +  from Host Adapter and initializes the Host Adapter structure.
  2.1473 +*/
  2.1474 +
  2.1475 +static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T
  2.1476 +						     *HostAdapter)
  2.1477 +{
  2.1478 +  BusLogic_BoardID_T BoardID;
  2.1479 +  BusLogic_Configuration_T Configuration;
  2.1480 +  BusLogic_SetupInformation_T SetupInformation;
  2.1481 +  BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
  2.1482 +  BusLogic_HostAdapterModelNumber_T HostAdapterModelNumber;
  2.1483 +  BusLogic_FirmwareVersion3rdDigit_T FirmwareVersion3rdDigit;
  2.1484 +  BusLogic_FirmwareVersionLetter_T FirmwareVersionLetter;
  2.1485 +  BusLogic_PCIHostAdapterInformation_T PCIHostAdapterInformation;
  2.1486 +  BusLogic_FetchHostAdapterLocalRAMRequest_T FetchHostAdapterLocalRAMRequest;
  2.1487 +  BusLogic_AutoSCSIData_T AutoSCSIData;
  2.1488 +  BusLogic_GeometryRegister_T GeometryRegister;
  2.1489 +  BusLogic_RequestedReplyLength_T RequestedReplyLength;
  2.1490 +  unsigned char *TargetPointer, Character;
  2.1491 +  int TargetID, i;
  2.1492 +  /*
  2.1493 +    Configuration Information for FlashPoint Host Adapters is provided in the
  2.1494 +    FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function.
  2.1495 +    Initialize fields in the Host Adapter structure from the FlashPoint_Info
  2.1496 +    structure.
  2.1497 +  */
  2.1498 +  if (BusLogic_FlashPointHostAdapterP(HostAdapter))
  2.1499 +    {
  2.1500 +      FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
  2.1501 +      TargetPointer = HostAdapter->ModelName;
  2.1502 +      *TargetPointer++ = 'B';
  2.1503 +      *TargetPointer++ = 'T';
  2.1504 +      *TargetPointer++ = '-';
  2.1505 +      for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++)
  2.1506 +	*TargetPointer++ = FlashPointInfo->ModelNumber[i];
  2.1507 +      *TargetPointer++ = '\0';
  2.1508 +      strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion);
  2.1509 +      HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID;
  2.1510 +      HostAdapter->ExtendedTranslationEnabled =
  2.1511 +	FlashPointInfo->ExtendedTranslationEnabled;
  2.1512 +      HostAdapter->ParityCheckingEnabled =
  2.1513 +	FlashPointInfo->ParityCheckingEnabled;
  2.1514 +      HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset;
  2.1515 +      HostAdapter->LevelSensitiveInterrupt = true;
  2.1516 +      HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI;
  2.1517 +      HostAdapter->HostDifferentialSCSI = false;
  2.1518 +      HostAdapter->HostSupportsSCAM = true;
  2.1519 +      HostAdapter->HostUltraSCSI = true;
  2.1520 +      HostAdapter->ExtendedLUNSupport = true;
  2.1521 +      HostAdapter->TerminationInfoValid = true;
  2.1522 +      HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated;
  2.1523 +      HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated;
  2.1524 +      HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled;
  2.1525 +      HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2;
  2.1526 +      HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
  2.1527 +      HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
  2.1528 +      HostAdapter->MaxLogicalUnits = 32;
  2.1529 +      HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
  2.1530 +      HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
  2.1531 +      HostAdapter->DriverQueueDepth = 255;
  2.1532 +      HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth;
  2.1533 +      HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted;
  2.1534 +      HostAdapter->FastPermitted = FlashPointInfo->FastPermitted;
  2.1535 +      HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted;
  2.1536 +      HostAdapter->WidePermitted = FlashPointInfo->WidePermitted;
  2.1537 +      HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted;
  2.1538 +      HostAdapter->TaggedQueuingPermitted = 0xFFFF;
  2.1539 +      goto Common;
  2.1540 +    }
  2.1541 +  /*
  2.1542 +    Issue the Inquire Board ID command.
  2.1543 +  */
  2.1544 +  if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0,
  2.1545 +		       &BoardID, sizeof(BoardID)) != sizeof(BoardID))
  2.1546 +    return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
  2.1547 +  /*
  2.1548 +    Issue the Inquire Configuration command.
  2.1549 +  */
  2.1550 +  if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0,
  2.1551 +		       &Configuration, sizeof(Configuration))
  2.1552 +      != sizeof(Configuration))
  2.1553 +    return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
  2.1554 +  /*
  2.1555 +    Issue the Inquire Setup Information command.
  2.1556 +  */
  2.1557 +  RequestedReplyLength = sizeof(SetupInformation);
  2.1558 +  if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
  2.1559 +		       &RequestedReplyLength, sizeof(RequestedReplyLength),
  2.1560 +		       &SetupInformation, sizeof(SetupInformation))
  2.1561 +      != sizeof(SetupInformation))
  2.1562 +    return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
  2.1563 +  /*
  2.1564 +    Issue the Inquire Extended Setup Information command.
  2.1565 +  */
  2.1566 +  RequestedReplyLength = sizeof(ExtendedSetupInformation);
  2.1567 +  if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation,
  2.1568 +		       &RequestedReplyLength, sizeof(RequestedReplyLength),
  2.1569 +		       &ExtendedSetupInformation,
  2.1570 +		       sizeof(ExtendedSetupInformation))
  2.1571 +      != sizeof(ExtendedSetupInformation))
  2.1572 +    return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
  2.1573 +  /*
  2.1574 +    Issue the Inquire Firmware Version 3rd Digit command.
  2.1575 +  */
  2.1576 +  FirmwareVersion3rdDigit = '\0';
  2.1577 +  if (BoardID.FirmwareVersion1stDigit > '0')
  2.1578 +    if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit,
  2.1579 +			 NULL, 0, &FirmwareVersion3rdDigit,
  2.1580 +			 sizeof(FirmwareVersion3rdDigit))
  2.1581 +	!= sizeof(FirmwareVersion3rdDigit))
  2.1582 +      return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
  2.1583 +  /*
  2.1584 +    Issue the Inquire Host Adapter Model Number command.
  2.1585 +  */
  2.1586 +  if (ExtendedSetupInformation.BusType == 'A' &&
  2.1587 +      BoardID.FirmwareVersion1stDigit == '2')
  2.1588 +    /* BusLogic BT-542B ISA 2.xx */
  2.1589 +    strcpy(HostAdapterModelNumber, "542B");
  2.1590 +  else if (ExtendedSetupInformation.BusType == 'E' &&
  2.1591 +	   BoardID.FirmwareVersion1stDigit == '2' &&
  2.1592 +	   (BoardID.FirmwareVersion2ndDigit <= '1' ||
  2.1593 +	    (BoardID.FirmwareVersion2ndDigit == '2' &&
  2.1594 +	     FirmwareVersion3rdDigit == '0')))
  2.1595 +    /* BusLogic BT-742A EISA 2.1x or 2.20 */
  2.1596 +    strcpy(HostAdapterModelNumber, "742A");
  2.1597 +  else if (ExtendedSetupInformation.BusType == 'E' &&
  2.1598 +	   BoardID.FirmwareVersion1stDigit == '0')
  2.1599 +    /* AMI FastDisk EISA Series 441 0.x */
  2.1600 +    strcpy(HostAdapterModelNumber, "747A");
  2.1601 +  else
  2.1602 +    {
  2.1603 +      RequestedReplyLength = sizeof(HostAdapterModelNumber);
  2.1604 +      if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber,
  2.1605 +			   &RequestedReplyLength, sizeof(RequestedReplyLength),
  2.1606 +			   &HostAdapterModelNumber,
  2.1607 +			   sizeof(HostAdapterModelNumber))
  2.1608 +	  != sizeof(HostAdapterModelNumber))
  2.1609 +	return BusLogic_Failure(HostAdapter,
  2.1610 +				"INQUIRE HOST ADAPTER MODEL NUMBER");
  2.1611 +    }
  2.1612 +  /*
  2.1613 +    BusLogic MultiMaster Host Adapters can be identified by their model number
  2.1614 +    and the major version number of their firmware as follows:
  2.1615 +
  2.1616 +    5.xx	BusLogic "W" Series Host Adapters:
  2.1617 +		  BT-948/958/958D
  2.1618 +    4.xx	BusLogic "C" Series Host Adapters:
  2.1619 +		  BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
  2.1620 +    3.xx	BusLogic "S" Series Host Adapters:
  2.1621 +		  BT-747S/747D/757S/757D/445S/545S/542D
  2.1622 +		  BT-542B/742A (revision H)
  2.1623 +    2.xx	BusLogic "A" Series Host Adapters:
  2.1624 +		  BT-542B/742A (revision G and below)
  2.1625 +    0.xx	AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
  2.1626 +  */
  2.1627 +  /*
  2.1628 +    Save the Model Name and Host Adapter Name in the Host Adapter structure.
  2.1629 +  */
  2.1630 +  TargetPointer = HostAdapter->ModelName;
  2.1631 +  *TargetPointer++ = 'B';
  2.1632 +  *TargetPointer++ = 'T';
  2.1633 +  *TargetPointer++ = '-';
  2.1634 +  for (i = 0; i < sizeof(HostAdapterModelNumber); i++)
  2.1635 +    {
  2.1636 +      Character = HostAdapterModelNumber[i];
  2.1637 +      if (Character == ' ' || Character == '\0') break;
  2.1638 +      *TargetPointer++ = Character;
  2.1639 +    }
  2.1640 +  *TargetPointer++ = '\0';
  2.1641 +  /*
  2.1642 +    Save the Firmware Version in the Host Adapter structure.
  2.1643 +  */
  2.1644 +  TargetPointer = HostAdapter->FirmwareVersion;
  2.1645 +  *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
  2.1646 +  *TargetPointer++ = '.';
  2.1647 +  *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
  2.1648 +  if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
  2.1649 +    *TargetPointer++ = FirmwareVersion3rdDigit;
  2.1650 +  *TargetPointer = '\0';
  2.1651 +  /*
  2.1652 +    Issue the Inquire Firmware Version Letter command.
  2.1653 +  */
  2.1654 +  if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0)
  2.1655 +    {
  2.1656 +      if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter,
  2.1657 +			   NULL, 0, &FirmwareVersionLetter,
  2.1658 +			   sizeof(FirmwareVersionLetter))
  2.1659 +	  != sizeof(FirmwareVersionLetter))
  2.1660 +	return BusLogic_Failure(HostAdapter,
  2.1661 +				"INQUIRE FIRMWARE VERSION LETTER");
  2.1662 +      if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
  2.1663 +	*TargetPointer++ = FirmwareVersionLetter;
  2.1664 +      *TargetPointer = '\0';
  2.1665 +    }
  2.1666 +  /*
  2.1667 +    Save the Host Adapter SCSI ID in the Host Adapter structure.
  2.1668 +  */
  2.1669 +  HostAdapter->SCSI_ID = Configuration.HostAdapterID;
  2.1670 +  /*
  2.1671 +    Determine the Bus Type and save it in the Host Adapter structure, determine
  2.1672 +    and save the IRQ Channel if necessary, and determine and save the DMA
  2.1673 +    Channel for ISA Host Adapters.
  2.1674 +  */
  2.1675 +  HostAdapter->HostAdapterBusType =
  2.1676 +    BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4'];
  2.1677 +  if (HostAdapter->IRQ_Channel == 0)
  2.1678 +    {
  2.1679 +      if (Configuration.IRQ_Channel9)
  2.1680 +	HostAdapter->IRQ_Channel = 9;
  2.1681 +      else if (Configuration.IRQ_Channel10)
  2.1682 +	HostAdapter->IRQ_Channel = 10;
  2.1683 +      else if (Configuration.IRQ_Channel11)
  2.1684 +	HostAdapter->IRQ_Channel = 11;
  2.1685 +      else if (Configuration.IRQ_Channel12)
  2.1686 +	HostAdapter->IRQ_Channel = 12;
  2.1687 +      else if (Configuration.IRQ_Channel14)
  2.1688 +	HostAdapter->IRQ_Channel = 14;
  2.1689 +      else if (Configuration.IRQ_Channel15)
  2.1690 +	HostAdapter->IRQ_Channel = 15;
  2.1691 +    }
  2.1692 +  if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus)
  2.1693 +    {
  2.1694 +      if (Configuration.DMA_Channel5)
  2.1695 +	HostAdapter->DMA_Channel = 5;
  2.1696 +      else if (Configuration.DMA_Channel6)
  2.1697 +	HostAdapter->DMA_Channel = 6;
  2.1698 +      else if (Configuration.DMA_Channel7)
  2.1699 +	HostAdapter->DMA_Channel = 7;
  2.1700 +    }
  2.1701 +  /*
  2.1702 +    Determine whether Extended Translation is enabled and save it in
  2.1703 +    the Host Adapter structure.
  2.1704 +  */
  2.1705 +  GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
  2.1706 +  HostAdapter->ExtendedTranslationEnabled =
  2.1707 +    GeometryRegister.Bits.ExtendedTranslationEnabled;
  2.1708 +  /*
  2.1709 +    Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
  2.1710 +    SCSI flag, Differential SCSI flag, SCAM Supported flag, and
  2.1711 +    Ultra SCSI flag in the Host Adapter structure.
  2.1712 +  */
  2.1713 +  HostAdapter->HostAdapterScatterGatherLimit =
  2.1714 +    ExtendedSetupInformation.ScatterGatherLimit;
  2.1715 +  HostAdapter->DriverScatterGatherLimit =
  2.1716 +    HostAdapter->HostAdapterScatterGatherLimit;
  2.1717 +  if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
  2.1718 +    HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
  2.1719 +  if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt)
  2.1720 +    HostAdapter->LevelSensitiveInterrupt = true;
  2.1721 +  HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI;
  2.1722 +  HostAdapter->HostDifferentialSCSI =
  2.1723 +    ExtendedSetupInformation.HostDifferentialSCSI;
  2.1724 +  HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM;
  2.1725 +  HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
  2.1726 +  /*
  2.1727 +    Determine whether Extended LUN Format CCBs are supported and save the
  2.1728 +    information in the Host Adapter structure.
  2.1729 +  */
  2.1730 +  if (HostAdapter->FirmwareVersion[0] == '5' ||
  2.1731 +      (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
  2.1732 +    HostAdapter->ExtendedLUNSupport = true;
  2.1733 +  /*
  2.1734 +    Issue the Inquire PCI Host Adapter Information command to read the
  2.1735 +    Termination Information from "W" series MultiMaster Host Adapters.
  2.1736 +  */
  2.1737 +  if (HostAdapter->FirmwareVersion[0] == '5')
  2.1738 +    {
  2.1739 +      if (BusLogic_Command(HostAdapter,
  2.1740 +			   BusLogic_InquirePCIHostAdapterInformation,
  2.1741 +			   NULL, 0, &PCIHostAdapterInformation,
  2.1742 +			   sizeof(PCIHostAdapterInformation))
  2.1743 +	  != sizeof(PCIHostAdapterInformation))
  2.1744 +	return BusLogic_Failure(HostAdapter,
  2.1745 +				"INQUIRE PCI HOST ADAPTER INFORMATION");
  2.1746 +      /*
  2.1747 +	Save the Termination Information in the Host Adapter structure.
  2.1748 +      */
  2.1749 +      if (PCIHostAdapterInformation.GenericInfoValid)
  2.1750 +	{
  2.1751 +	  HostAdapter->TerminationInfoValid = true;
  2.1752 +	  HostAdapter->LowByteTerminated =
  2.1753 +	    PCIHostAdapterInformation.LowByteTerminated;
  2.1754 +	  HostAdapter->HighByteTerminated =
  2.1755 +	    PCIHostAdapterInformation.HighByteTerminated;
  2.1756 +	}
  2.1757 +    }
  2.1758 +  /*
  2.1759 +    Issue the Fetch Host Adapter Local RAM command to read the AutoSCSI data
  2.1760 +    from "W" and "C" series MultiMaster Host Adapters.
  2.1761 +  */
  2.1762 +  if (HostAdapter->FirmwareVersion[0] >= '4')
  2.1763 +    {
  2.1764 +      FetchHostAdapterLocalRAMRequest.ByteOffset =
  2.1765 +	BusLogic_AutoSCSI_BaseOffset;
  2.1766 +      FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData);
  2.1767 +      if (BusLogic_Command(HostAdapter,
  2.1768 +			   BusLogic_FetchHostAdapterLocalRAM,
  2.1769 +			   &FetchHostAdapterLocalRAMRequest,
  2.1770 +			   sizeof(FetchHostAdapterLocalRAMRequest),
  2.1771 +			   &AutoSCSIData, sizeof(AutoSCSIData))
  2.1772 +	  != sizeof(AutoSCSIData))
  2.1773 +	return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM");
  2.1774 +      /*
  2.1775 +	Save the Parity Checking Enabled, Bus Reset Enabled, and Termination
  2.1776 +	Information in the Host Adapter structure.
  2.1777 +      */
  2.1778 +      HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled;
  2.1779 +      HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled;
  2.1780 +      if (HostAdapter->FirmwareVersion[0] == '4')
  2.1781 +	{
  2.1782 +	  HostAdapter->TerminationInfoValid = true;
  2.1783 +	  HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated;
  2.1784 +	  HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated;
  2.1785 +	}
  2.1786 +      /*
  2.1787 +	Save the Wide Permitted, Fast Permitted, Synchronous Permitted,
  2.1788 +	Disconnect Permitted, Ultra Permitted, and SCAM Information in the
  2.1789 +	Host Adapter structure.
  2.1790 +      */
  2.1791 +      HostAdapter->WidePermitted = AutoSCSIData.WidePermitted;
  2.1792 +      HostAdapter->FastPermitted = AutoSCSIData.FastPermitted;
  2.1793 +      HostAdapter->SynchronousPermitted =
  2.1794 +	AutoSCSIData.SynchronousPermitted;
  2.1795 +      HostAdapter->DisconnectPermitted =
  2.1796 +	AutoSCSIData.DisconnectPermitted;
  2.1797 +      if (HostAdapter->HostUltraSCSI)
  2.1798 +	HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted;
  2.1799 +      if (HostAdapter->HostSupportsSCAM)
  2.1800 +	{
  2.1801 +	  HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled;
  2.1802 +	  HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2;
  2.1803 +	}
  2.1804 +    }
  2.1805 +  /*
  2.1806 +    Initialize fields in the Host Adapter structure for "S" and "A" series
  2.1807 +    MultiMaster Host Adapters.
  2.1808 +  */
  2.1809 +  if (HostAdapter->FirmwareVersion[0] < '4')
  2.1810 +    {
  2.1811 +      if (SetupInformation.SynchronousInitiationEnabled)
  2.1812 +	{
  2.1813 +	  HostAdapter->SynchronousPermitted = 0xFF;
  2.1814 +	  if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)
  2.1815 +	    {
  2.1816 +	      if (ExtendedSetupInformation.Misc.FastOnEISA)
  2.1817 +		HostAdapter->FastPermitted = 0xFF;
  2.1818 +	      if (strcmp(HostAdapter->ModelName, "BT-757") == 0)
  2.1819 +		HostAdapter->WidePermitted = 0xFF;
  2.1820 +	    }
  2.1821 +	}
  2.1822 +      HostAdapter->DisconnectPermitted = 0xFF;
  2.1823 +      HostAdapter->ParityCheckingEnabled =
  2.1824 +	SetupInformation.ParityCheckingEnabled;
  2.1825 +      HostAdapter->BusResetEnabled = true;
  2.1826 +    }
  2.1827 +  /*
  2.1828 +    Determine the maximum number of Target IDs and Logical Units supported by
  2.1829 +    this driver for Wide and Narrow Host Adapters.
  2.1830 +  */
  2.1831 +  HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
  2.1832 +  HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8);
  2.1833 +  /*
  2.1834 +    Select appropriate values for the Mailbox Count, Driver Queue Depth,
  2.1835 +    Initial CCBs, and Incremental CCBs variables based on whether or not Strict
  2.1836 +    Round Robin Mode is supported.  If Strict Round Robin Mode is supported,
  2.1837 +    then there is no performance degradation in using the maximum possible
  2.1838 +    number of Outgoing and Incoming Mailboxes and allowing the Tagged and
  2.1839 +    Untagged Queue Depths to determine the actual utilization.  If Strict Round
  2.1840 +    Robin Mode is not supported, then the Host Adapter must scan all the
  2.1841 +    Outgoing Mailboxes whenever an Outgoing Mailbox entry is made, which can
  2.1842 +    cause a substantial performance penalty.  The host adapters actually have
  2.1843 +    room to store the following number of CCBs internally; that is, they can
  2.1844 +    internally queue and manage this many active commands on the SCSI bus
  2.1845 +    simultaneously.  Performance measurements demonstrate that the Driver Queue
  2.1846 +    Depth should be set to the Mailbox Count, rather than the Host Adapter
  2.1847 +    Queue Depth (internal CCB capacity), as it is more efficient to have the
  2.1848 +    queued commands waiting in Outgoing Mailboxes if necessary than to block
  2.1849 +    the process in the higher levels of the SCSI Subsystem.
  2.1850 +
  2.1851 +	192	  BT-948/958/958D
  2.1852 +	100	  BT-946C/956C/956CD/747C/757C/757CD/445C
  2.1853 +	 50	  BT-545C/540CF
  2.1854 +	 30	  BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
  2.1855 +  */
  2.1856 +  if (HostAdapter->FirmwareVersion[0] == '5')
  2.1857 +    HostAdapter->HostAdapterQueueDepth = 192;
  2.1858 +  else if (HostAdapter->FirmwareVersion[0] == '4')
  2.1859 +    HostAdapter->HostAdapterQueueDepth =
  2.1860 +      (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50);
  2.1861 +  else HostAdapter->HostAdapterQueueDepth = 30;
  2.1862 +  if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0)
  2.1863 +    {
  2.1864 +      HostAdapter->StrictRoundRobinModeSupport = true;
  2.1865 +      HostAdapter->MailboxCount = BusLogic_MaxMailboxes;
  2.1866 +    }
  2.1867 +  else
  2.1868 +    {
  2.1869 +      HostAdapter->StrictRoundRobinModeSupport = false;
  2.1870 +      HostAdapter->MailboxCount = 32;
  2.1871 +    }
  2.1872 +  HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount;
  2.1873 +  HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
  2.1874 +  HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
  2.1875 +  /*
  2.1876 +    Tagged Queuing support is available and operates properly on all "W" series
  2.1877 +    MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with
  2.1878 +    firmware version 4.22 and above, and on "S" series MultiMaster Host
  2.1879 +    Adapters with firmware version 3.35 and above.
  2.1880 +  */
  2.1881 +  HostAdapter->TaggedQueuingPermitted = 0;
  2.1882 +  switch (HostAdapter->FirmwareVersion[0])
  2.1883 +    {
  2.1884 +    case '5':
  2.1885 +      HostAdapter->TaggedQueuingPermitted = 0xFFFF;
  2.1886 +      break;
  2.1887 +    case '4':
  2.1888 +      if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
  2.1889 +	HostAdapter->TaggedQueuingPermitted = 0xFFFF;
  2.1890 +      break;
  2.1891 +    case '3':
  2.1892 +      if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
  2.1893 +	HostAdapter->TaggedQueuingPermitted = 0xFFFF;
  2.1894 +      break;
  2.1895 +    }
  2.1896 +  /*
  2.1897 +    Determine the Host Adapter BIOS Address if the BIOS is enabled and
  2.1898 +    save it in the Host Adapter structure.  The BIOS is disabled if the
  2.1899 +    BIOS_Address is 0.
  2.1900 +  */
  2.1901 +  HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
  2.1902 +  /*
  2.1903 +    ISA Host Adapters require Bounce Buffers if there is more than 16MB memory.
  2.1904 +  */
  2.1905 +  if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus &&
  2.1906 +      /*(void *) high_memory > (void *) MAX_DMA_ADDRESS*/ 1)
  2.1907 +    HostAdapter->BounceBuffersRequired = true;
  2.1908 +  /*
  2.1909 +    BusLogic BT-445S Host Adapters prior to board revision E have a hardware
  2.1910 +    bug whereby when the BIOS is enabled, transfers to/from the same address
  2.1911 +    range the BIOS occupies modulo 16MB are handled incorrectly.  Only properly
  2.1912 +    functioning BT-445S Host Adapters have firmware version 3.37, so require
  2.1913 +    that ISA Bounce Buffers be used for the buggy BT-445S models if there is
  2.1914 +    more than 16MB memory.
  2.1915 +  */
  2.1916 +  if (HostAdapter->BIOS_Address > 0 &&
  2.1917 +      strcmp(HostAdapter->ModelName, "BT-445S") == 0 &&
  2.1918 +      strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 &&
  2.1919 +      /*(void *) high_memory > (void *) MAX_DMA_ADDRESS*/ 1)
  2.1920 +    HostAdapter->BounceBuffersRequired = true;
  2.1921 +  /*
  2.1922 +    Initialize parameters common to MultiMaster and FlashPoint Host Adapters.
  2.1923 +  */
  2.1924 +Common:
  2.1925 +  /*
  2.1926 +    Initialize the Host Adapter Full Model Name from the Model Name.
  2.1927 +  */
  2.1928 +  strcpy(HostAdapter->FullModelName, "BusLogic ");
  2.1929 +  strcat(HostAdapter->FullModelName, HostAdapter->ModelName);
  2.1930 +  /*
  2.1931 +    Select an appropriate value for the Tagged Queue Depth either from a
  2.1932 +    BusLogic Driver Options specification, or based on whether this Host
  2.1933 +    Adapter requires that ISA Bounce Buffers be used.  The Tagged Queue Depth
  2.1934 +    is left at 0 for automatic determination in BusLogic_SelectQueueDepths.
  2.1935 +    Initialize the Untagged Queue Depth.
  2.1936 +  */
  2.1937 +  for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
  2.1938 +    {
  2.1939 +      unsigned char QueueDepth = 0;
  2.1940 +      if (HostAdapter->DriverOptions != NULL &&
  2.1941 +	  HostAdapter->DriverOptions->QueueDepth[TargetID] > 0)
  2.1942 +	QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID];
  2.1943 +      else if (HostAdapter->BounceBuffersRequired)
  2.1944 +	QueueDepth = BusLogic_TaggedQueueDepthBB;
  2.1945 +      HostAdapter->QueueDepth[TargetID] = QueueDepth;
  2.1946 +    }
  2.1947 +  if (HostAdapter->BounceBuffersRequired)
  2.1948 +    HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB;
  2.1949 +  else HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
  2.1950 +  if (HostAdapter->DriverOptions != NULL)
  2.1951 +    HostAdapter->CommonQueueDepth =
  2.1952 +      HostAdapter->DriverOptions->CommonQueueDepth;
  2.1953 +  if (HostAdapter->CommonQueueDepth > 0 &&
  2.1954 +      HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth)
  2.1955 +    HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth;
  2.1956 +  /*
  2.1957 +    Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
  2.1958 +    Therefore, mask the Tagged Queuing Permitted Default bits with the
  2.1959 +    Disconnect/Reconnect Permitted bits.
  2.1960 +  */
  2.1961 +  HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted;
  2.1962 +  /*
  2.1963 +    Combine the default Tagged Queuing Permitted bits with any BusLogic Driver
  2.1964 +    Options Tagged Queuing specification.
  2.1965 +  */
  2.1966 +  if (HostAdapter->DriverOptions != NULL)
  2.1967 +    HostAdapter->TaggedQueuingPermitted =
  2.1968 +      (HostAdapter->DriverOptions->TaggedQueuingPermitted &
  2.1969 +       HostAdapter->DriverOptions->TaggedQueuingPermittedMask) |
  2.1970 +      (HostAdapter->TaggedQueuingPermitted &
  2.1971 +       ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask);
  2.1972 +  /*
  2.1973 +    Select appropriate values for the Error Recovery Strategy array
  2.1974 +    either from a BusLogic Driver Options specification, or using
  2.1975 +    BusLogic_ErrorRecovery_Default.
  2.1976 +  */
  2.1977 +  for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
  2.1978 +    if (HostAdapter->DriverOptions != NULL)
  2.1979 +      HostAdapter->ErrorRecoveryStrategy[TargetID] =
  2.1980 +	HostAdapter->DriverOptions->ErrorRecoveryStrategy[TargetID];
  2.1981 +    else HostAdapter->ErrorRecoveryStrategy[TargetID] =
  2.1982 +	   BusLogic_ErrorRecovery_Default;
  2.1983 +  /*
  2.1984 +    Select an appropriate value for Bus Settle Time either from a BusLogic
  2.1985 +    Driver Options specification, or from BusLogic_DefaultBusSettleTime.
  2.1986 +  */
  2.1987 +  if (HostAdapter->DriverOptions != NULL &&
  2.1988 +      HostAdapter->DriverOptions->BusSettleTime > 0)
  2.1989 +    HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime;
  2.1990 +  else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
  2.1991 +  /*
  2.1992 +    Indicate reading the Host Adapter Configuration completed successfully.
  2.1993 +  */
  2.1994 +  return true;
  2.1995 +}
  2.1996 +
  2.1997 +
  2.1998 +/*
  2.1999 +  BusLogic_ReportHostAdapterConfiguration reports the configuration of
  2.2000 +  Host Adapter.
  2.2001 +*/
  2.2002 +
  2.2003 +static boolean BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T
  2.2004 +						       *HostAdapter)
  2.2005 +{
  2.2006 +  unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
  2.2007 +  unsigned short SynchronousPermitted, FastPermitted;
  2.2008 +  unsigned short UltraPermitted, WidePermitted;
  2.2009 +  unsigned short DisconnectPermitted, TaggedQueuingPermitted;
  2.2010 +  boolean CommonSynchronousNegotiation, CommonTaggedQueueDepth;
  2.2011 +  boolean CommonErrorRecovery;
  2.2012 +  char SynchronousString[BusLogic_MaxTargetDevices+1];
  2.2013 +  char WideString[BusLogic_MaxTargetDevices+1];
  2.2014 +  char DisconnectString[BusLogic_MaxTargetDevices+1];
  2.2015 +  char TaggedQueuingString[BusLogic_MaxTargetDevices+1];
  2.2016 +  char ErrorRecoveryString[BusLogic_MaxTargetDevices+1];
  2.2017 +  char *SynchronousMessage = SynchronousString;
  2.2018 +  char *WideMessage = WideString;
  2.2019 +  char *DisconnectMessage = DisconnectString;
  2.2020 +  char *TaggedQueuingMessage = TaggedQueuingString;
  2.2021 +  char *ErrorRecoveryMessage = ErrorRecoveryString;
  2.2022 +  int TargetID;
  2.2023 +  BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n",
  2.2024 +		HostAdapter, HostAdapter->ModelName,
  2.2025 +		BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType],
  2.2026 +		(HostAdapter->HostWideSCSI ? " Wide" : ""),
  2.2027 +		(HostAdapter->HostDifferentialSCSI ? " Differential" : ""),
  2.2028 +		(HostAdapter->HostUltraSCSI ? " Ultra" : ""));
  2.2029 +  BusLogic_Info("  Firmware Version: %s, I/O Address: 0x%X, "
  2.2030 +		"IRQ Channel: %d/%s\n", HostAdapter,
  2.2031 +		HostAdapter->FirmwareVersion,
  2.2032 +		HostAdapter->IO_Address, HostAdapter->IRQ_Channel,
  2.2033 +		(HostAdapter->LevelSensitiveInterrupt ? "Level" : "Edge"));
  2.2034 +  if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus)
  2.2035 +    {
  2.2036 +      BusLogic_Info("  DMA Channel: ", HostAdapter);
  2.2037 +      if (HostAdapter->DMA_Channel > 0)
  2.2038 +	BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel);
  2.2039 +      else BusLogic_Info("None, ", HostAdapter);
  2.2040 +      if (HostAdapter->BIOS_Address > 0)
  2.2041 +	BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter,
  2.2042 +		      HostAdapter->BIOS_Address);
  2.2043 +      else BusLogic_Info("BIOS Address: None, ", HostAdapter);
  2.2044 +    }
  2.2045 +  else
  2.2046 +    {
  2.2047 +      BusLogic_Info("  PCI Bus: %d, Device: %d, Address: ",
  2.2048 +		    HostAdapter, HostAdapter->Bus, HostAdapter->Device);
  2.2049 +      if (HostAdapter->PCI_Address > 0)
  2.2050 +	BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address);
  2.2051 +      else BusLogic_Info("Unassigned, ", HostAdapter);
  2.2052 +    }
  2.2053 +  BusLogic_Info("Host Adapter SCSI ID: %d\n", HostAdapter,
  2.2054 +		HostAdapter->SCSI_ID);
  2.2055 +  BusLogic_Info("  Parity Checking: %s, Extended Translation: %s\n",
  2.2056 +		HostAdapter,
  2.2057 +		(HostAdapter->ParityCheckingEnabled
  2.2058 +		 ? "Enabled" : "Disabled"),
  2.2059 +		(HostAdapter->ExtendedTranslationEnabled
  2.2060 +		 ? "Enabled" : "Disabled"));
  2.2061 +  AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID);
  2.2062 +  SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask;
  2.2063 +  FastPermitted = HostAdapter->FastPermitted & AllTargetsMask;
  2.2064 +  UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask;
  2.2065 +  if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) &&
  2.2066 +       (HostAdapter->FirmwareVersion[0] >= '4' ||
  2.2067 +	HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) ||
  2.2068 +      BusLogic_FlashPointHostAdapterP(HostAdapter))
  2.2069 +    {
  2.2070 +      CommonSynchronousNegotiation = false;
  2.2071 +      if (SynchronousPermitted == 0)
  2.2072 +	{
  2.2073 +	  SynchronousMessage = "Disabled";
  2.2074 +	  CommonSynchronousNegotiation = true;
  2.2075 +	}
  2.2076 +      else if (SynchronousPermitted == AllTargetsMask)
  2.2077 +	{
  2.2078 +	  if (FastPermitted == 0)
  2.2079 +	    {
  2.2080 +	      SynchronousMessage = "Slow";
  2.2081 +	      CommonSynchronousNegotiation = true;
  2.2082 +	    }
  2.2083 +	  else if (FastPermitted == AllTargetsMask)
  2.2084 +	    {
  2.2085 +	      if (UltraPermitted == 0)
  2.2086 +		{
  2.2087 +		  SynchronousMessage = "Fast";
  2.2088 +		  CommonSynchronousNegotiation = true;
  2.2089 +		}
  2.2090 +	      else if (UltraPermitted == AllTargetsMask)
  2.2091 +		{
  2.2092 +		  SynchronousMessage = "Ultra";
  2.2093 +		  CommonSynchronousNegotiation = true;
  2.2094 +		}
  2.2095 +	    }
  2.2096 +	}
  2.2097 +      if (!CommonSynchronousNegotiation)
  2.2098 +	{
  2.2099 +	  for (TargetID = 0;
  2.2100 +	       TargetID < HostAdapter->MaxTargetDevices;
  2.2101 +	       TargetID++)
  2.2102 +	    SynchronousString[TargetID] =
  2.2103 +	      ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' :
  2.2104 +	       (!(FastPermitted & (1 << TargetID)) ? 'S' :
  2.2105 +		(!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U')));
  2.2106 +	  SynchronousString[HostAdapter->SCSI_ID] = '#';
  2.2107 +	  SynchronousString[HostAdapter->MaxTargetDevices] = '\0';
  2.2108 +	}
  2.2109 +    }
  2.2110 +  else SynchronousMessage =
  2.2111 +	 (SynchronousPermitted == 0 ? "Disabled" : "Enabled");
  2.2112 +  WidePermitted = HostAdapter->WidePermitted & AllTargetsMask;
  2.2113 +  if (WidePermitted == 0)
  2.2114 +    WideMessage = "Disabled";
  2.2115 +  else if (WidePermitted == AllTargetsMask)
  2.2116 +    WideMessage = "Enabled";
  2.2117 +  else
  2.2118 +    {
  2.2119 +      for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.2120 +	 WideString[TargetID] =
  2.2121 +	   ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N');
  2.2122 +      WideString[HostAdapter->SCSI_ID] = '#';
  2.2123 +      WideString[HostAdapter->MaxTargetDevices] = '\0';
  2.2124 +    }
  2.2125 +  DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
  2.2126 +  if (DisconnectPermitted == 0)
  2.2127 +    DisconnectMessage = "Disabled";
  2.2128 +  else if (DisconnectPermitted == AllTargetsMask)
  2.2129 +    DisconnectMessage = "Enabled";
  2.2130 +  else
  2.2131 +    {
  2.2132 +      for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.2133 +	DisconnectString[TargetID] =
  2.2134 +	  ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
  2.2135 +      DisconnectString[HostAdapter->SCSI_ID] = '#';
  2.2136 +      DisconnectString[HostAdapter->MaxTargetDevices] = '\0';
  2.2137 +    }
  2.2138 +  TaggedQueuingPermitted =
  2.2139 +    HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
  2.2140 +  if (TaggedQueuingPermitted == 0)
  2.2141 +    TaggedQueuingMessage = "Disabled";
  2.2142 +  else if (TaggedQueuingPermitted == AllTargetsMask)
  2.2143 +    TaggedQueuingMessage = "Enabled";
  2.2144 +  else
  2.2145 +    {
  2.2146 +      for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.2147 +	TaggedQueuingString[TargetID] =
  2.2148 +	  ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
  2.2149 +      TaggedQueuingString[HostAdapter->SCSI_ID] = '#';
  2.2150 +      TaggedQueuingString[HostAdapter->MaxTargetDevices] = '\0';
  2.2151 +    }
  2.2152 +  BusLogic_Info("  Synchronous Negotiation: %s, Wide Negotiation: %s\n",
  2.2153 +		HostAdapter, SynchronousMessage, WideMessage);
  2.2154 +  BusLogic_Info("  Disconnect/Reconnect: %s, Tagged Queuing: %s\n",
  2.2155 +		HostAdapter, DisconnectMessage, TaggedQueuingMessage);
  2.2156 +  if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
  2.2157 +    {
  2.2158 +      BusLogic_Info("  Scatter/Gather Limit: %d of %d segments, "
  2.2159 +		    "Mailboxes: %d\n", HostAdapter,
  2.2160 +		    HostAdapter->DriverScatterGatherLimit,
  2.2161 +		    HostAdapter->HostAdapterScatterGatherLimit,
  2.2162 +		    HostAdapter->MailboxCount);
  2.2163 +      BusLogic_Info("  Driver Queue Depth: %d, "
  2.2164 +		    "Host Adapter Queue Depth: %d\n",
  2.2165 +		    HostAdapter, HostAdapter->DriverQueueDepth,
  2.2166 +		    HostAdapter->HostAdapterQueueDepth);
  2.2167 +    }
  2.2168 +  else BusLogic_Info("  Driver Queue Depth: %d, "
  2.2169 +		     "Scatter/Gather Limit: %d segments\n",
  2.2170 +		     HostAdapter, HostAdapter->DriverQueueDepth,
  2.2171 +		     HostAdapter->DriverScatterGatherLimit);
  2.2172 +  BusLogic_Info("  Tagged Queue Depth: ", HostAdapter);
  2.2173 +  CommonTaggedQueueDepth = true;
  2.2174 +  for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.2175 +    if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0])
  2.2176 +      {
  2.2177 +	CommonTaggedQueueDepth = false;
  2.2178 +	break;
  2.2179 +      }
  2.2180 +  if (CommonTaggedQueueDepth)
  2.2181 +    {
  2.2182 +      if (HostAdapter->QueueDepth[0] > 0)
  2.2183 +	BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]);
  2.2184 +      else BusLogic_Info("Automatic", HostAdapter);
  2.2185 +    }
  2.2186 +  else BusLogic_Info("Individual", HostAdapter);
  2.2187 +  BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter,
  2.2188 +		HostAdapter->UntaggedQueueDepth);
  2.2189 +  CommonErrorRecovery = true;
  2.2190 +  for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.2191 +    if (HostAdapter->ErrorRecoveryStrategy[TargetID] !=
  2.2192 +	HostAdapter->ErrorRecoveryStrategy[0])
  2.2193 +      {
  2.2194 +	CommonErrorRecovery = false;
  2.2195 +	break;
  2.2196 +      }
  2.2197 +  if (CommonErrorRecovery)
  2.2198 +    ErrorRecoveryMessage =
  2.2199 +      BusLogic_ErrorRecoveryStrategyNames[
  2.2200 +	HostAdapter->ErrorRecoveryStrategy[0]];
  2.2201 +  else
  2.2202 +    {
  2.2203 +      for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.2204 +	ErrorRecoveryString[TargetID] =
  2.2205 +	  BusLogic_ErrorRecoveryStrategyLetters[
  2.2206 +	    HostAdapter->ErrorRecoveryStrategy[TargetID]];
  2.2207 +      ErrorRecoveryString[HostAdapter->SCSI_ID] = '#';
  2.2208 +      ErrorRecoveryString[HostAdapter->MaxTargetDevices] = '\0';
  2.2209 +    }
  2.2210 +  BusLogic_Info("  Error Recovery Strategy: %s, SCSI Bus Reset: %s\n",
  2.2211 +		HostAdapter, ErrorRecoveryMessage,
  2.2212 +		(HostAdapter->BusResetEnabled ? "Enabled" : "Disabled"));
  2.2213 +  if (HostAdapter->TerminationInfoValid)
  2.2214 +    {
  2.2215 +      if (HostAdapter->HostWideSCSI)
  2.2216 +	BusLogic_Info("  SCSI Bus Termination: %s", HostAdapter,
  2.2217 +		      (HostAdapter->LowByteTerminated
  2.2218 +		       ? (HostAdapter->HighByteTerminated
  2.2219 +			  ? "Both Enabled" : "Low Enabled")
  2.2220 +		       : (HostAdapter->HighByteTerminated
  2.2221 +			  ? "High Enabled" : "Both Disabled")));
  2.2222 +      else BusLogic_Info("  SCSI Bus Termination: %s", HostAdapter,
  2.2223 +			 (HostAdapter->LowByteTerminated ?
  2.2224 +			  "Enabled" : "Disabled"));
  2.2225 +      if (HostAdapter->HostSupportsSCAM)
  2.2226 +	BusLogic_Info(", SCAM: %s", HostAdapter,
  2.2227 +		      (HostAdapter->SCAM_Enabled
  2.2228 +		       ? (HostAdapter->SCAM_Level2
  2.2229 +			  ? "Enabled, Level 2" : "Enabled, Level 1")
  2.2230 +		       : "Disabled"));
  2.2231 +      BusLogic_Info("\n", HostAdapter);
  2.2232 +    }
  2.2233 +  /*
  2.2234 +    Indicate reporting the Host Adapter configuration completed successfully.
  2.2235 +  */
  2.2236 +  return true;
  2.2237 +}
  2.2238 +
  2.2239 +
  2.2240 +/*
  2.2241 +  BusLogic_AcquireResources acquires the system resources necessary to use
  2.2242 +  Host Adapter.
  2.2243 +*/
  2.2244 +
  2.2245 +static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter)
  2.2246 +{
  2.2247 +  if (HostAdapter->IRQ_Channel == 0)
  2.2248 +    {
  2.2249 +      BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
  2.2250 +		     HostAdapter);
  2.2251 +      return false;
  2.2252 +    }
  2.2253 +  /*
  2.2254 +    Acquire shared access to the IRQ Channel.
  2.2255 +  */
  2.2256 +  if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
  2.2257 +		  SA_SHIRQ, HostAdapter->FullModelName, HostAdapter) < 0)
  2.2258 +    {
  2.2259 +      BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
  2.2260 +		     HostAdapter, HostAdapter->IRQ_Channel);
  2.2261 +      return false;
  2.2262 +    }
  2.2263 +  HostAdapter->IRQ_ChannelAcquired = true;
  2.2264 +  /*
  2.2265 +    Acquire exclusive access to the DMA Channel.
  2.2266 +  */
  2.2267 +  if (HostAdapter->DMA_Channel > 0)
  2.2268 +    {
  2.2269 +#if 0 /* XEN */
  2.2270 +      if (request_dma(HostAdapter->DMA_Channel,
  2.2271 +		      HostAdapter->FullModelName) < 0)
  2.2272 +	{
  2.2273 +	  BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n",
  2.2274 +			 HostAdapter, HostAdapter->DMA_Channel);
  2.2275 +	  return false;
  2.2276 +	}
  2.2277 +#endif
  2.2278 +      set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
  2.2279 +      enable_dma(HostAdapter->DMA_Channel);
  2.2280 +      HostAdapter->DMA_ChannelAcquired = true;
  2.2281 +    }
  2.2282 +  /*
  2.2283 +    Indicate the System Resource Acquisition completed successfully,
  2.2284 +  */
  2.2285 +  return true;
  2.2286 +}
  2.2287 +
  2.2288 +
  2.2289 +/*
  2.2290 +  BusLogic_ReleaseResources releases any system resources previously acquired
  2.2291 +  by BusLogic_AcquireResources.
  2.2292 +*/
  2.2293 +
  2.2294 +static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter)
  2.2295 +{
  2.2296 +  /*
  2.2297 +    Release shared access to the IRQ Channel.
  2.2298 +  */
  2.2299 +  if (HostAdapter->IRQ_ChannelAcquired)
  2.2300 +    free_irq(HostAdapter->IRQ_Channel, HostAdapter);
  2.2301 +#if 0 /* XEN */
  2.2302 +  /*
  2.2303 +    Release exclusive access to the DMA Channel.
  2.2304 +  */
  2.2305 +  if (HostAdapter->DMA_ChannelAcquired)
  2.2306 +    free_dma(HostAdapter->DMA_Channel);
  2.2307 +#endif
  2.2308 +}
  2.2309 +
  2.2310 +
  2.2311 +/*
  2.2312 +  BusLogic_InitializeHostAdapter initializes Host Adapter.  This is the only
  2.2313 +  function called during SCSI Host Adapter detection which modifies the state
  2.2314 +  of the Host Adapter from its initial power on or hard reset state.
  2.2315 +*/
  2.2316 +
  2.2317 +static boolean BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T
  2.2318 +					      *HostAdapter)
  2.2319 +{
  2.2320 +  BusLogic_ExtendedMailboxRequest_T ExtendedMailboxRequest;
  2.2321 +  BusLogic_RoundRobinModeRequest_T RoundRobinModeRequest;
  2.2322 +  BusLogic_SetCCBFormatRequest_T SetCCBFormatRequest;
  2.2323 +  int TargetID;
  2.2324 +  /*
  2.2325 +    Initialize the pointers to the first and last CCBs that are queued for
  2.2326 +    completion processing.
  2.2327 +  */
  2.2328 +  HostAdapter->FirstCompletedCCB = NULL;
  2.2329 +  HostAdapter->LastCompletedCCB = NULL;
  2.2330 +  /*
  2.2331 +    Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
  2.2332 +    Command Successful Flag, Active Commands, and Commands Since Reset
  2.2333 +    for each Target Device.
  2.2334 +  */
  2.2335 +  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.2336 +    {
  2.2337 +      HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
  2.2338 +      HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
  2.2339 +      HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
  2.2340 +      HostAdapter->ActiveCommands[TargetID] = 0;
  2.2341 +      HostAdapter->CommandsSinceReset[TargetID] = 0;
  2.2342 +    }
  2.2343 +  /*
  2.2344 +    FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
  2.2345 +  */
  2.2346 +  if (BusLogic_FlashPointHostAdapterP(HostAdapter)) goto Done;
  2.2347 +  /*
  2.2348 +    Initialize the Outgoing and Incoming Mailbox pointers.
  2.2349 +  */
  2.2350 +  HostAdapter->FirstOutgoingMailbox =
  2.2351 +    (BusLogic_OutgoingMailbox_T *) HostAdapter->MailboxSpace;
  2.2352 +  HostAdapter->LastOutgoingMailbox =
  2.2353 +    HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
  2.2354 +  HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
  2.2355 +  HostAdapter->FirstIncomingMailbox =
  2.2356 +    (BusLogic_IncomingMailbox_T *) (HostAdapter->LastOutgoingMailbox + 1);
  2.2357 +  HostAdapter->LastIncomingMailbox =
  2.2358 +    HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
  2.2359 +  HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
  2.2360 +  /*
  2.2361 +    Initialize the Outgoing and Incoming Mailbox structures.
  2.2362 +  */
  2.2363 +  memset(HostAdapter->FirstOutgoingMailbox, 0,
  2.2364 +	 HostAdapter->MailboxCount * sizeof(BusLogic_OutgoingMailbox_T));
  2.2365 +  memset(HostAdapter->FirstIncomingMailbox, 0,
  2.2366 +	 HostAdapter->MailboxCount * sizeof(BusLogic_IncomingMailbox_T));
  2.2367 +  /*
  2.2368 +    Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
  2.2369 +  */
  2.2370 +  ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
  2.2371 +  ExtendedMailboxRequest.BaseMailboxAddress =
  2.2372 +    Virtual_to_Bus(HostAdapter->FirstOutgoingMailbox);
  2.2373 +  if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox,
  2.2374 +		       &ExtendedMailboxRequest,
  2.2375 +		       sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
  2.2376 +    return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
  2.2377 +  /*
  2.2378 +    Enable Strict Round Robin Mode if supported by the Host Adapter.  In
  2.2379 +    Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing
  2.2380 +    Mailbox for each new command, rather than scanning through all the
  2.2381 +    Outgoing Mailboxes to find any that have new commands in them.  Strict
  2.2382 +    Round Robin Mode is significantly more efficient.
  2.2383 +  */
  2.2384 +  if (HostAdapter->StrictRoundRobinModeSupport)
  2.2385 +    {
  2.2386 +      RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
  2.2387 +      if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode,
  2.2388 +			   &RoundRobinModeRequest,
  2.2389 +			   sizeof(RoundRobinModeRequest), NULL, 0) < 0)
  2.2390 +	return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
  2.2391 +    }
  2.2392 +  /*
  2.2393 +    For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB
  2.2394 +    Format command to allow 32 Logical Units per Target Device.
  2.2395 +  */
  2.2396 +  if (HostAdapter->ExtendedLUNSupport)
  2.2397 +    {
  2.2398 +      SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB;
  2.2399 +      if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat,
  2.2400 +			   &SetCCBFormatRequest, sizeof(SetCCBFormatRequest),
  2.2401 +			   NULL, 0) < 0)
  2.2402 +	return BusLogic_Failure(HostAdapter, "SET CCB FORMAT");
  2.2403 +    }
  2.2404 +  /*
  2.2405 +    Announce Successful Initialization.
  2.2406 +  */
  2.2407 +Done:
  2.2408 +  if (!HostAdapter->HostAdapterInitialized)
  2.2409 +    {
  2.2410 +      BusLogic_Info("*** %s Initialized Successfully ***\n",
  2.2411 +		    HostAdapter, HostAdapter->FullModelName);
  2.2412 +      BusLogic_Info("\n", HostAdapter);
  2.2413 +    }
  2.2414 +  else BusLogic_Warning("*** %s Initialized Successfully ***\n",
  2.2415 +			HostAdapter, HostAdapter->FullModelName);
  2.2416 +  HostAdapter->HostAdapterInitialized = true;
  2.2417 +  /*
  2.2418 +    Indicate the Host Adapter Initialization completed successfully.
  2.2419 +  */
  2.2420 +  return true;
  2.2421 +}
  2.2422 +
  2.2423 +
  2.2424 +/*
  2.2425 +  BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
  2.2426 +  through Host Adapter.
  2.2427 +*/
  2.2428 +
  2.2429 +static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T
  2.2430 +					    *HostAdapter)
  2.2431 +{
  2.2432 +  BusLogic_InstalledDevices_T InstalledDevices;
  2.2433 +  BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
  2.2434 +  BusLogic_SetupInformation_T SetupInformation;
  2.2435 +  BusLogic_SynchronousPeriod_T SynchronousPeriod;
  2.2436 +  BusLogic_RequestedReplyLength_T RequestedReplyLength;
  2.2437 +  int TargetID;
  2.2438 +  /*
  2.2439 +    Wait a few seconds between the Host Adapter Hard Reset which initiates
  2.2440 +    a SCSI Bus Reset and issuing any SCSI Commands.  Some SCSI devices get
  2.2441 +    confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
  2.2442 +  */
  2.2443 +  BusLogic_Delay(HostAdapter->BusSettleTime);
  2.2444 +  /*
  2.2445 +    FlashPoint Host Adapters do not provide for Target Device Inquiry.
  2.2446 +  */
  2.2447 +  if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
  2.2448 +  /*
  2.2449 +    Inhibit the Target Device Inquiry if requested.
  2.2450 +  */
  2.2451 +  if (HostAdapter->DriverOptions != NULL &&
  2.2452 +      HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
  2.2453 +    return true;
  2.2454 +  /*
  2.2455 +    Issue the Inquire Target Devices command for host adapters with firmware
  2.2456 +    version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command
  2.2457 +    for older host adapters.  This is necessary to force Synchronous Transfer
  2.2458 +    Negotiation so that the Inquire Setup Information and Inquire Synchronous
  2.2459 +    Period commands will return valid data.  The Inquire Target Devices command
  2.2460 +    is preferable to Inquire Installed Devices ID 0 to 7 since it only probes
  2.2461 +    Logical Unit 0 of each Target Device.
  2.2462 +  */
  2.2463 +  if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0)
  2.2464 +    {
  2.2465 +      if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0,
  2.2466 +			   &InstalledDevices, sizeof(InstalledDevices))
  2.2467 +	  != sizeof(InstalledDevices))
  2.2468 +	return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES");
  2.2469 +      for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.2470 +	HostAdapter->TargetFlags[TargetID].TargetExists =
  2.2471 +	  (InstalledDevices & (1 << TargetID) ? true : false);
  2.2472 +    }
  2.2473 +  else
  2.2474 +    {
  2.2475 +      if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7,
  2.2476 +			   NULL, 0, &InstalledDevicesID0to7,
  2.2477 +			   sizeof(InstalledDevicesID0to7))
  2.2478 +	  != sizeof(InstalledDevicesID0to7))
  2.2479 +	return BusLogic_Failure(HostAdapter,
  2.2480 +				"INQUIRE INSTALLED DEVICES ID 0 TO 7");
  2.2481 +      for (TargetID = 0; TargetID < 8; TargetID++)
  2.2482 +	HostAdapter->TargetFlags[TargetID].TargetExists =
  2.2483 +	  (InstalledDevicesID0to7[TargetID] != 0 ? true : false);
  2.2484 +    }
  2.2485 +  /*
  2.2486 +    Issue the Inquire Setup Information command.
  2.2487 +  */
  2.2488 +  RequestedReplyLength = sizeof(SetupInformation);
  2.2489 +  if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
  2.2490 +		       &RequestedReplyLength, sizeof(RequestedReplyLength),
  2.2491 +		       &SetupInformation, sizeof(SetupInformation))
  2.2492 +      != sizeof(SetupInformation))
  2.2493 +    return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
  2.2494 +  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.2495 +      HostAdapter->SynchronousOffset[TargetID] =
  2.2496 +	(TargetID < 8
  2.2497 +	 ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset
  2.2498 +	 : SetupInformation.SynchronousValuesID8to15[TargetID-8].Offset);
  2.2499 +  if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0)
  2.2500 +    for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.2501 +      HostAdapter->TargetFlags[TargetID].WideTransfersActive =
  2.2502 +	(TargetID < 8
  2.2503 +	 ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID)
  2.2504 +	    ? true : false)
  2.2505 +	 : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID-8))
  2.2506 +	    ? true : false));
  2.2507 +  /*
  2.2508 +    Issue the Inquire Synchronous Period command.
  2.2509 +  */
  2.2510 +  if (HostAdapter->FirmwareVersion[0] >= '3')
  2.2511 +    {
  2.2512 +      RequestedReplyLength = sizeof(SynchronousPeriod);
  2.2513 +      if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod,
  2.2514 +			   &RequestedReplyLength, sizeof(RequestedReplyLength),
  2.2515 +			   &SynchronousPeriod, sizeof(SynchronousPeriod))
  2.2516 +	  != sizeof(SynchronousPeriod))
  2.2517 +	return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
  2.2518 +      for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.2519 +	HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
  2.2520 +    }
  2.2521 +  else
  2.2522 +    for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.2523 +      if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
  2.2524 +	HostAdapter->SynchronousPeriod[TargetID] =
  2.2525 +	  20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
  2.2526 +				   .TransferPeriod;
  2.2527 +  /*
  2.2528 +    Indicate the Target Device Inquiry completed successfully.
  2.2529 +  */
  2.2530 +  return true;
  2.2531 +}
  2.2532 +
  2.2533 +
  2.2534 +/*
  2.2535 +  BusLogic_ReportTargetDeviceInfo reports about the Target Devices accessible
  2.2536 +  through Host Adapter.
  2.2537 +*/
  2.2538 +
  2.2539 +static void BusLogic_ReportTargetDeviceInfo(BusLogic_HostAdapter_T
  2.2540 +					    *HostAdapter)
  2.2541 +{
  2.2542 +  int TargetID;
  2.2543 +  /*
  2.2544 +    Inhibit the Target Device Inquiry and Reporting if requested.
  2.2545 +  */
  2.2546 +  if (BusLogic_MultiMasterHostAdapterP(HostAdapter) &&
  2.2547 +      HostAdapter->DriverOptions != NULL &&
  2.2548 +      HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
  2.2549 +    return;
  2.2550 +  /*
  2.2551 +    Report on the Target Devices found.
  2.2552 +  */
  2.2553 +  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.2554 +    {
  2.2555 +      BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
  2.2556 +      if (TargetFlags->TargetExists && !TargetFlags->TargetInfoReported)
  2.2557 +	{
  2.2558 +	  int SynchronousTransferRate = 0;
  2.2559 +	  if (BusLogic_FlashPointHostAdapterP(HostAdapter))
  2.2560 +	    {
  2.2561 +	      unsigned char WideTransfersActive;
  2.2562 +	      FlashPoint_InquireTargetInfo(
  2.2563 +		HostAdapter->CardHandle, TargetID,
  2.2564 +		&HostAdapter->SynchronousPeriod[TargetID],
  2.2565 +		&HostAdapter->SynchronousOffset[TargetID],
  2.2566 +		&WideTransfersActive);
  2.2567 +	      TargetFlags->WideTransfersActive = WideTransfersActive;
  2.2568 +	    }
  2.2569 +	  else if (TargetFlags->WideTransfersSupported &&
  2.2570 +		   (HostAdapter->WidePermitted & (1 << TargetID)) &&
  2.2571 +		   strcmp(HostAdapter->FirmwareVersion, "5.06L") < 0)
  2.2572 +	    TargetFlags->WideTransfersActive = true;
  2.2573 +	  if (HostAdapter->SynchronousPeriod[TargetID] > 0)
  2.2574 +	    SynchronousTransferRate =
  2.2575 +	      100000 / HostAdapter->SynchronousPeriod[TargetID];
  2.2576 +	  if (TargetFlags->WideTransfersActive)
  2.2577 +	    SynchronousTransferRate <<= 1;
  2.2578 +	  if (SynchronousTransferRate >= 9950)
  2.2579 +	    {
  2.2580 +	      SynchronousTransferRate = (SynchronousTransferRate + 50) / 100;
  2.2581 +	      BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at "
  2.2582 +			    "%d.%01d MB/sec, offset %d\n",
  2.2583 +			    HostAdapter, TargetID,
  2.2584 +			    HostAdapter->QueueDepth[TargetID],
  2.2585 +			    (TargetFlags->WideTransfersActive ? "Wide " : ""),
  2.2586 +			    SynchronousTransferRate / 10,
  2.2587 +			    SynchronousTransferRate % 10,
  2.2588 +			    HostAdapter->SynchronousOffset[TargetID]);
  2.2589 +	    }
  2.2590 +	  else if (SynchronousTransferRate > 0)
  2.2591 +	    {
  2.2592 +	      SynchronousTransferRate = (SynchronousTransferRate + 5) / 10;
  2.2593 +	      BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at "
  2.2594 +			    "%d.%02d MB/sec, offset %d\n",
  2.2595 +			    HostAdapter, TargetID,
  2.2596 +			    HostAdapter->QueueDepth[TargetID],
  2.2597 +			    (TargetFlags->WideTransfersActive ? "Wide " : ""),
  2.2598 +			    SynchronousTransferRate / 100,
  2.2599 +			    SynchronousTransferRate % 100,
  2.2600 +			    HostAdapter->SynchronousOffset[TargetID]);
  2.2601 +	    }
  2.2602 +	  else BusLogic_Info("Target %d: Queue Depth %d, Asynchronous\n",
  2.2603 +			     HostAdapter, TargetID,
  2.2604 +			     HostAdapter->QueueDepth[TargetID]);
  2.2605 +	  TargetFlags->TargetInfoReported = true;
  2.2606 +	}
  2.2607 +    }
  2.2608 +}
  2.2609 +
  2.2610 +
  2.2611 +/*
  2.2612 +  BusLogic_InitializeHostStructure initializes the fields in the SCSI Host
  2.2613 +  structure.  The base, io_port, n_io_ports, irq, and dma_channel fields in the
  2.2614 +  SCSI Host structure are intentionally left uninitialized, as this driver
  2.2615 +  handles acquisition and release of these resources explicitly, as well as
  2.2616 +  ensuring exclusive access to the Host Adapter hardware and data structures
  2.2617 +  through explicit acquisition and release of the Host Adapter's Lock.
  2.2618 +*/
  2.2619 +
  2.2620 +static void BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T
  2.2621 +					       *HostAdapter,
  2.2622 +					     SCSI_Host_T *Host)
  2.2623 +{
  2.2624 +  Host->max_id = HostAdapter->MaxTargetDevices;
  2.2625 +  Host->max_lun = HostAdapter->MaxLogicalUnits;
  2.2626 +  Host->max_channel = 0;
  2.2627 +  Host->unique_id = HostAdapter->IO_Address;
  2.2628 +  Host->this_id = HostAdapter->SCSI_ID;
  2.2629 +  Host->can_queue = HostAdapter->DriverQueueDepth;
  2.2630 +  Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
  2.2631 +  Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
  2.2632 +  Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
  2.2633 +}
  2.2634 +
  2.2635 +
  2.2636 +/*
  2.2637 +  BusLogic_SelectQueueDepths selects Queue Depths for each Target Device based
  2.2638 +  on the Host Adapter's Total Queue Depth and the number, type, speed, and
  2.2639 +  capabilities of the Target Devices.  When called for the last Host Adapter,
  2.2640 +  it reports on the Target Device Information for all BusLogic Host Adapters
  2.2641 +  since all the Target Devices have now been probed.
  2.2642 +*/
  2.2643 +
  2.2644 +static void BusLogic_SelectQueueDepths(SCSI_Host_T *Host,
  2.2645 +				       SCSI_Device_T *DeviceList)
  2.2646 +{
  2.2647 +  BusLogic_HostAdapter_T *HostAdapter =
  2.2648 +    (BusLogic_HostAdapter_T *) Host->hostdata;
  2.2649 +  int TaggedDeviceCount = 0, AutomaticTaggedDeviceCount = 0;
  2.2650 +  int UntaggedDeviceCount = 0, AutomaticTaggedQueueDepth = 0;
  2.2651 +  int AllocatedQueueDepth = 0;
  2.2652 +  SCSI_Device_T *Device;
  2.2653 +  int TargetID;
  2.2654 +  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.2655 +    if (HostAdapter->TargetFlags[TargetID].TargetExists)
  2.2656 +      {
  2.2657 +	int QueueDepth = HostAdapter->QueueDepth[TargetID];
  2.2658 +	if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported &&
  2.2659 +	    (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
  2.2660 +	  {
  2.2661 +	    TaggedDeviceCount++;
  2.2662 +	    if (QueueDepth == 0) AutomaticTaggedDeviceCount++;
  2.2663 +	  }
  2.2664 +	else
  2.2665 +	  {
  2.2666 +	    UntaggedDeviceCount++;
  2.2667 +	    if (QueueDepth == 0 ||
  2.2668 +		QueueDepth > HostAdapter->UntaggedQueueDepth)
  2.2669 +	      {
  2.2670 +		QueueDepth = HostAdapter->UntaggedQueueDepth;
  2.2671 +		HostAdapter->QueueDepth[TargetID] = QueueDepth;
  2.2672 +	      }
  2.2673 +	  }
  2.2674 +	AllocatedQueueDepth += QueueDepth;
  2.2675 +	if (QueueDepth == 1)
  2.2676 +	  HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
  2.2677 +      }
  2.2678 +  HostAdapter->TargetDeviceCount = TaggedDeviceCount + UntaggedDeviceCount;
  2.2679 +  if (AutomaticTaggedDeviceCount > 0)
  2.2680 +    {
  2.2681 +      AutomaticTaggedQueueDepth =
  2.2682 +	(HostAdapter->HostAdapterQueueDepth - AllocatedQueueDepth)
  2.2683 +	/ AutomaticTaggedDeviceCount;
  2.2684 +      if (AutomaticTaggedQueueDepth > BusLogic_MaxAutomaticTaggedQueueDepth)
  2.2685 +	AutomaticTaggedQueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth;
  2.2686 +      if (AutomaticTaggedQueueDepth < BusLogic_MinAutomaticTaggedQueueDepth)
  2.2687 +	AutomaticTaggedQueueDepth = BusLogic_MinAutomaticTaggedQueueDepth;
  2.2688 +      for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.2689 +	if (HostAdapter->TargetFlags[TargetID].TargetExists &&
  2.2690 +	    HostAdapter->QueueDepth[TargetID] == 0)
  2.2691 +	  {
  2.2692 +	    AllocatedQueueDepth += AutomaticTaggedQueueDepth;
  2.2693 +	    HostAdapter->QueueDepth[TargetID] = AutomaticTaggedQueueDepth;
  2.2694 +	  }
  2.2695 +    }
  2.2696 +  for (Device = DeviceList; Device != NULL; Device = Device->next)
  2.2697 +    if (Device->host == Host)
  2.2698 +      Device->queue_depth = HostAdapter->QueueDepth[Device->id];
  2.2699 +  /* Allocate an extra CCB for each Target Device for a Bus Device Reset. */
  2.2700 +  AllocatedQueueDepth += HostAdapter->TargetDeviceCount;
  2.2701 +  if (AllocatedQueueDepth > HostAdapter->DriverQueueDepth)
  2.2702 +    AllocatedQueueDepth = HostAdapter->DriverQueueDepth;
  2.2703 +  BusLogic_CreateAdditionalCCBs(HostAdapter,
  2.2704 +				AllocatedQueueDepth
  2.2705 +				- HostAdapter->AllocatedCCBs,
  2.2706 +				false);
  2.2707 +  if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
  2.2708 +    for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
  2.2709 +	 HostAdapter != NULL;
  2.2710 +	 HostAdapter = HostAdapter->Next)
  2.2711 +      BusLogic_ReportTargetDeviceInfo(HostAdapter);
  2.2712 +}
  2.2713 +
  2.2714 +
  2.2715 +/*
  2.2716 +  BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
  2.2717 +  I/O Addresses where they may be located, initializing, registering, and
  2.2718 +  reporting the configuration of each BusLogic Host Adapter it finds.  It
  2.2719 +  returns the number of BusLogic Host Adapters successfully initialized and
  2.2720 +  registered.
  2.2721 +*/
  2.2722 +
  2.2723 +int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate)
  2.2724 +{
  2.2725 +  int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex;
  2.2726 +  BusLogic_HostAdapter_T *PrototypeHostAdapter;
  2.2727 +  if (BusLogic_ProbeOptions.NoProbe) return 0;
  2.2728 +  BusLogic_ProbeInfoList = (BusLogic_ProbeInfo_T *)
  2.2729 +    kmalloc(BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T),
  2.2730 +	    GFP_ATOMIC);
  2.2731 +  if (BusLogic_ProbeInfoList == NULL)
  2.2732 +    {
  2.2733 +      BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL);
  2.2734 +      return 0;
  2.2735 +    }
  2.2736 +  memset(BusLogic_ProbeInfoList, 0,
  2.2737 +	 BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T));
  2.2738 +  PrototypeHostAdapter = (BusLogic_HostAdapter_T *)
  2.2739 +    kmalloc(sizeof(BusLogic_HostAdapter_T), GFP_ATOMIC);
  2.2740 +  if (PrototypeHostAdapter == NULL)
  2.2741 +    {
  2.2742 +      kfree(BusLogic_ProbeInfoList);
  2.2743 +      BusLogic_Error("BusLogic: Unable to allocate Prototype "
  2.2744 +		     "Host Adapter\n", NULL);
  2.2745 +      return 0;
  2.2746 +    }
  2.2747 +  memset(PrototypeHostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
  2.2748 +#ifdef MODULE
  2.2749 +  if (BusLogic != NULL)
  2.2750 +    BusLogic_Setup(BusLogic);
  2.2751 +#endif
  2.2752 +  BusLogic_InitializeProbeInfoList(PrototypeHostAdapter);
  2.2753 +  for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++)
  2.2754 +    {
  2.2755 +      BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex];
  2.2756 +      BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
  2.2757 +      SCSI_Host_T *Host;
  2.2758 +      if (ProbeInfo->IO_Address == 0) continue;
  2.2759 +      memset(HostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
  2.2760 +      HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType;
  2.2761 +      HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType;
  2.2762 +      HostAdapter->IO_Address = ProbeInfo->IO_Address;
  2.2763 +      HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
  2.2764 +      HostAdapter->Bus = ProbeInfo->Bus;
  2.2765 +      HostAdapter->Device = ProbeInfo->Device;
  2.2766 +      HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
  2.2767 +      HostAdapter->AddressCount =
  2.2768 +	BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
  2.2769 +      /*
  2.2770 +	Probe the Host Adapter.  If unsuccessful, abort further initialization.
  2.2771 +      */
  2.2772 +      if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue;
  2.2773 +      /*
  2.2774 +	Hard Reset the Host Adapter.  If unsuccessful, abort further
  2.2775 +	initialization.
  2.2776 +      */
  2.2777 +      if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) continue;
  2.2778 +      /*
  2.2779 +	Check the Host Adapter.  If unsuccessful, abort further initialization.
  2.2780 +      */
  2.2781 +      if (!BusLogic_CheckHostAdapter(HostAdapter)) continue;
  2.2782 +      /*
  2.2783 +	Initialize the Driver Options field if provided.
  2.2784 +      */
  2.2785 +      if (DriverOptionsIndex < BusLogic_DriverOptionsCount)
  2.2786 +	HostAdapter->DriverOptions =
  2.2787 +	  &BusLogic_DriverOptions[DriverOptionsIndex++];
  2.2788 +      /*
  2.2789 +	Announce the Driver Version and Date, Author's Name, Copyright Notice,
  2.2790 +	and Electronic Mail Address.
  2.2791 +      */
  2.2792 +      BusLogic_AnnounceDriver(HostAdapter);
  2.2793 +      /*
  2.2794 +	Register usage of the I/O Address range.  From this point onward, any
  2.2795 +	failure will be assumed to be due to a problem with the Host Adapter,
  2.2796 +	rather than due to having mistakenly identified this port as belonging
  2.2797 +	to a BusLogic Host Adapter.  The I/O Address range will not be
  2.2798 +	released, thereby preventing it from being incorrectly identified as
  2.2799 +	any other type of Host Adapter.
  2.2800 +      */
  2.2801 +      request_region(HostAdapter->IO_Address, HostAdapter->AddressCount,
  2.2802 +		     "BusLogic");
  2.2803 +      /*
  2.2804 +	Register the SCSI Host structure.
  2.2805 +      */
  2.2806 +      Host = scsi_register(HostTemplate, sizeof(BusLogic_HostAdapter_T));
  2.2807 +      if(Host==NULL)
  2.2808 +      {
  2.2809 +      	release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
  2.2810 +      	continue;
  2.2811 +      }
  2.2812 +      HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata;
  2.2813 +      memcpy(HostAdapter, PrototypeHostAdapter, sizeof(BusLogic_HostAdapter_T));
  2.2814 +      HostAdapter->SCSI_Host = Host;
  2.2815 +      HostAdapter->HostNumber = Host->host_no;
  2.2816 +      Host->select_queue_depths = BusLogic_SelectQueueDepths;
  2.2817 +      /*
  2.2818 +	Add Host Adapter to the end of the list of registered BusLogic
  2.2819 +	Host Adapters.
  2.2820 +      */
  2.2821 +      BusLogic_RegisterHostAdapter(HostAdapter);
  2.2822 +      /*
  2.2823 +	Read the Host Adapter Configuration, Configure the Host Adapter,
  2.2824 +	Acquire the System Resources necessary to use the Host Adapter, then
  2.2825 +	Create the Initial CCBs, Initialize the Host Adapter, and finally
  2.2826 +	perform Target Device Inquiry.
  2.2827 +      */
  2.2828 +      if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
  2.2829 +	  BusLogic_ReportHostAdapterConfiguration(HostAdapter) &&
  2.2830 +	  BusLogic_AcquireResources(HostAdapter) &&
  2.2831 +	  BusLogic_CreateInitialCCBs(HostAdapter) &&
  2.2832 +	  BusLogic_InitializeHostAdapter(HostAdapter) &&
  2.2833 +	  BusLogic_TargetDeviceInquiry(HostAdapter))
  2.2834 +	{
  2.2835 +	  /*
  2.2836 +	    Initialization has been completed successfully.  Release and
  2.2837 +	    re-register usage of the I/O Address range so that the Model
  2.2838 +	    Name of the Host Adapter will appear, and initialize the SCSI
  2.2839 +	    Host structure.
  2.2840 +	  */
  2.2841 +	  release_region(HostAdapter->IO_Address,
  2.2842 +			 HostAdapter->AddressCount);
  2.2843 +	  request_region(HostAdapter->IO_Address,
  2.2844 +			 HostAdapter->AddressCount,
  2.2845 +			 HostAdapter->FullModelName);
  2.2846 +	  BusLogic_InitializeHostStructure(HostAdapter, Host);
  2.2847 +	  BusLogicHostAdapterCount++;
  2.2848 +	}
  2.2849 +      else
  2.2850 +	{
  2.2851 +	  /*
  2.2852 +	    An error occurred during Host Adapter Configuration Querying, Host
  2.2853 +	    Adapter Configuration, Resource Acquisition, CCB Creation, Host
  2.2854 +	    Adapter Initialization, or Target Device Inquiry, so remove Host
  2.2855 +	    Adapter from the list of registered BusLogic Host Adapters, destroy
  2.2856 +	    the CCBs, Release the System Resources, and Unregister the SCSI
  2.2857 +	    Host.
  2.2858 +	  */
  2.2859 +	  BusLogic_DestroyCCBs(HostAdapter);
  2.2860 +	  BusLogic_ReleaseResources(HostAdapter);
  2.2861 +	  BusLogic_UnregisterHostAdapter(HostAdapter);
  2.2862 +	  scsi_unregister(Host);
  2.2863 +	}
  2.2864 +    }
  2.2865 +  kfree(PrototypeHostAdapter);
  2.2866 +  kfree(BusLogic_ProbeInfoList);
  2.2867 +  BusLogic_ProbeInfoList = NULL;
  2.2868 +  return BusLogicHostAdapterCount;
  2.2869 +}
  2.2870 +
  2.2871 +
  2.2872 +/*
  2.2873 +  BusLogic_ReleaseHostAdapter releases all resources previously acquired to
  2.2874 +  support a specific Host Adapter, including the I/O Address range, and
  2.2875 +  unregisters the BusLogic Host Adapter.
  2.2876 +*/
  2.2877 +
  2.2878 +int BusLogic_ReleaseHostAdapter(SCSI_Host_T *Host)
  2.2879 +{
  2.2880 +  BusLogic_HostAdapter_T *HostAdapter =
  2.2881 +    (BusLogic_HostAdapter_T *) Host->hostdata;
  2.2882 +  /*
  2.2883 +    FlashPoint Host Adapters must first be released by the FlashPoint
  2.2884 +    SCCB Manager.
  2.2885 +  */
  2.2886 +  if (BusLogic_FlashPointHostAdapterP(HostAdapter))
  2.2887 +    FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle);
  2.2888 +  /*
  2.2889 +    Destroy the CCBs and release any system resources acquired to
  2.2890 +    support Host Adapter.
  2.2891 +  */
  2.2892 +  BusLogic_DestroyCCBs(HostAdapter);
  2.2893 +  BusLogic_ReleaseResources(HostAdapter);
  2.2894 +  /*
  2.2895 +    Release usage of the I/O Address range.
  2.2896 +  */
  2.2897 +  release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
  2.2898 +  /*
  2.2899 +    Remove Host Adapter from the list of registered BusLogic Host Adapters.
  2.2900 +  */
  2.2901 +  BusLogic_UnregisterHostAdapter(HostAdapter);
  2.2902 +  return 0;
  2.2903 +}
  2.2904 +
  2.2905 +
  2.2906 +/*
  2.2907 +  BusLogic_QueueCompletedCCB queues CCB for completion processing.
  2.2908 +*/
  2.2909 +
  2.2910 +static void BusLogic_QueueCompletedCCB(BusLogic_CCB_T *CCB)
  2.2911 +{
  2.2912 +  BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
  2.2913 +  CCB->Status = BusLogic_CCB_Completed;
  2.2914 +  CCB->Next = NULL;
  2.2915 +  if (HostAdapter->FirstCompletedCCB == NULL)
  2.2916 +    {
  2.2917 +      HostAdapter->FirstCompletedCCB = CCB;
  2.2918 +      HostAdapter->LastCompletedCCB = CCB;
  2.2919 +    }
  2.2920 +  else
  2.2921 +    {
  2.2922 +      HostAdapter->LastCompletedCCB->Next = CCB;
  2.2923 +      HostAdapter->LastCompletedCCB = CCB;
  2.2924 +    }
  2.2925 +  HostAdapter->ActiveCommands[CCB->TargetID]--;
  2.2926 +}
  2.2927 +
  2.2928 +
  2.2929 +/*
  2.2930 +  BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from
  2.2931 +  the Host Adapter Status and Target Device Status.
  2.2932 +*/
  2.2933 +
  2.2934 +static int BusLogic_ComputeResultCode(BusLogic_HostAdapter_T *HostAdapter,
  2.2935 +				      BusLogic_HostAdapterStatus_T
  2.2936 +					HostAdapterStatus,
  2.2937 +				      BusLogic_TargetDeviceStatus_T
  2.2938 +					TargetDeviceStatus)
  2.2939 +{
  2.2940 +  int HostStatus;
  2.2941 +  switch (HostAdapterStatus)
  2.2942 +    {
  2.2943 +    case BusLogic_CommandCompletedNormally:
  2.2944 +    case BusLogic_LinkedCommandCompleted:
  2.2945 +    case BusLogic_LinkedCommandCompletedWithFlag:
  2.2946 +      HostStatus = DID_OK;
  2.2947 +      break;
  2.2948 +    case BusLogic_SCSISelectionTimeout:
  2.2949 +      HostStatus = DID_TIME_OUT;
  2.2950 +      break;
  2.2951 +    case BusLogic_InvalidOutgoingMailboxActionCode:
  2.2952 +    case BusLogic_InvalidCommandOperationCode:
  2.2953 +    case BusLogic_InvalidCommandParameter:
  2.2954 +      BusLogic_Warning("BusLogic Driver Protocol Error 0x%02X\n",
  2.2955 +		       HostAdapter, HostAdapterStatus);
  2.2956 +    case BusLogic_DataUnderRun:
  2.2957 +    case BusLogic_DataOverRun:
  2.2958 +    case BusLogic_UnexpectedBusFree:
  2.2959 +    case BusLogic_LinkedCCBhasInvalidLUN:
  2.2960 +    case BusLogic_AutoRequestSenseFailed:
  2.2961 +    case BusLogic_TaggedQueuingMessageRejected:
  2.2962 +    case BusLogic_UnsupportedMessageReceived:
  2.2963 +    case BusLogic_HostAdapterHardwareFailed:
  2.2964 +    case BusLogic_TargetDeviceReconnectedImproperly:
  2.2965 +    case BusLogic_AbortQueueGenerated:
  2.2966 +    case BusLogic_HostAdapterSoftwareError:
  2.2967 +    case BusLogic_HostAdapterHardwareTimeoutError:
  2.2968 +    case BusLogic_SCSIParityErrorDetected:
  2.2969 +      HostStatus = DID_ERROR;
  2.2970 +      break;
  2.2971 +    case BusLogic_InvalidBusPhaseRequested:
  2.2972 +    case BusLogic_TargetFailedResponseToATN:
  2.2973 +    case BusLogic_HostAdapterAssertedRST:
  2.2974 +    case BusLogic_OtherDeviceAssertedRST:
  2.2975 +    case BusLogic_HostAdapterAssertedBusDeviceReset:
  2.2976 +      HostStatus = DID_RESET;
  2.2977 +      break;
  2.2978 +    default:
  2.2979 +      BusLogic_Warning("Unknown Host Adapter Status 0x%02X\n",
  2.2980 +		       HostAdapter, HostAdapterStatus);
  2.2981 +      HostStatus = DID_ERROR;
  2.2982 +      break;
  2.2983 +    }
  2.2984 +  return (HostStatus << 16) | TargetDeviceStatus;
  2.2985 +}
  2.2986 +
  2.2987 +
  2.2988 +/*
  2.2989 +  BusLogic_ScanIncomingMailboxes scans the Incoming Mailboxes saving any
  2.2990 +  Incoming Mailbox entries for completion processing.
  2.2991 +*/
  2.2992 +
  2.2993 +static void BusLogic_ScanIncomingMailboxes(BusLogic_HostAdapter_T *HostAdapter)
  2.2994 +{
  2.2995 +  /*
  2.2996 +    Scan through the Incoming Mailboxes in Strict Round Robin fashion, saving
  2.2997 +    any completed CCBs for further processing.  It is essential that for each
  2.2998 +    CCB and SCSI Command issued, command completion processing is performed
  2.2999 +    exactly once.  Therefore, only Incoming Mailboxes with completion code
  2.3000 +    Command Completed Without Error, Command Completed With Error, or Command
  2.3001 +    Aborted At Host Request are saved for completion processing.  When an
  2.3002 +    Incoming Mailbox has a completion code of Aborted Command Not Found, the
  2.3003 +    CCB had already completed or been aborted before the current Abort request
  2.3004 +    was processed, and so completion processing has already occurred and no
  2.3005 +    further action should be taken.
  2.3006 +  */
  2.3007 +  BusLogic_IncomingMailbox_T *NextIncomingMailbox =
  2.3008 +    HostAdapter->NextIncomingMailbox;
  2.3009 +  BusLogic_CompletionCode_T CompletionCode;
  2.3010 +  while ((CompletionCode = NextIncomingMailbox->CompletionCode) !=
  2.3011 +	 BusLogic_IncomingMailboxFree)
  2.3012 +    {
  2.3013 +      BusLogic_CCB_T *CCB = (BusLogic_CCB_T *)
  2.3014 +	Bus_to_Virtual(NextIncomingMailbox->CCB);
  2.3015 +      if (CompletionCode != BusLogic_AbortedCommandNotFound)
  2.3016 +	{
  2.3017 +	  if (CCB->Status == BusLogic_CCB_Active ||
  2.3018 +	      CCB->Status == BusLogic_CCB_Reset)
  2.3019 +	    {
  2.3020 +	      /*
  2.3021 +		Save the Completion Code for this CCB and queue the CCB
  2.3022 +		for completion processing.
  2.3023 +	      */
  2.3024 +	      CCB->CompletionCode = CompletionCode;
  2.3025 +	      BusLogic_QueueCompletedCCB(CCB);
  2.3026 +	    }
  2.3027 +	  else
  2.3028 +	    {
  2.3029 +	      /*
  2.3030 +		If a CCB ever appears in an Incoming Mailbox and is not marked
  2.3031 +		as status Active or Reset, then there is most likely a bug in
  2.3032 +		the Host Adapter firmware.
  2.3033 +	      */
  2.3034 +	      BusLogic_Warning("Illegal CCB #%ld status %d in "
  2.3035 +			       "Incoming Mailbox\n", HostAdapter,
  2.3036 +			       CCB->SerialNumber, CCB->Status);
  2.3037 +	    }
  2.3038 +	}
  2.3039 +      NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree;
  2.3040 +      if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
  2.3041 +	NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
  2.3042 +    }
  2.3043 +  HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
  2.3044 +}
  2.3045 +
  2.3046 +
  2.3047 +/*
  2.3048 +  BusLogic_ProcessCompletedCCBs iterates over the completed CCBs for Host
  2.3049 +  Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
  2.3050 +  calling the SCSI Subsystem Completion Routines.  The Host Adapter's Lock
  2.3051 +  should already have been acquired by the caller.
  2.3052 +*/
  2.3053 +
  2.3054 +static void BusLogic_ProcessCompletedCCBs(BusLogic_HostAdapter_T *HostAdapter)
  2.3055 +{
  2.3056 +  if (HostAdapter->ProcessCompletedCCBsActive) return;
  2.3057 +  HostAdapter->ProcessCompletedCCBsActive = true;
  2.3058 +  while (HostAdapter->FirstCompletedCCB != NULL)
  2.3059 +    {
  2.3060 +      BusLogic_CCB_T *CCB = HostAdapter->FirstCompletedCCB;
  2.3061 +      SCSI_Command_T *Command = CCB->Command;
  2.3062 +      HostAdapter->FirstCompletedCCB = CCB->Next;
  2.3063 +      if (HostAdapter->FirstCompletedCCB == NULL)
  2.3064 +	HostAdapter->LastCompletedCCB = NULL;
  2.3065 +      /*
  2.3066 +	Process the Completed CCB.
  2.3067 +      */
  2.3068 +      if (CCB->Opcode == BusLogic_BusDeviceReset)
  2.3069 +	{
  2.3070 +	  int TargetID = CCB->TargetID;
  2.3071 +	  BusLogic_Warning("Bus Device Reset CCB #%ld to Target "
  2.3072 +			   "%d Completed\n", HostAdapter,
  2.3073 +			   CCB->SerialNumber, TargetID);
  2.3074 +	  BusLogic_IncrementErrorCounter(
  2.3075 +	    &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted);
  2.3076 +	  HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
  2.3077 +	  HostAdapter->CommandsSinceReset[TargetID] = 0;
  2.3078 +	  HostAdapter->LastResetCompleted[TargetID] = jiffies;
  2.3079 +	  /*
  2.3080 +	    Place CCB back on the Host Adapter's free list.
  2.3081 +	  */
  2.3082 +	  BusLogic_DeallocateCCB(CCB);
  2.3083 +	  /*
  2.3084 +	    Bus Device Reset CCBs have the Command field non-NULL only when a
  2.3085 +	    Bus Device Reset was requested for a Command that did not have a
  2.3086 +	    currently active CCB in the Host Adapter (i.e., a Synchronous
  2.3087 +	    Bus Device Reset), and hence would not have its Completion Routine
  2.3088 +	    called otherwise.
  2.3089 +	  */
  2.3090 +	  while (Command != NULL)
  2.3091 +	    {
  2.3092 +	      SCSI_Command_T *NextCommand = Command->reset_chain;
  2.3093 +	      Command->reset_chain = NULL;
  2.3094 +	      Command->result = DID_RESET << 16;
  2.3095 +	      Command->scsi_done(Command);
  2.3096 +	      Command = NextCommand;
  2.3097 +	    }
  2.3098 +	  /*
  2.3099 +	    Iterate over the CCBs for this Host Adapter performing completion
  2.3100 +	    processing for any CCBs marked as Reset for this Target.
  2.3101 +	  */
  2.3102 +	  for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
  2.3103 +	    if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID)
  2.3104 +	      {
  2.3105 +		Command = CCB->Command;
  2.3106 +		BusLogic_DeallocateCCB(CCB);
  2.3107 +		HostAdapter->ActiveCommands[TargetID]--;
  2.3108 +		Command->result = DID_RESET << 16;
  2.3109 +		Command->scsi_done(Command);
  2.3110 +	      }
  2.3111 +	  HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
  2.3112 +	}
  2.3113 +      else
  2.3114 +	{
  2.3115 +	  /*
  2.3116 +	    Translate the Completion Code, Host Adapter Status, and Target
  2.3117 +	    Device Status into a SCSI Subsystem Result Code.
  2.3118 +	  */
  2.3119 +	  switch (CCB->CompletionCode)
  2.3120 +	    {
  2.3121 +	    case BusLogic_IncomingMailboxFree:
  2.3122 +	    case BusLogic_AbortedCommandNotFound:
  2.3123 +	    case BusLogic_InvalidCCB:
  2.3124 +	      BusLogic_Warning("CCB #%ld to Target %d Impossible State\n",
  2.3125 +			       HostAdapter, CCB->SerialNumber, CCB->TargetID);
  2.3126 +	      break;
  2.3127 +	    case BusLogic_CommandCompletedWithoutError:
  2.3128 +	      HostAdapter->TargetStatistics[CCB->TargetID]
  2.3129 +			   .CommandsCompleted++;
  2.3130 +	      HostAdapter->TargetFlags[CCB->TargetID]
  2.3131 +			   .CommandSuccessfulFlag = true;
  2.3132 +	      Command->result = DID_OK << 16;
  2.3133 +	      break;
  2.3134 +	    case BusLogic_CommandAbortedAtHostRequest:
  2.3135 +	      BusLogic_Warning("CCB #%ld to Target %d Aborted\n",
  2.3136 +			       HostAdapter, CCB->SerialNumber, CCB->TargetID);
  2.3137 +	      BusLogic_IncrementErrorCounter(
  2.3138 +		&HostAdapter->TargetStatistics[CCB->TargetID]
  2.3139 +			      .CommandAbortsCompleted);
  2.3140 +	      Command->result = DID_ABORT << 16;
  2.3141 +	      break;
  2.3142 +	    case BusLogic_CommandCompletedWithError:
  2.3143 +	      Command->result =
  2.3144 +		BusLogic_ComputeResultCode(HostAdapter,
  2.3145 +					   CCB->HostAdapterStatus,
  2.3146 +					   CCB->TargetDeviceStatus);
  2.3147 +	      if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
  2.3148 +		{
  2.3149 +		  HostAdapter->TargetStatistics[CCB->TargetID]
  2.3150 +			       .CommandsCompleted++;
  2.3151 +		  if (BusLogic_GlobalOptions.TraceErrors)
  2.3152 +		    {
  2.3153 +		      int i;
  2.3154 +		      BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
  2.3155 +				      "Adapter Status %02X "
  2.3156 +				      "Target Status %02X\n",
  2.3157 +				      HostAdapter, CCB->SerialNumber,
  2.3158 +				      CCB->TargetID, Command->result,
  2.3159 +				      CCB->HostAdapterStatus,
  2.3160 +				      CCB->TargetDeviceStatus);
  2.3161 +		      BusLogic_Notice("CDB   ", HostAdapter);
  2.3162 +		      for (i = 0; i < CCB->CDB_Length; i++)
  2.3163 +			BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]);
  2.3164 +		      BusLogic_Notice("\n", HostAdapter);
  2.3165 +		      BusLogic_Notice("Sense ", HostAdapter);
  2.3166 +		      for (i = 0; i < CCB->SenseDataLength; i++)
  2.3167 +			BusLogic_Notice(" %02X", HostAdapter,
  2.3168 +					Command->sense_buffer[i]);
  2.3169 +		      BusLogic_Notice("\n", HostAdapter);
  2.3170 +		    }
  2.3171 +		}
  2.3172 +	      break;
  2.3173 +	    }
  2.3174 +	  /*
  2.3175 +	    When an INQUIRY command completes normally, save the
  2.3176 +	    CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
  2.3177 +	    Wide Data Transfers Supported) bits.
  2.3178 +	  */
  2.3179 +	  if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 &&
  2.3180 +	      CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally)
  2.3181 +	    {
  2.3182 +	      BusLogic_TargetFlags_T *TargetFlags =
  2.3183 +		&HostAdapter->TargetFlags[CCB->TargetID];
  2.3184 +	      SCSI_Inquiry_T *InquiryResult =
  2.3185 +		(SCSI_Inquiry_T *) Command->request_buffer;
  2.3186 +	      TargetFlags->TargetExists = true;
  2.3187 +	      TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
  2.3188 +	      TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
  2.3189 +	    }
  2.3190 +	  /*
  2.3191 +	    Place CCB back on the Host Adapter's free list.
  2.3192 +	  */
  2.3193 +	  BusLogic_DeallocateCCB(CCB);
  2.3194 +	  /*
  2.3195 +	    Call the SCSI Command Completion Routine.
  2.3196 +	  */
  2.3197 +	  Command->scsi_done(Command);
  2.3198 +	}
  2.3199 +    }
  2.3200 +  HostAdapter->ProcessCompletedCCBsActive = false;
  2.3201 +}
  2.3202 +
  2.3203 +
  2.3204 +/*
  2.3205 +  BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
  2.3206 +  Adapters.
  2.3207 +*/
  2.3208 +
  2.3209 +static void BusLogic_InterruptHandler(int IRQ_Channel,
  2.3210 +				      void *DeviceIdentifier,
  2.3211 +				      Registers_T *InterruptRegisters)
  2.3212 +{
  2.3213 +  BusLogic_HostAdapter_T *HostAdapter =
  2.3214 +    (BusLogic_HostAdapter_T *) DeviceIdentifier;
  2.3215 +  ProcessorFlags_T ProcessorFlags;
  2.3216 +  /*
  2.3217 +    Acquire exclusive access to Host Adapter.
  2.3218 +  */
  2.3219 +  BusLogic_AcquireHostAdapterLockIH(HostAdapter, &ProcessorFlags);
  2.3220 +  /*
  2.3221 +    Handle Interrupts appropriately for each Host Adapter type.
  2.3222 +  */
  2.3223 +  if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
  2.3224 +    {
  2.3225 +      BusLogic_InterruptRegister_T InterruptRegister;
  2.3226 +      /*
  2.3227 +	Read the Host Adapter Interrupt Register.
  2.3228 +      */
  2.3229 +      InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
  2.3230 +      if (InterruptRegister.Bits.InterruptValid)
  2.3231 +	{
  2.3232 +	  /*
  2.3233 +	    Acknowledge the interrupt and reset the Host Adapter
  2.3234 +	    Interrupt Register.
  2.3235 +	  */
  2.3236 +	  BusLogic_InterruptReset(HostAdapter);
  2.3237 +	  /*
  2.3238 +	    Process valid External SCSI Bus Reset and Incoming Mailbox
  2.3239 +	    Loaded Interrupts.  Command Complete Interrupts are noted,
  2.3240 +	    and Outgoing Mailbox Available Interrupts are ignored, as
  2.3241 +	    they are never enabled.
  2.3242 +	  */
  2.3243 +	  if (InterruptRegister.Bits.ExternalBusReset)
  2.3244 +	    HostAdapter->HostAdapterExternalReset = true;
  2.3245 +	  else if (InterruptRegister.Bits.IncomingMailboxLoaded)
  2.3246 +	    BusLogic_ScanIncomingMailboxes(HostAdapter);
  2.3247 +	  else if (InterruptRegister.Bits.CommandComplete)
  2.3248 +	    HostAdapter->HostAdapterCommandCompleted = true;
  2.3249 +	}
  2.3250 +    }
  2.3251 +  else
  2.3252 +    {
  2.3253 +      /*
  2.3254 +	Check if there is a pending interrupt for this Host Adapter.
  2.3255 +      */
  2.3256 +      if (FlashPoint_InterruptPending(HostAdapter->CardHandle))
  2.3257 +	switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle))
  2.3258 +	  {
  2.3259 +	  case FlashPoint_NormalInterrupt:
  2.3260 +	    break;
  2.3261 +	  case FlashPoint_ExternalBusReset:
  2.3262 +	    HostAdapter->HostAdapterExternalReset = true;
  2.3263 +	    break;
  2.3264 +	  case FlashPoint_InternalError:
  2.3265 +	    BusLogic_Warning("Internal FlashPoint Error detected"
  2.3266 +			     " - Resetting Host Adapter\n", HostAdapter);
  2.3267 +	    HostAdapter->HostAdapterInternalError = true;
  2.3268 +	    break;
  2.3269 +	  }
  2.3270 +    }
  2.3271 +  /*
  2.3272 +    Process any completed CCBs.
  2.3273 +  */
  2.3274 +  if (HostAdapter->FirstCompletedCCB != NULL)
  2.3275 +    BusLogic_ProcessCompletedCCBs(HostAdapter);
  2.3276 +  /*
  2.3277 +    Reset the Host Adapter if requested.
  2.3278 +  */
  2.3279 +  if (HostAdapter->HostAdapterExternalReset ||
  2.3280 +      HostAdapter->HostAdapterInternalError)
  2.3281 +    {
  2.3282 +      BusLogic_ResetHostAdapter(HostAdapter, NULL, 0);
  2.3283 +      HostAdapter->HostAdapterExternalReset = false;
  2.3284 +      HostAdapter->HostAdapterInternalError = false;
  2.3285 +#if 0 /* XEN */
  2.3286 +      scsi_mark_host_reset(HostAdapter->SCSI_Host);
  2.3287 +#endif
  2.3288 +    }
  2.3289 +  /*
  2.3290 +    Release exclusive access to Host Adapter.
  2.3291 +  */
  2.3292 +  BusLogic_ReleaseHostAdapterLockIH(HostAdapter, &ProcessorFlags);
  2.3293 +}
  2.3294 +
  2.3295 +
  2.3296 +/*
  2.3297 +  BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
  2.3298 +  Mailbox for execution by Host Adapter.  The Host Adapter's Lock should
  2.3299 +  already have been acquired by the caller.
  2.3300 +*/
  2.3301 +
  2.3302 +static boolean BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T
  2.3303 +					       *HostAdapter,
  2.3304 +					     BusLogic_ActionCode_T ActionCode,
  2.3305 +					     BusLogic_CCB_T *CCB)
  2.3306 +{
  2.3307 +  BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
  2.3308 +  NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
  2.3309 +  if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
  2.3310 +    {
  2.3311 +      CCB->Status = BusLogic_CCB_Active;
  2.3312 +      /*
  2.3313 +	The CCB field must be written before the Action Code field since
  2.3314 +	the Host Adapter is operating asynchronously and the locking code
  2.3315 +	does not protect against simultaneous access by the Host Adapter.
  2.3316 +      */
  2.3317 +      NextOutgoingMailbox->CCB = Virtual_to_Bus(CCB);
  2.3318 +      NextOutgoingMailbox->ActionCode = ActionCode;
  2.3319 +      BusLogic_StartMailboxCommand(HostAdapter);
  2.3320 +      if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
  2.3321 +	NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
  2.3322 +      HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
  2.3323 +      if (ActionCode == BusLogic_MailboxStartCommand)
  2.3324 +	{
  2.3325 +	  HostAdapter->ActiveCommands[CCB->TargetID]++;
  2.3326 +	  if (CCB->Opcode != BusLogic_BusDeviceReset)
  2.3327 +	    HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++;
  2.3328 +	}
  2.3329 +      return true;
  2.3330 +    }
  2.3331 +  return false;
  2.3332 +}
  2.3333 +
  2.3334 +
  2.3335 +/*
  2.3336 +  BusLogic_QueueCommand creates a CCB for Command and places it into an
  2.3337 +  Outgoing Mailbox for execution by the associated Host Adapter.
  2.3338 +*/
  2.3339 +
  2.3340 +int BusLogic_QueueCommand(SCSI_Command_T *Command,
  2.3341 +			  void (*CompletionRoutine)(SCSI_Command_T *))
  2.3342 +{
  2.3343 +  BusLogic_HostAdapter_T *HostAdapter =
  2.3344 +    (BusLogic_HostAdapter_T *) Command->host->hostdata;
  2.3345 +  BusLogic_TargetFlags_T *TargetFlags =
  2.3346 +    &HostAdapter->TargetFlags[Command->target];
  2.3347 +  BusLogic_TargetStatistics_T *TargetStatistics =
  2.3348 +    HostAdapter->TargetStatistics;
  2.3349 +  unsigned char *CDB = Command->cmnd;
  2.3350 +  int CDB_Length = Command->cmd_len;
  2.3351 +  int TargetID = Command->target;
  2.3352 +  int LogicalUnit = Command->lun;
  2.3353 +  void *BufferPointer = Command->request_buffer;
  2.3354 +  int BufferLength = Command->request_bufflen;
  2.3355 +  int SegmentCount = Command->use_sg;
  2.3356 +  ProcessorFlags_T ProcessorFlags;
  2.3357 +  BusLogic_CCB_T *CCB;
  2.3358 +  /*
  2.3359 +    SCSI REQUEST_SENSE commands will be executed automatically by the Host
  2.3360 +    Adapter for any errors, so they should not be executed explicitly unless
  2.3361 +    the Sense Data is zero indicating that no error occurred.
  2.3362 +  */
  2.3363 +  if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0)
  2.3364 +    {
  2.3365 +      Command->result = DID_OK << 16;
  2.3366 +      CompletionRoutine(Command);
  2.3367 +      return 0;
  2.3368 +    }
  2.3369 +  /*
  2.3370 +    Acquire exclusive access to Host Adapter.
  2.3371 +  */
  2.3372 +  BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
  2.3373 +  /*
  2.3374 +    Allocate a CCB from the Host Adapter's free list.  In the unlikely event
  2.3375 +    that there are none available and memory allocation fails, wait 1 second
  2.3376 +    and try again.  If that fails, the Host Adapter is probably hung so signal
  2.3377 +    an error as a Host Adapter Hard Reset should be initiated soon.
  2.3378 +  */
  2.3379 +  CCB = BusLogic_AllocateCCB(HostAdapter);
  2.3380 +  if (CCB == NULL)
  2.3381 +    {
  2.3382 +      BusLogic_Delay(1);
  2.3383 +      CCB = BusLogic_AllocateCCB(HostAdapter);
  2.3384 +      if (CCB == NULL)
  2.3385 +	{
  2.3386 +	  Command->result = DID_ERROR << 16;
  2.3387 +	  CompletionRoutine(Command);
  2.3388 +	  goto Done;
  2.3389 +	}
  2.3390 +    }
  2.3391 +  /*
  2.3392 +    Initialize the fields in the BusLogic Command Control Block (CCB).
  2.3393 +  */
  2.3394 +  if (SegmentCount == 0)
  2.3395 +    {
  2.3396 +      CCB->Opcode = BusLogic_InitiatorCCB;
  2.3397 +      CCB->DataLength = BufferLength;
  2.3398 +      CCB->DataPointer = Virtual_to_Bus(BufferPointer);
  2.3399 +    }
  2.3400 +  else
  2.3401 +    {
  2.3402 +      SCSI_ScatterList_T *ScatterList = (SCSI_ScatterList_T *) BufferPointer;
  2.3403 +      int Segment;
  2.3404 +      CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
  2.3405 +      CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T);
  2.3406 +      if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
  2.3407 +	CCB->DataPointer = Virtual_to_Bus(CCB->ScatterGatherList);
  2.3408 +      else CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
  2.3409 +      for (Segment = 0; Segment < SegmentCount; Segment++)
  2.3410 +	{
  2.3411 +	  CCB->ScatterGatherList[Segment].SegmentByteCount =
  2.3412 +	    ScatterList[Segment].length;
  2.3413 +	  CCB->ScatterGatherList[Segment].SegmentDataPointer =
  2.3414 +	    Virtual_to_Bus(ScatterList[Segment].address);
  2.3415 +	}
  2.3416 +    }
  2.3417 +  switch (CDB[0])
  2.3418 +    {
  2.3419 +    case READ_6:
  2.3420 +    case READ_10:
  2.3421 +      CCB->DataDirection = BusLogic_DataInLengthChecked;
  2.3422 +      TargetStatistics[TargetID].ReadCommands++;
  2.3423 +      BusLogic_IncrementByteCounter(
  2.3424 +	&TargetStatistics[TargetID].TotalBytesRead, BufferLength);
  2.3425 +      BusLogic_IncrementSizeBucket(
  2.3426 +	TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength);
  2.3427 +      break;
  2.3428 +    case WRITE_6:
  2.3429 +    case WRITE_10:
  2.3430 +      CCB->DataDirection = BusLogic_DataOutLengthChecked;
  2.3431 +      TargetStatistics[TargetID].WriteCommands++;
  2.3432 +      BusLogic_IncrementByteCounter(
  2.3433 +	&TargetStatistics[TargetID].TotalBytesWritten, BufferLength);
  2.3434 +      BusLogic_IncrementSizeBucket(
  2.3435 +	TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength);
  2.3436 +      break;
  2.3437 +    default:
  2.3438 +      CCB->DataDirection = BusLogic_UncheckedDataTransfer;
  2.3439 +      break;
  2.3440 +    }
  2.3441 +  CCB->CDB_Length = CDB_Length;
  2.3442 +  CCB->SenseDataLength = sizeof(Command->sense_buffer);
  2.3443 +  CCB->HostAdapterStatus = 0;
  2.3444 +  CCB->TargetDeviceStatus = 0;
  2.3445 +  CCB->TargetID = TargetID;
  2.3446 +  CCB->LogicalUnit = LogicalUnit;
  2.3447 +  CCB->TagEnable = false;
  2.3448 +  CCB->LegacyTagEnable = false;
  2.3449 +  /*
  2.3450 +    BusLogic recommends that after a Reset the first couple of commands that
  2.3451 +    are sent to a Target Device be sent in a non Tagged Queue fashion so that
  2.3452 +    the Host Adapter and Target Device can establish Synchronous and Wide
  2.3453 +    Transfer before Queue Tag messages can interfere with the Synchronous and
  2.3454 +    Wide Negotiation messages.  By waiting to enable Tagged Queuing until after
  2.3455 +    the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is
  2.3456 +    assured that after a Reset any pending commands are requeued before Tagged
  2.3457 +    Queuing is enabled and that the Tagged Queuing message will not occur while
  2.3458 +    the partition table is being printed.  In addition, some devices do not
  2.3459 +    properly handle the transition from non-tagged to tagged commands, so it is
  2.3460 +    necessary to wait until there are no pending commands for a target device
  2.3461 +    before queuing tagged commands.
  2.3462 +  */
  2.3463 +  if (HostAdapter->CommandsSinceReset[TargetID]++ >=
  2.3464 +	BusLogic_MaxTaggedQueueDepth &&
  2.3465 +      !TargetFlags->TaggedQueuingActive &&
  2.3466 +      HostAdapter->ActiveCommands[TargetID] == 0 &&
  2.3467 +      TargetFlags->TaggedQueuingSupported &&
  2.3468 +      (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
  2.3469 +    {
  2.3470 +      TargetFlags->TaggedQueuingActive = true;
  2.3471 +      BusLogic_Notice("Tagged Queuing now active for Target %d\n",
  2.3472 +		      HostAdapter, TargetID);
  2.3473 +    }
  2.3474 +  if (TargetFlags->TaggedQueuingActive)
  2.3475 +    {
  2.3476 +      BusLogic_QueueTag_T QueueTag = BusLogic_SimpleQueueTag;
  2.3477 +      /*
  2.3478 +	When using Tagged Queuing with Simple Queue Tags, it appears that disk
  2.3479 +	drive controllers do not guarantee that a queued command will not
  2.3480 +	remain in a disconnected state indefinitely if commands that read or
  2.3481 +	write nearer the head position continue to arrive without interruption.
  2.3482 +	Therefore, for each Target Device this driver keeps track of the last
  2.3483 +	time either the queue was empty or an Ordered Queue Tag was issued.  If
  2.3484 +	more than 4 seconds (one fifth of the 20 second disk timeout) have
  2.3485 +	elapsed since this last sequence point, this command will be issued
  2.3486 +	with an Ordered Queue Tag rather than a Simple Queue Tag, which forces
  2.3487 +	the Target Device to complete all previously queued commands before
  2.3488 +	this command may be executed.
  2.3489 +      */
  2.3490 +      if (HostAdapter->ActiveCommands[TargetID] == 0)
  2.3491 +	HostAdapter->LastSequencePoint[TargetID] = jiffies;
  2.3492 +      else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 4*HZ)
  2.3493 +	{
  2.3494 +	  HostAdapter->LastSequencePoint[TargetID] = jiffies;
  2.3495 +	  QueueTag = BusLogic_OrderedQueueTag;
  2.3496 +	}
  2.3497 +      if (HostAdapter->ExtendedLUNSupport)
  2.3498 +	{
  2.3499 +	  CCB->TagEnable = true;
  2.3500 +	  CCB->QueueTag = QueueTag;
  2.3501 +	}
  2.3502 +      else
  2.3503 +	{
  2.3504 +	  CCB->LegacyTagEnable = true;
  2.3505 +	  CCB->LegacyQueueTag = QueueTag;
  2.3506 +	}
  2.3507 +    }
  2.3508 +  memcpy(CCB->CDB, CDB, CDB_Length);
  2.3509 +  CCB->SenseDataPointer = Virtual_to_Bus(&Command->sense_buffer);
  2.3510 +  CCB->Command = Command;
  2.3511 +  Command->scsi_done = CompletionRoutine;
  2.3512 +  if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
  2.3513 +    {
  2.3514 +      /*
  2.3515 +	Place the CCB in an Outgoing Mailbox.  The higher levels of the SCSI
  2.3516 +	Subsystem should not attempt to queue more commands than can be placed
  2.3517 +	in Outgoing Mailboxes, so there should always be one free.  In the
  2.3518 +	unlikely event that there are none available, wait 1 second and try
  2.3519 +	again.  If that fails, the Host Adapter is probably hung so signal an
  2.3520 +	error as a Host Adapter Hard Reset should be initiated soon.
  2.3521 +      */
  2.3522 +      if (!BusLogic_WriteOutgoingMailbox(
  2.3523 +	     HostAdapter, BusLogic_MailboxStartCommand, CCB))
  2.3524 +	{
  2.3525 +	  BusLogic_Warning("Unable to write Outgoing Mailbox - "
  2.3526 +			   "Pausing for 1 second\n", HostAdapter);
  2.3527 +	  BusLogic_Delay(1);
  2.3528 +	  if (!BusLogic_WriteOutgoingMailbox(
  2.3529 +		 HostAdapter, BusLogic_MailboxStartCommand, CCB))
  2.3530 +	    {
  2.3531 +	      BusLogic_Warning("Still unable to write Outgoing Mailbox - "
  2.3532 +			       "Host Adapter Dead?\n", HostAdapter);
  2.3533 +	      BusLogic_DeallocateCCB(CCB);
  2.3534 +	      Command->result = DID_ERROR << 16;
  2.3535 +	      Command->scsi_done(Command);
  2.3536 +	    }
  2.3537 +	}
  2.3538 +    }
  2.3539 +  else
  2.3540 +    {
  2.3541 +      /*
  2.3542 +	Call the FlashPoint SCCB Manager to start execution of the CCB.
  2.3543 +      */
  2.3544 +      CCB->Status = BusLogic_CCB_Active;
  2.3545 +      HostAdapter->ActiveCommands[TargetID]++;
  2.3546 +      TargetStatistics[TargetID].CommandsAttempted++;
  2.3547 +      FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
  2.3548 +      /*
  2.3549 +	The Command may have already completed and BusLogic_QueueCompletedCCB
  2.3550 +	been called, or it may still be pending.
  2.3551 +      */
  2.3552 +      if (CCB->Status == BusLogic_CCB_Completed)
  2.3553 +	BusLogic_ProcessCompletedCCBs(HostAdapter);
  2.3554 +    }
  2.3555 +  /*
  2.3556 +    Release exclusive access to Host Adapter.
  2.3557 +  */
  2.3558 +Done:
  2.3559 +  BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
  2.3560 +  return 0;
  2.3561 +}
  2.3562 +
  2.3563 +
  2.3564 +/*
  2.3565 +  BusLogic_AbortCommand aborts Command if possible.
  2.3566 +*/
  2.3567 +
  2.3568 +int BusLogic_AbortCommand(SCSI_Command_T *Command)
  2.3569 +{
  2.3570 +  BusLogic_HostAdapter_T *HostAdapter =
  2.3571 +    (BusLogic_HostAdapter_T *) Command->host->hostdata;
  2.3572 +  int TargetID = Command->target;
  2.3573 +  ProcessorFlags_T ProcessorFlags;
  2.3574 +  BusLogic_CCB_T *CCB;
  2.3575 +  int Result;
  2.3576 +  BusLogic_IncrementErrorCounter(
  2.3577 +    &HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested);
  2.3578 +  /*
  2.3579 +    Acquire exclusive access to Host Adapter.
  2.3580 +  */
  2.3581 +  BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
  2.3582 +  /*
  2.3583 +    If this Command has already completed, then no Abort is necessary.
  2.3584 +  */
  2.3585 +  if (Command->serial_number != Command->serial_number_at_timeout)
  2.3586 +    {
  2.3587 +      BusLogic_Warning("Unable to Abort Command to Target %d - "
  2.3588 +		       "Already Completed\n", HostAdapter, TargetID);
  2.3589 +      Result = SCSI_ABORT_NOT_RUNNING;
  2.3590 +      goto Done;
  2.3591 +    }
  2.3592 +  /*
  2.3593 +    Attempt to find an Active CCB for this Command.  If no Active CCB for this
  2.3594 +    Command is found, then no Abort is necessary.
  2.3595 +  */
  2.3596 +  for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
  2.3597 +    if (CCB->Command == Command) break;
  2.3598 +  if (CCB == NULL)
  2.3599 +    {
  2.3600 +      BusLogic_Warning("Unable to Abort Command to Target %d - "
  2.3601 +		       "No CCB Found\n", HostAdapter, TargetID);
  2.3602 +      Result = SCSI_ABORT_NOT_RUNNING;
  2.3603 +      goto Done;
  2.3604 +    }
  2.3605 +  else if (CCB->Status == BusLogic_CCB_Completed)
  2.3606 +    {
  2.3607 +      BusLogic_Warning("Unable to Abort Command to Target %d - "
  2.3608 +		       "CCB Completed\n", HostAdapter, TargetID);
  2.3609 +      Result = SCSI_ABORT_NOT_RUNNING;
  2.3610 +      goto Done;
  2.3611 +    }
  2.3612 +  else if (CCB->Status == BusLogic_CCB_Reset)
  2.3613 +    {
  2.3614 +      BusLogic_Warning("Unable to Abort Command to Target %d - "
  2.3615 +		       "CCB Reset\n", HostAdapter, TargetID);
  2.3616 +      Result = SCSI_ABORT_PENDING;
  2.3617 +      goto Done;
  2.3618 +    }
  2.3619 +  if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
  2.3620 +    {
  2.3621 +      /*
  2.3622 +	Attempt to Abort this CCB.  MultiMaster Firmware versions prior to 5.xx
  2.3623 +	do not generate Abort Tag messages, but only generate the non-tagged
  2.3624 +	Abort message.  Since non-tagged commands are not sent by the Host
  2.3625 +	Adapter until the queue of outstanding tagged commands has completed,
  2.3626 +	and the Abort message is treated as a non-tagged command, it is
  2.3627 +	effectively impossible to abort commands when Tagged Queuing is active.
  2.3628 +	Firmware version 5.xx does generate Abort Tag messages, so it is
  2.3629 +	possible to abort commands when Tagged Queuing is active.
  2.3630 +      */
  2.3631 +      if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
  2.3632 +	  HostAdapter->FirmwareVersion[0] < '5')
  2.3633 +	{
  2.3634 +	  BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
  2.3635 +			   "Abort Tag Not Supported\n",
  2.3636 +			   HostAdapter, CCB->SerialNumber, TargetID);
  2.3637 +	  Result = SCSI_ABORT_SNOOZE;
  2.3638 +	}
  2.3639 +      else if (BusLogic_WriteOutgoingMailbox(
  2.3640 +		 HostAdapter, BusLogic_MailboxAbortCommand, CCB))
  2.3641 +	{
  2.3642 +	  BusLogic_Warning("Aborting CCB #%ld to Target %d\n",
  2.3643 +			   HostAdapter, CCB->SerialNumber, TargetID);
  2.3644 +	  BusLogic_IncrementErrorCounter(
  2.3645 +	    &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
  2.3646 +	  Result = SCSI_ABORT_PENDING;
  2.3647 +	}
  2.3648 +      else
  2.3649 +	{
  2.3650 +	  BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
  2.3651 +			   "No Outgoing Mailboxes\n",
  2.3652 +			    HostAdapter, CCB->SerialNumber, TargetID);
  2.3653 +	  Result = SCSI_ABORT_BUSY;
  2.3654 +	}
  2.3655 +    }
  2.3656 +  else
  2.3657 +    {
  2.3658 +      /*
  2.3659 +	Call the FlashPoint SCCB Manager to abort execution of the CCB.
  2.3660 +      */
  2.3661 +      BusLogic_Warning("Aborting CCB #%ld to Target %d\n",
  2.3662 +		       HostAdapter, CCB->SerialNumber, TargetID);
  2.3663 +      BusLogic_IncrementErrorCounter(
  2.3664 +	&HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
  2.3665 +      FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB);
  2.3666 +      /*
  2.3667 +	The Abort may have already been completed and
  2.3668 +	BusLogic_QueueCompletedCCB been called, or it
  2.3669 +	may still be pending.
  2.3670 +      */
  2.3671 +      Result = SCSI_ABORT_PENDING;
  2.3672 +      if (CCB->Status == BusLogic_CCB_Completed)
  2.3673 +	{
  2.3674 +	  BusLogic_ProcessCompletedCCBs(HostAdapter);
  2.3675 +	  Result = SCSI_ABORT_SUCCESS;
  2.3676 +	}
  2.3677 +    }
  2.3678 +  /*
  2.3679 +    Release exclusive access to Host Adapter.
  2.3680 +  */
  2.3681 +Done:
  2.3682 +  BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
  2.3683 +  return Result;
  2.3684 +}
  2.3685 +
  2.3686 +
  2.3687 +/*
  2.3688 +  BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
  2.3689 +  currently executing SCSI Commands as having been Reset.
  2.3690 +*/
  2.3691 +
  2.3692 +static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter,
  2.3693 +				     SCSI_Command_T *Command,
  2.3694 +				     unsigned int ResetFlags)
  2.3695 +{
  2.3696 +  ProcessorFlags_T ProcessorFlags;
  2.3697 +  BusLogic_CCB_T *CCB;
  2.3698 +  int TargetID, Result;
  2.3699 +  boolean HardReset;
  2.3700 +  if (HostAdapter->HostAdapterExternalReset)
  2.3701 +    {
  2.3702 +      BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets);
  2.3703 +      HardReset = false;
  2.3704 +    }
  2.3705 +  else if (HostAdapter->HostAdapterInternalError)
  2.3706 +    {
  2.3707 +      BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors);
  2.3708 +      HardReset = true;
  2.3709 +    }
  2.3710 +  else
  2.3711 +    {
  2.3712 +      BusLogic_IncrementErrorCounter(
  2.3713 +	&HostAdapter->TargetStatistics[Command->target]
  2.3714 +		      .HostAdapterResetsRequested);
  2.3715 +      HardReset = true;
  2.3716 +    }
  2.3717 +  /*
  2.3718 +    Acquire exclusive access to Host Adapter.
  2.3719 +  */
  2.3720 +  BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
  2.3721 +  /*
  2.3722 +    If this is an Asynchronous Reset and this Command has already completed,
  2.3723 +    then no Reset is necessary.
  2.3724 +  */
  2.3725 +  if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
  2.3726 +    {
  2.3727 +      TargetID = Command->target;
  2.3728 +      if (Command->serial_number != Command->serial_number_at_timeout)
  2.3729 +	{
  2.3730 +	  BusLogic_Warning("Unable to Reset Command to Target %d - "
  2.3731 +			   "Already Completed or Reset\n",
  2.3732 +			   HostAdapter, TargetID);
  2.3733 +	  Result = SCSI_RESET_NOT_RUNNING;
  2.3734 +	  goto Done;
  2.3735 +      }
  2.3736 +      for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
  2.3737 +	if (CCB->Command == Command) break;
  2.3738 +      if (CCB == NULL)
  2.3739 +	{
  2.3740 +	  BusLogic_Warning("Unable to Reset Command to Target %d - "
  2.3741 +			   "No CCB Found\n", HostAdapter, TargetID);
  2.3742 +	  Result = SCSI_RESET_NOT_RUNNING;
  2.3743 +	  goto Done;
  2.3744 +	}
  2.3745 +      else if (CCB->Status == BusLogic_CCB_Completed)
  2.3746 +	{
  2.3747 +	  BusLogic_Warning("Unable to Reset Command to Target %d - "
  2.3748 +			   "CCB Completed\n", HostAdapter, TargetID);
  2.3749 +	  Result = SCSI_RESET_NOT_RUNNING;
  2.3750 +	  goto Done;
  2.3751 +	}
  2.3752 +      else if (CCB->Status == BusLogic_CCB_Reset &&
  2.3753 +	       HostAdapter->BusDeviceResetPendingCCB[TargetID] == NULL)
  2.3754 +	{
  2.3755 +	  BusLogic_Warning("Unable to Reset Command to Target %d - "
  2.3756 +			   "Reset Pending\n", HostAdapter, TargetID);
  2.3757 +	  Result = SCSI_RESET_PENDING;
  2.3758 +	  goto Done;
  2.3759 +	}
  2.3760 +    }
  2.3761 +  if (Command == NULL)
  2.3762 +    {
  2.3763 +      if (HostAdapter->HostAdapterInternalError)
  2.3764 +	BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n",
  2.3765 +			 HostAdapter, HostAdapter->FullModelName);
  2.3766 +      else BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n",
  2.3767 +			    HostAdapter, HostAdapter->FullModelName);
  2.3768 +    }
  2.3769 +  else
  2.3770 +    {
  2.3771 +      BusLogic_Warning("Resetting %s due to Target %d\n", HostAdapter,
  2.3772 +		       HostAdapter->FullModelName, Command->target);
  2.3773 +      BusLogic_IncrementErrorCounter(
  2.3774 +	&HostAdapter->TargetStatistics[Command->target]
  2.3775 +		      .HostAdapterResetsAttempted);
  2.3776 +    }
  2.3777 +  /*
  2.3778 +    Attempt to Reset and Reinitialize the Host Adapter.
  2.3779 +  */
  2.3780 +  if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) &&
  2.3781 +	BusLogic_InitializeHostAdapter(HostAdapter)))
  2.3782 +    {
  2.3783 +      BusLogic_Error("Resetting %s Failed\n", HostAdapter,
  2.3784 +		     HostAdapter->FullModelName);
  2.3785 +      Result = SCSI_RESET_ERROR;
  2.3786 +      goto Done;
  2.3787 +    }
  2.3788 +  if (Command != NULL)
  2.3789 +    BusLogic_IncrementErrorCounter(
  2.3790 +      &HostAdapter->TargetStatistics[Command->target]
  2.3791 +		    .HostAdapterResetsCompleted);
  2.3792 +  /*
  2.3793 +    Mark all currently executing CCBs as having been Reset.
  2.3794 +  */
  2.3795 +  for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
  2.3796 +    if (CCB->Status == BusLogic_CCB_Active)
  2.3797 +      CCB->Status = BusLogic_CCB_Reset;
  2.3798 +  /*
  2.3799 +    Wait a few seconds between the Host Adapter Hard Reset which initiates
  2.3800 +    a SCSI Bus Reset and issuing any SCSI Commands.  Some SCSI devices get
  2.3801 +    confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
  2.3802 +    Note that a timer interrupt may occur here, but all active CCBs have
  2.3803 +    already been marked Reset and so a reentrant call will return Pending.
  2.3804 +  */
  2.3805 +  if (HardReset)
  2.3806 +    BusLogic_Delay(HostAdapter->BusSettleTime);
  2.3807 +  /*
  2.3808 +    If this is a Synchronous Reset, perform completion processing for
  2.3809 +    the Command being Reset.
  2.3810 +  */
  2.3811 +  if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
  2.3812 +    {
  2.3813 +      Command->result = DID_RESET << 16;
  2.3814 +      Command->scsi_done(Command);
  2.3815 +    }
  2.3816 +  /*
  2.3817 +    Perform completion processing for all CCBs marked as Reset.
  2.3818 +  */
  2.3819 +  for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
  2.3820 +    if (CCB->Status == BusLogic_CCB_Reset)
  2.3821 +      {
  2.3822 +	Command = CCB->Command;
  2.3823 +	BusLogic_DeallocateCCB(CCB);
  2.3824 +	while (Command != NULL)
  2.3825 +	  {
  2.3826 +	    SCSI_Command_T *NextCommand = Command->reset_chain;
  2.3827 +	    Command->reset_chain = NULL;
  2.3828 +	    Command->result = DID_RESET << 16;
  2.3829 +	    Command->scsi_done(Command);
  2.3830 +	    Command = NextCommand;
  2.3831 +	  }
  2.3832 +      }
  2.3833 +  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.3834 +    {
  2.3835 +      HostAdapter->LastResetAttempted[TargetID] = jiffies;
  2.3836 +      HostAdapter->LastResetCompleted[TargetID] = jiffies;
  2.3837 +    }
  2.3838 +  Result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET;
  2.3839 +  /*
  2.3840 +    Release exclusive access to Host Adapter.
  2.3841 +  */
  2.3842 +Done:
  2.3843 +  BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
  2.3844 +  return Result;
  2.3845 +}
  2.3846 +
  2.3847 +
  2.3848 +/*
  2.3849 +  BusLogic_SendBusDeviceReset sends a Bus Device Reset to the Target
  2.3850 +  Device associated with Command.
  2.3851 +*/
  2.3852 +
  2.3853 +static int BusLogic_SendBusDeviceReset(BusLogic_HostAdapter_T *HostAdapter,
  2.3854 +				       SCSI_Command_T *Command,
  2.3855 +				       unsigned int ResetFlags)
  2.3856 +{
  2.3857 +  int TargetID = Command->target;
  2.3858 +  BusLogic_CCB_T *CCB, *XCCB;
  2.3859 +  ProcessorFlags_T ProcessorFlags;
  2.3860 +  int Result = -1;
  2.3861 +  BusLogic_IncrementErrorCounter(
  2.3862 +    &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsRequested);
  2.3863 +  /*
  2.3864 +    Acquire exclusive access to Host Adapter.
  2.3865 +  */
  2.3866 +  BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
  2.3867 +  /*
  2.3868 +    If this is an Asynchronous Reset and this Command has already completed,
  2.3869 +    then no Reset is necessary.
  2.3870 +  */
  2.3871 +  if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
  2.3872 +    {
  2.3873 +      if (Command->serial_number != Command->serial_number_at_timeout)
  2.3874 +	{
  2.3875 +	  BusLogic_Warning("Unable to Reset Command to Target %d - "
  2.3876 +			   "Already Completed\n", HostAdapter, TargetID);
  2.3877 +	  Result = SCSI_RESET_NOT_RUNNING;
  2.3878 +	  goto Done;
  2.3879 +	}
  2.3880 +      for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
  2.3881 +	if (CCB->Command == Command) break;
  2.3882 +      if (CCB == NULL)
  2.3883 +	{
  2.3884 +	  BusLogic_Warning("Unable to Reset Command to Target %d - "
  2.3885 +			   "No CCB Found\n", HostAdapter, TargetID);
  2.3886 +	  Result = SCSI_RESET_NOT_RUNNING;
  2.3887 +	  goto Done;
  2.3888 +	}
  2.3889 +      else if (CCB->Status == BusLogic_CCB_Completed)
  2.3890 +	{
  2.3891 +	  BusLogic_Warning("Unable to Reset Command to Target %d - "
  2.3892 +			   "CCB Completed\n", HostAdapter, TargetID);
  2.3893 +	  Result = SCSI_RESET_NOT_RUNNING;
  2.3894 +	  goto Done;
  2.3895 +	}
  2.3896 +      else if (CCB->Status == BusLogic_CCB_Reset)
  2.3897 +	{
  2.3898 +	  BusLogic_Warning("Unable to Reset Command to Target %d - "
  2.3899 +			   "Reset Pending\n", HostAdapter, TargetID);
  2.3900 +	  Result = SCSI_RESET_PENDING;
  2.3901 +	  goto Done;
  2.3902 +	}
  2.3903 +      else if (HostAdapter->BusDeviceResetPendingCCB[TargetID] != NULL)
  2.3904 +	{
  2.3905 +	  BusLogic_Warning("Bus Device Reset already pending to Target %d\n",
  2.3906 +			   HostAdapter, TargetID);
  2.3907 +	  goto Done;
  2.3908 +	}
  2.3909 +    }
  2.3910 +  /*
  2.3911 +    If this is a Synchronous Reset and a Bus Device Reset is already pending
  2.3912 +    for this Target Device, do not send a second one.  Add this Command to
  2.3913 +    the list of Commands for which completion processing must be performed
  2.3914 +    when the Bus Device Reset CCB completes.
  2.3915 +  */
  2.3916 +  if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
  2.3917 +    if ((CCB = HostAdapter->BusDeviceResetPendingCCB[TargetID]) != NULL)
  2.3918 +      {
  2.3919 +	Command->reset_chain = CCB->Command;
  2.3920 +	CCB->Command = Command;
  2.3921 +	BusLogic_Warning("Unable to Reset Command to Target %d - "
  2.3922 +			 "Reset Pending\n", HostAdapter, TargetID);
  2.3923 +	Result = SCSI_RESET_PENDING;
  2.3924 +	goto Done;
  2.3925 +      }
  2.3926 +  if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
  2.3927 +    {
  2.3928 +      /*
  2.3929 +	MultiMaster Firmware versions prior to 5.xx treat a Bus Device Reset as
  2.3930 +	a non-tagged command.  Since non-tagged commands are not sent by the
  2.3931 +	Host Adapter until the queue of outstanding tagged commands has
  2.3932 +	completed, it is effectively impossible to send a Bus Device Reset
  2.3933 +	while there are tagged commands outstanding.  Therefore, in that case a
  2.3934 +	full Host Adapter Hard Reset and SCSI Bus Reset must be done.
  2.3935 +      */
  2.3936 +      if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
  2.3937 +	  HostAdapter->ActiveCommands[TargetID] > 0 &&
  2.3938 +	  HostAdapter->FirmwareVersion[0] < '5')
  2.3939 +	goto Done;
  2.3940 +    }
  2.3941 +  /*
  2.3942 +    Allocate a CCB from the Host Adapter's free list.  In the unlikely event
  2.3943 +    that there are none available and memory allocation fails, attempt a full
  2.3944 +    Host Adapter Hard Reset and SCSI Bus Reset.
  2.3945 +  */
  2.3946 +  CCB = BusLogic_AllocateCCB(HostAdapter);
  2.3947 +  if (CCB == NULL) goto Done;
  2.3948 +  BusLogic_Warning("Sending Bus Device Reset CCB #%ld to Target %d\n",
  2.3949 +		   HostAdapter, CCB->SerialNumber, TargetID);
  2.3950 +  CCB->Opcode = BusLogic_BusDeviceReset;
  2.3951 +  CCB->TargetID = TargetID;
  2.3952 +  /*
  2.3953 +    For Synchronous Resets, arrange for the interrupt handler to perform
  2.3954 +    completion processing for the Command being Reset.
  2.3955 +  */
  2.3956 +  if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
  2.3957 +    {
  2.3958 +      Command->reset_chain = NULL;
  2.3959 +      CCB->Command = Command;
  2.3960 +    }
  2.3961 +  if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
  2.3962 +    {
  2.3963 +      /*
  2.3964 +	Attempt to write an Outgoing Mailbox with the Bus Device Reset CCB.
  2.3965 +	If sending a Bus Device Reset is impossible, attempt a full Host
  2.3966 +	Adapter Hard Reset and SCSI Bus Reset.
  2.3967 +      */
  2.3968 +      if (!(BusLogic_WriteOutgoingMailbox(
  2.3969 +	      HostAdapter, BusLogic_MailboxStartCommand, CCB)))
  2.3970 +	{
  2.3971 +	  BusLogic_Warning("Unable to write Outgoing Mailbox for "
  2.3972 +			   "Bus Device Reset\n", HostAdapter);
  2.3973 +	  BusLogic_DeallocateCCB(CCB);
  2.3974 +	  goto Done;
  2.3975 +	}
  2.3976 +    }
  2.3977 +  else
  2.3978 +    {
  2.3979 +      /*
  2.3980 +	Call the FlashPoint SCCB Manager to start execution of the CCB.
  2.3981 +      */
  2.3982 +      CCB->Status = BusLogic_CCB_Active;
  2.3983 +      HostAdapter->ActiveCommands[TargetID]++;
  2.3984 +      FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
  2.3985 +    }
  2.3986 +  /*
  2.3987 +    If there is a currently executing CCB in the Host Adapter for this Command
  2.3988 +    (i.e. this is an Asynchronous Reset), then an Incoming Mailbox entry may be
  2.3989 +    made with a completion code of BusLogic_HostAdapterAssertedBusDeviceReset.
  2.3990 +    If there is no active CCB for this Command (i.e. this is a Synchronous
  2.3991 +    Reset), then the Bus Device Reset CCB's Command field will have been set
  2.3992 +    to the Command so that the interrupt for the completion of the Bus Device
  2.3993 +    Reset can call the Completion Routine for the Command.  On successful
  2.3994 +    execution of a Bus Device Reset, older firmware versions did return the
  2.3995 +    pending CCBs with the appropriate completion code, but more recent firmware
  2.3996 +    versions only return the Bus Device Reset CCB itself.  This driver handles
  2.3997 +    both cases by marking all the currently executing CCBs to this Target
  2.3998 +    Device as Reset.  When the Bus Device Reset CCB is processed by the
  2.3999 +    interrupt handler, any remaining CCBs marked as Reset will have completion
  2.4000 +    processing performed.
  2.4001 +  */
  2.4002 +  BusLogic_IncrementErrorCounter(
  2.4003 +    &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsAttempted);
  2.4004 +  HostAdapter->BusDeviceResetPendingCCB[TargetID] = CCB;
  2.4005 +  HostAdapter->LastResetAttempted[TargetID] = jiffies;
  2.4006 +  for (XCCB = HostAdapter->All_CCBs; XCCB != NULL; XCCB = XCCB->NextAll)
  2.4007 +    if (XCCB->Status == BusLogic_CCB_Active && XCCB->TargetID == TargetID)
  2.4008 +      XCCB->Status = BusLogic_CCB_Reset;
  2.4009 +  /*
  2.4010 +    FlashPoint Host Adapters may have already completed the Bus Device
  2.4011 +    Reset and BusLogic_QueueCompletedCCB been called, or it may still be
  2.4012 +    pending.
  2.4013 +  */
  2.4014 +  Result = SCSI_RESET_PENDING;
  2.4015 +  if (BusLogic_FlashPointHostAdapterP(HostAdapter))
  2.4016 +    if (CCB->Status == BusLogic_CCB_Completed)
  2.4017 +      {
  2.4018 +	BusLogic_ProcessCompletedCCBs(HostAdapter);
  2.4019 +	Result = SCSI_RESET_SUCCESS;
  2.4020 +      }
  2.4021 +  /*
  2.4022 +    If a Bus Device Reset was not possible for some reason, force a full
  2.4023 +    Host Adapter Hard Reset and SCSI Bus Reset.
  2.4024 +  */
  2.4025 +Done:
  2.4026 +  if (Result < 0)
  2.4027 +    Result = BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
  2.4028 +  /*
  2.4029 +    Release exclusive access to Host Adapter.
  2.4030 +  */
  2.4031 +  BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
  2.4032 +  return Result;
  2.4033 +}
  2.4034 +
  2.4035 +
  2.4036 +/*
  2.4037 +  BusLogic_ResetCommand takes appropriate action to reset Command.
  2.4038 +*/
  2.4039 +
  2.4040 +int BusLogic_ResetCommand(SCSI_Command_T *Command, unsigned int ResetFlags)
  2.4041 +{
  2.4042 +  BusLogic_HostAdapter_T *HostAdapter =
  2.4043 +    (BusLogic_HostAdapter_T *) Command->host->hostdata;
  2.4044 +  int TargetID = Command->target;
  2.4045 +  BusLogic_ErrorRecoveryStrategy_T
  2.4046 +    ErrorRecoveryStrategy = HostAdapter->ErrorRecoveryStrategy[TargetID];
  2.4047 +  /*
  2.4048 +    Disable Tagged Queuing if it is active for this Target Device and if
  2.4049 +    it has been less than 10 minutes since the last reset occurred, or since
  2.4050 +    the system was initialized if no prior resets have occurred.
  2.4051 +  */
  2.4052 +  if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
  2.4053 +      jiffies - HostAdapter->LastResetCompleted[TargetID] < 10*60*HZ)
  2.4054 +    {
  2.4055 +      HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
  2.4056 +      HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
  2.4057 +      BusLogic_Warning("Tagged Queuing now disabled for Target %d\n",
  2.4058 +		       HostAdapter, TargetID);
  2.4059 +    }
  2.4060 +  switch (ErrorRecoveryStrategy)
  2.4061 +    {
  2.4062 +    case BusLogic_ErrorRecovery_Default:
  2.4063 +      if (ResetFlags & SCSI_RESET_SUGGEST_HOST_RESET)
  2.4064 +	return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
  2.4065 +      else if (ResetFlags & SCSI_RESET_SUGGEST_BUS_RESET)
  2.4066 +	return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
  2.4067 +      /* Fall through to Bus Device Reset case. */
  2.4068 +    case BusLogic_ErrorRecovery_BusDeviceReset:
  2.4069 +      /*
  2.4070 +	The Bus Device Reset Error Recovery Strategy only graduates to a Hard
  2.4071 +	Reset when no commands have completed successfully since the last Bus
  2.4072 +	Device Reset and it has been at least 100 milliseconds.  This prevents
  2.4073 +	a sequence of commands that all timeout together from immediately
  2.4074 +	forcing a Hard Reset before the Bus Device Reset has had a chance to
  2.4075 +	clear the error condition.
  2.4076 +      */
  2.4077 +      if (HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag ||
  2.4078 +	  jiffies - HostAdapter->LastResetAttempted[TargetID] < HZ/10)
  2.4079 +	{
  2.4080 +	  HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
  2.4081 +	  return BusLogic_SendBusDeviceReset(HostAdapter, Command, ResetFlags);
  2.4082 +	}
  2.4083 +      /* Fall through to Hard Reset case. */
  2.4084 +    case BusLogic_ErrorRecovery_HardReset:
  2.4085 +      return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
  2.4086 +    case BusLogic_ErrorRecovery_None:
  2.4087 +      BusLogic_Warning("Error Recovery for Target %d Suppressed\n",
  2.4088 +		       HostAdapter, TargetID);
  2.4089 +      break;
  2.4090 +    }
  2.4091 +  return SCSI_RESET_PUNT;
  2.4092 +}
  2.4093 +
  2.4094 +
  2.4095 +#if 0 /* XEN */
  2.4096 +/*
  2.4097 +  BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
  2.4098 +  Parameters for Disk.  The default disk geometry is 64 heads, 32 sectors, and
  2.4099 +  the appropriate number of cylinders so as not to exceed drive capacity.  In
  2.4100 +  order for disks equal to or larger than 1 GB to be addressable by the BIOS
  2.4101 +  without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
  2.4102 +  may be enabled in AutoSCSI on FlashPoint Host Adapters and on "W" and "C"
  2.4103 +  series MultiMaster Host Adapters, or by a dip switch setting on "S" and "A"
  2.4104 +  series MultiMaster Host Adapters.  With Extended Translation enabled, drives
  2.4105 +  between 1 GB inclusive and 2 GB exclusive are given a disk geometry of 128
  2.4106 +  heads and 32 sectors, and drives above 2 GB inclusive are given a disk
  2.4107 +  geometry of 255 heads and 63 sectors.  However, if the BIOS detects that the
  2.4108 +  Extended Translation setting does not match the geometry in the partition
  2.4109 +  table, then the translation inferred from the partition table will be used by
  2.4110 +  the BIOS, and a warning may be displayed.
  2.4111 +*/
  2.4112 +
  2.4113 +int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
  2.4114 +				int *Parameters)
  2.4115 +{
  2.4116 +  BusLogic_HostAdapter_T *HostAdapter =
  2.4117 +    (BusLogic_HostAdapter_T *) Disk->device->host->hostdata;
  2.4118 +  BIOS_DiskParameters_T *DiskParameters = (BIOS_DiskParameters_T *) Parameters;
  2.4119 +  struct buffer_head *BufferHead;
  2.4120 +  if (HostAdapter->ExtendedTranslationEnabled &&
  2.4121 +      Disk->capacity >= 2*1024*1024 /* 1 GB in 512 byte sectors */)
  2.4122 +    {
  2.4123 +      if (Disk->capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */)
  2.4124 +	{
  2.4125 +	  DiskParameters->Heads = 255;
  2.4126 +	  DiskParameters->Sectors = 63;
  2.4127 +	}
  2.4128 +      else
  2.4129 +	{
  2.4130 +	  DiskParameters->Heads = 128;
  2.4131 +	  DiskParameters->Sectors = 32;
  2.4132 +	}
  2.4133 +    }
  2.4134 +  else
  2.4135 +    {
  2.4136 +      DiskParameters->Heads = 64;
  2.4137 +      DiskParameters->Sectors = 32;
  2.4138 +    }
  2.4139 +  DiskParameters->Cylinders =
  2.4140 +    Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
  2.4141 +  /*
  2.4142 +    Attempt to read the first 1024 bytes from the disk device.
  2.4143 +  */
  2.4144 +  BufferHead = bread(MKDEV(MAJOR(Device), MINOR(Device) & ~0x0F), 0, block_size(Device));
  2.4145 +  if (BufferHead == NULL) return 0;
  2.4146 +  /*
  2.4147 +    If the boot sector partition table flag is valid, search for a partition
  2.4148 +    table entry whose end_head matches one of the standard BusLogic geometry
  2.4149 +    translations (64/32, 128/32, or 255/63).
  2.4150 +  */
  2.4151 +  if (*(unsigned short *) (BufferHead->b_data + 0x1FE) == 0xAA55)
  2.4152 +    {
  2.4153 +      PartitionTable_T *FirstPartitionEntry =
  2.4154 +	(PartitionTable_T *) (BufferHead->b_data + 0x1BE);
  2.4155 +      PartitionTable_T *PartitionEntry = FirstPartitionEntry;
  2.4156 +      int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
  2.4157 +      unsigned char PartitionEntryEndHead, PartitionEntryEndSector;
  2.4158 +      for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++)
  2.4159 +	{
  2.4160 +	  PartitionEntryEndHead = PartitionEntry->end_head;
  2.4161 +	  PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F;
  2.4162 +	  if (PartitionEntryEndHead == 64-1)
  2.4163 +	    {
  2.4164 +	      DiskParameters->Heads = 64;
  2.4165 +	      DiskParameters->Sectors = 32;
  2.4166 +	      break;
  2.4167 +	    }
  2.4168 +	  else if (PartitionEntryEndHead == 128-1)
  2.4169 +	    {
  2.4170 +	      DiskParameters->Heads = 128;
  2.4171 +	      DiskParameters->Sectors = 32;
  2.4172 +	      break;
  2.4173 +	    }
  2.4174 +	  else if (PartitionEntryEndHead == 255-1)
  2.4175 +	    {
  2.4176 +	      DiskParameters->Heads = 255;
  2.4177 +	      DiskParameters->Sectors = 63;
  2.4178 +	      break;
  2.4179 +	    }
  2.4180 +	  PartitionEntry++;
  2.4181 +	}
  2.4182 +      if (PartitionNumber == 4)
  2.4183 +	{
  2.4184 +	  PartitionEntryEndHead = FirstPartitionEntry->end_head;
  2.4185 +	  PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F;
  2.4186 +	}
  2.4187 +      DiskParameters->Cylinders =
  2.4188 +	Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
  2.4189 +      if (PartitionNumber < 4 &&
  2.4190 +	  PartitionEntryEndSector == DiskParameters->Sectors)
  2.4191 +	{
  2.4192 +	  if (DiskParameters->Cylinders != SavedCylinders)
  2.4193 +	    BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n",
  2.4194 +			     HostAdapter,
  2.4195 +			     DiskParameters->Heads, DiskParameters->Sectors);
  2.4196 +	}
  2.4197 +      else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0)
  2.4198 +	{
  2.4199 +	  BusLogic_Warning("Warning: Partition Table appears to "
  2.4200 +			   "have Geometry %d/%d which is\n", HostAdapter,
  2.4201 +			   PartitionEntryEndHead + 1,
  2.4202 +			   PartitionEntryEndSector);
  2.4203 +	  BusLogic_Warning("not compatible with current BusLogic "
  2.4204 +			   "Host Adapter Geometry %d/%d\n", HostAdapter,
  2.4205 +			   DiskParameters->Heads, DiskParameters->Sectors);
  2.4206 +	}
  2.4207 +    }
  2.4208 +  brelse(BufferHead);
  2.4209 +  return 0;
  2.4210 +}
  2.4211 +
  2.4212 +
  2.4213 +/*
  2.4214 +  BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
  2.4215 +*/
  2.4216 +
  2.4217 +int BusLogic_ProcDirectoryInfo(char *ProcBuffer, char **StartPointer,
  2.4218 +			       off_t Offset, int BytesAvailable,
  2.4219 +			       int HostNumber, int WriteFlag)
  2.4220 +{
  2.4221 +  BusLogic_HostAdapter_T *HostAdapter;
  2.4222 +  BusLogic_TargetStatistics_T *TargetStatistics;
  2.4223 +  int TargetID, Length;
  2.4224 +  char *Buffer;
  2.4225 +  for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
  2.4226 +       HostAdapter != NULL;
  2.4227 +       HostAdapter = HostAdapter->Next)
  2.4228 +    if (HostAdapter->HostNumber == HostNumber) break;
  2.4229 +  if (HostAdapter == NULL)
  2.4230 +    {
  2.4231 +      BusLogic_Error("Cannot find Host Adapter for SCSI Host %d\n",
  2.4232 +		     NULL, HostNumber);
  2.4233 +      return 0;
  2.4234 +    }
  2.4235 +  TargetStatistics = HostAdapter->TargetStatistics;
  2.4236 +  if (WriteFlag)
  2.4237 +    {
  2.4238 +      HostAdapter->ExternalHostAdapterResets = 0;
  2.4239 +      HostAdapter->HostAdapterInternalErrors = 0;
  2.4240 +      memset(TargetStatistics, 0,
  2.4241 +	     BusLogic_MaxTargetDevices * sizeof(BusLogic_TargetStatistics_T));
  2.4242 +      return 0;
  2.4243 +    }
  2.4244 +  Buffer = HostAdapter->MessageBuffer;
  2.4245 +  Length = HostAdapter->MessageBufferLength;
  2.4246 +  Length += sprintf(&Buffer[Length], "\n\
  2.4247 +Current Driver Queue Depth:	%d\n\
  2.4248 +Currently Allocated CCBs:	%d\n",
  2.4249 +		    HostAdapter->DriverQueueDepth,
  2.4250 +		    HostAdapter->AllocatedCCBs);
  2.4251 +  Length += sprintf(&Buffer[Length], "\n\n\
  2.4252 +			   DATA TRANSFER STATISTICS\n\
  2.4253 +\n\
  2.4254 +Target	Tagged Queuing	Queue Depth  Active  Attempted	Completed\n\
  2.4255 +======	==============	===========  ======  =========	=========\n");
  2.4256 +  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.4257 +    {
  2.4258 +      BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
  2.4259 +      if (!TargetFlags->TargetExists) continue;
  2.4260 +      Length +=
  2.4261 +	sprintf(&Buffer[Length], "  %2d	%s", TargetID,
  2.4262 +		(TargetFlags->TaggedQueuingSupported
  2.4263 +		 ? (TargetFlags->TaggedQueuingActive
  2.4264 +		    ? "    Active"
  2.4265 +		    : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
  2.4266 +		       ? "  Permitted" : "   Disabled"))
  2.4267 +		 : "Not Supported"));
  2.4268 +      Length += sprintf(&Buffer[Length],
  2.4269 +			"	    %3d       %3u    %9u	%9u\n",
  2.4270 +			HostAdapter->QueueDepth[TargetID],
  2.4271 +			HostAdapter->ActiveCommands[TargetID],
  2.4272 +			TargetStatistics[TargetID].CommandsAttempted,
  2.4273 +			TargetStatistics[TargetID].CommandsCompleted);
  2.4274 +    }
  2.4275 +  Length += sprintf(&Buffer[Length], "\n\
  2.4276 +Target  Read Commands  Write Commands   Total Bytes Read    Total Bytes Written\n\
  2.4277 +======  =============  ==============  ===================  ===================\n");
  2.4278 +  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.4279 +    {
  2.4280 +      BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
  2.4281 +      if (!TargetFlags->TargetExists) continue;
  2.4282 +      Length +=
  2.4283 +	sprintf(&Buffer[Length], "  %2d	  %9u	 %9u", TargetID,
  2.4284 +		TargetStatistics[TargetID].ReadCommands,
  2.4285 +		TargetStatistics[TargetID].WriteCommands);
  2.4286 +      if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0)
  2.4287 +	Length +=
  2.4288 +	  sprintf(&Buffer[Length], "     %9u%09u",
  2.4289 +		  TargetStatistics[TargetID].TotalBytesRead.Billions,
  2.4290 +		  TargetStatistics[TargetID].TotalBytesRead.Units);
  2.4291 +      else
  2.4292 +	Length +=
  2.4293 +	  sprintf(&Buffer[Length], "		%9u",
  2.4294 +		  TargetStatistics[TargetID].TotalBytesRead.Units);
  2.4295 +      if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0)
  2.4296 +	Length +=
  2.4297 +	  sprintf(&Buffer[Length], "   %9u%09u\n",
  2.4298 +		  TargetStatistics[TargetID].TotalBytesWritten.Billions,
  2.4299 +		  TargetStatistics[TargetID].TotalBytesWritten.Units);
  2.4300 +      else
  2.4301 +	Length +=
  2.4302 +	  sprintf(&Buffer[Length], "	     %9u\n",
  2.4303 +		  TargetStatistics[TargetID].TotalBytesWritten.Units);
  2.4304 +    }
  2.4305 +  Length += sprintf(&Buffer[Length], "\n\
  2.4306 +Target  Command    0-1KB      1-2KB      2-4KB      4-8KB     8-16KB\n\
  2.4307 +======  =======  =========  =========  =========  =========  =========\n");
  2.4308 +  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.4309 +    {
  2.4310 +      BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
  2.4311 +      if (!TargetFlags->TargetExists) continue;
  2.4312 +      Length +=
  2.4313 +	sprintf(&Buffer[Length],
  2.4314 +		"  %2d	 Read	 %9u  %9u  %9u  %9u  %9u\n", TargetID,
  2.4315 +		TargetStatistics[TargetID].ReadCommandSizeBuckets[0],
  2.4316 +		TargetStatistics[TargetID].ReadCommandSizeBuckets[1],
  2.4317 +		TargetStatistics[TargetID].ReadCommandSizeBuckets[2],
  2.4318 +		TargetStatistics[TargetID].ReadCommandSizeBuckets[3],
  2.4319 +		TargetStatistics[TargetID].ReadCommandSizeBuckets[4]);
  2.4320 +      Length +=
  2.4321 +	sprintf(&Buffer[Length],
  2.4322 +		"  %2d	 Write	 %9u  %9u  %9u  %9u  %9u\n", TargetID,
  2.4323 +		TargetStatistics[TargetID].WriteCommandSizeBuckets[0],
  2.4324 +		TargetStatistics[TargetID].WriteCommandSizeBuckets[1],
  2.4325 +		TargetStatistics[TargetID].WriteCommandSizeBuckets[2],
  2.4326 +		TargetStatistics[TargetID].WriteCommandSizeBuckets[3],
  2.4327 +		TargetStatistics[TargetID].WriteCommandSizeBuckets[4]);
  2.4328 +    }
  2.4329 +  Length += sprintf(&Buffer[Length], "\n\
  2.4330 +Target  Command   16-32KB    32-64KB   64-128KB   128-256KB   256KB+\n\
  2.4331 +======  =======  =========  =========  =========  =========  =========\n");
  2.4332 +  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.4333 +    {
  2.4334 +      BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
  2.4335 +      if (!TargetFlags->TargetExists) continue;
  2.4336 +      Length +=
  2.4337 +	sprintf(&Buffer[Length],
  2.4338 +		"  %2d	 Read	 %9u  %9u  %9u  %9u  %9u\n", TargetID,
  2.4339 +		TargetStatistics[TargetID].ReadCommandSizeBuckets[5],
  2.4340 +		TargetStatistics[TargetID].ReadCommandSizeBuckets[6],
  2.4341 +		TargetStatistics[TargetID].ReadCommandSizeBuckets[7],
  2.4342 +		TargetStatistics[TargetID].ReadCommandSizeBuckets[8],
  2.4343 +		TargetStatistics[TargetID].ReadCommandSizeBuckets[9]);
  2.4344 +      Length +=
  2.4345 +	sprintf(&Buffer[Length],
  2.4346 +		"  %2d	 Write	 %9u  %9u  %9u  %9u  %9u\n", TargetID,
  2.4347 +		TargetStatistics[TargetID].WriteCommandSizeBuckets[5],
  2.4348 +		TargetStatistics[TargetID].WriteCommandSizeBuckets[6],
  2.4349 +		TargetStatistics[TargetID].WriteCommandSizeBuckets[7],
  2.4350 +		TargetStatistics[TargetID].WriteCommandSizeBuckets[8],
  2.4351 +		TargetStatistics[TargetID].WriteCommandSizeBuckets[9]);
  2.4352 +    }
  2.4353 +  Length += sprintf(&Buffer[Length], "\n\n\
  2.4354 +			   ERROR RECOVERY STATISTICS\n\
  2.4355 +\n\
  2.4356 +	  Command Aborts      Bus Device Resets	  Host Adapter Resets\n\
  2.4357 +Target	Requested Completed  Requested Completed  Requested Completed\n\
  2.4358 +  ID	\\\\\\\\ Attempted ////  \\\\\\\\ Attempted ////  \\\\\\\\ Attempted ////\n\
  2.4359 +======	 ===== ===== =====    ===== ===== =====	   ===== ===== =====\n");
  2.4360 +  for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
  2.4361 +    {
  2.4362 +      BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
  2.4363 +      if (!TargetFlags->TargetExists) continue;
  2.4364 +      Length +=
  2.4365 +	sprintf(&Buffer[Length], "\
  2.4366 +  %2d	 %5d %5d %5d    %5d %5d %5d	   %5d %5d %5d\n", TargetID,
  2.4367 +		TargetStatistics[TargetID].CommandAbortsRequested,
  2.4368 +		TargetStatistics[TargetID].CommandAbortsAttempted,
  2.4369 +		TargetStatistics[TargetID].CommandAbortsCompleted,
  2.4370 +		TargetStatistics[TargetID].BusDeviceResetsRequested,
  2.4371 +		TargetStatistics[TargetID].BusDeviceResetsAttempted,
  2.4372 +		TargetStatistics[TargetID].BusDeviceResetsCompleted,
  2.4373 +		TargetStatistics[TargetID].HostAdapterResetsRequested,
  2.4374 +		TargetStatistics[TargetID].HostAdapterResetsAttempted,
  2.4375 +		TargetStatistics[TargetID].HostAdapterResetsCompleted);
  2.4376 +    }
  2.4377 +  Length += sprintf(&Buffer[Length], "\nExternal Host Adapter Resets: %d\n",
  2.4378 +		    HostAdapter->ExternalHostAdapterResets);
  2.4379 +  Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %d\n",
  2.4380 +		    HostAdapter->HostAdapterInternalErrors);
  2.4381 +  if (Length >= BusLogic_MessageBufferSize)
  2.4382 +    BusLogic_Error("Message Buffer length %d exceeds size %d\n",
  2.4383 +		   HostAdapter, Length, BusLogic_MessageBufferSize);
  2.4384 +  if ((Length -= Offset) <= 0) return 0;
  2.4385 +  if (Length >= BytesAvailable) Length = BytesAvailable;
  2.4386 +  memcpy(ProcBuffer, HostAdapter->MessageBuffer + Offset, Length);
  2.4387 +  *StartPointer = ProcBuffer;
  2.4388 +  return Length;
  2.4389 +}
  2.4390 +
  2.4391 +#endif /* !XEN */
  2.4392 +
  2.4393 +/*
  2.4394 +  BusLogic_Message prints Driver Messages.
  2.4395 +*/
  2.4396 +
  2.4397 +static void BusLogic_Message(BusLogic_MessageLevel_T MessageLevel,
  2.4398 +			     char *Format,
  2.4399 +			     BusLogic_HostAdapter_T *HostAdapter,
  2.4400 +			     ...)
  2.4401 +{
  2.4402 +  static char Buffer[BusLogic_LineBufferSize];
  2.4403 +  static boolean BeginningOfLine = true;
  2.4404 +  va_list Arguments;
  2.4405 +  int Length = 0;
  2.4406 +  va_start(Arguments, HostAdapter);
  2.4407 +  Length = vsprintf(Buffer, Format, Arguments);
  2.4408 +  va_end(Arguments);
  2.4409 +  if (MessageLevel == BusLogic_AnnounceLevel)
  2.4410 +    {
  2.4411 +      static int AnnouncementLines = 0;
  2.4412 +      strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength],
  2.4413 +	     Buffer);
  2.4414 +      HostAdapter->MessageBufferLength += Length;
  2.4415 +      if (++AnnouncementLines <= 2)
  2.4416 +	printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
  2.4417 +    }
  2.4418 +  else if (MessageLevel == BusLogic_InfoLevel)
  2.4419 +    {
  2.4420 +      strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength],
  2.4421 +	     Buffer);
  2.4422 +      HostAdapter->MessageBufferLength += Length;
  2.4423 +      if (BeginningOfLine)
  2.4424 +	{
  2.4425 +	  if (Buffer[0] != '\n' || Length > 1)
  2.4426 +	    printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
  2.4427 +		   HostAdapter->HostNumber, Buffer);
  2.4428 +	}
  2.4429 +      else printk("%s", Buffer);
  2.4430 +    }
  2.4431 +  else
  2.4432 +    {
  2.4433 +      if (BeginningOfLine)
  2.4434 +	{
  2.4435 +	  if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized)
  2.4436 +	    printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
  2.4437 +		   HostAdapter->HostNumber, Buffer);
  2.4438 +	  else printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
  2.4439 +	}
  2.4440 +      else printk("%s", Buffer);
  2.4441 +    }
  2.4442 +  BeginningOfLine = (Buffer[Length-1] == '\n');
  2.4443 +}
  2.4444 +
  2.4445 +
  2.4446 +/*
  2.4447 +  BusLogic_ParseKeyword parses an individual option keyword.  It returns true
  2.4448 +  and updates the pointer if the keyword is recognized and false otherwise.
  2.4449 +*/
  2.4450 +
  2.4451 +static boolean BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
  2.4452 +{
  2.4453 +  char *Pointer = *StringPointer;
  2.4454 +  while (*Keyword != '\0')
  2.4455 +    {
  2.4456 +      char StringChar = *Pointer++;
  2.4457 +      char KeywordChar = *Keyword++;
  2.4458 +      if (StringChar >= 'A' && StringChar <= 'Z')
  2.4459 +	StringChar += 'a' - 'Z';
  2.4460 +      if (KeywordChar >= 'A' && KeywordChar <= 'Z')
  2.4461 +	KeywordChar += 'a' - 'Z';
  2.4462 +      if (StringChar != KeywordChar) return false;
  2.4463 +    }
  2.4464 +  *StringPointer = Pointer;
  2.4465 +  return true;
  2.4466 +}
  2.4467 +
  2.4468 +#if 0 /* XEN */
  2.4469 +/*
  2.4470 +  BusLogic_ParseDriverOptions handles processing of BusLogic Driver Options
  2.4471 +  specifications.
  2.4472 +
  2.4473 +  BusLogic Driver Options may be specified either via the Linux Kernel Command
  2.4474 +  Line or via the Loadable Kernel Module Installation Facility.  Driver Options
  2.4475 +  for multiple host adapters may be specified either by separating the option
  2.4476 +  strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
  2.4477 +  command line.  Individual option specifications for a single host adapter are
  2.4478 +  separated by commas.  The Probing and Debugging Options apply to all host
  2.4479 +  adapters whereas the remaining options apply individually only to the
  2.4480 +  selected host adapter.
  2.4481 +
  2.4482 +  The BusLogic Driver Probing Options comprise the following:
  2.4483 +
  2.4484 +  IO:<integer>
  2.4485 +
  2.4486 +    The "IO:" option specifies an ISA I/O Address to be probed for a non-PCI
  2.4487 +    MultiMaster Host Adapter.  If neither "IO:" nor "NoProbeISA" options are
  2.4488 +    specified, then the standard list of BusLogic MultiMaster ISA I/O Addresses
  2.4489 +    will be probed (0x330, 0x334, 0x230, 0x234, 0x130, and 0x134).  Multiple
  2.4490 +    "IO:" options may be specified to precisely determine the I/O Addresses to
  2.4491 +    be probed, but the probe order will always follow the standard list.
  2.4492 +
  2.4493 +  NoProbe
  2.4494 +
  2.4495 +    The "NoProbe" option disables all probing and therefore no BusLogic Host
  2.4496 +    Adapters will be detected.
  2.4497 +
  2.4498 +  NoProbeISA
  2.4499 +
  2.4500 +    The "NoProbeISA" option disables probing of the standard BusLogic ISA I/O
  2.4501 +    Addresses and therefore only PCI MultiMaster and FlashPoint Host Adapters
  2.4502 +    will be detected.
  2.4503 +
  2.4504 +  NoProbePCI
  2.4505 +
  2.4506 +    The "NoProbePCI" options disables the interrogation of PCI Configuration
  2.4507 +    Space and therefore only ISA Multimaster Host Adapters will be detected, as
  2.4508 +    well as PCI Multimaster Host Adapters that have their ISA Compatible I/O
  2.4509 +    Port set to "Primary" or "Alternate".
  2.4510 +
  2.4511 +  NoSortPCI
  2.4512 +
  2.4513 +    The "NoSortPCI" option forces PCI MultiMaster Host Adapters to be
  2.4514 +    enumerated in the order provided by the PCI BIOS, ignoring any setting of
  2.4515 +    the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option.
  2.4516 +
  2.4517 +  MultiMasterFirst
  2.4518 +
  2.4519 +    The "MultiMasterFirst" option forces MultiMaster Host Adapters to be probed
  2.4520 +    before FlashPoint Host Adapters.  By default, if both FlashPoint and PCI
  2.4521 +    MultiMaster Host Adapters are present, this driver will probe for
  2.4522 +    FlashPoint Host Adapters first unless the BIOS primary disk is controlled
  2.4523 +    by the first PCI MultiMaster Host Adapter, in which case MultiMaster Host
  2.4524 +    Adapters will be probed first.
  2.4525 +
  2.4526 +  FlashPointFirst
  2.4527 +
  2.4528 +    The "FlashPointFirst" option forces FlashPoint Host Adapters to be probed
  2.4529 +    before MultiMaster Host Adapters.
  2.4530 +
  2.4531 +  The BusLogic Driver Tagged Queuing Options allow for explicitly specifying
  2.4532 +  the Queue Depth and whether Tagged Queuing is permitted for each Target
  2.4533 +  Device (assuming that the Target Device supports Tagged Queuing).  The Queue
  2.4534 +  Depth is the number of SCSI Commands that are allowed to be concurrently
  2.4535 +  presented for execution (either to the Host Adapter or Target Device).  Note
  2.4536 +  that explicitly enabling Tagged Queuing may lead to problems; the option to
  2.4537 +  enable or disable Tagged Queuing is provided primarily to allow disabling
  2.4538 +  Tagged Queuing on Target Devices that do not implement it correctly.  The
  2.4539 +  following options are available:
  2.4540 +
  2.4541 +  QueueDepth:<integer>
  2.4542 +
  2.4543 +    The "QueueDepth:" or QD:" option specifies the Queue Depth to use for all
  2.4544 +    Target Devices that support Tagged Queuing, as well as the maximum Queue
  2.4545 +    Depth for devices that do not support Tagged Queuing.  If no Queue Depth
  2.4546 +    option is provided, the Queue Depth will be determined automatically based
  2.4547 +    on the Host Adapter's Total Queue Depth and the number, type, speed, and
  2.4548 +    capabilities of the detected Target Devices.  For Host Adapters that
  2.4549 +    require ISA Bounce Buffers, the Queue Depth is automatically set by default
  2.4550 +    to BusLogic_TaggedQueueDepthBB or BusLogic_UntaggedQueueDepthBB to avoid
  2.4551 +    excessive preallocation of DMA Bounce Buffer memory.  Target Devices that
  2.4552 +    do not support Tagged Queuing always have their Queue Depth set to
  2.4553 +    BusLogic_UntaggedQueueDepth or BusLogic_UntaggedQueueDepthBB, unless a
  2.4554 +    lower Queue Depth option is provided.  A Queue Depth of 1 automatically
  2.4555 +    disables Tagged Queuing.
  2.4556 +
  2.4557 +  QueueDepth:[<integer>,<integer>...]
  2.4558 +
  2.4559 +    The "QueueDepth:[...]" or "QD:[...]" option specifies the Queue Depth
  2.4560 +    individually for each Target Device.  If an <integer> is omitted, the
  2.4561 +    associated Target Device will have its Queue Depth selected automatically.
  2.4562 +
  2.4563 +  TaggedQueuing:Default
  2.4564 +
  2.4565 +    The "TaggedQueuing:Default" or "TQ:Default" option permits Tagged Queuing
  2.4566 +    based on the firmware version of the BusLogic Host Adapter and based on
  2.4567 +    whether the Queue Depth allows queuing multiple commands.
  2.4568 +
  2.4569 +  TaggedQueuing:Enable
  2.4570 +
  2.4571 +    The "TaggedQueuing:Enable" or "TQ:Enable" option enables Tagged Queuing for
  2.4572 +    all Target Devices on this Host Adapter, overriding any limitation that
  2.4573 +    would otherwise be imposed based on the Host Adapter firmware version.
  2.4574 +
  2.4575 +  TaggedQueuing:Disable
  2.4576 +
  2.4577 +    The "TaggedQueuing:Disable" or "TQ:Disable" option disables Tagged Queuing
  2.4578 +    for all Target Devices on this Host Adapter.
  2.4579 +
  2.4580 +  TaggedQueuing:<Target-Spec>
  2.4581 +
  2.4582 +    The "TaggedQueuing:<Target-Spec>" or "TQ:<Target-Spec>" option controls
  2.4583 +    Tagged Queuing individually for each Target Device.  <Target-Spec> is a
  2.4584 +    sequence of "Y", "N", and "X" characters.  "Y" enables Tagged Queuing, "N"
  2.4585 +    disables Tagged Queuing, and "X" accepts the default based on the firmware
  2.4586 +    version.  The first character refers to Target Device 0, the second to
  2.4587 +    Target Device 1, and so on; if the sequence of "Y", "N", and "X" characters
  2.4588 +    does not cover all the Target Devices, unspecified characters are assumed
  2.4589 +    to be "X".
  2.4590 +
  2.4591 +  The BusLogic Driver Error Recovery Option allows for explicitly specifying
  2.4592 +  the Error Recovery action to be performed when BusLogic_ResetCommand is
  2.4593 +  called due to a SCSI Command failing to complete successfully.  The following
  2.4594 +  options are available:
  2.4595 +
  2.4596 +  ErrorRecovery:Default
  2.4597 +
  2.4598 +    The "ErrorRecovery:Default" or "ER:Default" option selects between the Hard
  2.4599 +    Reset and Bus Device Reset options based on the recommendation of the SCSI
  2.4600 +    Subsystem.
  2.4601 +
  2.4602 +  ErrorRecovery:HardReset
  2.4603 +
  2.4604 +    The "ErrorRecovery:HardReset" or "ER:HardReset" option will initiate a Host
  2.4605 +    Adapter Hard Reset which also causes a SCSI Bus Reset.
  2.4606 +
  2.4607 +  ErrorRecovery:BusDeviceReset
  2.4608 +
  2.4609 +    The "ErrorRecovery:BusDeviceReset" or "ER:BusDeviceReset" option will send
  2.4610 +    a Bus Device Reset message to the individual Target Device causing the
  2.4611 +    error.  If Error Recovery is again initiated for this Target Device and no
  2.4612 +    SCSI Command to this Target Device has completed successfully since the Bus
  2.4613 +    Device Reset message was sent, then a Hard Reset will be attempted.
  2.4614 +
  2.4615 +  ErrorRecovery:None
  2.4616 +
  2.4617 +    The "ErrorRecovery:None" or "ER:None" option suppresses Error Recovery.
  2.4618 +    This option should only be selected if a SCSI Bus Reset or Bus Device Reset
  2.4619 +    will cause the Target Device or a critical operation to suffer a complete
  2.4620 +    and unrecoverable failure.
  2.4621 +
  2.4622 +  ErrorRecovery:<Target-Spec>
  2.4623 +
  2.4624 +    The "ErrorRecovery:<Target-Spec>" or "ER:<Target-Spec>" option controls
  2.4625 +    Error Recovery individually for each Target Device.  <Target-Spec> is a
  2.4626 +    sequence of "D", "H", "B", and "N" characters.  "D" selects Default, "H"
  2.4627 +    selects Hard Reset, "B" selects Bus Device Reset, and "N" selects None.
  2.4628 +    The first character refers to Target Device 0, the second to Target Device
  2.4629 +    1, and so on; if the sequence of "D", "H", "B", and "N" characters does not
  2.4630 +    cover all the possible Target Devices, unspecified characters are assumed
  2.4631 +    to be "D".
  2.4632 +
  2.4633 +  The BusLogic Driver Miscellaneous Options comprise the following:
  2.4634 +
  2.4635 +  BusSettleTime:<seconds>
  2.4636 +
  2.4637 +    The "BusSettleTime:" or "BST:" option specifies the Bus Settle Time in
  2.4638 +    seconds.  The Bus Settle Time is the amount of time to wait between a Host
  2.4639 +    Adapter Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI
  2.4640 +    Commands.  If unspecified, it defaults to BusLogic_DefaultBusSettleTime.
  2.4641 +
  2.4642 +  InhibitTargetInquiry
  2.4643 +
  2.4644 +    The "InhibitTargetInquiry" option inhibits the execution of an Inquire
  2.4645 +    Target Devices or Inquire Installed Devices command on MultiMaster Host
  2.4646 +    Adapters.  This may be necessary with some older Target Devices that do not
  2.4647 +    respond correctly when Logical Units above 0 are addressed.
  2.4648 +
  2.4649 +  The BusLogic Driver Debugging Options comprise the following:
  2.4650 +
  2.4651 +  TraceProbe
  2.4652 +
  2.4653 +    The "TraceProbe" option enables tracing of Host Adapter Probing.
  2.4654 +
  2.4655 +  TraceHardwareReset
  2.4656 +
  2.4657 +    The "TraceHardwareReset" option enables tracing of Host Adapter Hardware
  2.4658 +    Reset.
  2.4659 +
  2.4660 +  TraceConfiguration
  2.4661 +
  2.4662 +    The "TraceConfiguration" option enables tracing of Host Adapter
  2.4663 +    Configuration.
  2.4664 +
  2.4665 +  TraceErrors
  2.4666 +
  2.4667 +    The "TraceErrors" option enables tracing of SCSI Commands that return an
  2.4668 +    error from the Target Device.  The CDB and Sense Data will be printed for
  2.4669 +    each SCSI Command that fails.
  2.4670 +
  2.4671 +  Debug
  2.4672 +
  2.4673 +    The "Debug" option enables all debugging options.
  2.4674 +
  2.4675 +  The following examples demonstrate setting the Queue Depth for Target Devices
  2.4676 +  1 and 2 on the first host adapter to 7 and 15, the Queue Depth for all Target
  2.4677 +  Devices on the second host adapter to 31, and the Bus Settle Time on the
  2.4678 +  second host adapter to 30 seconds.
  2.4679 +
  2.4680 +  Linux Kernel Command Line:
  2.4681 +
  2.4682 +    linux BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30
  2.4683 +
  2.4684 +  LILO Linux Boot Loader (in /etc/lilo.conf):
  2.4685 +
  2.4686 +    append = "BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"
  2.4687 +
  2.4688 +  INSMOD Loadable Kernel Module Installation Facility:
  2.4689 +
  2.4690 +    insmod BusLogic.o \
  2.4691 +	'BusLogic="QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"'
  2.4692 +
  2.4693 +  NOTE: Module Utilities 2.1.71 or later is required for correct parsing
  2.4694 +	of driver options containing commas.
  2.4695 +
  2.4696 +*/
  2.4697 +
  2.4698 +static int __init BusLogic_ParseDriverOptions(char *OptionsString)
  2.4699 +{
  2.4700 +  while (true)
  2.4701 +    {
  2.4702 +      BusLogic_DriverOptions_T *DriverOptions =
  2.4703 +	&BusLogic_DriverOptions[BusLogic_DriverOptionsCount++];
  2.4704 +      int TargetID;
  2.4705 +      memset(DriverOptions, 0, sizeof(BusLogic_DriverOptions_T));
  2.4706 +      for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
  2.4707 +	DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2.4708 +	  BusLogic_ErrorRecovery_Default;
  2.4709 +      while (*OptionsString != '\0' && *OptionsString != ';')
  2.4710 +	{
  2.4711 +	  /* Probing Options. */
  2.4712 +	  if (BusLogic_ParseKeyword(&OptionsString, "IO:"))
  2.4713 +	    {
  2.4714 +	      BusLogic_IO_Address_T IO_Address =
  2.4715 +		simple_strtoul(OptionsString, &OptionsString, 0);
  2.4716 +	      BusLogic_ProbeOptions.LimitedProbeISA = true;
  2.4717 +	      switch (IO_Address)
  2.4718 +		{
  2.4719 +		case 0x330:
  2.4720 +		  BusLogic_ProbeOptions.Probe330 = true;
  2.4721 +		  break;
  2.4722 +		case 0x334:
  2.4723 +		  BusLogic_ProbeOptions.Probe334 = true;
  2.4724 +		  break;
  2.4725 +		case 0x230:
  2.4726 +		  BusLogic_ProbeOptions.Probe230 = true;
  2.4727 +		  break;
  2.4728 +		case 0x234:
  2.4729 +		  BusLogic_ProbeOptions.Probe234 = true;
  2.4730 +		  break;
  2.4731 +		case 0x130:
  2.4732 +		  BusLogic_ProbeOptions.Probe130 = true;
  2.4733 +		  break;
  2.4734 +		case 0x134:
  2.4735 +		  BusLogic_ProbeOptions.Probe134 = true;
  2.4736 +		  break;
  2.4737 +		default:
  2.4738 +		  BusLogic_Error("BusLogic: Invalid Driver Options "
  2.4739 +				 "(illegal I/O Address 0x%X)\n",
  2.4740 +				 NULL, IO_Address);
  2.4741 +		  return 0;
  2.4742 +		}
  2.4743 +	    }
  2.4744 +	  else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA"))
  2.4745 +	    BusLogic_ProbeOptions.NoProbeISA = true;
  2.4746 +	  else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI"))
  2.4747 +	    BusLogic_ProbeOptions.NoProbePCI = true;
  2.4748 +	  else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe"))
  2.4749 +	    BusLogic_ProbeOptions.NoProbe = true;
  2.4750 +	  else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI"))
  2.4751 +	    BusLogic_ProbeOptions.NoSortPCI = true;
  2.4752 +	  else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst"))
  2.4753 +	    BusLogic_ProbeOptions.MultiMasterFirst = true;
  2.4754 +	  else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst"))
  2.4755 +	    BusLogic_ProbeOptions.FlashPointFirst = true;
  2.4756 +	  /* Tagged Queuing Options. */
  2.4757 +	  else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") ||
  2.4758 +		   BusLogic_ParseKeyword(&OptionsString, "QD:["))
  2.4759 +	    {
  2.4760 +	      for (TargetID = 0;
  2.4761 +		   TargetID < BusLogic_MaxTargetDevices;
  2.4762 +		   TargetID++)
  2.4763 +		{
  2.4764 +		  unsigned short QueueDepth =
  2.4765 +		    simple_strtoul(OptionsString, &OptionsString, 0);
  2.4766 +		  if (QueueDepth > BusLogic_MaxTaggedQueueDepth)
  2.4767 +		    {
  2.4768 +		      BusLogic_Error("BusLogic: Invalid Driver Options "
  2.4769 +				     "(illegal Queue Depth %d)\n",
  2.4770 +				     NULL, QueueDepth);
  2.4771 +		      return 0;
  2.4772 +		    }
  2.4773 +		  DriverOptions->QueueDepth[TargetID] = QueueDepth;
  2.4774 +		  if (*OptionsString == ',')
  2.4775 +		    OptionsString++;
  2.4776 +		  else if (*OptionsString == ']')
  2.4777 +		    break;
  2.4778 +		  else
  2.4779 +		    {
  2.4780 +		      BusLogic_Error("BusLogic: Invalid Driver Options "
  2.4781 +				     "(',' or ']' expected at '%s')\n",
  2.4782 +				     NULL, OptionsString);
  2.4783 +		      return 0;
  2.4784 +		    }
  2.4785 +		}
  2.4786 +	      if (*OptionsString != ']')
  2.4787 +		{
  2.4788 +		  BusLogic_Error("BusLogic: Invalid Driver Options "
  2.4789 +				 "(']' expected at '%s')\n",
  2.4790 +				 NULL, OptionsString);
  2.4791 +		  return 0;
  2.4792 +		}
  2.4793 +	      else OptionsString++;
  2.4794 +	    }
  2.4795 +	  else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") ||
  2.4796 +		   BusLogic_ParseKeyword(&OptionsString, "QD:"))
  2.4797 +	    {
  2.4798 +	      unsigned short QueueDepth =
  2.4799 +		simple_strtoul(OptionsString, &OptionsString, 0);
  2.4800 +	      if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth)
  2.4801 +		{
  2.4802 +		  BusLogic_Error("BusLogic: Invalid Driver Options "
  2.4803 +				 "(illegal Queue Depth %d)\n",
  2.4804 +				 NULL, QueueDepth);
  2.4805 +		  return 0;
  2.4806 +		}
  2.4807 +	      DriverOptions->CommonQueueDepth = QueueDepth;
  2.4808 +	      for (TargetID = 0;
  2.4809 +		   TargetID < BusLogic_MaxTargetDevices;
  2.4810 +		   TargetID++)
  2.4811 +		DriverOptions->QueueDepth[TargetID] = QueueDepth;
  2.4812 +	    }
  2.4813 +	  else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") ||
  2.4814 +		   BusLogic_ParseKeyword(&OptionsString, "TQ:"))
  2.4815 +	    {
  2.4816 +	      if (BusLogic_ParseKeyword(&OptionsString, "Default"))
  2.4817 +		{
  2.4818 +		  DriverOptions->TaggedQueuingPermitted = 0x0000;
  2.4819 +		  DriverOptions->TaggedQueuingPermittedMask = 0x0000;
  2.4820 +		}
  2.4821 +	      else if (BusLogic_ParseKeyword(&OptionsString, "Enable"))
  2.4822 +		{
  2.4823 +		  DriverOptions->TaggedQueuingPermitted = 0xFFFF;
  2.4824 +		  DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
  2.4825 +		}
  2.4826 +	      else if (BusLogic_ParseKeyword(&OptionsString, "Disable"))
  2.4827 +		{
  2.4828 +		  DriverOptions->TaggedQueuingPermitted = 0x0000;
  2.4829 +		  DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
  2.4830 +		}
  2.4831 +	      else
  2.4832 +		{
  2.4833 +		  unsigned short TargetBit;
  2.4834 +		  for (TargetID = 0, TargetBit = 1;
  2.4835 +		       TargetID < BusLogic_MaxTargetDevices;
  2.4836 +		       TargetID++, TargetBit <<= 1)
  2.4837 +		    switch (*OptionsString++)
  2.4838 +		      {
  2.4839 +		      case 'Y':
  2.4840 +			DriverOptions->TaggedQueuingPermitted |= TargetBit;
  2.4841 +			DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
  2.4842 +			break;
  2.4843 +		      case 'N':
  2.4844 +			DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
  2.4845 +			DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
  2.4846 +			break;
  2.4847 +		      case 'X':
  2.4848 +			break;
  2.4849 +		      default:
  2.4850 +			OptionsString--;
  2.4851 +			TargetID = BusLogic_MaxTargetDevices;
  2.4852 +			break;
  2.4853 +		      }
  2.4854 +		}
  2.4855 +	    }
  2.4856 +	  /* Error Recovery Option. */
  2.4857 +	  else if (BusLogic_ParseKeyword(&OptionsString, "ErrorRecovery:") ||
  2.4858 +		   BusLogic_ParseKeyword(&OptionsString, "ER:"))
  2.4859 +	    {
  2.4860 +	      if (BusLogic_ParseKeyword(&OptionsString, "Default"))
  2.4861 +		for (TargetID = 0;
  2.4862 +		     TargetID < BusLogic_MaxTargetDevices;
  2.4863 +		     TargetID++)
  2.4864 +		  DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2.4865 +		    BusLogic_ErrorRecovery_Default;
  2.4866 +	      else if (BusLogic_ParseKeyword(&OptionsString, "HardReset"))
  2.4867 +		for (TargetID = 0;
  2.4868 +		     TargetID < BusLogic_MaxTargetDevices;
  2.4869 +		     TargetID++)
  2.4870 +		  DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2.4871 +		    BusLogic_ErrorRecovery_HardReset;
  2.4872 +	      else if (BusLogic_ParseKeyword(&OptionsString, "BusDeviceReset"))
  2.4873 +		for (TargetID = 0;
  2.4874 +		     TargetID < BusLogic_MaxTargetDevices;
  2.4875 +		     TargetID++)
  2.4876 +		  DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2.4877 +		    BusLogic_ErrorRecovery_BusDeviceReset;
  2.4878 +	      else if (BusLogic_ParseKeyword(&OptionsString, "None"))
  2.4879 +		for (TargetID = 0;
  2.4880 +		     TargetID < BusLogic_MaxTargetDevices;
  2.4881 +		     TargetID++)
  2.4882 +		  DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2.4883 +		    BusLogic_ErrorRecovery_None;
  2.4884 +	      else
  2.4885 +		for (TargetID = 0;
  2.4886 +		     TargetID < BusLogic_MaxTargetDevices;
  2.4887 +		     TargetID++)
  2.4888 +		  switch (*OptionsString++)
  2.4889 +		    {
  2.4890 +		    case 'D':
  2.4891 +		      DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2.4892 +			BusLogic_ErrorRecovery_Default;
  2.4893 +		      break;
  2.4894 +		    case 'H':
  2.4895 +		      DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2.4896 +			BusLogic_ErrorRecovery_HardReset;
  2.4897 +		      break;
  2.4898 +		    case 'B':
  2.4899 +		      DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2.4900 +			BusLogic_ErrorRecovery_BusDeviceReset;
  2.4901 +		      break;
  2.4902 +		    case 'N':
  2.4903 +		      DriverOptions->ErrorRecoveryStrategy[TargetID] =
  2.4904 +			BusLogic_ErrorRecovery_None;
  2.4905 +		      break;
  2.4906 +		    default:
  2.4907 +		      OptionsString--;
  2.4908 +		      TargetID = BusLogic_MaxTargetDevices;
  2.4909 +		      break;
  2.4910 +		    }
  2.4911 +	    }
  2.4912 +	  /* Miscellaneous Options. */
  2.4913 +	  else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") ||
  2.4914 +		   BusLogic_ParseKeyword(&OptionsString, "BST:"))
  2.4915 +	    {
  2.4916 +	      unsigned short BusSettleTime =
  2.4917 +		simple_strtoul(OptionsString, &OptionsString, 0);
  2.4918 +	      if (BusSettleTime > 5 * 60)
  2.4919 +		{
  2.4920 +		  BusLogic_Error("BusLogic: Invalid Driver Options "
  2.4921 +				 "(illegal Bus Settle Time %d)\n",
  2.4922 +				 NULL, BusSettleTime);
  2.4923 +		  return 0;
  2.4924 +		}
  2.4925 +	      DriverOptions->BusSettleTime = BusSettleTime;
  2.4926 +	    }
  2.4927 +	  else if (BusLogic_ParseKeyword(&OptionsString,
  2.4928 +					 "InhibitTargetInquiry"))
  2.4929 +	    DriverOptions->LocalOptions.InhibitTargetInquiry = true;
  2.4930 +	  /* Debugging Options. */
  2.4931 +	  else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe"))
  2.4932 +	      BusLogic_GlobalOptions.TraceProbe = true;
  2.4933 +	  else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset"))
  2.4934 +	      BusLogic_GlobalOptions.TraceHardwareReset = true;
  2.4935 +	  else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration"))
  2.4936 +	      BusLogic_GlobalOptions.TraceConfiguration = true;
  2.4937 +	  else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors"))
  2.4938 +	      BusLogic_GlobalOptions.TraceErrors = true;
  2.4939 +	  else if (BusLogic_ParseKeyword(&OptionsString, "Debug"))
  2.4940 +	    {
  2.4941 +	      BusLogic_GlobalOptions.TraceProbe = true;
  2.4942 +	      BusLogic_GlobalOptions.TraceHardwareReset = true;
  2.4943 +	      BusLogic_GlobalOptions.TraceConfiguration = true;
  2.4944 +	      BusLogic_GlobalOptions.TraceErrors = true;
  2.4945 +	    }
  2.4946 +	  if (*OptionsString == ',')
  2.4947 +	    OptionsString++;
  2.4948 +	  else if (*OptionsString != ';' && *OptionsString != '\0')
  2.4949 +	    {
  2.4950 +	      BusLogic_Error("BusLogic: Unexpected Driver Option '%s' "
  2.4951 +			     "ignored\n", NULL, OptionsString);
  2.4952 +	      *OptionsString = '\0';
  2.4953 +	    }
  2.4954 +	}
  2.4955 +      if (!(BusLogic_DriverOptionsCount == 0 ||
  2.4956 +	    BusLogic_ProbeInfoCount == 0 ||
  2.4957 +	    BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount))
  2.4958 +	{
  2.4959 +	  BusLogic_Error("BusLogic: Invalid Driver Options "
  2.4960 +			 "(all or no I/O Addresses must be specified)\n", NULL);
  2.4961 +	  return 0;
  2.4962 +	}
  2.4963 +      /*
  2.4964 +	Tagged Queuing is disabled when the Queue Depth is 1 since queuing
  2.4965 +	multiple commands is not possible.
  2.4966 +      */
  2.4967 +      for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
  2.4968 +	if (DriverOptions->QueueDepth[TargetID] == 1)
  2.4969 +	  {
  2.4970 +	    unsigned short TargetBit = 1 << TargetID;
  2.4971 +	    DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
  2.4972 +	    DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
  2.4973 +	  }
  2.4974 +      if (*OptionsString == ';') OptionsString++;
  2.4975 +      if (*OptionsString == '\0') return 0;
  2.4976 +    }
  2.4977 +    return 1;
  2.4978 +}
  2.4979 +
  2.4980 +
  2.4981 +/*
  2.4982 +  BusLogic_Setup handles processing of Kernel Command Line Arguments.
  2.4983 +*/
  2.4984 +
  2.4985 +static int __init 
  2.4986 +BusLogic_Setup(char *str)
  2.4987 +{
  2.4988 +	int ints[3];
  2.4989 +
  2.4990 +	(void)get_options(str, ARRAY_SIZE(ints), ints);
  2.4991 +
  2.4992 +	if (ints[0] != 0) {
  2.4993 +		BusLogic_Error("BusLogic: Obsolete Command Line Entry "
  2.4994 +				"Format Ignored\n", NULL);
  2.4995 +		return 0;
  2.4996 +	}
  2.4997 +	if (str == NULL || *str == '\0')
  2.4998 +		return 0;
  2.4999 +	return BusLogic_ParseDriverOptions(str);
  2.5000 +}
  2.5001 +
  2.5002 +__setup("BusLogic=", BusLogic_Setup);
  2.5003 +
  2.5004 +#endif /* !XEN */
  2.5005 +
  2.5006 +/*
  2.5007 +  Get it all started
  2.5008 +*/
  2.5009 +MODULE_LICENSE("GPL");
  2.5010 +
  2.5011 +static SCSI_Host_Template_T driver_template = BUSLOGIC;
  2.5012 +
  2.5013 +#include "scsi_module.c.inc"
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/xen/drivers/scsi/BusLogic.h	Sat Nov 08 11:06:04 2003 +0000
     3.3 @@ -0,0 +1,1813 @@
     3.4 +/*
     3.5 +
     3.6 +  Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters
     3.7 +
     3.8 +  Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>
     3.9 +
    3.10 +  This program is free software; you may redistribute and/or modify it under
    3.11 +  the terms of the GNU General Public License Version 2 as published by the
    3.12 +  Free Software Foundation.
    3.13 +
    3.14 +  This program is distributed in the hope that it will be useful, but
    3.15 +  WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
    3.16 +  or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    3.17 +  for complete details.
    3.18 +
    3.19 +  The author respectfully requests that any modifications to this software be
    3.20 +  sent directly to him for evaluation and testing.
    3.21 +
    3.22 +  Special thanks to Wayne Yen, Jin-Lon Hon, and Alex Win of BusLogic, whose
    3.23 +  advice has been invaluable, to David Gentzel, for writing the original Linux
    3.24 +  BusLogic driver, and to Paul Gortmaker, for being such a dedicated test site.
    3.25 +
    3.26 +  Finally, special thanks to Mylex/BusLogic for making the FlashPoint SCCB
    3.27 +  Manager available as freely redistributable source code.
    3.28 +
    3.29 +*/
    3.30 +
    3.31 +
    3.32 +#include <linux/config.h>
    3.33 +
    3.34 +
    3.35 +/*
    3.36 +  Define types for some of the structures that interface with the rest
    3.37 +  of the Linux Kernel and SCSI Subsystem.
    3.38 +*/
    3.39 +
    3.40 +typedef kdev_t KernelDevice_T;
    3.41 +typedef unsigned long ProcessorFlags_T;
    3.42 +typedef struct pt_regs Registers_T;
    3.43 +typedef struct partition PartitionTable_T;
    3.44 +typedef struct pci_dev PCI_Device_T;
    3.45 +typedef Scsi_Host_Template SCSI_Host_Template_T;
    3.46 +typedef struct Scsi_Host SCSI_Host_T;
    3.47 +typedef struct scsi_device SCSI_Device_T;
    3.48 +typedef struct scsi_disk SCSI_Disk_T;
    3.49 +typedef struct scsi_cmnd SCSI_Command_T;
    3.50 +typedef struct scatterlist SCSI_ScatterList_T;
    3.51 +
    3.52 +
    3.53 +/*
    3.54 +  Define prototypes for the BusLogic Driver Interface Functions.
    3.55 +*/
    3.56 +
    3.57 +extern const char *BusLogic_DriverInfo(SCSI_Host_T *);
    3.58 +extern int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *);
    3.59 +extern int BusLogic_ReleaseHostAdapter(SCSI_Host_T *);
    3.60 +extern int BusLogic_QueueCommand(SCSI_Command_T *,
    3.61 +				 void (*CompletionRoutine)(SCSI_Command_T *));
    3.62 +extern int BusLogic_AbortCommand(SCSI_Command_T *);
    3.63 +extern int BusLogic_ResetCommand(SCSI_Command_T *, unsigned int);
    3.64 +extern int BusLogic_BIOSDiskParameters(SCSI_Disk_T *, KernelDevice_T, int *);
    3.65 +#if 0 /* XEN */
    3.66 +extern int BusLogic_ProcDirectoryInfo(char *, char **, off_t, int, int, int);
    3.67 +#endif
    3.68 +
    3.69 +
    3.70 +/*
    3.71 +  Define the BusLogic SCSI Host Template structure.
    3.72 +*/
    3.73 +
    3.74 +#define BUSLOGIC							       \
    3.75 +  { /*proc_name:      "BusLogic",*/			  /* ProcFS Directory Entry */ \
    3.76 +    /*proc_info:      BusLogic_ProcDirectoryInfo,*/	  /* ProcFS Info Function   */ \
    3.77 +    name:           "BusLogic",			  /* Driver Name            */ \
    3.78 +    detect:         BusLogic_DetectHostAdapter,	  /* Detect Host Adapter    */ \
    3.79 +    release:        BusLogic_ReleaseHostAdapter,  /* Release Host Adapter   */ \
    3.80 +    info:           BusLogic_DriverInfo,	  /* Driver Info Function   */ \
    3.81 +    queuecommand:   BusLogic_QueueCommand,	  /* Queue Command Function */ \
    3.82 +    abort:          BusLogic_AbortCommand,	  /* Abort Command Function */ \
    3.83 +    reset:          BusLogic_ResetCommand,	  /* Reset Command Function */ \
    3.84 +    /*bios_param:     BusLogic_BIOSDiskParameters,*/  /* BIOS Disk Parameters   */ \
    3.85 +    unchecked_isa_dma: 1,			  /* Default Initial Value  */ \
    3.86 +    max_sectors:    128,			  /* I/O queue len limit    */ \
    3.87 +    use_clustering: ENABLE_CLUSTERING }		  /* Enable Clustering	    */
    3.88 +
    3.89 +
    3.90 +/*
    3.91 +  BusLogic_DriverVersion protects the private portion of this file.
    3.92 +*/
    3.93 +
    3.94 +#ifdef BusLogic_DriverVersion
    3.95 +
    3.96 +
    3.97 +/*
    3.98 +  FlashPoint support is only available for the Intel x86 Architecture with
    3.99 +  CONFIG_PCI set.
   3.100 +*/
   3.101 +
   3.102 +#ifndef __i386__
   3.103 +#undef CONFIG_SCSI_OMIT_FLASHPOINT
   3.104 +#define CONFIG_SCSI_OMIT_FLASHPOINT
   3.105 +#endif
   3.106 +
   3.107 +#ifndef CONFIG_PCI
   3.108 +#undef CONFIG_SCSI_OMIT_FLASHPOINT
   3.109 +#define CONFIG_SCSI_OMIT_FLASHPOINT
   3.110 +#define BusLogic_InitializeProbeInfoListISA \
   3.111 +  BusLogic_InitializeProbeInfoList
   3.112 +#endif
   3.113 +
   3.114 +
   3.115 +/*
   3.116 +  Define the maximum number of BusLogic Host Adapters supported by this driver.
   3.117 +*/
   3.118 +
   3.119 +#define BusLogic_MaxHostAdapters		16
   3.120 +
   3.121 +
   3.122 +/*
   3.123 +  Define the maximum number of Target Devices supported by this driver.
   3.124 +*/
   3.125 +
   3.126 +#define BusLogic_MaxTargetDevices		16
   3.127 +
   3.128 +
   3.129 +/*
   3.130 +  Define the maximum number of Scatter/Gather Segments used by this driver.
   3.131 +  For optimal performance, it is important that this limit be at least as
   3.132 +  large as the largest single request generated by the I/O Subsystem.
   3.133 +*/
   3.134 +
   3.135 +#define BusLogic_ScatterGatherLimit		128
   3.136 +
   3.137 +
   3.138 +/*
   3.139 +  Define the maximum, maximum automatic, minimum automatic, and default Queue
   3.140 +  Depth to allow for Target Devices depending on whether or not they support
   3.141 +  Tagged Queuing and whether or not ISA Bounce Buffers are required.
   3.142 +*/
   3.143 +
   3.144 +#define BusLogic_MaxTaggedQueueDepth		64
   3.145 +#define BusLogic_MaxAutomaticTaggedQueueDepth	28
   3.146 +#define BusLogic_MinAutomaticTaggedQueueDepth	7
   3.147 +#define BusLogic_TaggedQueueDepthBB		3
   3.148 +#define BusLogic_UntaggedQueueDepth		3
   3.149 +#define BusLogic_UntaggedQueueDepthBB		2
   3.150 +
   3.151 +
   3.152 +/*
   3.153 +  Define the default amount of time in seconds to wait between a Host Adapter
   3.154 +  Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI commands.
   3.155 +  Some SCSI devices get confused if they receive SCSI commands too soon after
   3.156 +  a SCSI Bus Reset.
   3.157 +*/
   3.158 +
   3.159 +#define BusLogic_DefaultBusSettleTime		2
   3.160 +
   3.161 +
   3.162 +/*
   3.163 +  Define the maximum number of Mailboxes that should be used for MultiMaster
   3.164 +  Host Adapters.  This number is chosen to be larger than the maximum Host
   3.165 +  Adapter Queue Depth and small enough so that the Host Adapter structure
   3.166 +  does not cross an allocation block size boundary.
   3.167 +*/
   3.168 +
   3.169 +#define BusLogic_MaxMailboxes			211
   3.170 +
   3.171 +
   3.172 +/*
   3.173 +  Define the number of CCBs that should be allocated as a group to optimize
   3.174 +  Kernel memory allocation.
   3.175 +*/
   3.176 +
   3.177 +#define BusLogic_CCB_AllocationGroupSize	7
   3.178 +
   3.179 +
   3.180 +/*
   3.181 +  Define the Host Adapter Line and Message Buffer Sizes.
   3.182 +*/
   3.183 +
   3.184 +#define BusLogic_LineBufferSize			100
   3.185 +#define BusLogic_MessageBufferSize		9700
   3.186 +
   3.187 +
   3.188 +/*
   3.189 +  Define the Driver Message Levels.
   3.190 +*/
   3.191 +
   3.192 +typedef enum BusLogic_MessageLevel
   3.193 +{
   3.194 +  BusLogic_AnnounceLevel =			0,
   3.195 +  BusLogic_InfoLevel =				1,
   3.196 +  BusLogic_NoticeLevel =			2,
   3.197 +  BusLogic_WarningLevel =			3,
   3.198 +  BusLogic_ErrorLevel =				4
   3.199 +}
   3.200 +BusLogic_MessageLevel_T;
   3.201 +
   3.202 +static char
   3.203 +  *BusLogic_MessageLevelMap[] =
   3.204 +    { KERN_NOTICE, KERN_NOTICE, KERN_NOTICE, KERN_WARNING, KERN_ERR };
   3.205 +
   3.206 +
   3.207 +/*
   3.208 +  Define Driver Message macros.
   3.209 +*/
   3.210 +
   3.211 +#define BusLogic_Announce(Format, Arguments...) \
   3.212 +  BusLogic_Message(BusLogic_AnnounceLevel, Format, ##Arguments)
   3.213 +
   3.214 +#define BusLogic_Info(Format, Arguments...) \
   3.215 +  BusLogic_Message(BusLogic_InfoLevel, Format, ##Arguments)
   3.216 +
   3.217 +#define BusLogic_Notice(Format, Arguments...) \
   3.218 +  BusLogic_Message(BusLogic_NoticeLevel, Format, ##Arguments)
   3.219 +
   3.220 +#define BusLogic_Warning(Format, Arguments...) \
   3.221 +  BusLogic_Message(BusLogic_WarningLevel, Format, ##Arguments)
   3.222 +
   3.223 +#define BusLogic_Error(Format, Arguments...) \
   3.224 +  BusLogic_Message(BusLogic_ErrorLevel, Format, ##Arguments)
   3.225 +
   3.226 +
   3.227 +/*
   3.228 +  Define the types of BusLogic Host Adapters that are supported and the number
   3.229 +  of I/O Addresses required by each type.
   3.230 +*/
   3.231 +
   3.232 +typedef enum
   3.233 +{
   3.234 +  BusLogic_MultiMaster =			1,
   3.235 +  BusLogic_FlashPoint =				2
   3.236 +}
   3.237 +__attribute__ ((packed))
   3.238 +BusLogic_HostAdapterType_T;
   3.239 +
   3.240 +#define BusLogic_MultiMasterAddressCount	4
   3.241 +#define BusLogic_FlashPointAddressCount		256
   3.242 +
   3.243 +static int
   3.244 +  BusLogic_HostAdapterAddressCount[3] =
   3.245 +    { 0, BusLogic_MultiMasterAddressCount, BusLogic_FlashPointAddressCount };
   3.246 +
   3.247 +
   3.248 +/*
   3.249 +  Define macros for testing the Host Adapter Type.
   3.250 +*/
   3.251 +
   3.252 +#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
   3.253 +
   3.254 +#define BusLogic_MultiMasterHostAdapterP(HostAdapter) \
   3.255 +  (HostAdapter->HostAdapterType == BusLogic_MultiMaster)
   3.256 +
   3.257 +#define BusLogic_FlashPointHostAdapterP(HostAdapter) \
   3.258 +  (HostAdapter->HostAdapterType == BusLogic_FlashPoint)
   3.259 +
   3.260 +#else
   3.261 +
   3.262 +#define BusLogic_MultiMasterHostAdapterP(HostAdapter) \
   3.263 +  (true)
   3.264 +
   3.265 +#define BusLogic_FlashPointHostAdapterP(HostAdapter) \
   3.266 +  (false)
   3.267 +
   3.268 +#endif
   3.269 +
   3.270 +
   3.271 +/*
   3.272 +  Define the possible Host Adapter Bus Types.
   3.273 +*/
   3.274 +
   3.275 +typedef enum
   3.276 +{
   3.277 +  BusLogic_Unknown_Bus =			0,
   3.278 +  BusLogic_ISA_Bus =				1,
   3.279 +  BusLogic_EISA_Bus =				2,
   3.280 +  BusLogic_PCI_Bus =				3,
   3.281 +  BusLogic_VESA_Bus =				4,
   3.282 +  BusLogic_MCA_Bus =				5
   3.283 +}
   3.284 +__attribute__ ((packed))
   3.285 +BusLogic_HostAdapterBusType_T;
   3.286 +
   3.287 +static char
   3.288 +  *BusLogic_HostAdapterBusNames[] =
   3.289 +    { "Unknown", "ISA", "EISA", "PCI", "VESA", "MCA" };
   3.290 +
   3.291 +static BusLogic_HostAdapterBusType_T
   3.292 +  BusLogic_HostAdapterBusTypes[] =
   3.293 +    { BusLogic_VESA_Bus,				/* BT-4xx */
   3.294 +      BusLogic_ISA_Bus,					/* BT-5xx */
   3.295 +      BusLogic_MCA_Bus,					/* BT-6xx */
   3.296 +      BusLogic_EISA_Bus,				/* BT-7xx */
   3.297 +      BusLogic_Unknown_Bus,				/* BT-8xx */
   3.298 +      BusLogic_PCI_Bus };				/* BT-9xx */
   3.299 +
   3.300 +
   3.301 +/*
   3.302 +  Define the possible Host Adapter BIOS Disk Geometry Translations.
   3.303 +*/
   3.304 +
   3.305 +typedef enum BusLogic_BIOS_DiskGeometryTranslation
   3.306 +{
   3.307 +  BusLogic_BIOS_Disk_Not_Installed =		0,
   3.308 +  BusLogic_BIOS_Disk_Installed_64x32 =		1,
   3.309 +  BusLogic_BIOS_Disk_Installed_128x32 =		2,
   3.310 +  BusLogic_BIOS_Disk_Installed_255x63 =		3
   3.311 +}
   3.312 +__attribute__ ((packed))
   3.313 +BusLogic_BIOS_DiskGeometryTranslation_T;
   3.314 +
   3.315 +
   3.316 +/*
   3.317 +  Define a Boolean data type.
   3.318 +*/
   3.319 +
   3.320 +typedef enum { false, true } __attribute__ ((packed)) boolean;
   3.321 +
   3.322 +
   3.323 +/*
   3.324 +  Define a 32 bit I/O Address data type.
   3.325 +*/
   3.326 +
   3.327 +typedef unsigned int BusLogic_IO_Address_T;
   3.328 +
   3.329 +
   3.330 +/*
   3.331 +  Define a 32 bit PCI Bus Address data type.
   3.332 +*/
   3.333 +
   3.334 +typedef unsigned int BusLogic_PCI_Address_T;
   3.335 +
   3.336 +
   3.337 +/*
   3.338 +  Define a 32 bit Base Address data type.
   3.339 +*/
   3.340 +
   3.341 +typedef unsigned int BusLogic_Base_Address_T;
   3.342 +
   3.343 +
   3.344 +/*
   3.345 +  Define a 32 bit Bus Address data type.
   3.346 +*/
   3.347 +
   3.348 +typedef unsigned int BusLogic_BusAddress_T;
   3.349 +
   3.350 +
   3.351 +/*
   3.352 +  Define a 32 bit Byte Count data type.
   3.353 +*/
   3.354 +
   3.355 +typedef unsigned int BusLogic_ByteCount_T;
   3.356 +
   3.357 +
   3.358 +/*
   3.359 +  Define a 10^18 Statistics Byte Counter data type.
   3.360 +*/
   3.361 +
   3.362 +typedef struct BusLogic_ByteCounter
   3.363 +{
   3.364 +  unsigned int Units;
   3.365 +  unsigned int Billions;
   3.366 +}
   3.367 +BusLogic_ByteCounter_T;
   3.368 +
   3.369 +
   3.370 +/*
   3.371 +  Define the structure for I/O Address and Bus Probing Information.
   3.372 +*/
   3.373 +
   3.374 +typedef struct BusLogic_ProbeInfo
   3.375 +{
   3.376 +  BusLogic_HostAdapterType_T HostAdapterType;
   3.377 +  BusLogic_HostAdapterBusType_T HostAdapterBusType;
   3.378 +  BusLogic_IO_Address_T IO_Address;
   3.379 +  BusLogic_PCI_Address_T PCI_Address;
   3.380 +  unsigned char Bus;
   3.381 +  unsigned char Device;
   3.382 +  unsigned char IRQ_Channel;
   3.383 +}
   3.384 +BusLogic_ProbeInfo_T;
   3.385 +
   3.386 +
   3.387 +/*
   3.388 +  Define the Probe Options.
   3.389 +*/
   3.390 +
   3.391 +typedef struct BusLogic_ProbeOptions
   3.392 +{
   3.393 +  boolean NoProbe:1;					/* Bit 0 */
   3.394 +  boolean NoProbeISA:1;					/* Bit 1 */
   3.395 +  boolean NoProbePCI:1;					/* Bit 2 */
   3.396 +  boolean NoSortPCI:1;					/* Bit 3 */
   3.397 +  boolean MultiMasterFirst:1;				/* Bit 4 */
   3.398 +  boolean FlashPointFirst:1;				/* Bit 5 */
   3.399 +  boolean LimitedProbeISA:1;				/* Bit 6 */
   3.400 +  boolean Probe330:1;					/* Bit 7 */
   3.401 +  boolean Probe334:1;					/* Bit 8 */
   3.402 +  boolean Probe230:1;					/* Bit 9 */
   3.403 +  boolean Probe234:1;					/* Bit 10 */
   3.404 +  boolean Probe130:1;					/* Bit 11 */
   3.405 +  boolean Probe134:1;					/* Bit 12 */
   3.406 +}
   3.407 +BusLogic_ProbeOptions_T;
   3.408 +
   3.409 +
   3.410 +/*
   3.411 +  Define the Global Options.
   3.412 +*/
   3.413 +
   3.414 +typedef struct BusLogic_GlobalOptions
   3.415 +{
   3.416 +  boolean TraceProbe:1;					/* Bit 0 */
   3.417 +  boolean TraceHardwareReset:1;				/* Bit 1 */
   3.418 +  boolean TraceConfiguration:1;				/* Bit 2 */
   3.419 +  boolean TraceErrors:1;				/* Bit 3 */
   3.420 +}
   3.421 +BusLogic_GlobalOptions_T;
   3.422 +
   3.423 +
   3.424 +/*
   3.425 +  Define the Local Options.
   3.426 +*/
   3.427 +
   3.428 +typedef struct BusLogic_LocalOptions
   3.429 +{
   3.430 +  boolean InhibitTargetInquiry:1;			/* Bit 0 */
   3.431 +}
   3.432 +BusLogic_LocalOptions_T;
   3.433 +
   3.434 +
   3.435 +/*
   3.436 +  Define the Error Recovery Strategy Options.
   3.437 +*/
   3.438 +
   3.439 +typedef enum
   3.440 +{
   3.441 +  BusLogic_ErrorRecovery_Default =		0,
   3.442 +  BusLogic_ErrorRecovery_BusDeviceReset =	1,
   3.443 +  BusLogic_ErrorRecovery_HardReset =		2,
   3.444 +  BusLogic_ErrorRecovery_None =			3
   3.445 +}
   3.446 +__attribute__ ((packed))
   3.447 +BusLogic_ErrorRecoveryStrategy_T;
   3.448 +
   3.449 +static char
   3.450 +  *BusLogic_ErrorRecoveryStrategyNames[] =
   3.451 +    { "Default", "Bus Device Reset", "Hard Reset", "None" },
   3.452 +  BusLogic_ErrorRecoveryStrategyLetters[] =
   3.453 +    { 'D', 'B', 'H', 'N' };
   3.454 +
   3.455 +
   3.456 +/*
   3.457 +  Define the BusLogic SCSI Host Adapter I/O Register Offsets.
   3.458 +*/
   3.459 +
   3.460 +#define BusLogic_ControlRegisterOffset		0	/* WO register */
   3.461 +#define BusLogic_StatusRegisterOffset		0	/* RO register */
   3.462 +#define BusLogic_CommandParameterRegisterOffset	1	/* WO register */
   3.463 +#define BusLogic_DataInRegisterOffset		1	/* RO register */
   3.464 +#define BusLogic_InterruptRegisterOffset	2	/* RO register */
   3.465 +#define BusLogic_GeometryRegisterOffset		3	/* RO register */
   3.466 +
   3.467 +
   3.468 +/*
   3.469 +  Define the structure of the write-only Control Register.
   3.470 +*/
   3.471 +
   3.472 +typedef union BusLogic_ControlRegister
   3.473 +{
   3.474 +  unsigned char All;
   3.475 +  struct {
   3.476 +    unsigned char :4;					/* Bits 0-3 */
   3.477 +    boolean SCSIBusReset:1;				/* Bit 4 */
   3.478 +    boolean InterruptReset:1;				/* Bit 5 */
   3.479 +    boolean SoftReset:1;				/* Bit 6 */
   3.480 +    boolean HardReset:1;				/* Bit 7 */
   3.481 +  } Bits;
   3.482 +}
   3.483 +BusLogic_ControlRegister_T;
   3.484 +
   3.485 +
   3.486 +/*
   3.487 +  Define the structure of the read-only Status Register.
   3.488 +*/
   3.489 +
   3.490 +typedef union BusLogic_StatusRegister
   3.491 +{
   3.492 +  unsigned char All;
   3.493 +  struct {
   3.494 +    boolean CommandInvalid:1;				/* Bit 0 */
   3.495 +    boolean Reserved:1;					/* Bit 1 */
   3.496 +    boolean DataInRegisterReady:1;			/* Bit 2 */
   3.497 +    boolean CommandParameterRegisterBusy:1;		/* Bit 3 */
   3.498 +    boolean HostAdapterReady:1;				/* Bit 4 */
   3.499 +    boolean InitializationRequired:1;			/* Bit 5 */
   3.500 +    boolean DiagnosticFailure:1;			/* Bit 6 */
   3.501 +    boolean DiagnosticActive:1;				/* Bit 7 */
   3.502 +  } Bits;
   3.503 +}
   3.504 +BusLogic_StatusRegister_T;
   3.505 +
   3.506 +
   3.507 +/*
   3.508 +  Define the structure of the read-only Interrupt Register.
   3.509 +*/
   3.510 +
   3.511 +typedef union BusLogic_InterruptRegister
   3.512 +{
   3.513 +  unsigned char All;
   3.514 +  struct {
   3.515 +    boolean IncomingMailboxLoaded:1;			/* Bit 0 */
   3.516 +    boolean OutgoingMailboxAvailable:1;			/* Bit 1 */
   3.517 +    boolean CommandComplete:1;				/* Bit 2 */
   3.518 +    boolean ExternalBusReset:1;				/* Bit 3 */
   3.519 +    unsigned char Reserved:3;				/* Bits 4-6 */
   3.520 +    boolean InterruptValid:1;				/* Bit 7 */
   3.521 +  } Bits;
   3.522 +}
   3.523 +BusLogic_InterruptRegister_T;
   3.524 +
   3.525 +
   3.526 +/*
   3.527 +  Define the structure of the read-only Geometry Register.
   3.528 +*/
   3.529 +
   3.530 +typedef union BusLogic_GeometryRegister
   3.531 +{
   3.532 +  unsigned char All;
   3.533 +  struct {
   3.534 +    BusLogic_BIOS_DiskGeometryTranslation_T Drive0Geometry:2; /* Bits 0-1 */
   3.535 +    BusLogic_BIOS_DiskGeometryTranslation_T Drive1Geometry:2; /* Bits 2-3 */
   3.536 +    unsigned char :3;					/* Bits 4-6 */
   3.537 +    boolean ExtendedTranslationEnabled:1;		/* Bit 7 */
   3.538 +  } Bits;
   3.539 +}
   3.540 +BusLogic_GeometryRegister_T;
   3.541 +
   3.542 +
   3.543 +/*
   3.544 +  Define the BusLogic SCSI Host Adapter Command Register Operation Codes.
   3.545 +*/
   3.546 +
   3.547 +typedef enum
   3.548 +{
   3.549 +  BusLogic_TestCommandCompleteInterrupt =	0x00,
   3.550 +  BusLogic_InitializeMailbox =			0x01,
   3.551 +  BusLogic_ExecuteMailboxCommand =		0x02,
   3.552 +  BusLogic_ExecuteBIOSCommand =			0x03,
   3.553 +  BusLogic_InquireBoardID =			0x04,
   3.554 +  BusLogic_EnableOutgoingMailboxAvailableInt =	0x05,
   3.555 +  BusLogic_SetSCSISelectionTimeout =		0x06,
   3.556 +  BusLogic_SetPreemptTimeOnBus =		0x07,
   3.557 +  BusLogic_SetTimeOffBus =			0x08,
   3.558 +  BusLogic_SetBusTransferRate =			0x09,
   3.559 +  BusLogic_InquireInstalledDevicesID0to7 =	0x0A,
   3.560 +  BusLogic_InquireConfiguration =		0x0B,
   3.561 +  BusLogic_EnableTargetMode =			0x0C,
   3.562 +  BusLogic_InquireSetupInformation =		0x0D,
   3.563 +  BusLogic_WriteAdapterLocalRAM =		0x1A,
   3.564 +  BusLogic_ReadAdapterLocalRAM =		0x1B,
   3.565 +  BusLogic_WriteBusMasterChipFIFO =		0x1C,
   3.566 +  BusLogic_ReadBusMasterChipFIFO =		0x1D,
   3.567 +  BusLogic_EchoCommandData =			0x1F,
   3.568 +  BusLogic_HostAdapterDiagnostic =		0x20,
   3.569 +  BusLogic_SetAdapterOptions =			0x21,
   3.570 +  BusLogic_InquireInstalledDevicesID8to15 =	0x23,
   3.571 +  BusLogic_InquireTargetDevices =		0x24,
   3.572 +  BusLogic_DisableHostAdapterInterrupt =	0x25,
   3.573 +  BusLogic_InitializeExtendedMailbox =		0x81,
   3.574 +  BusLogic_ExecuteSCSICommand =			0x83,
   3.575 +  BusLogic_InquireFirmwareVersion3rdDigit =	0x84,
   3.576 +  BusLogic_InquireFirmwareVersionLetter =	0x85,
   3.577 +  BusLogic_InquirePCIHostAdapterInformation =	0x86,
   3.578 +  BusLogic_InquireHostAdapterModelNumber =	0x8B,
   3.579 +  BusLogic_InquireSynchronousPeriod =		0x8C,
   3.580 +  BusLogic_InquireExtendedSetupInformation =	0x8D,
   3.581 +  BusLogic_EnableStrictRoundRobinMode =		0x8F,
   3.582 +  BusLogic_StoreHostAdapterLocalRAM =		0x90,
   3.583 +  BusLogic_FetchHostAdapterLocalRAM =		0x91,
   3.584 +  BusLogic_StoreLocalDataInEEPROM =		0x92,
   3.585 +  BusLogic_UploadAutoSCSICode =			0x94,
   3.586 +  BusLogic_ModifyIOAddress =			0x95,
   3.587 +  BusLogic_SetCCBFormat =			0x96,
   3.588 +  BusLogic_WriteInquiryBuffer =			0x9A,
   3.589 +  BusLogic_ReadInquiryBuffer =			0x9B,
   3.590 +  BusLogic_FlashROMUploadDownload =		0xA7,
   3.591 +  BusLogic_ReadSCAMData =			0xA8,
   3.592 +  BusLogic_WriteSCAMData =			0xA9
   3.593 +}
   3.594 +BusLogic_OperationCode_T;
   3.595 +
   3.596 +
   3.597 +/*
   3.598 +  Define the Inquire Board ID reply structure.
   3.599 +*/
   3.600 +
   3.601 +typedef struct BusLogic_BoardID
   3.602 +{
   3.603 +  unsigned char BoardType;				/* Byte 0 */
   3.604 +  unsigned char CustomFeatures;				/* Byte 1 */
   3.605 +  unsigned char FirmwareVersion1stDigit;		/* Byte 2 */
   3.606 +  unsigned char FirmwareVersion2ndDigit;		/* Byte 3 */
   3.607 +}
   3.608 +BusLogic_BoardID_T;
   3.609 +
   3.610 +
   3.611 +/*
   3.612 +  Define the Inquire Installed Devices ID 0 to 7 and Inquire Installed
   3.613 +  Devices ID 8 to 15 reply type.  For each Target Device, a byte is returned
   3.614 +  where bit 0 set indicates that Logical Unit 0 exists, bit 1 set indicates
   3.615 +  that Logical Unit 1 exists, and so on.
   3.616 +*/
   3.617 +
   3.618 +typedef unsigned char BusLogic_InstalledDevices8_T[8];
   3.619 +
   3.620 +
   3.621 +/*
   3.622 +  Define the Inquire Target Devices reply type.  Inquire Target Devices only
   3.623 +  tests Logical Unit 0 of each Target Device unlike the Inquire Installed
   3.624 +  Devices commands which test Logical Units 0 - 7.  Two bytes are returned,
   3.625 +  where byte 0 bit 0 set indicates that Target Device 0 exists, and so on.
   3.626 +*/
   3.627 +
   3.628 +typedef unsigned short BusLogic_InstalledDevices_T;
   3.629 +
   3.630 +
   3.631 +/*
   3.632 +  Define the Inquire Configuration reply structure.
   3.633 +*/
   3.634 +
   3.635 +typedef struct BusLogic_Configuration
   3.636 +{
   3.637 +  unsigned char :5;					/* Byte 0 Bits 0-4 */
   3.638 +  boolean DMA_Channel5:1;				/* Byte 0 Bit 5 */
   3.639 +  boolean DMA_Channel6:1;				/* Byte 0 Bit 6 */
   3.640 +  boolean DMA_Channel7:1;				/* Byte 0 Bit 7 */
   3.641 +  boolean IRQ_Channel9:1;				/* Byte 1 Bit 0 */
   3.642 +  boolean IRQ_Channel10:1;				/* Byte 1 Bit 1 */
   3.643 +  boolean IRQ_Channel11:1;				/* Byte 1 Bit 2 */
   3.644 +  boolean IRQ_Channel12:1;				/* Byte 1 Bit 3 */
   3.645 +  unsigned char :1;					/* Byte 1 Bit 4 */
   3.646 +  boolean IRQ_Channel14:1;				/* Byte 1 Bit 5 */
   3.647 +  boolean IRQ_Channel15:1;				/* Byte 1 Bit 6 */
   3.648 +  unsigned char :1;					/* Byte 1 Bit 7 */
   3.649 +  unsigned char HostAdapterID:4;			/* Byte 2 Bits 0-3 */
   3.650 +  unsigned char :4;					/* Byte 2 Bits 4-7 */
   3.651 +}
   3.652 +BusLogic_Configuration_T;
   3.653 +
   3.654 +
   3.655 +/*
   3.656 +  Define the Inquire Setup Information reply structure.
   3.657 +*/
   3.658 +
   3.659 +typedef struct BusLogic_SynchronousValue
   3.660 +{
   3.661 +  unsigned char Offset:4;				/* Bits 0-3 */
   3.662 +  unsigned char TransferPeriod:3;			/* Bits 4-6 */
   3.663 +  boolean Synchronous:1;				/* Bit 7 */
   3.664 +}
   3.665 +BusLogic_SynchronousValue_T;
   3.666 +
   3.667 +typedef BusLogic_SynchronousValue_T
   3.668 +  BusLogic_SynchronousValues8_T[8];
   3.669 +
   3.670 +typedef BusLogic_SynchronousValue_T
   3.671 +  BusLogic_SynchronousValues_T[BusLogic_MaxTargetDevices];
   3.672 +
   3.673 +typedef struct BusLogic_SetupInformation
   3.674 +{
   3.675 +  boolean SynchronousInitiationEnabled:1;		/* Byte 0 Bit 0 */
   3.676 +  boolean ParityCheckingEnabled:1;			/* Byte 0 Bit 1 */
   3.677 +  unsigned char :6;					/* Byte 0 Bits 2-7 */
   3.678 +  unsigned char BusTransferRate;			/* Byte 1 */
   3.679 +  unsigned char PreemptTimeOnBus;			/* Byte 2 */
   3.680 +  unsigned char TimeOffBus;				/* Byte 3 */
   3.681 +  unsigned char MailboxCount;				/* Byte 4 */
   3.682 +  unsigned char MailboxAddress[3];			/* Bytes 5-7 */
   3.683 +  BusLogic_SynchronousValues8_T SynchronousValuesID0to7; /* Bytes 8-15 */
   3.684 +  unsigned char DisconnectPermittedID0to7;		/* Byte 16 */
   3.685 +  unsigned char Signature;				/* Byte 17 */
   3.686 +  unsigned char CharacterD;				/* Byte 18 */
   3.687 +  unsigned char HostBusType;				/* Byte 19 */
   3.688 +  unsigned char WideTransfersPermittedID0to7;		/* Byte 20 */
   3.689 +  unsigned char WideTransfersActiveID0to7;		/* Byte 21 */
   3.690 +  BusLogic_SynchronousValues8_T SynchronousValuesID8to15; /* Bytes 22-29 */
   3.691 +  unsigned char DisconnectPermittedID8to15;		/* Byte 30 */
   3.692 +  unsigned char :8;					/* Byte 31 */
   3.693 +  unsigned char WideTransfersPermittedID8to15;		/* Byte 32 */
   3.694 +  unsigned char WideTransfersActiveID8to15;		/* Byte 33 */
   3.695 +}
   3.696 +BusLogic_SetupInformation_T;
   3.697 +
   3.698 +
   3.699 +/*
   3.700 +  Define the Initialize Extended Mailbox request structure.
   3.701 +*/
   3.702 +
   3.703 +typedef struct BusLogic_ExtendedMailboxRequest
   3.704 +{
   3.705 +  unsigned char MailboxCount;				/* Byte 0 */
   3.706 +  BusLogic_BusAddress_T BaseMailboxAddress;		/* Bytes 1-4 */
   3.707 +}
   3.708 +__attribute__ ((packed))
   3.709 +BusLogic_ExtendedMailboxRequest_T;
   3.710 +
   3.711 +
   3.712 +/*
   3.713 +  Define the Inquire Firmware Version 3rd Digit reply type.
   3.714 +*/
   3.715 +
   3.716 +typedef unsigned char BusLogic_FirmwareVersion3rdDigit_T;
   3.717 +
   3.718 +
   3.719 +/*
   3.720 +  Define the Inquire Firmware Version Letter reply type.
   3.721 +*/
   3.722 +
   3.723 +typedef unsigned char BusLogic_FirmwareVersionLetter_T;
   3.724 +
   3.725 +
   3.726 +/*
   3.727 +  Define the Inquire PCI Host Adapter Information reply type.  The ISA
   3.728 +  Compatible I/O Port values are defined here and are also used with
   3.729 +  the Modify I/O Address command.
   3.730 +*/
   3.731 +
   3.732 +typedef enum BusLogic_ISACompatibleIOPort
   3.733 +{
   3.734 +  BusLogic_IO_330 =				0,
   3.735 +  BusLogic_IO_334 =				1,
   3.736 +  BusLogic_IO_230 =				2,
   3.737 +  BusLogic_IO_234 =				3,
   3.738 +  BusLogic_IO_130 =				4,
   3.739 +  BusLogic_IO_134 =				5,
   3.740 +  BusLogic_IO_Disable =				6,
   3.741 +  BusLogic_IO_Disable2 =			7
   3.742 +}
   3.743 +__attribute__ ((packed))
   3.744 +BusLogic_ISACompatibleIOPort_T;
   3.745 +
   3.746 +typedef struct BusLogic_PCIHostAdapterInformation
   3.747 +{
   3.748 +  BusLogic_ISACompatibleIOPort_T ISACompatibleIOPort;	/* Byte 0 */
   3.749 +  unsigned char PCIAssignedIRQChannel;			/* Byte 1 */
   3.750 +  boolean LowByteTerminated:1;				/* Byte 2 Bit 0 */
   3.751 +  boolean HighByteTerminated:1;				/* Byte 2 Bit 1 */
   3.752 +  unsigned char :2;					/* Byte 2 Bits 2-3 */
   3.753 +  boolean JP1:1;					/* Byte 2 Bit 4 */
   3.754 +  boolean JP2:1;					/* Byte 2 Bit 5 */
   3.755 +  boolean JP3:1;					/* Byte 2 Bit 6 */
   3.756 +  boolean GenericInfoValid:1;				/* Byte 2 Bit 7 */
   3.757 +  unsigned char :8;					/* Byte 3 */
   3.758 +}
   3.759 +BusLogic_PCIHostAdapterInformation_T;
   3.760 +
   3.761 +
   3.762 +/*
   3.763 +  Define the Inquire Host Adapter Model Number reply type.
   3.764 +*/
   3.765 +
   3.766 +typedef unsigned char BusLogic_HostAdapterModelNumber_T[5];
   3.767 +
   3.768 +
   3.769 +/*
   3.770 +  Define the Inquire Synchronous Period reply type.  For each Target Device,
   3.771 +  a byte is returned which represents the Synchronous Transfer Period in units
   3.772 +  of 10 nanoseconds.
   3.773 +*/
   3.774 +
   3.775 +typedef unsigned char BusLogic_SynchronousPeriod_T[BusLogic_MaxTargetDevices];
   3.776 +
   3.777 +
   3.778 +/*
   3.779 +  Define the Inquire Extended Setup Information reply structure.
   3.780 +*/
   3.781 +
   3.782 +typedef struct BusLogic_ExtendedSetupInformation
   3.783 +{
   3.784 +  unsigned char BusType;				/* Byte 0 */
   3.785 +  unsigned char BIOS_Address;				/* Byte 1 */
   3.786 +  unsigned short ScatterGatherLimit;			/* Bytes 2-3 */
   3.787 +  unsigned char MailboxCount;				/* Byte 4 */
   3.788 +  BusLogic_BusAddress_T BaseMailboxAddress;		/* Bytes 5-8 */
   3.789 +  struct { unsigned char :2;				/* Byte 9 Bits 0-1 */
   3.790 +	   boolean FastOnEISA:1;			/* Byte 9 Bit 2 */
   3.791 +	   unsigned char :3;				/* Byte 9 Bits 3-5 */
   3.792 +	   boolean LevelSensitiveInterrupt:1;		/* Byte 9 Bit 6 */
   3.793 +	   unsigned char :1; } Misc;			/* Byte 9 Bit 7 */
   3.794 +  unsigned char FirmwareRevision[3];			/* Bytes 10-12 */
   3.795 +  boolean HostWideSCSI:1;				/* Byte 13 Bit 0 */
   3.796 +  boolean HostDifferentialSCSI:1;			/* Byte 13 Bit 1 */
   3.797 +  boolean HostSupportsSCAM:1;				/* Byte 13 Bit 2 */
   3.798 +  boolean HostUltraSCSI:1;				/* Byte 13 Bit 3 */
   3.799 +  boolean HostSmartTermination:1;			/* Byte 13 Bit 4 */
   3.800 +  unsigned char :3;					/* Byte 13 Bits 5-7 */
   3.801 +}
   3.802 +__attribute__ ((packed))
   3.803 +BusLogic_ExtendedSetupInformation_T;
   3.804 +
   3.805 +
   3.806 +/*
   3.807 +  Define the Enable Strict Round Robin Mode request type.
   3.808 +*/
   3.809 +
   3.810 +typedef enum BusLogic_RoundRobinModeRequest
   3.811 +{
   3.812 +  BusLogic_AggressiveRoundRobinMode =		0,
   3.813 +  BusLogic_StrictRoundRobinMode =		1
   3.814 +}
   3.815 +__attribute__ ((packed))
   3.816 +BusLogic_RoundRobinModeRequest_T;
   3.817 +
   3.818 +
   3.819 +/*
   3.820 +  Define the Fetch Host Adapter Local RAM request type.
   3.821 +*/
   3.822 +
   3.823 +#define BusLogic_BIOS_BaseOffset		0
   3.824 +#define BusLogic_AutoSCSI_BaseOffset		64
   3.825 +
   3.826 +typedef struct BusLogic_FetchHostAdapterLocalRAMRequest
   3.827 +{
   3.828 +  unsigned char ByteOffset;				/* Byte 0 */
   3.829 +  unsigned char ByteCount;				/* Byte 1 */
   3.830 +}
   3.831 +BusLogic_FetchHostAdapterLocalRAMRequest_T;
   3.832 +
   3.833 +
   3.834 +/*
   3.835 +  Define the Host Adapter Local RAM AutoSCSI structure.
   3.836 +*/
   3.837 +
   3.838 +typedef struct BusLogic_AutoSCSIData
   3.839 +{
   3.840 +  unsigned char InternalFactorySignature[2];		/* Bytes 0-1 */
   3.841 +  unsigned char InformationByteCount;			/* Byte 2 */
   3.842 +  unsigned char HostAdapterType[6];			/* Bytes 3-8 */
   3.843 +  unsigned char :8;					/* Byte 9 */
   3.844 +  boolean FloppyEnabled:1;				/* Byte 10 Bit 0 */
   3.845 +  boolean FloppySecondary:1;				/* Byte 10 Bit 1 */
   3.846 +  boolean LevelSensitiveInterrupt:1;			/* Byte 10 Bit 2 */
   3.847 +  unsigned char :2;					/* Byte 10 Bits 3-4 */
   3.848 +  unsigned char SystemRAMAreaForBIOS:3;			/* Byte 10 Bits 5-7 */
   3.849 +  unsigned char DMA_Channel:7;				/* Byte 11 Bits 0-6 */
   3.850 +  boolean DMA_AutoConfiguration:1;			/* Byte 11 Bit 7 */
   3.851 +  unsigned char IRQ_Channel:7;				/* Byte 12 Bits 0-6 */
   3.852 +  boolean IRQ_AutoConfiguration:1;			/* Byte 12 Bit 7 */
   3.853 +  unsigned char DMA_TransferRate;			/* Byte 13 */
   3.854 +  unsigned char SCSI_ID;				/* Byte 14 */
   3.855 +  boolean LowByteTerminated:1;				/* Byte 15 Bit 0 */
   3.856 +  boolean ParityCheckingEnabled:1;			/* Byte 15 Bit 1 */
   3.857 +  boolean HighByteTerminated:1;				/* Byte 15 Bit 2 */
   3.858 +  boolean NoisyCablingEnvironment:1;			/* Byte 15 Bit 3 */
   3.859 +  boolean FastSynchronousNegotiation:1;			/* Byte 15 Bit 4 */
   3.860 +  boolean BusResetEnabled:1;				/* Byte 15 Bit 5 */
   3.861 +  boolean :1;						/* Byte 15 Bit 6 */
   3.862 +  boolean ActiveNegationEnabled:1;			/* Byte 15 Bit 7 */
   3.863 +  unsigned char BusOnDelay;				/* Byte 16 */
   3.864 +  unsigned char BusOffDelay;				/* Byte 17 */
   3.865 +  boolean HostAdapterBIOSEnabled:1;			/* Byte 18 Bit 0 */
   3.866 +  boolean BIOSRedirectionOfINT19Enabled:1;		/* Byte 18 Bit 1 */
   3.867 +  boolean ExtendedTranslationEnabled:1;			/* Byte 18 Bit 2 */
   3.868 +  boolean MapRemovableAsFixedEnabled:1;			/* Byte 18 Bit 3 */
   3.869 +  boolean :1;						/* Byte 18 Bit 4 */
   3.870 +  boolean BIOSSupportsMoreThan2DrivesEnabled:1;		/* Byte 18 Bit 5 */
   3.871 +  boolean BIOSInterruptModeEnabled:1;			/* Byte 18 Bit 6 */
   3.872 +  boolean FlopticalSupportEnabled:1;			/* Byte 19 Bit 7 */
   3.873 +  unsigned short DeviceEnabled;				/* Bytes 19-20 */
   3.874 +  unsigned short WidePermitted;				/* Bytes 21-22 */
   3.875 +  unsigned short FastPermitted;				/* Bytes 23-24 */
   3.876 +  unsigned short SynchronousPermitted;			/* Bytes 25-26 */
   3.877 +  unsigned short DisconnectPermitted;			/* Bytes 27-28 */
   3.878 +  unsigned short SendStartUnitCommand;			/* Bytes 29-30 */
   3.879 +  unsigned short IgnoreInBIOSScan;			/* Bytes 31-32 */
   3.880 +  unsigned char PCIInterruptPin:2;			/* Byte 33 Bits 0-1 */
   3.881 +  unsigned char HostAdapterIOPortAddress:2;		/* Byte 33 Bits 2-3 */
   3.882 +  boolean StrictRoundRobinModeEnabled:1;		/* Byte 33 Bit 4 */
   3.883 +  boolean VESABusSpeedGreaterThan33MHz:1;		/* Byte 33 Bit 5 */
   3.884 +  boolean VESABurstWriteEnabled:1;			/* Byte 33 Bit 6 */
   3.885 +  boolean VESABurstReadEnabled:1;			/* Byte 33 Bit 7 */
   3.886 +  unsigned short UltraPermitted;			/* Bytes 34-35 */
   3.887 +  unsigned int :32;					/* Bytes 36-39 */
   3.888 +  unsigned char :8;					/* Byte 40 */
   3.889 +  unsigned char AutoSCSIMaximumLUN;			/* Byte 41 */
   3.890 +  boolean :1;						/* Byte 42 Bit 0 */
   3.891 +  boolean SCAM_Dominant:1;				/* Byte 42 Bit 1 */
   3.892 +  boolean SCAM_Enabled:1;				/* Byte 42 Bit 2 */
   3.893 +  boolean SCAM_Level2:1;				/* Byte 42 Bit 3 */
   3.894 +  unsigned char :4;					/* Byte 42 Bits 4-7 */
   3.895 +  boolean INT13ExtensionEnabled:1;			/* Byte 43 Bit 0 */
   3.896 +  boolean :1;						/* Byte 43 Bit 1 */
   3.897 +  boolean CDROMBootEnabled:1;				/* Byte 43 Bit 2 */
   3.898 +  unsigned char :5;					/* Byte 43 Bits 3-7 */
   3.899 +  unsigned char BootTargetID:4;				/* Byte 44 Bits 0-3 */
   3.900 +  unsigned char BootChannel:4;				/* Byte 44 Bits 4-7 */
   3.901 +  unsigned char ForceBusDeviceScanningOrder:1;		/* Byte 45 Bit 0 */
   3.902 +  unsigned char :7;					/* Byte 45 Bits 1-7 */
   3.903 +  unsigned short NonTaggedToAlternateLUNPermitted;	/* Bytes 46-47 */
   3.904 +  unsigned short RenegotiateSyncAfterCheckCondition;	/* Bytes 48-49 */
   3.905 +  unsigned char Reserved[10];				/* Bytes 50-59 */
   3.906 +  unsigned char ManufacturingDiagnostic[2];		/* Bytes 60-61 */
   3.907 +  unsigned short Checksum;				/* Bytes 62-63 */
   3.908 +}
   3.909 +__attribute__ ((packed))
   3.910 +BusLogic_AutoSCSIData_T;
   3.911 +
   3.912 +
   3.913 +/*
   3.914 +  Define the Host Adapter Local RAM Auto SCSI Byte 45 structure.
   3.915 +*/
   3.916 +
   3.917 +typedef struct BusLogic_AutoSCSIByte45
   3.918 +{
   3.919 +  unsigned char ForceBusDeviceScanningOrder:1;		/* Bit 0 */
   3.920 +  unsigned char :7;					/* Bits 1-7 */
   3.921 +}
   3.922 +BusLogic_AutoSCSIByte45_T;
   3.923 +
   3.924 +
   3.925 +/*
   3.926 +  Define the Host Adapter Local RAM BIOS Drive Map Byte structure.
   3.927 +*/
   3.928 +
   3.929 +#define BusLogic_BIOS_DriveMapOffset		17
   3.930 +
   3.931 +typedef struct BusLogic_BIOSDriveMapByte
   3.932 +{
   3.933 +  unsigned char TargetIDBit3:1;				/* Bit 0 */
   3.934 +  unsigned char :2;					/* Bits 1-2 */
   3.935 +  BusLogic_BIOS_DiskGeometryTranslation_T DiskGeometry:2; /* Bits 3-4 */
   3.936 +  unsigned char TargetID:3;				/* Bits 5-7 */
   3.937 +}
   3.938 +BusLogic_BIOSDriveMapByte_T;
   3.939 +
   3.940 +
   3.941 +/*
   3.942 +  Define the Modify I/O Address request type.  On PCI Host Adapters, the
   3.943 +  Modify I/O Address command allows modification of the ISA compatible I/O
   3.944 +  Address that the Host Adapter responds to; it does not affect the PCI
   3.945 +  compliant I/O Address assigned at system initialization.
   3.946 +*/
   3.947 +
   3.948 +typedef BusLogic_ISACompatibleIOPort_T BusLogic_ModifyIOAddressRequest_T;
   3.949 +
   3.950 +
   3.951 +/*
   3.952 +  Define the Set CCB Format request type.  Extended LUN Format CCBs are
   3.953 +  necessary to support more than 8 Logical Units per Target Device.
   3.954 +*/
   3.955 +
   3.956 +typedef enum BusLogic_SetCCBFormatRequest
   3.957 +{
   3.958 +  BusLogic_LegacyLUNFormatCCB =			0,
   3.959 +  BusLogic_ExtendedLUNFormatCCB =		1
   3.960 +}
   3.961 +__attribute__ ((packed))
   3.962 +BusLogic_SetCCBFormatRequest_T;
   3.963 +
   3.964 +
   3.965 +/*
   3.966 +  Define the Requested Reply Length type used by the Inquire Setup Information,
   3.967 +  Inquire Host Adapter Model Number, Inquire Synchronous Period, and Inquire
   3.968 +  Extended Setup Information commands.
   3.969 +*/
   3.970 +
   3.971 +typedef unsigned char BusLogic_RequestedReplyLength_T;
   3.972 +
   3.973 +
   3.974 +/*
   3.975 +  Define the Outgoing Mailbox Action Codes.
   3.976 +*/
   3.977 +
   3.978 +typedef enum
   3.979 +{
   3.980 +  BusLogic_OutgoingMailboxFree =		0x00,
   3.981 +  BusLogic_MailboxStartCommand =		0x01,
   3.982 +  BusLogic_MailboxAbortCommand =		0x02
   3.983 +}
   3.984 +__attribute__ ((packed))
   3.985 +BusLogic_ActionCode_T;
   3.986 +
   3.987 +
   3.988 +/*
   3.989 +  Define the Incoming Mailbox Completion Codes.  The MultiMaster Firmware
   3.990 +  only uses codes 0 - 4.  The FlashPoint SCCB Manager has no mailboxes, so
   3.991 +  completion codes are stored in the CCB; it only uses codes 1, 2, 4, and 5.
   3.992 +*/
   3.993 +
   3.994 +typedef enum
   3.995 +{
   3.996 +  BusLogic_IncomingMailboxFree =		0x00,
   3.997 +  BusLogic_CommandCompletedWithoutError =	0x01,
   3.998 +  BusLogic_CommandAbortedAtHostRequest =	0x02,
   3.999 +  BusLogic_AbortedCommandNotFound =		0x03,
  3.1000 +  BusLogic_CommandCompletedWithError =		0x04,
  3.1001 +  BusLogic_InvalidCCB =				0x05
  3.1002 +}
  3.1003 +__attribute__ ((packed))
  3.1004 +BusLogic_CompletionCode_T;
  3.1005 +
  3.1006 +
  3.1007 +/*
  3.1008 +  Define the Command Control Block (CCB) Opcodes.
  3.1009 +*/
  3.1010 +
  3.1011 +typedef enum
  3.1012 +{
  3.1013 +  BusLogic_InitiatorCCB =			0x00,
  3.1014 +  BusLogic_TargetCCB =				0x01,
  3.1015 +  BusLogic_InitiatorCCB_ScatterGather =		0x02,
  3.1016 +  BusLogic_InitiatorCCB_ResidualDataLength =	0x03,
  3.1017 +  BusLogic_InitiatorCCB_ScatterGatherResidual =	0x04,
  3.1018 +  BusLogic_BusDeviceReset =			0x81
  3.1019 +}
  3.1020 +__attribute__ ((packed))
  3.1021 +BusLogic_CCB_Opcode_T;
  3.1022 +
  3.1023 +
  3.1024 +/*
  3.1025 +  Define the CCB Data Direction Codes.
  3.1026 +*/
  3.1027 +
  3.1028 +typedef enum
  3.1029 +{
  3.1030 +  BusLogic_UncheckedDataTransfer =		0,
  3.1031 +  BusLogic_DataInLengthChecked =		1,
  3.1032 +  BusLogic_DataOutLengthChecked =		2,
  3.1033 +  BusLogic_NoDataTransfer =			3
  3.1034 +}
  3.1035 +BusLogic_DataDirection_T;
  3.1036 +
  3.1037 +
  3.1038 +/*
  3.1039 +  Define the Host Adapter Status Codes.  The MultiMaster Firmware does not
  3.1040 +  return status code 0x0C; it uses 0x12 for both overruns and underruns.
  3.1041 +*/
  3.1042 +
  3.1043 +typedef enum
  3.1044 +{
  3.1045 +  BusLogic_CommandCompletedNormally =		0x00,
  3.1046 +  BusLogic_LinkedCommandCompleted =		0x0A,
  3.1047 +  BusLogic_LinkedCommandCompletedWithFlag =	0x0B,
  3.1048 +  BusLogic_DataUnderRun =			0x0C,
  3.1049 +  BusLogic_SCSISelectionTimeout =		0x11,
  3.1050 +  BusLogic_DataOverRun =			0x12,
  3.1051 +  BusLogic_UnexpectedBusFree =			0x13,
  3.1052 +  BusLogic_InvalidBusPhaseRequested =		0x14,
  3.1053 +  BusLogic_InvalidOutgoingMailboxActionCode =	0x15,
  3.1054 +  BusLogic_InvalidCommandOperationCode =	0x16,
  3.1055 +  BusLogic_LinkedCCBhasInvalidLUN =		0x17,
  3.1056 +  BusLogic_InvalidCommandParameter =		0x1A,
  3.1057 +  BusLogic_AutoRequestSenseFailed =		0x1B,
  3.1058 +  BusLogic_TaggedQueuingMessageRejected =	0x1C,
  3.1059 +  BusLogic_UnsupportedMessageReceived =		0x1D,
  3.1060 +  BusLogic_HostAdapterHardwareFailed =		0x20,
  3.1061 +  BusLogic_TargetFailedResponseToATN =		0x21,
  3.1062 +  BusLogic_HostAdapterAssertedRST =		0x22,
  3.1063 +  BusLogic_OtherDeviceAssertedRST =		0x23,
  3.1064 +  BusLogic_TargetDeviceReconnectedImproperly =	0x24,
  3.1065 +  BusLogic_HostAdapterAssertedBusDeviceReset =	0x25,
  3.1066 +  BusLogic_AbortQueueGenerated =		0x26,
  3.1067 +  BusLogic_HostAdapterSoftwareError =		0x27,
  3.1068 +  BusLogic_HostAdapterHardwareTimeoutError =	0x30,
  3.1069 +  BusLogic_SCSIParityErrorDetected =		0x34
  3.1070 +}
  3.1071 +__attribute__ ((packed))
  3.1072 +BusLogic_HostAdapterStatus_T;
  3.1073 +
  3.1074 +
  3.1075 +/*
  3.1076 +  Define the SCSI Target Device Status Codes.
  3.1077 +*/
  3.1078 +
  3.1079 +typedef enum
  3.1080 +{
  3.1081 +  BusLogic_OperationGood =			0x00,
  3.1082 +  BusLogic_CheckCondition =			0x02,
  3.1083 +  BusLogic_DeviceBusy =				0x08
  3.1084 +}
  3.1085 +__attribute__ ((packed))
  3.1086 +BusLogic_TargetDeviceStatus_T;
  3.1087 +
  3.1088 +
  3.1089 +/*
  3.1090 +  Define the Queue Tag Codes.
  3.1091 +*/
  3.1092 +
  3.1093 +typedef enum
  3.1094 +{
  3.1095 +  BusLogic_SimpleQueueTag =			0,
  3.1096 +  BusLogic_HeadOfQueueTag =			1,
  3.1097 +  BusLogic_OrderedQueueTag =			2,
  3.1098 +  BusLogic_ReservedQT =				3
  3.1099 +}
  3.1100 +BusLogic_QueueTag_T;
  3.1101 +
  3.1102 +
  3.1103 +/*
  3.1104 +  Define the SCSI Command Descriptor Block (CDB).
  3.1105 +*/
  3.1106 +
  3.1107 +#define BusLogic_CDB_MaxLength			12
  3.1108 +
  3.1109 +typedef unsigned char SCSI_CDB_T[BusLogic_CDB_MaxLength];
  3.1110 +
  3.1111 +
  3.1112 +/*
  3.1113 +  Define the Scatter/Gather Segment structure required by the MultiMaster
  3.1114 +  Firmware Interface and the FlashPoint SCCB Manager.
  3.1115 +*/
  3.1116 +
  3.1117 +typedef struct BusLogic_ScatterGatherSegment
  3.1118 +{
  3.1119 +  BusLogic_ByteCount_T SegmentByteCount;		/* Bytes 0-3 */
  3.1120 +  BusLogic_BusAddress_T SegmentDataPointer;		/* Bytes 4-7 */
  3.1121 +}
  3.1122 +BusLogic_ScatterGatherSegment_T;
  3.1123 +
  3.1124 +
  3.1125 +/*
  3.1126 +  Define the Driver CCB Status Codes.
  3.1127 +*/
  3.1128 +
  3.1129 +typedef enum
  3.1130 +{
  3.1131 +  BusLogic_CCB_Free =				0,
  3.1132 +  BusLogic_CCB_Active =				1,
  3.1133 +  BusLogic_CCB_Completed =			2,
  3.1134 +  BusLogic_CCB_Reset =				3
  3.1135 +}
  3.1136 +__attribute__ ((packed))
  3.1137 +BusLogic_CCB_Status_T;
  3.1138 +
  3.1139 +
  3.1140 +/*
  3.1141 +  Define the 32 Bit Mode Command Control Block (CCB) structure.  The first 40
  3.1142 +  bytes are defined by and common to both the MultiMaster Firmware and the
  3.1143 +  FlashPoint SCCB Manager.  The next 60 bytes are defined by the FlashPoint
  3.1144 +  SCCB Manager.  The remaining components are defined by the Linux BusLogic
  3.1145 +  Driver.  Extended LUN Format CCBs differ from Legacy LUN Format 32 Bit Mode
  3.1146 +  CCBs only in having the TagEnable and QueueTag fields moved from byte 17 to
  3.1147 +  byte 1, and the Logical Unit field in byte 17 expanded to 6 bits.  In theory,
  3.1148 +  Extended LUN Format CCBs can support up to 64 Logical Units, but in practice
  3.1149 +  many devices will respond improperly to Logical Units between 32 and 63, and
  3.1150 +  the SCSI-2 specification defines Bit 5 as LUNTAR.  Extended LUN Format CCBs
  3.1151 +  are used by recent versions of the MultiMaster Firmware, as well as by the
  3.1152 +  FlashPoint SCCB Manager; the FlashPoint SCCB Manager only supports 32 Logical
  3.1153 +  Units.  Since 64 Logical Units are unlikely to be needed in practice, and
  3.1154 +  since they are problematic for the above reasons, and since limiting them to
  3.1155 +  5 bits simplifies the CCB structure definition, this driver only supports
  3.1156 +  32 Logical Units per Target Device.
  3.1157 +*/
  3.1158 +
  3.1159 +typedef struct BusLogic_CCB
  3.1160 +{
  3.1161 +  /*
  3.1162 +    MultiMaster Firmware and FlashPoint SCCB Manager Common Portion.
  3.1163 +  */
  3.1164 +  BusLogic_CCB_Opcode_T Opcode;				/* Byte 0 */
  3.1165 +  unsigned char :3;					/* Byte 1 Bits 0-2 */
  3.1166 +  BusLogic_DataDirection_T DataDirection:2;		/* Byte 1 Bits 3-4 */
  3.1167 +  boolean TagEnable:1;					/* Byte 1 Bit 5 */
  3.1168 +  BusLogic_QueueTag_T QueueTag:2;			/* Byte 1 Bits 6-7 */
  3.1169 +  unsigned char CDB_Length;				/* Byte 2 */
  3.1170 +  unsigned char SenseDataLength;			/* Byte 3 */
  3.1171 +  BusLogic_ByteCount_T DataLength;			/* Bytes 4-7 */
  3.1172 +  BusLogic_BusAddress_T DataPointer;			/* Bytes 8-11 */
  3.1173 +  unsigned char :8;					/* Byte 12 */
  3.1174 +  unsigned char :8;					/* Byte 13 */
  3.1175 +  BusLogic_HostAdapterStatus_T HostAdapterStatus;	/* Byte 14 */
  3.1176 +  BusLogic_TargetDeviceStatus_T TargetDeviceStatus;	/* Byte 15 */
  3.1177 +  unsigned char TargetID;				/* Byte 16 */
  3.1178 +  unsigned char LogicalUnit:5;				/* Byte 17 Bits 0-4 */
  3.1179 +  boolean LegacyTagEnable:1;				/* Byte 17 Bit 5 */
  3.1180 +  BusLogic_QueueTag_T LegacyQueueTag:2;			/* Byte 17 Bits 6-7 */
  3.1181 +  SCSI_CDB_T CDB;					/* Bytes 18-29 */
  3.1182 +  unsigned char :8;					/* Byte 30 */
  3.1183 +  unsigned char :8;					/* Byte 31 */
  3.1184 +  unsigned int :32;					/* Bytes 32-35 */
  3.1185 +  BusLogic_BusAddress_T SenseDataPointer;		/* Bytes 36-39 */
  3.1186 +  /*
  3.1187 +    FlashPoint SCCB Manager Defined Portion.
  3.1188 +  */
  3.1189 +  void (*CallbackFunction)(struct BusLogic_CCB *);	/* Bytes 40-43 */
  3.1190 +  BusLogic_Base_Address_T BaseAddress;			/* Bytes 44-47 */
  3.1191 +  BusLogic_CompletionCode_T CompletionCode;		/* Byte 48 */
  3.1192 +#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
  3.1193 +  unsigned char :8;					/* Byte 49 */
  3.1194 +  unsigned short OS_Flags;				/* Bytes 50-51 */
  3.1195 +  unsigned char Private[48];				/* Bytes 52-99 */
  3.1196 +#endif
  3.1197 +  /*
  3.1198 +    BusLogic Linux Driver Defined Portion.
  3.1199 +  */
  3.1200 +  boolean AllocationGroupHead;
  3.1201 +  BusLogic_CCB_Status_T Status;
  3.1202 +  unsigned long SerialNumber;
  3.1203 +  SCSI_Command_T *Command;
  3.1204 +  struct BusLogic_HostAdapter *HostAdapter;
  3.1205 +  struct BusLogic_CCB *Next;
  3.1206 +  struct BusLogic_CCB *NextAll;
  3.1207 +  BusLogic_ScatterGatherSegment_T
  3.1208 +    ScatterGatherList[BusLogic_ScatterGatherLimit];
  3.1209 +}
  3.1210 +BusLogic_CCB_T;
  3.1211 +
  3.1212 +
  3.1213 +/*
  3.1214 +  Define the 32 Bit Mode Outgoing Mailbox structure.
  3.1215 +*/
  3.1216 +
  3.1217 +typedef struct BusLogic_OutgoingMailbox
  3.1218 +{
  3.1219 +  BusLogic_BusAddress_T CCB;				/* Bytes 0-3 */
  3.1220 +  unsigned int :24;					/* Bytes 4-6 */
  3.1221 +  BusLogic_ActionCode_T ActionCode;			/* Byte 7 */
  3.1222 +}
  3.1223 +BusLogic_OutgoingMailbox_T;
  3.1224 +
  3.1225 +
  3.1226 +/*
  3.1227 +  Define the 32 Bit Mode Incoming Mailbox structure.
  3.1228 +*/
  3.1229 +
  3.1230 +typedef struct BusLogic_IncomingMailbox
  3.1231 +{
  3.1232 +  BusLogic_BusAddress_T CCB;				/* Bytes 0-3 */
  3.1233 +  BusLogic_HostAdapterStatus_T HostAdapterStatus;	/* Byte 4 */
  3.1234 +  BusLogic_TargetDeviceStatus_T TargetDeviceStatus;	/* Byte 5 */
  3.1235 +  unsigned char :8;					/* Byte 6 */
  3.1236 +  BusLogic_CompletionCode_T CompletionCode;		/* Byte 7 */
  3.1237 +}
  3.1238 +BusLogic_IncomingMailbox_T;
  3.1239 +
  3.1240 +
  3.1241 +/*
  3.1242 +  Define the BusLogic Driver Options structure.
  3.1243 +*/
  3.1244 +
  3.1245 +typedef struct BusLogic_DriverOptions
  3.1246 +{
  3.1247 +  unsigned short TaggedQueuingPermitted;
  3.1248 +  unsigned short TaggedQueuingPermittedMask;
  3.1249 +  unsigned short BusSettleTime;
  3.1250 +  BusLogic_LocalOptions_T LocalOptions;
  3.1251 +  unsigned char CommonQueueDepth;
  3.1252 +  unsigned char QueueDepth[BusLogic_MaxTargetDevices];
  3.1253 +  BusLogic_ErrorRecoveryStrategy_T
  3.1254 +    ErrorRecoveryStrategy[BusLogic_MaxTargetDevices];
  3.1255 +}
  3.1256 +BusLogic_DriverOptions_T;
  3.1257 +
  3.1258 +
  3.1259 +/*
  3.1260 +  Define the Host Adapter Target Flags structure.
  3.1261 +*/
  3.1262 +
  3.1263 +typedef struct BusLogic_TargetFlags
  3.1264 +{
  3.1265 +  boolean TargetExists:1;
  3.1266 +  boolean TaggedQueuingSupported:1;
  3.1267 +  boolean WideTransfersSupported:1;
  3.1268 +  boolean TaggedQueuingActive:1;
  3.1269 +  boolean WideTransfersActive:1;
  3.1270 +  boolean CommandSuccessfulFlag:1;
  3.1271 +  boolean TargetInfoReported:1;
  3.1272 +}
  3.1273 +BusLogic_TargetFlags_T;
  3.1274 +
  3.1275 +
  3.1276 +/*
  3.1277 +  Define the Host Adapter Target Statistics structure.
  3.1278 +*/
  3.1279 +
  3.1280 +#define BusLogic_SizeBuckets			10
  3.1281 +
  3.1282 +typedef unsigned int BusLogic_CommandSizeBuckets_T[BusLogic_SizeBuckets];
  3.1283 +
  3.1284 +typedef struct BusLogic_TargetStatistics
  3.1285 +{
  3.1286 +  unsigned int CommandsAttempted;
  3.1287 +  unsigned int CommandsCompleted;
  3.1288 +  unsigned int ReadCommands;
  3.1289 +  unsigned int WriteCommands;
  3.1290 +  BusLogic_ByteCounter_T TotalBytesRead;
  3.1291 +  BusLogic_ByteCounter_T TotalBytesWritten;
  3.1292 +  BusLogic_CommandSizeBuckets_T ReadCommandSizeBuckets;
  3.1293 +  BusLogic_CommandSizeBuckets_T WriteCommandSizeBuckets;
  3.1294 +  unsigned short CommandAbortsRequested;
  3.1295 +  unsigned short CommandAbortsAttempted;
  3.1296 +  unsigned short CommandAbortsCompleted;
  3.1297 +  unsigned short BusDeviceResetsRequested;
  3.1298 +  unsigned short BusDeviceResetsAttempted;
  3.1299 +  unsigned short BusDeviceResetsCompleted;
  3.1300 +  unsigned short HostAdapterResetsRequested;
  3.1301 +  unsigned short HostAdapterResetsAttempted;
  3.1302 +  unsigned short HostAdapterResetsCompleted;
  3.1303 +}
  3.1304 +BusLogic_TargetStatistics_T;
  3.1305 +
  3.1306 +
  3.1307 +/*
  3.1308 +  Define the FlashPoint Card Handle data type.
  3.1309 +*/
  3.1310 +
  3.1311 +#define FlashPoint_BadCardHandle		0xFFFFFFFF
  3.1312 +
  3.1313 +typedef unsigned int FlashPoint_CardHandle_T;
  3.1314 +
  3.1315 +
  3.1316 +/*
  3.1317 +  Define the FlashPoint Information structure.  This structure is defined
  3.1318 +  by the FlashPoint SCCB Manager.
  3.1319 +*/
  3.1320 +
  3.1321 +typedef struct FlashPoint_Info
  3.1322 +{
  3.1323 +  BusLogic_Base_Address_T BaseAddress;			/* Bytes 0-3 */
  3.1324 +  boolean Present;					/* Byte 4 */
  3.1325 +  unsigned char IRQ_Channel;				/* Byte 5 */
  3.1326 +  unsigned char SCSI_ID;				/* Byte 6 */
  3.1327 +  unsigned char SCSI_LUN;				/* Byte 7 */
  3.1328 +  unsigned short FirmwareRevision;			/* Bytes 8-9 */
  3.1329 +  unsigned short SynchronousPermitted;			/* Bytes 10-11 */
  3.1330 +  unsigned short FastPermitted;				/* Bytes 12-13 */
  3.1331 +  unsigned short UltraPermitted;			/* Bytes 14-15 */
  3.1332 +  unsigned short DisconnectPermitted;			/* Bytes 16-17 */
  3.1333 +  unsigned short WidePermitted;				/* Bytes 18-19 */
  3.1334 +  boolean ParityCheckingEnabled:1;			/* Byte 20 Bit 0 */
  3.1335 +  boolean HostWideSCSI:1;				/* Byte 20 Bit 1 */
  3.1336 +  boolean HostSoftReset:1;				/* Byte 20 Bit 2 */
  3.1337 +  boolean ExtendedTranslationEnabled:1;			/* Byte 20 Bit 3 */
  3.1338 +  boolean LowByteTerminated:1;				/* Byte 20 Bit 4 */
  3.1339 +  boolean HighByteTerminated:1;				/* Byte 20 Bit 5 */
  3.1340 +  boolean ReportDataUnderrun:1;				/* Byte 20 Bit 6 */
  3.1341 +  boolean SCAM_Enabled:1;				/* Byte 20 Bit 7 */
  3.1342 +  boolean SCAM_Level2:1;				/* Byte 21 Bit 0 */
  3.1343 +  unsigned char :7;					/* Byte 21 Bits 1-7 */
  3.1344 +  unsigned char Family;					/* Byte 22 */
  3.1345 +  unsigned char BusType;				/* Byte 23 */
  3.1346 +  unsigned char ModelNumber[3];				/* Bytes 24-26 */
  3.1347 +  unsigned char RelativeCardNumber;			/* Byte 27 */
  3.1348 +  unsigned char Reserved[4];				/* Bytes 28-31 */
  3.1349 +  unsigned int OS_Reserved;				/* Bytes 32-35 */
  3.1350 +  unsigned char TranslationInfo[4];			/* Bytes 36-39 */
  3.1351 +  unsigned int Reserved2[5];				/* Bytes 40-59 */
  3.1352 +  unsigned int SecondaryRange;				/* Bytes 60-63 */
  3.1353 +}
  3.1354 +FlashPoint_Info_T;
  3.1355 +
  3.1356 +
  3.1357 +/*
  3.1358 +  Define the BusLogic Driver Host Adapter structure.
  3.1359 +*/
  3.1360 +
  3.1361 +typedef struct BusLogic_HostAdapter
  3.1362 +{
  3.1363 +  SCSI_Host_T *SCSI_Host;
  3.1364 +  BusLogic_HostAdapterType_T HostAdapterType;
  3.1365 +  BusLogic_HostAdapterBusType_T HostAdapterBusType;
  3.1366 +  BusLogic_IO_Address_T IO_Address;
  3.1367 +  BusLogic_PCI_Address_T PCI_Address;
  3.1368 +  unsigned short AddressCount;
  3.1369 +  unsigned char HostNumber;
  3.1370 +  unsigned char ModelName[9];
  3.1371 +  unsigned char FirmwareVersion[6];
  3.1372 +  unsigned char FullModelName[18];
  3.1373 +  unsigned char Bus;
  3.1374 +  unsigned char Device;
  3.1375 +  unsigned char IRQ_Channel;
  3.1376 +  unsigned char DMA_Channel;
  3.1377 +  unsigned char SCSI_ID;
  3.1378 +  boolean IRQ_ChannelAcquired:1;
  3.1379 +  boolean DMA_ChannelAcquired:1;
  3.1380 +  boolean ExtendedTranslationEnabled:1;
  3.1381 +  boolean ParityCheckingEnabled:1;
  3.1382 +  boolean BusResetEnabled:1;
  3.1383 +  boolean LevelSensitiveInterrupt:1;
  3.1384 +  boolean HostWideSCSI:1;
  3.1385 +  boolean HostDifferentialSCSI:1;
  3.1386 +  boolean HostSupportsSCAM:1;
  3.1387 +  boolean HostUltraSCSI:1;
  3.1388 +  boolean ExtendedLUNSupport:1;
  3.1389 +  boolean TerminationInfoValid:1;
  3.1390 +  boolean LowByteTerminated:1;
  3.1391 +  boolean HighByteTerminated:1;
  3.1392 +  boolean BounceBuffersRequired:1;
  3.1393 +  boolean StrictRoundRobinModeSupport:1;
  3.1394 +  boolean SCAM_Enabled:1;
  3.1395 +  boolean SCAM_Level2:1;
  3.1396 +  boolean HostAdapterInitialized:1;
  3.1397 +  boolean HostAdapterExternalReset:1;
  3.1398 +  boolean HostAdapterInternalError:1;
  3.1399 +  boolean ProcessCompletedCCBsActive;
  3.1400 +  volatile boolean HostAdapterCommandCompleted;
  3.1401 +  unsigned short HostAdapterScatterGatherLimit;
  3.1402 +  unsigned short DriverScatterGatherLimit;
  3.1403 +  unsigned short MaxTargetDevices;
  3.1404 +  unsigned short MaxLogicalUnits;
  3.1405 +  unsigned short MailboxCount;
  3.1406 +  unsigned short InitialCCBs;
  3.1407 +  unsigned short IncrementalCCBs;
  3.1408 +  unsigned short AllocatedCCBs;
  3.1409 +  unsigned short DriverQueueDepth;
  3.1410 +  unsigned short HostAdapterQueueDepth;
  3.1411 +  unsigned short UntaggedQueueDepth;
  3.1412 +  unsigned short CommonQueueDepth;
  3.1413 +  unsigned short BusSettleTime;
  3.1414 +  unsigned short SynchronousPermitted;
  3.1415 +  unsigned short FastPermitted;
  3.1416 +  unsigned short UltraPermitted;
  3.1417 +  unsigned short WidePermitted;
  3.1418 +  unsigned short DisconnectPermitted;
  3.1419 +  unsigned short TaggedQueuingPermitted;
  3.1420 +  unsigned short ExternalHostAdapterResets;
  3.1421 +  unsigned short HostAdapterInternalErrors;
  3.1422 +  unsigned short TargetDeviceCount;
  3.1423 +  unsigned short MessageBufferLength;
  3.1424 +  BusLogic_BusAddress_T BIOS_Address;
  3.1425 +  BusLogic_DriverOptions_T *DriverOptions;
  3.1426 +  FlashPoint_Info_T FlashPointInfo;
  3.1427 +  FlashPoint_CardHandle_T CardHandle;
  3.1428 +  struct BusLogic_HostAdapter *Next;
  3.1429 +  BusLogic_CCB_T *All_CCBs;
  3.1430 +  BusLogic_CCB_T *Free_CCBs;
  3.1431 +  BusLogic_CCB_T *FirstCompletedCCB;
  3.1432 +  BusLogic_CCB_T *LastCompletedCCB;
  3.1433 +  BusLogic_CCB_T *BusDeviceResetPendingCCB[BusLogic_MaxTargetDevices];
  3.1434 +  BusLogic_ErrorRecoveryStrategy_T
  3.1435 +    ErrorRecoveryStrategy[BusLogic_MaxTargetDevices];
  3.1436 +  BusLogic_TargetFlags_T TargetFlags[BusLogic_MaxTargetDevices];
  3.1437 +  unsigned char QueueDepth[BusLogic_MaxTargetDevices];
  3.1438 +  unsigned char SynchronousPeriod[BusLogic_MaxTargetDevices];
  3.1439 +  unsigned char SynchronousOffset[BusLogic_MaxTargetDevices];
  3.1440 +  unsigned char ActiveCommands[BusLogic_MaxTargetDevices];
  3.1441 +  unsigned int CommandsSinceReset[BusLogic_MaxTargetDevices];
  3.1442 +  unsigned long LastSequencePoint[BusLogic_MaxTargetDevices];
  3.1443 +  unsigned long LastResetAttempted[BusLogic_MaxTargetDevices];
  3.1444 +  unsigned long LastResetCompleted[BusLogic_MaxTargetDevices];
  3.1445 +  BusLogic_OutgoingMailbox_T *FirstOutgoingMailbox;
  3.1446 +  BusLogic_OutgoingMailbox_T *LastOutgoingMailbox;
  3.1447 +  BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
  3.1448 +  BusLogic_IncomingMailbox_T *FirstIncomingMailbox;
  3.1449 +  BusLogic_IncomingMailbox_T *LastIncomingMailbox;
  3.1450 +  BusLogic_IncomingMailbox_T *NextIncomingMailbox;
  3.1451 +  BusLogic_TargetStatistics_T TargetStatistics[BusLogic_MaxTargetDevices];
  3.1452 +  unsigned char MailboxSpace[BusLogic_MaxMailboxes
  3.1453 +			     * (sizeof(BusLogic_OutgoingMailbox_T)
  3.1454 +				+ sizeof(BusLogic_IncomingMailbox_T))];
  3.1455 +  char MessageBuffer[BusLogic_MessageBufferSize];
  3.1456 +}
  3.1457 +BusLogic_HostAdapter_T;
  3.1458 +
  3.1459 +
  3.1460 +/*
  3.1461 +  Define a structure for the BIOS Disk Parameters.
  3.1462 +*/
  3.1463 +
  3.1464 +typedef struct BIOS_DiskParameters
  3.1465 +{
  3.1466 +  int Heads;
  3.1467 +  int Sectors;
  3.1468 +  int Cylinders;
  3.1469 +}
  3.1470 +BIOS_DiskParameters_T;
  3.1471 +
  3.1472 +
  3.1473 +/*
  3.1474 +  Define a structure for the SCSI Inquiry command results.
  3.1475 +*/
  3.1476 +
  3.1477 +typedef struct SCSI_Inquiry
  3.1478 +{
  3.1479 +  unsigned char PeripheralDeviceType:5;			/* Byte 0 Bits 0-4 */
  3.1480 +  unsigned char PeripheralQualifier:3;			/* Byte 0 Bits 5-7 */
  3.1481 +  unsigned char DeviceTypeModifier:7;			/* Byte 1 Bits 0-6 */
  3.1482 +  boolean RMB:1;					/* Byte 1 Bit 7 */
  3.1483 +  unsigned char ANSI_ApprovedVersion:3;			/* Byte 2 Bits 0-2 */
  3.1484 +  unsigned char ECMA_Version:3;				/* Byte 2 Bits 3-5 */
  3.1485 +  unsigned char ISO_Version:2;				/* Byte 2 Bits 6-7 */
  3.1486 +  unsigned char ResponseDataFormat:4;			/* Byte 3 Bits 0-3 */
  3.1487 +  unsigned char :2;					/* Byte 3 Bits 4-5 */
  3.1488 +  boolean TrmIOP:1;					/* Byte 3 Bit 6 */
  3.1489 +  boolean AENC:1;					/* Byte 3 Bit 7 */
  3.1490 +  unsigned char AdditionalLength;			/* Byte 4 */
  3.1491 +  unsigned char :8;					/* Byte 5 */
  3.1492 +  unsigned char :8;					/* Byte 6 */
  3.1493 +  boolean SftRe:1;					/* Byte 7 Bit 0 */
  3.1494 +  boolean CmdQue:1;					/* Byte 7 Bit 1 */
  3.1495 +  boolean :1;						/* Byte 7 Bit 2 */
  3.1496 +  boolean Linked:1;					/* Byte 7 Bit 3 */
  3.1497 +  boolean Sync:1;					/* Byte 7 Bit 4 */
  3.1498 +  boolean WBus16:1;					/* Byte 7 Bit 5 */
  3.1499 +  boolean WBus32:1;					/* Byte 7 Bit 6 */
  3.1500 +  boolean RelAdr:1;					/* Byte 7 Bit 7 */
  3.1501 +  unsigned char VendorIdentification[8];		/* Bytes 8-15 */
  3.1502 +  unsigned char ProductIdentification[16];		/* Bytes 16-31 */
  3.1503 +  unsigned char ProductRevisionLevel[4];		/* Bytes 32-35 */
  3.1504 +}
  3.1505 +SCSI_Inquiry_T;
  3.1506 +
  3.1507 +
  3.1508 +/*
  3.1509 +  BusLogic_AcquireHostAdapterLock acquires exclusive access to Host Adapter.
  3.1510 +*/
  3.1511 +
  3.1512 +static inline
  3.1513 +void BusLogic_AcquireHostAdapterLock(BusLogic_HostAdapter_T *HostAdapter,
  3.1514 +				     ProcessorFlags_T *ProcessorFlags)
  3.1515 +{
  3.1516 +}
  3.1517 +
  3.1518 +
  3.1519 +/*
  3.1520 +  BusLogic_ReleaseHostAdapterLock releases exclusive access to Host Adapter.
  3.1521 +*/
  3.1522 +
  3.1523 +static inline
  3.1524 +void BusLogic_ReleaseHostAdapterLock(BusLogic_HostAdapter_T *HostAdapter,
  3.1525 +				     ProcessorFlags_T *ProcessorFlags)
  3.1526 +{
  3.1527 +}
  3.1528 +
  3.1529 +
  3.1530 +/*
  3.1531 +  BusLogic_AcquireHostAdapterLockIH acquires exclusive access to Host Adapter,
  3.1532 +  but is only called from the interrupt handler.
  3.1533 +*/
  3.1534 +
  3.1535 +static inline
  3.1536 +void BusLogic_AcquireHostAdapterLockIH(BusLogic_HostAdapter_T *HostAdapter,
  3.1537 +				       ProcessorFlags_T *ProcessorFlags)
  3.1538 +{
  3.1539 +  spin_lock_irqsave(&io_request_lock, *ProcessorFlags);
  3.1540 +}
  3.1541 +
  3.1542 +
  3.1543 +/*
  3.1544 +  BusLogic_ReleaseHostAdapterLockIH releases exclusive access to Host Adapter,
  3.1545 +  but is only called from the interrupt handler.
  3.1546 +*/
  3.1547 +
  3.1548 +static inline
  3.1549 +void BusLogic_ReleaseHostAdapterLockIH(BusLogic_HostAdapter_T *HostAdapter,
  3.1550 +				       ProcessorFlags_T *ProcessorFlags)
  3.1551 +{
  3.1552 +  spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags);
  3.1553 +}
  3.1554 +
  3.1555 +
  3.1556 +/*
  3.1557 +  Define functions to provide an abstraction for reading and writing the
  3.1558 +  Host Adapter I/O Registers.
  3.1559 +*/
  3.1560 +
  3.1561 +static inline
  3.1562 +void BusLogic_SCSIBusReset(BusLogic_HostAdapter_T *HostAdapter)
  3.1563 +{
  3.1564 +  BusLogic_ControlRegister_T ControlRegister;
  3.1565 +  ControlRegister.All = 0;
  3.1566 +  ControlRegister.Bits.SCSIBusReset = true;
  3.1567 +  outb(ControlRegister.All,
  3.1568 +       HostAdapter->IO_Address + BusLogic_ControlRegisterOffset);
  3.1569 +}
  3.1570 +
  3.1571 +static inline
  3.1572 +void BusLogic_InterruptReset(BusLogic_HostAdapter_T *HostAdapter)
  3.1573 +{
  3.1574 +  BusLogic_ControlRegister_T ControlRegister;
  3.1575 +  ControlRegister.All = 0;
  3.1576 +  ControlRegister.Bits.InterruptReset = true;
  3.1577 +  outb(ControlRegister.All,
  3.1578 +       HostAdapter->IO_Address + BusLogic_ControlRegisterOffset);
  3.1579 +}
  3.1580 +
  3.1581 +static inline
  3.1582 +void BusLogic_SoftReset(BusLogic_HostAdapter_T *HostAdapter)
  3.1583 +{
  3.1584 +  BusLogic_ControlRegister_T ControlRegister;
  3.1585 +  ControlRegister.All = 0;
  3.1586 +  ControlRegister.Bits.SoftReset = true;
  3.1587 +  outb(ControlRegister.All,
  3.1588 +       HostAdapter->IO_Address + BusLogic_ControlRegisterOffset);
  3.1589 +}
  3.1590 +
  3.1591 +static inline
  3.1592 +void BusLogic_HardReset(BusLogic_HostAdapter_T *HostAdapter)
  3.1593 +{
  3.1594 +  BusLogic_ControlRegister_T ControlRegister;
  3.1595 +  ControlRegister.All = 0;
  3.1596 +  ControlRegister.Bits.HardReset = true;
  3.1597 +  outb(ControlRegister.All,
  3.1598 +       HostAdapter->IO_Address + BusLogic_ControlRegisterOffset);
  3.1599 +}
  3.1600 +
  3.1601 +static inline
  3.1602 +unsigned char BusLogic_ReadStatusRegister(BusLogic_HostAdapter_T *HostAdapter)
  3.1603 +{
  3.1604 +  return inb(HostAdapter->IO_Address + BusLogic_StatusRegisterOffset);
  3.1605 +}
  3.1606 +
  3.1607 +static inline
  3.1608 +void BusLogic_WriteCommandParameterRegister(BusLogic_HostAdapter_T
  3.1609 +					      *HostAdapter,
  3.1610 +					    unsigned char Value)
  3.1611 +{
  3.1612 +  outb(Value,
  3.1613 +       HostAdapter->IO_Address + BusLogic_CommandParameterRegisterOffset);
  3.1614 +}
  3.1615 +
  3.1616 +static inline
  3.1617 +unsigned char BusLogic_ReadDataInRegister(BusLogic_HostAdapter_T *HostAdapter)
  3.1618 +{
  3.1619 +  return inb(HostAdapter->IO_Address + BusLogic_DataInRegisterOffset);
  3.1620 +}
  3.1621 +
  3.1622 +static inline
  3.1623 +unsigned char BusLogic_ReadInterruptRegister(BusLogic_HostAdapter_T
  3.1624 +					     *HostAdapter)
  3.1625 +{
  3.1626 +  return inb(HostAdapter->IO_Address + BusLogic_InterruptRegisterOffset);
  3.1627 +}
  3.1628 +
  3.1629 +static inline
  3.1630 +unsigned char BusLogic_ReadGeometryRegister(BusLogic_HostAdapter_T
  3.1631 +					    *HostAdapter)
  3.1632 +{
  3.1633 +  return inb(HostAdapter->IO_Address + BusLogic_GeometryRegisterOffset);
  3.1634 +}
  3.1635 +
  3.1636 +
  3.1637 +/*
  3.1638 +  BusLogic_StartMailboxCommand issues an Execute Mailbox Command, which
  3.1639 +  notifies the Host Adapter that an entry has been made in an Outgoing
  3.1640 +  Mailbox.
  3.1641 +*/
  3.1642 +
  3.1643 +static inline
  3.1644 +void BusLogic_StartMailboxCommand(BusLogic_HostAdapter_T *HostAdapter)
  3.1645 +{
  3.1646 +  BusLogic_WriteCommandParameterRegister(HostAdapter,
  3.1647 +					 BusLogic_ExecuteMailboxCommand);
  3.1648 +}
  3.1649 +
  3.1650 +
  3.1651 +/*
  3.1652 +  BusLogic_Delay waits for Seconds to elapse.
  3.1653 +*/
  3.1654 +
  3.1655 +static inline void BusLogic_Delay(int Seconds)
  3.1656 +{
  3.1657 +  int Milliseconds = 1000 * Seconds;
  3.1658 +  unsigned long ProcessorFlags;
  3.1659 +  save_flags(ProcessorFlags);
  3.1660 +  sti();
  3.1661 +  while (--Milliseconds >= 0) udelay(1000);
  3.1662 +  restore_flags(ProcessorFlags);
  3.1663 +}
  3.1664 +
  3.1665 +
  3.1666 +/*
  3.1667 +  Virtual_to_Bus and Bus_to_Virtual map between Kernel Virtual Addresses
  3.1668 +  and PCI/VLB/EISA/ISA Bus Addresses.
  3.1669 +*/
  3.1670 +
  3.1671 +static inline BusLogic_BusAddress_T Virtual_to_Bus(void *VirtualAddress)
  3.1672 +{
  3.1673 +  return (BusLogic_BusAddress_T) virt_to_bus(VirtualAddress);
  3.1674 +}
  3.1675 +
  3.1676 +static inline void *Bus_to_Virtual(BusLogic_BusAddress_T BusAddress)
  3.1677 +{
  3.1678 +  return (void *) bus_to_virt(BusAddress);
  3.1679 +}
  3.1680 +
  3.1681 +
  3.1682 +/*
  3.1683 +  Virtual_to_32Bit_Virtual maps between Kernel Virtual Addresses and
  3.1684 +  32 bit Kernel Virtual Addresses.  This avoids compilation warnings
  3.1685 +  on 64 bit architectures.
  3.1686 +*/
  3.1687 +
  3.1688 +static inline
  3.1689 +BusLogic_BusAddress_T Virtual_to_32Bit_Virtual(void *VirtualAddress)
  3.1690 +{
  3.1691 +  return (BusLogic_BusAddress_T) (unsigned long) VirtualAddress;
  3.1692 +}
  3.1693 +
  3.1694 +
  3.1695 +/*
  3.1696 +  BusLogic_IncrementErrorCounter increments Error Counter by 1, stopping at
  3.1697 +  65535 rather than wrapping around to 0.
  3.1698 +*/
  3.1699 +
  3.1700 +static inline void BusLogic_IncrementErrorCounter(unsigned short *ErrorCounter)
  3.1701 +{
  3.1702 +  if (*ErrorCounter < 65535) (*ErrorCounter)++;
  3.1703 +}
  3.1704 +
  3.1705 +
  3.1706 +/*
  3.1707 +  BusLogic_IncrementByteCounter increments Byte Counter by Amount.
  3.1708 +*/
  3.1709 +
  3.1710 +static inline void BusLogic_IncrementByteCounter(BusLogic_ByteCounter_T
  3.1711 +						   *ByteCounter,
  3.1712 +						 unsigned int Amount)
  3.1713 +{
  3.1714 +  ByteCounter->Units += Amount;
  3.1715 +  if (ByteCounter->Units > 999999999)
  3.1716 +    {
  3.1717 +      ByteCounter->Units -= 1000000000;
  3.1718 +      ByteCounter->Billions++;
  3.1719 +    }
  3.1720 +}
  3.1721 +
  3.1722 +
  3.1723 +/*
  3.1724 +  BusLogic_IncrementSizeBucket increments the Bucket for Amount.
  3.1725 +*/
  3.1726 +
  3.1727 +static inline void BusLogic_IncrementSizeBucket(BusLogic_CommandSizeBuckets_T
  3.1728 +						  CommandSizeBuckets,
  3.1729 +						unsigned int Amount)
  3.1730 +{
  3.1731 +  int Index = 0;
  3.1732 +  if (Amount < 8*1024)
  3.1733 +    {
  3.1734 +      if (Amount < 2*1024)
  3.1735 +	Index = (Amount < 1*1024 ? 0 : 1);
  3.1736 +      else Index = (Amount < 4*1024 ? 2 : 3);
  3.1737 +    }
  3.1738 +  else if (Amount < 128*1024)
  3.1739 +    {
  3.1740 +      if (Amount < 32*1024)
  3.1741 +	Index = (Amount < 16*1024 ? 4 : 5);
  3.1742 +      else Index = (Amount < 64*1024 ? 6 : 7);
  3.1743 +    }
  3.1744 +  else Index = (Amount < 256*1024 ? 8 : 9);
  3.1745 +  CommandSizeBuckets[Index]++;
  3.1746 +}
  3.1747 +
  3.1748 +
  3.1749 +/*
  3.1750 +  Define the version number of the FlashPoint Firmware (SCCB Manager).
  3.1751 +*/
  3.1752 +
  3.1753 +#define FlashPoint_FirmwareVersion		"5.02"
  3.1754 +
  3.1755 +
  3.1756 +/*
  3.1757 +  Define the possible return values from FlashPoint_HandleInterrupt.
  3.1758 +*/
  3.1759 +
  3.1760 +#define FlashPoint_NormalInterrupt		0x00
  3.1761 +#define FlashPoint_InternalError		0xFE
  3.1762 +#define FlashPoint_ExternalBusReset		0xFF
  3.1763 +
  3.1764 +
  3.1765 +/*
  3.1766 +  Define prototypes for the forward referenced BusLogic Driver
  3.1767 +  Internal Functions.
  3.1768 +*/
  3.1769 +
  3.1770 +static void BusLogic_QueueCompletedCCB(BusLogic_CCB_T *);
  3.1771 +static void BusLogic_InterruptHandler(int, void *, Registers_T *);
  3.1772 +static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *,
  3.1773 +				     SCSI_Command_T *, unsigned int);
  3.1774 +static void BusLogic_Message(BusLogic_MessageLevel_T, char *,
  3.1775 +			     BusLogic_HostAdapter_T *, ...);
  3.1776 +
  3.1777 +/*
  3.1778 +  Declare the Initialization Functions.
  3.1779 +*/
  3.1780 +
  3.1781 +static void BusLogic_AnnounceDriver(BusLogic_HostAdapter_T *) __init;
  3.1782 +static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *) __init;
  3.1783 +static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *) __init;
  3.1784 +static boolean BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *) __init;
  3.1785 +static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *) __init;
  3.1786 +static void BusLogic_AppendProbeAddressISA(BusLogic_IO_Address_T) __init;
  3.1787 +static void
  3.1788 +BusLogic_InitializeProbeInfoListISA(BusLogic_HostAdapter_T *) __init;
  3.1789 +static void BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *, int) __init;
  3.1790 +static int
  3.1791 +BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T *) __init;
  3.1792 +static int
  3.1793 +BusLogic_InitializeFlashPointProbeInfo(BusLogic_HostAdapter_T *) __init;
  3.1794 +static void BusLogic_InitializeProbeInfoList(BusLogic_HostAdapter_T *) __init;
  3.1795 +static boolean BusLogic_Failure(BusLogic_HostAdapter_T *, char *) __init;
  3.1796 +static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *) __init;
  3.1797 +static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *) __init;
  3.1798 +static boolean
  3.1799 +BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T *) __init;
  3.1800 +static boolean
  3.1801 +BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T *) __init;
  3.1802 +static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *) __init;
  3.1803 +static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *) __init;
  3.1804 +static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T *) __init;
  3.1805 +static void BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T *,
  3.1806 +					     SCSI_Host_T *) __init;
  3.1807 +int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *) __init;
  3.1808 +int BusLogic_ReleaseHostAdapter(SCSI_Host_T *) __init;
  3.1809 +static boolean BusLogic_ParseKeyword(char **, char *) __init;
  3.1810 +#if 0 /* XEN */
  3.1811 +static int BusLogic_ParseDriverOptions(char *) __init;
  3.1812 +static int BusLogic_Setup(char *) __init;
  3.1813 +#endif
  3.1814 +
  3.1815 +
  3.1816 +#endif /* BusLogic_DriverVersion */
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xen/drivers/scsi/FlashPoint.c.inc	Sat Nov 08 11:06:04 2003 +0000
     4.3 @@ -0,0 +1,12159 @@
     4.4 +/*
     4.5 +
     4.6 +  FlashPoint.c -- FlashPoint SCCB Manager for Linux
     4.7 +
     4.8 +  This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
     4.9 +  Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
    4.10 +  Linux compatibility.  It was provided by BusLogic in the form of 16 separate
    4.11 +  source files, which would have unnecessarily cluttered the scsi directory, so
    4.12 +  the individual files have been combined into this single file.
    4.13 +
    4.14 +  Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
    4.15 +
    4.16 +  This file is available under both the GNU General Public License
    4.17 +  and a BSD-style copyright; see LICENSE.FlashPoint for details.
    4.18 +
    4.19 +*/
    4.20 +
    4.21 +
    4.22 +#include <linux/config.h>
    4.23 +
    4.24 +
    4.25 +#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
    4.26 +
    4.27 +
    4.28 +#define UNIX
    4.29 +#define FW_TYPE		_SCCB_MGR_
    4.30 +#define MAX_CARDS	8
    4.31 +#undef BUSTYPE_PCI
    4.32 +
    4.33 +
    4.34 +#define OS_InPortByte(port)		inb(port)
    4.35 +#define OS_InPortWord(port)		inw(port)
    4.36 +#define OS_InPortLong(port)		inl(port)
    4.37 +#define OS_OutPortByte(port, value)	outb(value, port)
    4.38 +#define OS_OutPortWord(port, value)	outw(value, port)
    4.39 +#define OS_OutPortLong(port, value)	outl(value, port)
    4.40 +#define OS_Lock(x)
    4.41 +#define OS_UnLock(x)
    4.42 +
    4.43 +
    4.44 +/*
    4.45 +  Define name replacements for compatibility with the Linux BusLogic Driver.
    4.46 +*/
    4.47 +
    4.48 +#define SccbMgr_sense_adapter		FlashPoint_ProbeHostAdapter
    4.49 +#define SccbMgr_config_adapter		FlashPoint_HardwareResetHostAdapter
    4.50 +#define SccbMgr_unload_card		FlashPoint_ReleaseHostAdapter
    4.51 +#define SccbMgr_start_sccb		FlashPoint_StartCCB
    4.52 +#define SccbMgr_abort_sccb		FlashPoint_AbortCCB
    4.53 +#define SccbMgr_my_int			FlashPoint_InterruptPending
    4.54 +#define SccbMgr_isr			FlashPoint_HandleInterrupt
    4.55 +
    4.56 +
    4.57 +/*
    4.58 +  Define name replacements to avoid kernel namespace pollution.
    4.59 +*/
    4.60 +
    4.61 +#define BL_Card				FPT_BL_Card
    4.62 +#define BusMasterInit			FPT_BusMasterInit
    4.63 +#define CalcCrc16			FPT_CalcCrc16
    4.64 +#define CalcLrc				FPT_CalcLrc
    4.65 +#define ChkIfChipInitialized		FPT_ChkIfChipInitialized
    4.66 +#define DiagBusMaster			FPT_DiagBusMaster
    4.67 +#define DiagEEPROM			FPT_DiagEEPROM
    4.68 +#define DiagXbow			FPT_DiagXbow
    4.69 +#define GetTarLun			FPT_GetTarLun
    4.70 +#define RNVRamData			FPT_RNVRamData
    4.71 +#define RdStack				FPT_RdStack
    4.72 +#define SccbMgrTableInitAll		FPT_SccbMgrTableInitAll
    4.73 +#define SccbMgrTableInitCard		FPT_SccbMgrTableInitCard
    4.74 +#define SccbMgrTableInitTarget		FPT_SccbMgrTableInitTarget
    4.75 +#define SccbMgr_bad_isr			FPT_SccbMgr_bad_isr
    4.76 +#define SccbMgr_scsi_reset		FPT_SccbMgr_scsi_reset
    4.77 +#define SccbMgr_timer_expired		FPT_SccbMgr_timer_expired
    4.78 +#define SendMsg				FPT_SendMsg
    4.79 +#define Wait				FPT_Wait
    4.80 +#define Wait1Second			FPT_Wait1Second
    4.81 +#define WrStack				FPT_WrStack
    4.82 +#define XbowInit			FPT_XbowInit
    4.83 +#define autoCmdCmplt			FPT_autoCmdCmplt
    4.84 +#define autoLoadDefaultMap		FPT_autoLoadDefaultMap
    4.85 +#define busMstrDataXferStart		FPT_busMstrDataXferStart
    4.86 +#define busMstrSGDataXferStart		FPT_busMstrSGDataXferStart
    4.87 +#define busMstrTimeOut			FPT_busMstrTimeOut
    4.88 +#define dataXferProcessor		FPT_dataXferProcessor
    4.89 +#define default_intena			FPT_default_intena
    4.90 +#define hostDataXferAbort		FPT_hostDataXferAbort
    4.91 +#define hostDataXferRestart		FPT_hostDataXferRestart
    4.92 +#define inisci				FPT_inisci
    4.93 +#define mbCards				FPT_mbCards
    4.94 +#define nvRamInfo			FPT_nvRamInfo
    4.95 +#define phaseBusFree			FPT_phaseBusFree
    4.96 +#define phaseChkFifo			FPT_phaseChkFifo
    4.97 +#define phaseCommand			FPT_phaseCommand
    4.98 +#define phaseDataIn			FPT_phaseDataIn
    4.99 +#define phaseDataOut			FPT_phaseDataOut
   4.100 +#define phaseDecode			FPT_phaseDecode
   4.101 +#define phaseIllegal			FPT_phaseIllegal
   4.102 +#define phaseMsgIn			FPT_phaseMsgIn
   4.103 +#define phaseMsgOut			FPT_phaseMsgOut
   4.104 +#define phaseStatus			FPT_phaseStatus
   4.105 +#define queueAddSccb			FPT_queueAddSccb
   4.106 +#define queueCmdComplete		FPT_queueCmdComplete
   4.107 +#define queueDisconnect			FPT_queueDisconnect
   4.108 +#define queueFindSccb			FPT_queueFindSccb
   4.109 +#define queueFlushSccb			FPT_queueFlushSccb
   4.110 +#define queueFlushTargSccb		FPT_queueFlushTargSccb
   4.111 +#define queueSearchSelect		FPT_queueSearchSelect
   4.112 +#define queueSelectFail			FPT_queueSelectFail
   4.113 +#define s_PhaseTbl			FPT_s_PhaseTbl
   4.114 +#define scamHAString			FPT_scamHAString
   4.115 +#define scamInfo			FPT_scamInfo
   4.116 +#define scarb				FPT_scarb
   4.117 +#define scasid				FPT_scasid
   4.118 +#define scbusf				FPT_scbusf
   4.119 +#define sccbMgrTbl			FPT_sccbMgrTbl
   4.120 +#define schkdd				FPT_schkdd
   4.121 +#define scini				FPT_scini
   4.122 +#define sciso				FPT_sciso
   4.123 +#define scmachid			FPT_scmachid
   4.124 +#define scsavdi				FPT_scsavdi
   4.125 +#define scsel				FPT_scsel
   4.126 +#define scsell				FPT_scsell
   4.127 +#define scsendi				FPT_scsendi
   4.128 +#define scvalq				FPT_scvalq
   4.129 +#define scwirod				FPT_scwirod
   4.130 +#define scwiros				FPT_scwiros
   4.131 +#define scwtsel				FPT_scwtsel
   4.132 +#define scxferc				FPT_scxferc
   4.133 +#define sdecm				FPT_sdecm
   4.134 +#define sfm				FPT_sfm
   4.135 +#define shandem				FPT_shandem
   4.136 +#define sinits				FPT_sinits
   4.137 +#define sisyncn				FPT_sisyncn
   4.138 +#define sisyncr				FPT_sisyncr
   4.139 +#define siwidn				FPT_siwidn
   4.140 +#define siwidr				FPT_siwidr
   4.141 +#define sres				FPT_sres
   4.142 +#define sresb				FPT_sresb
   4.143 +#define ssel				FPT_ssel
   4.144 +#define ssenss				FPT_ssenss
   4.145 +#define sssyncv				FPT_sssyncv
   4.146 +#define stsyncn				FPT_stsyncn
   4.147 +#define stwidn				FPT_stwidn
   4.148 +#define sxfrp				FPT_sxfrp
   4.149 +#define utilEERead			FPT_utilEERead
   4.150 +#define utilEEReadOrg			FPT_utilEEReadOrg
   4.151 +#define utilEESendCmdAddr		FPT_utilEESendCmdAddr
   4.152 +#define utilEEWrite			FPT_utilEEWrite
   4.153 +#define utilEEWriteOnOff		FPT_utilEEWriteOnOff
   4.154 +#define utilUpdateResidual		FPT_utilUpdateResidual
   4.155 +
   4.156 +
   4.157 +/*----------------------------------------------------------------------
   4.158 + *
   4.159 + *
   4.160 + *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
   4.161 + *
   4.162 + *   This file is available under both the GNU General Public License
   4.163 + *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
   4.164 + *
   4.165 + *   $Workfile:   globals.h  $
   4.166 + *
   4.167 + *   Description:  Common shared global defines.
   4.168 + *
   4.169 + *   $Date: 1996/09/04 01:26:13 $
   4.170 + *
   4.171 + *   $Revision: 1.11 $
   4.172 + *
   4.173 + *----------------------------------------------------------------------*/
   4.174 +#ifndef __GLOBALS_H__
   4.175 +#define __GLOBALS_H__
   4.176 +
   4.177 +#define _UCB_MGR_  1
   4.178 +#define _SCCB_MGR_ 2
   4.179 +
   4.180 +/*#include <osflags.h>*/
   4.181 +
   4.182 +#define MAX_CDBLEN  12
   4.183 +
   4.184 +#define SCAM_LEV_2	1
   4.185 +
   4.186 +#define CRCMASK	0xA001
   4.187 +
   4.188 +/*  In your osflags.h file, please ENSURE that only ONE OS FLAG 
   4.189 +    is on at a time !!! Also, please make sure you turn set the 
   4.190 + 	 variable FW_TYPE to either _UCB_MGR_ or _SCCB_MGR_  !!! */
   4.191 +
   4.192 +#if defined(DOS) || defined(WIN95_16) || defined(OS2) || defined(OTHER_16)
   4.193 +   #define       COMPILER_16_BIT 1
   4.194 +#elif defined(NETWARE) || defined(NT) || defined(WIN95_32) || defined(UNIX) || defined(OTHER_32) || defined(SOLARIS_REAL_MODE)
   4.195 +   #define       COMPILER_32_BIT 1
   4.196 +#endif
   4.197 +
   4.198 +
   4.199 +#define     BL_VENDOR_ID      0x104B
   4.200 +#define     FP_DEVICE_ID      0x8130
   4.201 +#define     MM_DEVICE_ID      0x1040
   4.202 +
   4.203 +
   4.204 +#ifndef FALSE
   4.205 +#define FALSE           0
   4.206 +#endif
   4.207 +#ifndef TRUE
   4.208 +#define TRUE            (!(FALSE))
   4.209 +#endif
   4.210 +
   4.211 +#ifndef NULL
   4.212 +#define NULL            0
   4.213 +#endif
   4.214 +
   4.215 +#define FAILURE         0xFFFFFFFFL
   4.216 +
   4.217 +
   4.218 +typedef unsigned char   UCHAR;
   4.219 +typedef unsigned short  USHORT;
   4.220 +typedef unsigned int    UINT;
   4.221 +typedef unsigned long   ULONG;
   4.222 +typedef unsigned char * PUCHAR;
   4.223 +typedef unsigned short* PUSHORT;
   4.224 +typedef unsigned long * PULONG;
   4.225 +typedef void *          PVOID;
   4.226 +
   4.227 +
   4.228 +#if defined(COMPILER_16_BIT)
   4.229 +typedef unsigned char far       * uchar_ptr;
   4.230 +typedef unsigned short far      * ushort_ptr;
   4.231 +typedef unsigned long far       * ulong_ptr;
   4.232 +#endif  /* 16_BIT_COMPILER */
   4.233 +
   4.234 +#if defined(COMPILER_32_BIT)
   4.235 +typedef unsigned char           * uchar_ptr;
   4.236 +typedef unsigned short          * ushort_ptr;
   4.237 +typedef unsigned long           * ulong_ptr;
   4.238 +#endif  /* 32_BIT_COMPILER */
   4.239 +
   4.240 +
   4.241 +/*	 			NEW TYPE DEFINITIONS (shared with Mylex North)
   4.242 +
   4.243 +**  Use following type defines to avoid confusion in 16 and 32-bit
   4.244 +**  environments.  Avoid using 'int' as it denotes 16 bits in 16-bit
   4.245 +**  environment and 32 in 32-bit environments.
   4.246 +
   4.247 +*/
   4.248 +
   4.249 +#define s08bits	char
   4.250 +#define s16bits 	short
   4.251 +#define s32bits	long
   4.252 +
   4.253 +#define u08bits	unsigned s08bits
   4.254 +#define u16bits	unsigned s16bits
   4.255 +#define u32bits	unsigned s32bits
   4.256 +
   4.257 +#if defined(COMPILER_16_BIT)
   4.258 +
   4.259 +typedef u08bits far 	* pu08bits;
   4.260 +typedef u16bits far 	* pu16bits;
   4.261 +typedef u32bits far	* pu32bits;
   4.262 +
   4.263 +#endif	/* COMPILER_16_BIT */
   4.264 +
   4.265 +#if defined(COMPILER_32_BIT)
   4.266 +
   4.267 +typedef u08bits 	* pu08bits;
   4.268 +typedef u16bits 	* pu16bits;
   4.269 +typedef u32bits 	* pu32bits;
   4.270 +
   4.271 +#endif	/* COMPILER_32_BIT */
   4.272 +
   4.273 +
   4.274 +#define BIT(x)          ((UCHAR)(1<<(x)))    /* single-bit mask in bit position x */
   4.275 +#define BITW(x)          ((USHORT)(1<<(x)))  /* single-bit mask in bit position x */
   4.276 +
   4.277 +
   4.278 +
   4.279 +#if defined(DOS)
   4.280 +/*#include <dos.h>*/
   4.281 +	#undef inportb          /* undefine for Borland Lib */
   4.282 +	#undef inport           /* they may have define I/O function in LIB */
   4.283 +	#undef outportb
   4.284 +	#undef outport
   4.285 +
   4.286 +	#define OS_InPortByte(ioport) 		inportb(ioport)
   4.287 +	#define OS_InPortWord(ioport) 		inport(ioport)
   4.288 +	#define OS_InPortLong(ioport)			inportq(ioport, val)
   4.289 +	#define OS_OutPortByte(ioport, val) outportb(ioport, val)
   4.290 +	#define OS_OutPortWord(ioport, val)	outport(ioport, val)
   4.291 +	#define OS_OutPortLong(ioport)		outportq(ioport, val)
   4.292 +#endif	/* DOS */
   4.293 +
   4.294 +#if defined(NETWARE) || defined(OTHER_32) ||  defined(OTHER_16)
   4.295 +	extern u08bits	OS_InPortByte(u32bits ioport);
   4.296 +	extern u16bits	OS_InPortWord(u32bits ioport);
   4.297 +	extern u32bits	OS_InPortLong(u32bits ioport);
   4.298 +
   4.299 +	extern OS_InPortByteBuffer(u32bits ioport, pu08bits buffer, u32bits count);
   4.300 +	extern OS_InPortWordBuffer(u32bits ioport, pu16bits buffer, u32bits count);
   4.301 +	extern OS_OutPortByte(u32bits ioport, u08bits val);
   4.302 +	extern OS_OutPortWord(u32bits ioport, u16bits val);
   4.303 +	extern OS_OutPortLong(u32bits ioport, u32bits val);
   4.304 +	extern OS_OutPortByteBuffer(u32bits ioport, pu08bits buffer, u32bits count);
   4.305 +	extern OS_OutPortWordBuffer(u32bits ioport, pu16bits buffer, u32bits count);
   4.306 +#endif	/* NETWARE || OTHER_32 || OTHER_16 */
   4.307 +
   4.308 +#if defined (NT) || defined(WIN95_32) || defined(WIN95_16)
   4.309 +	#if defined(NT)
   4.310 +
   4.311 +		extern __declspec(dllimport) u08bits ScsiPortReadPortUchar(pu08bits ioport);
   4.312 +		extern __declspec(dllimport) u16bits ScsiPortReadPortUshort(pu16bits ioport);
   4.313 +		extern __declspec(dllimport) u32bits ScsiPortReadPortUlong(pu32bits ioport);
   4.314 +		extern __declspec(dllimport) void ScsiPortWritePortUchar(pu08bits ioport, u08bits val);
   4.315 +		extern __declspec(dllimport) void ScsiPortWritePortUshort(pu16bits port, u16bits val);
   4.316 +		extern __declspec(dllimport) void ScsiPortWritePortUlong(pu32bits port, u32bits val);
   4.317 +
   4.318 +	#else
   4.319 +
   4.320 +		extern u08bits ScsiPortReadPortUchar(pu08bits ioport);
   4.321 +		extern u16bits ScsiPortReadPortUshort(pu16bits ioport);
   4.322 +		extern u32bits ScsiPortReadPortUlong(pu32bits ioport);
   4.323 +		extern void ScsiPortWritePortUchar(pu08bits ioport, u08bits val);
   4.324 +		extern void ScsiPortWritePortUshort(pu16bits port, u16bits val);
   4.325 +		extern void ScsiPortWritePortUlong(pu32bits port, u32bits val);
   4.326 +	#endif
   4.327 +
   4.328 +
   4.329 +	#define OS_InPortByte(ioport) ScsiPortReadPortUchar((pu08bits) ioport)
   4.330 +	#define OS_InPortWord(ioport) ScsiPortReadPortUshort((pu16bits) ioport)
   4.331 +	#define OS_InPortLong(ioport) ScsiPortReadPortUlong((pu32bits) ioport)
   4.332 +
   4.333 +	#define OS_OutPortByte(ioport, val) ScsiPortWritePortUchar((pu08bits) ioport, (u08bits) val)
   4.334 +	#define OS_OutPortWord(ioport, val) ScsiPortWritePortUshort((pu16bits) ioport, (u16bits) val)
   4.335 +	#define OS_OutPortLong(ioport, val) ScsiPortWritePortUlong((pu32bits) ioport, (u32bits) val)
   4.336 +	#define OS_OutPortByteBuffer(ioport, buffer, count) \
   4.337 +		ScsiPortWritePortBufferUchar((pu08bits)&port, (pu08bits) buffer, (u32bits) count)
   4.338 +	#define OS_OutPortWordBuffer(ioport, buffer, count) \
   4.339 +		ScsiPortWritePortBufferUshort((pu16bits)&port, (pu16bits) buffer, (u32bits) count)
   4.340 +
   4.341 +	#define OS_Lock(x)
   4.342 +	#define OS_UnLock(x)
   4.343 +#endif /* NT || WIN95_32 || WIN95_16 */
   4.344 +
   4.345 +#if defined (UNIX) && !defined(OS_InPortByte)
   4.346 +	#define OS_InPortByte(ioport)    inb((u16bits)ioport)
   4.347 +	#define OS_InPortWord(ioport)    inw((u16bits)ioport)
   4.348 +	#define OS_InPortLong(ioport)    inl((u16bits)ioport)
   4.349 +	#define OS_OutPortByte(ioport,val)  outb((u16bits)ioport, (u08bits)val)
   4.350 +	#define OS_OutPortWord(ioport,val)  outw((u16bits)ioport, (u16bits)val)
   4.351 +	#define OS_OutPortLong(ioport,val)  outl((u16bits)ioport, (u32bits)val)
   4.352 +
   4.353 +	#define OS_Lock(x)
   4.354 +	#define OS_UnLock(x)
   4.355 +#endif /* UNIX */
   4.356 +
   4.357 +
   4.358 +#if defined(OS2)
   4.359 +	extern u08bits	inb(u32bits ioport);
   4.360 +	extern u16bits	inw(u32bits ioport);
   4.361 +	extern void	outb(u32bits ioport, u08bits val);
   4.362 +	extern void	outw(u32bits ioport, u16bits val);
   4.363 +
   4.364 +	#define OS_InPortByte(ioport)			inb(ioport)
   4.365 +	#define OS_InPortWord(ioport)			inw(ioport)
   4.366 +	#define OS_OutPortByte(ioport, val)	outb(ioport, val)
   4.367 +	#define OS_OutPortWord(ioport, val)	outw(ioport, val)
   4.368 +	extern u32bits	OS_InPortLong(u32bits ioport);
   4.369 +	extern void	OS_OutPortLong(u32bits ioport, u32bits val);
   4.370 +
   4.371 +	#define OS_Lock(x)
   4.372 +	#define OS_UnLock(x)
   4.373 +#endif /* OS2 */
   4.374 +
   4.375 +#if defined(SOLARIS_REAL_MODE)
   4.376 +
   4.377 +extern unsigned char    inb(unsigned long ioport);
   4.378 +extern unsigned short   inw(unsigned long ioport);
   4.379 +
   4.380 +#define OS_InPortByte(ioport)    inb(ioport)
   4.381 +#define OS_InPortWord(ioport)    inw(ioport)
   4.382 +
   4.383 +extern void OS_OutPortByte(unsigned long ioport, unsigned char val);
   4.384 +extern void OS_OutPortWord(unsigned long ioport, unsigned short val);
   4.385 +extern unsigned long  OS_InPortLong(unsigned long ioport);
   4.386 +extern void     OS_OutPortLong(unsigned long ioport, unsigned long val);
   4.387 +
   4.388 +#define OS_Lock(x)
   4.389 +#define OS_UnLock(x)
   4.390 +
   4.391 +#endif  /* SOLARIS_REAL_MODE */
   4.392 +
   4.393 +#endif  /* __GLOBALS_H__ */
   4.394 +
   4.395 +/*----------------------------------------------------------------------
   4.396 + *
   4.397 + *
   4.398 + *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
   4.399 + *
   4.400 + *   This file is available under both the GNU General Public License
   4.401 + *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
   4.402 + *
   4.403 + *   $Workfile:   sccbmgr.h  $
   4.404 + *
   4.405 + *   Description:  Common shared SCCB Interface defines and SCCB 
   4.406 + *						 Manager specifics defines.
   4.407 + *
   4.408 + *   $Date: 1996/10/24 23:09:33 $
   4.409 + *
   4.410 + *   $Revision: 1.14 $
   4.411 + *
   4.412 + *----------------------------------------------------------------------*/
   4.413 +
   4.414 +#ifndef __SCCB_H__
   4.415 +#define __SCCB_H__
   4.416 +
   4.417 +/*#include <osflags.h>*/
   4.418 +/*#include <globals.h>*/
   4.419 +
   4.420 +#if defined(BUGBUG)
   4.421 +#define debug_size 32
   4.422 +#endif
   4.423 +
   4.424 +#if defined(DOS)
   4.425 +
   4.426 +   typedef struct _SCCB near *PSCCB;
   4.427 +	#if (FW_TYPE == _SCCB_MGR_)
   4.428 +   	typedef void (*CALL_BK_FN)(PSCCB);
   4.429 +	#endif
   4.430 +
   4.431 +#elif defined(OS2)
   4.432 +
   4.433 +   typedef struct _SCCB far *PSCCB;
   4.434 +	#if (FW_TYPE == _SCCB_MGR_)
   4.435 +   	typedef void (far *CALL_BK_FN)(PSCCB);
   4.436 +	#endif
   4.437 +
   4.438 +#else
   4.439 +
   4.440 +   typedef struct _SCCB *PSCCB;
   4.441 +	#if (FW_TYPE == _SCCB_MGR_)
   4.442 +   	typedef void (*CALL_BK_FN)(PSCCB);
   4.443 +	#endif
   4.444 +
   4.445 +#endif
   4.446 +
   4.447 +
   4.448 +typedef struct SCCBMgr_info {
   4.449 +   ULONG    si_baseaddr;
   4.450 +   UCHAR    si_present;
   4.451 +   UCHAR    si_intvect;
   4.452 +   UCHAR    si_id;
   4.453 +   UCHAR    si_lun;
   4.454 +   USHORT   si_fw_revision;
   4.455 +   USHORT   si_per_targ_init_sync;
   4.456 +   USHORT   si_per_targ_fast_nego;
   4.457 +   USHORT   si_per_targ_ultra_nego;
   4.458 +   USHORT   si_per_targ_no_disc;
   4.459 +   USHORT   si_per_targ_wide_nego;
   4.460 +   USHORT   si_flags;
   4.461 +   UCHAR    si_card_family;
   4.462 +   UCHAR    si_bustype;
   4.463 +   UCHAR    si_card_model[3];
   4.464 +   UCHAR    si_relative_cardnum;
   4.465 +   UCHAR    si_reserved[4];
   4.466 +   ULONG    si_OS_reserved;
   4.467 +   UCHAR    si_XlatInfo[4];
   4.468 +   ULONG    si_reserved2[5];
   4.469 +   ULONG    si_secondary_range;
   4.470 +} SCCBMGR_INFO;
   4.471 +
   4.472 +#if defined(DOS)
   4.473 +   typedef SCCBMGR_INFO *      PSCCBMGR_INFO;
   4.474 +#else
   4.475 +   #if defined (COMPILER_16_BIT)
   4.476 +   typedef SCCBMGR_INFO far *  PSCCBMGR_INFO;
   4.477 +   #else
   4.478 +   typedef SCCBMGR_INFO *      PSCCBMGR_INFO;
   4.479 +   #endif
   4.480 +#endif // defined(DOS)
   4.481 +
   4.482 +
   4.483 +
   4.484 +
   4.485 +#if (FW_TYPE==_SCCB_MGR_)
   4.486 +	#define SCSI_PARITY_ENA		  0x0001
   4.487 +	#define LOW_BYTE_TERM		  0x0010
   4.488 +	#define HIGH_BYTE_TERM		  0x0020
   4.489 +	#define BUSTYPE_PCI	  0x3
   4.490 +#endif
   4.491 +
   4.492 +#define SUPPORT_16TAR_32LUN	  0x0002
   4.493 +#define SOFT_RESET		  0x0004
   4.494 +#define EXTENDED_TRANSLATION	  0x0008
   4.495 +#define POST_ALL_UNDERRRUNS	  0x0040
   4.496 +#define FLAG_SCAM_ENABLED	  0x0080
   4.497 +#define FLAG_SCAM_LEVEL2	  0x0100
   4.498 +
   4.499 +
   4.500 +
   4.501 +
   4.502 +#define HARPOON_FAMILY        0x02
   4.503 +
   4.504 +
   4.505 +#define ISA_BUS_CARD          0x01
   4.506 +#define EISA_BUS_CARD         0x02
   4.507 +#define PCI_BUS_CARD          0x03
   4.508 +#define VESA_BUS_CARD         0x04
   4.509 +
   4.510 +/* SCCB struc used for both SCCB and UCB manager compiles! 
   4.511 + * The UCB Manager treats the SCCB as it's 'native hardware structure' 
   4.512 + */
   4.513 +
   4.514 +
   4.515 +#pragma pack(1)
   4.516 +typedef struct _SCCB {
   4.517 +   UCHAR OperationCode;
   4.518 +   UCHAR ControlByte;
   4.519 +   UCHAR CdbLength;
   4.520 +   UCHAR RequestSenseLength;
   4.521 +   ULONG DataLength;
   4.522 +   ULONG DataPointer;
   4.523 +   UCHAR CcbRes[2];
   4.524 +   UCHAR HostStatus;
   4.525 +   UCHAR TargetStatus;
   4.526 +   UCHAR TargID;
   4.527 +   UCHAR Lun;
   4.528 +   UCHAR Cdb[12];
   4.529 +   UCHAR CcbRes1;
   4.530 +   UCHAR Reserved1;
   4.531 +   ULONG Reserved2;
   4.532 +   ULONG SensePointer;
   4.533 +
   4.534 +
   4.535 +   CALL_BK_FN SccbCallback;                  /* VOID (*SccbCallback)(); */
   4.536 +   ULONG  SccbIOPort;                        /* Identifies board base port */
   4.537 +   UCHAR  SccbStatus;
   4.538 +   UCHAR  SCCBRes2;
   4.539 +   USHORT SccbOSFlags;
   4.540 +
   4.541 +
   4.542 +   ULONG   Sccb_XferCnt;            /* actual transfer count */
   4.543 +   ULONG   Sccb_ATC;
   4.544 +   ULONG   SccbVirtDataPtr;         /* virtual addr for OS/2 */
   4.545 +   ULONG   Sccb_res1;
   4.546 +   USHORT  Sccb_MGRFlags;
   4.547 +   USHORT  Sccb_sgseg;
   4.548 +   UCHAR   Sccb_scsimsg;            /* identify msg for selection */
   4.549 +   UCHAR   Sccb_tag;
   4.550 +   UCHAR   Sccb_scsistat;
   4.551 +   UCHAR   Sccb_idmsg;              /* image of last msg in */
   4.552 +   PSCCB   Sccb_forwardlink;
   4.553 +   PSCCB   Sccb_backlink;
   4.554 +   ULONG   Sccb_savedATC;
   4.555 +   UCHAR   Save_Cdb[6];
   4.556 +   UCHAR   Save_CdbLen;
   4.557 +   UCHAR   Sccb_XferState;
   4.558 +   ULONG   Sccb_SGoffset;
   4.559 +#if (FW_TYPE == _UCB_MGR_)
   4.560 +   PUCB    Sccb_ucb_ptr;
   4.561 +#endif
   4.562 +   } SCCB;
   4.563 +
   4.564 +#define SCCB_SIZE sizeof(SCCB)
   4.565 +
   4.566 +#pragma pack()
   4.567 +
   4.568 +
   4.569 +
   4.570 +#define SCSI_INITIATOR_COMMAND    0x00
   4.571 +#define TARGET_MODE_COMMAND       0x01
   4.572 +#define SCATTER_GATHER_COMMAND    0x02
   4.573 +#define RESIDUAL_COMMAND          0x03
   4.574 +#define RESIDUAL_SG_COMMAND       0x04
   4.575 +#define RESET_COMMAND             0x81
   4.576 +
   4.577 +
   4.578 +#define F_USE_CMD_Q              0x20     /*Inidcates TAGGED command. */
   4.579 +#define TAG_TYPE_MASK            0xC0     /*Type of tag msg to send. */
   4.580 +#define TAG_Q_MASK               0xE0
   4.581 +#define SCCB_DATA_XFER_OUT       0x10     /* Write */
   4.582 +#define SCCB_DATA_XFER_IN        0x08     /* Read */
   4.583 +
   4.584 +
   4.585 +#define FOURTEEN_BYTES           0x00     /* Request Sense Buffer size */
   4.586 +#define NO_AUTO_REQUEST_SENSE    0x01     /* No Request Sense Buffer */
   4.587 +
   4.588 +
   4.589 +#define BUS_FREE_ST     0       
   4.590 +#define SELECT_ST       1
   4.591 +#define SELECT_BDR_ST   2     /* Select w\ Bus Device Reset */
   4.592 +#define SELECT_SN_ST    3     /* Select w\ Sync Nego */
   4.593 +#define SELECT_WN_ST    4     /* Select w\ Wide Data Nego */
   4.594 +#define SELECT_Q_ST     5     /* Select w\ Tagged Q'ing */
   4.595 +#define COMMAND_ST      6
   4.596 +#define DATA_OUT_ST     7
   4.597 +#define DATA_IN_ST      8
   4.598 +#define DISCONNECT_ST   9
   4.599 +#define STATUS_ST       10
   4.600 +#define ABORT_ST        11
   4.601 +#define MESSAGE_ST      12
   4.602 +
   4.603 +
   4.604 +#define F_HOST_XFER_DIR                0x01
   4.605 +#define F_ALL_XFERRED                  0x02
   4.606 +#define F_SG_XFER                      0x04
   4.607 +#define F_AUTO_SENSE                   0x08
   4.608 +#define F_ODD_BALL_CNT                 0x10
   4.609 +#define F_NO_DATA_YET                  0x80
   4.610 +
   4.611 +
   4.612 +#define F_STATUSLOADED                 0x01
   4.613 +#define F_MSGLOADED                    0x02
   4.614 +#define F_DEV_SELECTED                 0x04
   4.615 +
   4.616 +
   4.617 +#define SCCB_COMPLETE               0x00  /* SCCB completed without error */
   4.618 +#define SCCB_DATA_UNDER_RUN         0x0C
   4.619 +#define SCCB_SELECTION_TIMEOUT      0x11  /* Set SCSI selection timed out */
   4.620 +#define SCCB_DATA_OVER_RUN          0x12
   4.621 +#define SCCB_UNEXPECTED_BUS_FREE    0x13  /* Target dropped SCSI BSY */
   4.622 +#define SCCB_PHASE_SEQUENCE_FAIL    0x14  /* Target bus phase sequence failure */
   4.623 +
   4.624 +#define SCCB_INVALID_OP_CODE        0x16  /* SCCB invalid operation code */
   4.625 +#define SCCB_INVALID_SCCB           0x1A  /* Invalid SCCB - bad parameter */
   4.626 +#define SCCB_GROSS_FW_ERR           0x27  /* Major problem! */
   4.627 +#define SCCB_BM_ERR                 0x30  /* BusMaster error. */
   4.628 +#define SCCB_PARITY_ERR             0x34  /* SCSI parity error */
   4.629 +
   4.630 +
   4.631 +
   4.632 +#if (FW_TYPE==_UCB_MGR_)  
   4.633 +   #define  HBA_AUTO_SENSE_FAIL        0x1B  
   4.634 +   #define  HBA_TQ_REJECTED            0x1C  
   4.635 +   #define  HBA_UNSUPPORTED_MSG         0x1D  
   4.636 +   #define  HBA_HW_ERROR               0x20  
   4.637 +   #define  HBA_ATN_NOT_RESPONDED      0x21  
   4.638 +   #define  HBA_SCSI_RESET_BY_ADAPTER  0x22
   4.639 +   #define  HBA_SCSI_RESET_BY_TARGET   0x23
   4.640 +   #define  HBA_WRONG_CONNECTION       0x24
   4.641 +   #define  HBA_BUS_DEVICE_RESET       0x25
   4.642 +   #define  HBA_ABORT_QUEUE            0x26
   4.643 +
   4.644 +#else // these are not defined in BUDI/UCB
   4.645 +
   4.646 +   #define SCCB_INVALID_DIRECTION      0x18  /* Invalid target direction */
   4.647 +   #define SCCB_DUPLICATE_SCCB         0x19  /* Duplicate SCCB */
   4.648 +   #define SCCB_SCSI_RST               0x35  /* SCSI RESET detected. */
   4.649 +
   4.650 +#endif // (FW_TYPE==_UCB_MGR_)  
   4.651 +
   4.652 +
   4.653 +#define SCCB_IN_PROCESS            0x00
   4.654 +#define SCCB_SUCCESS               0x01
   4.655 +#define SCCB_ABORT                 0x02
   4.656 +#define SCCB_NOT_FOUND             0x03
   4.657 +#define SCCB_ERROR                 0x04
   4.658 +#define SCCB_INVALID               0x05
   4.659 +
   4.660 +#define SCCB_SIZE sizeof(SCCB)
   4.661 +
   4.662 +
   4.663 +
   4.664 +
   4.665 +#if (FW_TYPE == _UCB_MGR_)
   4.666 +	void SccbMgr_start_sccb(CARD_HANDLE pCurrCard, PUCB p_ucb);
   4.667 +	s32bits SccbMgr_abort_sccb(CARD_HANDLE pCurrCard, PUCB p_ucb);
   4.668 +	u08bits SccbMgr_my_int(CARD_HANDLE pCurrCard);
   4.669 +	s32bits SccbMgr_isr(CARD_HANDLE pCurrCard);
   4.670 +	void SccbMgr_scsi_reset(CARD_HANDLE pCurrCard);
   4.671 +	void SccbMgr_timer_expired(CARD_HANDLE pCurrCard);
   4.672 +	void SccbMgr_unload_card(CARD_HANDLE pCurrCard);
   4.673 +	void SccbMgr_restore_foreign_state(CARD_HANDLE pCurrCard);
   4.674 +	void SccbMgr_restore_native_state(CARD_HANDLE pCurrCard);
   4.675 +	void SccbMgr_save_foreign_state(PADAPTER_INFO pAdapterInfo);
   4.676 +
   4.677 +#endif
   4.678 +
   4.679 +
   4.680 +#if (FW_TYPE == _SCCB_MGR_)
   4.681 +
   4.682 + #if defined (DOS)
   4.683 +	int    SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo);
   4.684 +	USHORT SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo);
   4.685 +	void  SccbMgr_start_sccb(USHORT pCurrCard, PSCCB p_SCCB);
   4.686 +	int   SccbMgr_abort_sccb(USHORT pCurrCard, PSCCB p_SCCB);
   4.687 +	UCHAR SccbMgr_my_int(USHORT pCurrCard);
   4.688 +	int   SccbMgr_isr(USHORT pCurrCard);
   4.689 +	void  SccbMgr_scsi_reset(USHORT pCurrCard);
   4.690 +	void  SccbMgr_timer_expired(USHORT pCurrCard);
   4.691 +	USHORT SccbMgr_status(USHORT pCurrCard);
   4.692 +	void SccbMgr_unload_card(USHORT pCurrCard);
   4.693 +
   4.694 + #else    //non-DOS
   4.695 +
   4.696 +	int   SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo);
   4.697 +	ULONG SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo);
   4.698 +	void  SccbMgr_start_sccb(ULONG pCurrCard, PSCCB p_SCCB);
   4.699 +	int   SccbMgr_abort_sccb(ULONG pCurrCard, PSCCB p_SCCB);
   4.700 +	UCHAR SccbMgr_my_int(ULONG pCurrCard);
   4.701 +	int   SccbMgr_isr(ULONG pCurrCard);
   4.702 +	void  SccbMgr_scsi_reset(ULONG pCurrCard);
   4.703 +	void  SccbMgr_enable_int(ULONG pCurrCard);
   4.704 +	void  SccbMgr_disable_int(ULONG pCurrCard);
   4.705 +	void  SccbMgr_timer_expired(ULONG pCurrCard);
   4.706 +	void SccbMgr_unload_card(ULONG pCurrCard);
   4.707 +
   4.708 +  #endif
   4.709 +#endif  // (FW_TYPE == _SCCB_MGR_)
   4.710 +
   4.711 +#endif  /* __SCCB_H__ */
   4.712 +
   4.713 +/*----------------------------------------------------------------------
   4.714 + *
   4.715 + *
   4.716 + *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
   4.717 + *
   4.718 + *   This file is available under both the GNU General Public License
   4.719 + *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
   4.720 + *
   4.721 + *   $Workfile:   blx30.h  $
   4.722 + *
   4.723 + *   Description: This module contains SCCB/UCB Manager implementation
   4.724 + *                specific stuff.
   4.725 + *
   4.726 + *   $Date: 1996/11/13 18:34:22 $
   4.727 + *
   4.728 + *   $Revision: 1.10 $
   4.729 + *
   4.730 + *----------------------------------------------------------------------*/
   4.731 +
   4.732 +
   4.733 +#ifndef __blx30_H__
   4.734 +#define __blx30_H__
   4.735 +
   4.736 +/*#include <globals.h>*/
   4.737 +
   4.738 +#define  ORION_FW_REV      3110
   4.739 +
   4.740 +
   4.741 +
   4.742 +
   4.743 +#define HARP_REVD    1
   4.744 +
   4.745 +
   4.746 +#if defined(DOS)
   4.747 +#define QUEUE_DEPTH     8+1            /*1 for Normal disconnect 0 for Q'ing. */
   4.748 +#else
   4.749 +#define QUEUE_DEPTH     254+1            /*1 for Normal disconnect 32 for Q'ing. */
   4.750 +#endif   // defined(DOS)
   4.751 +
   4.752 +#define	MAX_MB_CARDS	4					/* Max. no of cards suppoerted on Mother Board */
   4.753 +
   4.754 +#define WIDE_SCSI       1
   4.755 +
   4.756 +#if defined(WIDE_SCSI)
   4.757 +   #if defined(DOS)
   4.758 +      #define MAX_SCSI_TAR    16
   4.759 +      #define MAX_LUN         8
   4.760 +		#define LUN_MASK			0x07
   4.761 +   #else
   4.762 +      #define MAX_SCSI_TAR    16
   4.763 +      #define MAX_LUN         32
   4.764 +		#define LUN_MASK			0x1f
   4.765 +	
   4.766 +   #endif
   4.767 +#else
   4.768 +   #define MAX_SCSI_TAR    8
   4.769 +   #define MAX_LUN         8
   4.770 +	#define LUN_MASK			0x07
   4.771 +#endif 
   4.772 +
   4.773 +#if defined(HARP_REVA)
   4.774 +#define SG_BUF_CNT      15             /*Number of prefetched elements. */
   4.775 +#else
   4.776 +#define SG_BUF_CNT      16             /*Number of prefetched elements. */
   4.777 +#endif
   4.778 +
   4.779 +#define SG_ELEMENT_SIZE 8              /*Eight byte per element. */
   4.780 +#define SG_LOCAL_MASK   0x00000000L
   4.781 +#define SG_ELEMENT_MASK 0xFFFFFFFFL
   4.782 +
   4.783 +
   4.784 +#if (FW_TYPE == _UCB_MGR_)
   4.785 +	#define OPC_DECODE_NORMAL       0x0f7f
   4.786 +#endif   // _UCB_MGR_
   4.787 +
   4.788 +
   4.789 +
   4.790 +#if defined(DOS)
   4.791 +
   4.792 +/*#include <dos.h>*/
   4.793 +	#define RD_HARPOON(ioport)          (OS_InPortByte(ioport))
   4.794 +	#define RDW_HARPOON(ioport)         (OS_InPortWord(ioport))
   4.795 +	#define WR_HARPOON(ioport,val)      (OS_OutPortByte(ioport,val))
   4.796 +	#define WRW_HARPOON(ioport,val)     (OS_OutPortWord(ioport,val))
   4.797 +
   4.798 +	#define RD_HARP32(port,offset,data)  asm{db 66h;         \
   4.799 +                                       push ax;             \
   4.800 +                                       mov dx,port;         \
   4.801 +                                       add dx, offset;      \
   4.802 +                                       db 66h;              \
   4.803 +                                       in ax,dx;            \
   4.804 +                                       db 66h;              \
   4.805 +                                       mov word ptr data,ax;\
   4.806 +                                       db 66h;              \
   4.807 +                                       pop ax}
   4.808 +
   4.809 +	#define WR_HARP32(port,offset,data) asm{db 66h;          \
   4.810 +                                       push ax;             \
   4.811 +                                       mov dx,port;         \
   4.812 +                                       add dx, offset;      \
   4.813 +                                       db 66h;              \
   4.814 +                                       mov ax,word ptr data;\
   4.815 +                                       db 66h;              \
   4.816 +                                       out dx,ax;           \
   4.817 +                                       db 66h;              \
   4.818 +                                       pop ax}
   4.819 +#endif	/* DOS */
   4.820 +
   4.821 +#if defined(NETWARE) || defined(OTHER_32) ||  defined(OTHER_16)
   4.822 +	#define RD_HARPOON(ioport)     OS_InPortByte((unsigned long)ioport)
   4.823 +	#define RDW_HARPOON(ioport)    OS_InPortWord((unsigned long)ioport)
   4.824 +	#define RD_HARP32(ioport,offset,data) (data = OS_InPortLong(ioport + offset))
   4.825 +	#define WR_HARPOON(ioport,val) OS_OutPortByte((ULONG)ioport,(UCHAR) val)
   4.826 +	#define WRW_HARPOON(ioport,val)  OS_OutPortWord((ULONG)ioport,(USHORT)val)
   4.827 +	#define WR_HARP32(ioport,offset,data)  OS_OutPortLong((ioport + offset), data)
   4.828 +#endif	/* NETWARE || OTHER_32 || OTHER_16 */
   4.829 +
   4.830 +#if defined(NT) || defined(WIN95_32) || defined(WIN95_16)
   4.831 +	#define RD_HARPOON(ioport)          OS_InPortByte((ULONG)ioport)
   4.832 +	#define RDW_HARPOON(ioport)         OS_InPortWord((ULONG)ioport)
   4.833 +	#define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((ULONG)(ioport + offset)))
   4.834 +	#define WR_HARPOON(ioport,val)      OS_OutPortByte((ULONG)ioport,(UCHAR) val)
   4.835 +	#define WRW_HARPOON(ioport,val)     OS_OutPortWord((ULONG)ioport,(USHORT)val)
   4.836 +	#define WR_HARP32(ioport,offset,data)  OS_OutPortLong((ULONG)(ioport + offset), data)
   4.837 +#endif /* NT || WIN95_32 || WIN95_16 */
   4.838 +
   4.839 +#if defined (UNIX)
   4.840 +	#define RD_HARPOON(ioport)          OS_InPortByte((u32bits)ioport)
   4.841 +	#define RDW_HARPOON(ioport)         OS_InPortWord((u32bits)ioport)
   4.842 +	#define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((u32bits)(ioport + offset)))
   4.843 +	#define WR_HARPOON(ioport,val)      OS_OutPortByte((u32bits)ioport,(u08bits) val)
   4.844 +	#define WRW_HARPOON(ioport,val)       OS_OutPortWord((u32bits)ioport,(u16bits)val)
   4.845 +	#define WR_HARP32(ioport,offset,data)  OS_OutPortLong((u32bits)(ioport + offset), data)
   4.846 +#endif /* UNIX */
   4.847 +
   4.848 +#if defined(OS2)
   4.849 +	#define RD_HARPOON(ioport)          OS_InPortByte((unsigned long)ioport)
   4.850 +	#define RDW_HARPOON(ioport)         OS_InPortWord((unsigned long)ioport)
   4.851 +	#define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((ULONG)(ioport + offset)))
   4.852 +	#define WR_HARPOON(ioport,val)      OS_OutPortByte((ULONG)ioport,(UCHAR) val)
   4.853 +	#define WRW_HARPOON(ioport,val)       OS_OutPortWord((ULONG)ioport,(USHORT)val)
   4.854 +	#define WR_HARP32(ioport,offset,data)  OS_OutPortLong(((ULONG)(ioport + offset)), data)
   4.855 +#endif /* OS2 */
   4.856 +
   4.857 +#if defined(SOLARIS_REAL_MODE)
   4.858 +
   4.859 +	#define RD_HARPOON(ioport)          OS_InPortByte((unsigned long)ioport)
   4.860 +	#define RDW_HARPOON(ioport)         OS_InPortWord((unsigned long)ioport)
   4.861 +	#define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((ULONG)(ioport + offset)))
   4.862 +	#define WR_HARPOON(ioport,val)      OS_OutPortByte((ULONG)ioport,(UCHAR) val)
   4.863 +	#define WRW_HARPOON(ioport,val)       OS_OutPortWord((ULONG)ioport,(USHORT)val)
   4.864 +	#define WR_HARP32(ioport,offset,data)  OS_OutPortLong((ULONG)(ioport + offset), (ULONG)data)
   4.865 +
   4.866 +#endif  /* SOLARIS_REAL_MODE */
   4.867 +
   4.868 +#endif  /* __BLX30_H__ */
   4.869 +
   4.870 +
   4.871 +/*----------------------------------------------------------------------
   4.872 + * 
   4.873 + *
   4.874 + *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
   4.875 + *
   4.876 + *   This file is available under both the GNU General Public License
   4.877 + *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
   4.878 + *
   4.879 + *   $Workfile:   target.h  $
   4.880 + *
   4.881 + *   Description:  Definitions for Target related structures
   4.882 + *
   4.883 + *   $Date: 1996/12/11 22:06:20 $
   4.884 + *
   4.885 + *   $Revision: 1.9 $
   4.886 + *
   4.887 + *----------------------------------------------------------------------*/
   4.888 +
   4.889 +#ifndef __TARGET__
   4.890 +#define __TARGET__
   4.891 +
   4.892 +/*#include <globals.h>*/
   4.893 +/*#include <blx30.h>*/
   4.894 +
   4.895 +
   4.896 +#define  TAR_SYNC_MASK     (BIT(7)+BIT(6))
   4.897 +#define  SYNC_UNKNOWN      0x00
   4.898 +#define  SYNC_TRYING               BIT(6)
   4.899 +#define  SYNC_SUPPORTED    (BIT(7)+BIT(6))
   4.900 +
   4.901 +#define  TAR_WIDE_MASK     (BIT(5)+BIT(4))
   4.902 +#define  WIDE_DISABLED     0x00
   4.903 +#define  WIDE_ENABLED              BIT(4)
   4.904 +#define  WIDE_NEGOCIATED   BIT(5)
   4.905 +
   4.906 +#define  TAR_TAG_Q_MASK    (BIT(3)+BIT(2))
   4.907 +#define  TAG_Q_UNKNOWN     0x00
   4.908 +#define  TAG_Q_TRYING              BIT(2)
   4.909 +#define  TAG_Q_REJECT      BIT(3)
   4.910 +#define  TAG_Q_SUPPORTED   (BIT(3)+BIT(2))
   4.911 +
   4.912 +#define  TAR_ALLOW_DISC    BIT(0)
   4.913 +
   4.914 +
   4.915 +#define  EE_SYNC_MASK      (BIT(0)+BIT(1))
   4.916 +#define  EE_SYNC_ASYNC     0x00
   4.917 +#define  EE_SYNC_5MB       BIT(0)
   4.918 +#define  EE_SYNC_10MB      BIT(1)
   4.919 +#define  EE_SYNC_20MB      (BIT(0)+BIT(1))
   4.920 +
   4.921 +#define  EE_ALLOW_DISC     BIT(6)
   4.922 +#define  EE_WIDE_SCSI      BIT(7)
   4.923 +
   4.924 +
   4.925 +#if defined(DOS)
   4.926 +   typedef struct SCCBMgr_tar_info near *PSCCBMgr_tar_info;
   4.927 +
   4.928 +#elif defined(OS2)
   4.929 +   typedef struct SCCBMgr_tar_info far *PSCCBMgr_tar_info;
   4.930 +
   4.931 +#else
   4.932 +   typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
   4.933 +
   4.934 +#endif
   4.935 +
   4.936 +
   4.937 +typedef struct SCCBMgr_tar_info {
   4.938 +
   4.939 +   PSCCB    TarSelQ_Head;
   4.940 +   PSCCB    TarSelQ_Tail;
   4.941 +   UCHAR    TarLUN_CA;        /*Contingent Allgiance */
   4.942 +   UCHAR    TarTagQ_Cnt;
   4.943 +   UCHAR    TarSelQ_Cnt;
   4.944 +   UCHAR    TarStatus;
   4.945 +   UCHAR    TarEEValue;
   4.946 +   UCHAR 	TarSyncCtrl;
   4.947 +   UCHAR 	TarReserved[2];			/* for alignment */ 
   4.948 +   UCHAR 	LunDiscQ_Idx[MAX_LUN];
   4.949 +   UCHAR    TarLUNBusy[MAX_LUN];
   4.950 +} SCCBMGR_TAR_INFO;
   4.951 +
   4.952 +typedef struct NVRAMInfo {
   4.953 +	UCHAR		niModel;								/* Model No. of card */
   4.954 +	UCHAR		niCardNo;							/* Card no. */
   4.955 +#if defined(DOS)
   4.956 +	USHORT	niBaseAddr;							/* Port Address of card */
   4.957 +#else
   4.958 +	ULONG		niBaseAddr;							/* Port Address of card */
   4.959 +#endif
   4.960 +	UCHAR		niSysConf;							/* Adapter Configuration byte - Byte 16 of eeprom map */
   4.961 +	UCHAR		niScsiConf;							/* SCSI Configuration byte - Byte 17 of eeprom map */
   4.962 +	UCHAR		niScamConf;							/* SCAM Configuration byte - Byte 20 of eeprom map */
   4.963 +	UCHAR		niAdapId;							/* Host Adapter ID - Byte 24 of eerpom map */
   4.964 +	UCHAR		niSyncTbl[MAX_SCSI_TAR / 2];	/* Sync/Wide byte of targets */
   4.965 +	UCHAR		niScamTbl[MAX_SCSI_TAR][4];	/* Compressed Scam name string of Targets */
   4.966 +}NVRAMINFO;
   4.967 +
   4.968 +#if defined(DOS)
   4.969 +typedef NVRAMINFO near *PNVRamInfo;
   4.970 +#elif defined (OS2)
   4.971 +typedef NVRAMINFO far *PNVRamInfo;
   4.972 +#else
   4.973 +typedef NVRAMINFO *PNVRamInfo;
   4.974 +#endif
   4.975 +
   4.976 +#define	MODEL_LT		1
   4.977 +#define	MODEL_DL		2
   4.978 +#define	MODEL_LW		3
   4.979 +#define	MODEL_DW		4
   4.980 +
   4.981 +
   4.982 +typedef struct SCCBcard {
   4.983 +   PSCCB currentSCCB;
   4.984 +#if (FW_TYPE==_SCCB_MGR_)
   4.985 +   PSCCBMGR_INFO cardInfo;
   4.986 +#else
   4.987 +   PADAPTER_INFO cardInfo;
   4.988 +#endif
   4.989 +
   4.990 +#if defined(DOS)
   4.991 +   USHORT ioPort;
   4.992 +#else
   4.993 +   ULONG ioPort;
   4.994 +#endif
   4.995 +
   4.996 +   USHORT cmdCounter;
   4.997 +   UCHAR  discQCount;
   4.998 +   UCHAR  tagQ_Lst; 
   4.999 +   UCHAR cardIndex;
  4.1000 +   UCHAR scanIndex;
  4.1001 +   UCHAR globalFlags;
  4.1002 +   UCHAR ourId;
  4.1003 +   PNVRamInfo pNvRamInfo;
  4.1004 +   PSCCB discQ_Tbl[QUEUE_DEPTH]; 
  4.1005 +      
  4.1006 +}SCCBCARD;
  4.1007 +
  4.1008 +#if defined(DOS)
  4.1009 +typedef struct SCCBcard near *PSCCBcard;
  4.1010 +#elif defined (OS2)
  4.1011 +typedef struct SCCBcard far *PSCCBcard;
  4.1012 +#else
  4.1013 +typedef struct SCCBcard *PSCCBcard;
  4.1014 +#endif
  4.1015 +
  4.1016 +
  4.1017 +#define F_TAG_STARTED		0x01
  4.1018 +#define F_CONLUN_IO			0x02
  4.1019 +#define F_DO_RENEGO			0x04
  4.1020 +#define F_NO_FILTER			0x08
  4.1021 +#define F_GREEN_PC			0x10
  4.1022 +#define F_HOST_XFER_ACT		0x20
  4.1023 +#define F_NEW_SCCB_CMD		0x40
  4.1024 +#define F_UPDATE_EEPROM		0x80
  4.1025 +
  4.1026 +
  4.1027 +#define  ID_STRING_LENGTH  32
  4.1028 +#define  TYPE_CODE0        0x63           /*Level2 Mstr (bits 7-6),  */
  4.1029 +
  4.1030 +#define  TYPE_CODE1        00             /*No ID yet */
  4.1031 +
  4.1032 +#define  SLV_TYPE_CODE0    0xA3           /*Priority Bit set (bits 7-6),  */
  4.1033 +
  4.1034 +#define  ASSIGN_ID   0x00
  4.1035 +#define  SET_P_FLAG  0x01
  4.1036 +#define  CFG_CMPLT   0x03
  4.1037 +#define  DOM_MSTR    0x0F
  4.1038 +#define  SYNC_PTRN   0x1F
  4.1039 +
  4.1040 +#define  ID_0_7      0x18
  4.1041 +#define  ID_8_F      0x11
  4.1042 +#define  ID_10_17    0x12
  4.1043 +#define  ID_18_1F    0x0B
  4.1044 +#define  MISC_CODE   0x14
  4.1045 +#define  CLR_P_FLAG  0x18
  4.1046 +#define  LOCATE_ON   0x12
  4.1047 +#define  LOCATE_OFF  0x0B
  4.1048 +
  4.1049 +#define  LVL_1_MST   0x00
  4.1050 +#define  LVL_2_MST   0x40
  4.1051 +#define  DOM_LVL_2   0xC0
  4.1052 +
  4.1053 +
  4.1054 +#define  INIT_SELTD  0x01
  4.1055 +#define  LEVEL2_TAR  0x02
  4.1056 +
  4.1057 +
  4.1058 +enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
  4.1059 +                  ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
  4.1060 +                  CLR_PRIORITY,NO_ID_AVAIL };
  4.1061 +
  4.1062 +typedef struct SCCBscam_info {
  4.1063 +
  4.1064 +   UCHAR    id_string[ID_STRING_LENGTH];
  4.1065 +   enum scam_id_st state;
  4.1066 +    
  4.1067 +} SCCBSCAM_INFO, *PSCCBSCAM_INFO;
  4.1068 +
  4.1069 +#endif
  4.1070 +/*----------------------------------------------------------------------
  4.1071 + *
  4.1072 + *
  4.1073 + *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
  4.1074 + *
  4.1075 + *   This file is available under both the GNU General Public License
  4.1076 + *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
  4.1077 + *
  4.1078 + *   $Workfile:   scsi2.h  $
  4.1079 + *
  4.1080 + *   Description:  Register definitions for HARPOON ASIC.
  4.1081 + *
  4.1082 + *   $Date: 1996/11/13 18:32:57 $
  4.1083 + *
  4.1084 + *   $Revision: 1.4 $
  4.1085 + *
  4.1086 + *----------------------------------------------------------------------*/
  4.1087 +
  4.1088 +#ifndef __SCSI_H__
  4.1089 +#define __SCSI_H__
  4.1090 +
  4.1091 +
  4.1092 +
  4.1093 +#define  SCSI_TEST_UNIT_READY    0x00
  4.1094 +#define  SCSI_REZERO_UNIT        0x01
  4.1095 +#define  SCSI_REQUEST_SENSE      0x03
  4.1096 +#define  SCSI_FORMAT_UNIT        0x04
  4.1097 +#define  SCSI_REASSIGN           0x07
  4.1098 +#define  SCSI_READ               0x08
  4.1099 +#define  SCSI_WRITE              0x0A
  4.1100 +#define  SCSI_SEEK               0x0B
  4.1101 +#define  SCSI_INQUIRY            0x12
  4.1102 +#define  SCSI_MODE_SELECT        0x15
  4.1103 +#define  SCSI_RESERVE_UNIT       0x16
  4.1104 +#define  SCSI_RELEASE_UNIT       0x17
  4.1105 +#define  SCSI_MODE_SENSE         0x1A
  4.1106 +#define  SCSI_START_STOP_UNIT    0x1B
  4.1107 +#define  SCSI_SEND_DIAGNOSTIC    0x1D
  4.1108 +#define  SCSI_READ_CAPACITY      0x25
  4.1109 +#define  SCSI_READ_EXTENDED      0x28
  4.1110 +#define  SCSI_WRITE_EXTENDED     0x2A
  4.1111 +#define  SCSI_SEEK_EXTENDED      0x2B
  4.1112 +#define  SCSI_WRITE_AND_VERIFY   0x2E
  4.1113 +#define  SCSI_VERIFY             0x2F
  4.1114 +#define  SCSI_READ_DEFECT_DATA   0x37
  4.1115 +#define  SCSI_WRITE_BUFFER       0x3B
  4.1116 +#define  SCSI_READ_BUFFER        0x3C
  4.1117 +#define  SCSI_RECV_DIAGNOSTIC    0x1C
  4.1118 +#define  SCSI_READ_LONG          0x3E
  4.1119 +#define  SCSI_WRITE_LONG         0x3F
  4.1120 +#define  SCSI_LAST_SCSI_CMND     SCSI_WRITE_LONG
  4.1121 +#define  SCSI_INVALID_CMND       0xFF
  4.1122 +
  4.1123 +
  4.1124 +
  4.1125 +#define  SSGOOD                  0x00
  4.1126 +#define  SSCHECK                 0x02
  4.1127 +#define  SSCOND_MET              0x04
  4.1128 +#define  SSBUSY                  0x08
  4.1129 +#define  SSRESERVATION_CONFLICT  0x18
  4.1130 +#define  SSCMD_TERM              0x22
  4.1131 +#define  SSQ_FULL                0x28
  4.1132 +
  4.1133 +
  4.1134 +#define  SKNO_SEN                0x00
  4.1135 +#define  SKRECOV_ERR             0x01
  4.1136 +#define  SKNOT_RDY               0x02
  4.1137 +#define  SKMED_ERR               0x03
  4.1138 +#define  SKHW_ERR                0x04
  4.1139 +#define  SKILL_REQ               0x05
  4.1140 +#define  SKUNIT_ATTN             0x06
  4.1141 +#define  SKDATA_PROTECT          0x07
  4.1142 +#define  SKBLNK_CHK              0x08
  4.1143 +#define  SKCPY_ABORT             0x0A
  4.1144 +#define  SKABORT_CMD             0x0B
  4.1145 +#define  SKEQUAL                 0x0C
  4.1146 +#define  SKVOL_OVF               0x0D
  4.1147 +#define  SKMIS_CMP               0x0E
  4.1148 +
  4.1149 +
  4.1150 +#define  SMCMD_COMP              0x00
  4.1151 +#define  SMEXT                   0x01
  4.1152 +#define  SMSAVE_DATA_PTR         0x02
  4.1153 +#define  SMREST_DATA_PTR         0x03
  4.1154 +#define  SMDISC                  0x04
  4.1155 +#define  SMINIT_DETEC_ERR        0x05
  4.1156 +#define  SMABORT                 0x06
  4.1157 +#define  SMREJECT                0x07
  4.1158 +#define  SMNO_OP                 0x08
  4.1159 +#define  SMPARITY                0x09
  4.1160 +#define  SMDEV_RESET             0x0C
  4.1161 +#define	SMABORT_TAG					0x0D
  4.1162 +#define	SMINIT_RECOVERY			0x0F
  4.1163 +#define	SMREL_RECOVERY				0x10
  4.1164 +
  4.1165 +#define  SMIDENT                 0x80
  4.1166 +#define  DISC_PRIV               0x40
  4.1167 +
  4.1168 +
  4.1169 +#define  SMSYNC                  0x01
  4.1170 +#define  SM10MBS                 0x19     /* 100ns           */
  4.1171 +#define  SM5MBS                  0x32     /* 200ns           */
  4.1172 +#define  SMOFFSET                0x0F     /* Maxoffset value */
  4.1173 +#define  SMWDTR                  0x03
  4.1174 +#define  SM8BIT                  0x00
  4.1175 +#define  SM16BIT                 0x01
  4.1176 +#define  SM32BIT                 0x02
  4.1177 +#define  SMIGNORWR               0x23     /* Ignore Wide Residue */
  4.1178 +
  4.1179 +
  4.1180 +#define  ARBITRATION_DELAY       0x01     /* 2.4us using a 40Mhz clock */
  4.1181 +#define  BUS_SETTLE_DELAY        0x01     /* 400ns */
  4.1182 +#define  BUS_CLEAR_DELAY         0x01     /* 800ns */
  4.1183 +
  4.1184 +
  4.1185 +
  4.1186 +#define  SPHASE_TO               0x0A  /* 10 second timeout waiting for */
  4.1187 +#define  SCMD_TO                 0x0F  /* Overall command timeout */
  4.1188 +
  4.1189 +
  4.1190 +
  4.1191 +#define  SIX_BYTE_CMD            0x06
  4.1192 +#define  TEN_BYTE_CMD            0x0A
  4.1193 +#define  TWELVE_BYTE_CMD         0x0C
  4.1194 +
  4.1195 +#define  ASYNC                   0x00
  4.1196 +#define  PERI25NS                0x06  /* 25/4ns to next clock for xbow. */
  4.1197 +#define  SYNC10MBS               0x19
  4.1198 +#define  SYNC5MBS                0x32
  4.1199 +#define  MAX_OFFSET              0x0F  /* Maxbyteoffset for Sync Xfers */
  4.1200 +
  4.1201 +#endif
  4.1202 +/*----------------------------------------------------------------------
  4.1203 + *  
  4.1204 + *
  4.1205 + *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
  4.1206 + *
  4.1207 + *   This file is available under both the GNU General Public License
  4.1208 + *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
  4.1209 + *
  4.1210 + *   $Workfile:   eeprom.h  $
  4.1211 + *
  4.1212 + *   Description:  Definitions for EEPROM related structures
  4.1213 + *
  4.1214 + *   $Date: 1996/11/13 18:28:39 $
  4.1215 + *
  4.1216 + *   $Revision: 1.4 $
  4.1217 + *
  4.1218 + *----------------------------------------------------------------------*/
  4.1219 +
  4.1220 +#ifndef __EEPROM__
  4.1221 +#define __EEPROM__
  4.1222 +
  4.1223 +/*#include <globals.h>*/
  4.1224 +
  4.1225 +#define  EEPROM_WD_CNT     256
  4.1226 +
  4.1227 +#define  EEPROM_CHECK_SUM  0
  4.1228 +#define  FW_SIGNATURE      2
  4.1229 +#define  MODEL_NUMB_0      4
  4.1230 +#define  MODEL_NUMB_1      5
  4.1231 +#define  MODEL_NUMB_2      6
  4.1232 +#define  MODEL_NUMB_3      7
  4.1233 +#define  MODEL_NUMB_4      8
  4.1234 +#define  MODEL_NUMB_5      9
  4.1235 +#define  IO_BASE_ADDR      10
  4.1236 +#define  IRQ_NUMBER        12
  4.1237 +#define  PCI_INT_PIN       13
  4.1238 +#define  BUS_DELAY         14       /*On time in byte 14 off delay in 15 */
  4.1239 +#define  SYSTEM_CONFIG     16
  4.1240 +#define  SCSI_CONFIG       17
  4.1241 +#define  BIOS_CONFIG       18
  4.1242 +#define  SPIN_UP_DELAY     19
  4.1243 +#define  SCAM_CONFIG       20
  4.1244 +#define  ADAPTER_SCSI_ID   24
  4.1245 +
  4.1246 +
  4.1247 +#define  IGNORE_B_SCAN     32
  4.1248 +#define  SEND_START_ENA    34
  4.1249 +#define  DEVICE_ENABLE     36
  4.1250 +
  4.1251 +#define  SYNC_RATE_TBL     38
  4.1252 +#define  SYNC_RATE_TBL01   38
  4.1253 +#define  SYNC_RATE_TBL23   40
  4.1254 +#define  SYNC_RATE_TBL45   42
  4.1255 +#define  SYNC_RATE_TBL67   44
  4.1256 +#define  SYNC_RATE_TBL89   46
  4.1257 +#define  SYNC_RATE_TBLab   48
  4.1258 +#define  SYNC_RATE_TBLcd   50
  4.1259 +#define  SYNC_RATE_TBLef   52
  4.1260 +
  4.1261 +
  4.1262 +
  4.1263 +#define  EE_SCAMBASE      256 
  4.1264 +
  4.1265 +
  4.1266 +
  4.1267 +   #define  DOM_MASTER     (BIT(0) + BIT(1))
  4.1268 +   #define  SCAM_ENABLED   BIT(2)
  4.1269 +   #define  SCAM_LEVEL2    BIT(3)
  4.1270 +
  4.1271 +
  4.1272 +	#define	RENEGO_ENA		BITW(10)
  4.1273 +	#define	CONNIO_ENA		BITW(11)
  4.1274 +   #define  GREEN_PC_ENA   BITW(12)
  4.1275 +
  4.1276 +
  4.1277 +   #define  AUTO_RATE_00   00
  4.1278 +   #define  AUTO_RATE_05   01
  4.1279 +   #define  AUTO_RATE_10   02
  4.1280 +   #define  AUTO_RATE_20   03
  4.1281 +
  4.1282 +   #define  WIDE_NEGO_BIT     BIT(7)
  4.1283 +   #define  DISC_ENABLE_BIT   BIT(6)
  4.1284 +
  4.1285 +
  4.1286 +#endif
  4.1287 +/*----------------------------------------------------------------------
  4.1288 + *
  4.1289 + *
  4.1290 + *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
  4.1291 + *
  4.1292 + *   This file is available under both the GNU General Public License
  4.1293 + *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
  4.1294 + *
  4.1295 + *   $Workfile:   harpoon.h  $
  4.1296 + *
  4.1297 + *   Description:  Register definitions for HARPOON ASIC.
  4.1298 + *
  4.1299 + *   $Date: 1997/07/09 21:44:36 $
  4.1300 + *
  4.1301 + *   $Revision: 1.9 $
  4.1302 + *
  4.1303 + *----------------------------------------------------------------------*/
  4.1304 +
  4.1305 +
  4.1306 +/*#include <globals.h>*/
  4.1307 +
  4.1308 +#ifndef __HARPOON__
  4.1309 +#define __HARPOON__
  4.1310 +
  4.1311 +
  4.1312 +   #define  hp_vendor_id_0       0x00		/* LSB */
  4.1313 +      #define  ORION_VEND_0   0x4B
  4.1314 + 
  4.1315 +   #define  hp_vendor_id_1       0x01		/* MSB */
  4.1316 +      #define  ORION_VEND_1   0x10
  4.1317 +
  4.1318 +   #define  hp_device_id_0       0x02		/* LSB */
  4.1319 +      #define  ORION_DEV_0    0x30 
  4.1320 +
  4.1321 +   #define  hp_device_id_1       0x03		/* MSB */
  4.1322 +      #define  ORION_DEV_1    0x81 
  4.1323 +
  4.1324 +	/* Sub Vendor ID and Sub Device ID only available in
  4.1325 +		Harpoon Version 2 and higher */
  4.1326 +
  4.1327 +   #define  hp_sub_vendor_id_0   0x04		/* LSB */
  4.1328 +   #define  hp_sub_vendor_id_1   0x05		/* MSB */
  4.1329 +   #define  hp_sub_device_id_0   0x06		/* LSB */
  4.1330 +   #define  hp_sub_device_id_1   0x07		/* MSB */
  4.1331 +
  4.1332 +
  4.1333 +   #define  hp_dual_addr_lo      0x08
  4.1334 +   #define  hp_dual_addr_lmi     0x09
  4.1335 +   #define  hp_dual_addr_hmi     0x0A
  4.1336 +   #define  hp_dual_addr_hi      0x0B
  4.1337 +
  4.1338 +   #define  hp_semaphore         0x0C
  4.1339 +      #define SCCB_MGR_ACTIVE    BIT(0)
  4.1340 +      #define TICKLE_ME          BIT(1)
  4.1341 +      #define SCCB_MGR_PRESENT   BIT(3)
  4.1342 +      #define BIOS_IN_USE        BIT(4)
  4.1343 +
  4.1344 +   #define  hp_user_defined_D    0x0D
  4.1345 +
  4.1346 +   #define  hp_reserved_E        0x0E
  4.1347 +
  4.1348 +   #define  hp_sys_ctrl          0x0F
  4.1349 +
  4.1350 +      #define  STOP_CLK          BIT(0)      /*Turn off BusMaster Clock */
  4.1351 +      #define  DRVR_RST          BIT(1)      /*Firmware Reset to 80C15 chip */
  4.1352 +      #define  HALT_MACH         BIT(3)      /*Halt State Machine      */
  4.1353 +      #define  HARD_ABORT        BIT(4)      /*Hard Abort              */
  4.1354 +      #define  DIAG_MODE         BIT(5)      /*Diagnostic Mode         */
  4.1355 +
  4.1356 +      #define  BM_ABORT_TMOUT    0x50        /*Halt State machine time out */
  4.1357 +
  4.1358 +   #define  hp_sys_cfg           0x10
  4.1359 +
  4.1360 +      #define  DONT_RST_FIFO     BIT(7)      /*Don't reset FIFO      */
  4.1361 +
  4.1362 +
  4.1363 +   #define  hp_host_ctrl0        0x11
  4.1364 +
  4.1365 +      #define  DUAL_ADDR_MODE    BIT(0)   /*Enable 64-bit addresses */
  4.1366 +      #define  IO_MEM_SPACE      BIT(1)   /*I/O Memory Space    */
  4.1367 +      #define  RESOURCE_LOCK     BIT(2)   /*Enable Resource Lock */
  4.1368 +      #define  IGNOR_ACCESS_ERR  BIT(3)   /*Ignore Access Error */
  4.1369 +      #define  HOST_INT_EDGE     BIT(4)   /*Host interrupt level/edge mode sel */
  4.1370 +      #define  SIX_CLOCKS        BIT(5)   /*6 Clocks between Strobe   */
  4.1371 +      #define  DMA_EVEN_PARITY   BIT(6)   /*Enable DMA Enen Parity */
  4.1372 +
  4.1373 +/*
  4.1374 +      #define  BURST_MODE        BIT(0)
  4.1375 +*/
  4.1376 +
  4.1377 +   #define  hp_reserved_12       0x12
  4.1378 +
  4.1379 +   #define  hp_host_blk_cnt      0x13
  4.1380 +
  4.1381 +      #define  XFER_BLK1         0x00     /*     0 0 0  1 byte per block*/
  4.1382 +      #define  XFER_BLK2         0x01     /*     0 0 1  2 byte per block*/
  4.1383 +      #define  XFER_BLK4         0x02     /*     0 1 0  4 byte per block*/
  4.1384 +      #define  XFER_BLK8         0x03     /*     0 1 1  8 byte per block*/
  4.1385 +      #define  XFER_BLK16        0x04     /*     1 0 0 16 byte per block*/
  4.1386 +      #define  XFER_BLK32        0x05     /*     1 0 1 32 byte per block*/
  4.1387 +      #define  XFER_BLK64        0x06     /*     1 1 0 64 byte per block*/
  4.1388 +   
  4.1389 +      #define  BM_THRESHOLD      0x40     /* PCI mode can only xfer 16 bytes*/
  4.1390 +
  4.1391 +
  4.1392 +   #define  hp_reserved_14       0x14
  4.1393 +   #define  hp_reserved_15       0x15
  4.1394 +   #define  hp_reserved_16       0x16
  4.1395 +
  4.1396 +   #define  hp_int_mask          0x17
  4.1397 +
  4.1398 +      #define  INT_CMD_COMPL     BIT(0)   /* DMA command complete   */
  4.1399 +      #define  INT_EXT_STATUS    BIT(1)   /* Extended Status Set    */
  4.1400 +      #define  INT_SCSI          BIT(2)   /* Scsi block interrupt   */
  4.1401 +      #define  INT_FIFO_RDY      BIT(4)   /* FIFO data ready        */
  4.1402 +
  4.1403 +
  4.1404 +   #define  hp_xfer_cnt_lo       0x18
  4.1405 +   #define  hp_xfer_cnt_mi       0x19
  4.1406 +   #define  hp_xfer_cnt_hi       0x1A
  4.1407 +   #define  hp_xfer_cmd          0x1B
  4.1408 +
  4.1409 +      #define  XFER_HOST_DMA     0x00     /*     0 0 0 Transfer Host -> DMA */
  4.1410 +      #define  XFER_DMA_HOST     0x01     /*     0 0 1 Transfer DMA  -> Host */
  4.1411 +      #define  XFER_HOST_MPU     0x02     /*     0 1 0 Transfer Host -> MPU  */
  4.1412 +      #define  XFER_MPU_HOST     0x03     /*     0 1 1 Transfer MPU  -> Host */
  4.1413 +      #define  XFER_DMA_MPU      0x04     /*     1 0 0 Transfer DMA  -> MPU  */
  4.1414 +      #define  XFER_MPU_DMA      0x05     /*     1 0 1 Transfer MPU  -> DMA  */
  4.1415 +      #define  SET_SEMAPHORE     0x06     /*     1 1 0 Set Semaphore         */
  4.1416 +      #define  XFER_NOP          0x07     /*     1 1 1 Transfer NOP          */
  4.1417 +      #define  XFER_MB_MPU       0x06     /*     1 1 0 Transfer MB -> MPU */
  4.1418 +      #define  XFER_MB_DMA       0x07     /*     1 1 1 Transfer MB -> DMA */
  4.1419 +
  4.1420 +
  4.1421 +      #define  XFER_HOST_AUTO    0x00     /*     0 0 Auto Transfer Size   */
  4.1422 +      #define  XFER_HOST_8BIT    0x08     /*     0 1 8 BIT Transfer Size  */
  4.1423 +      #define  XFER_HOST_16BIT   0x10     /*     1 0 16 BIT Transfer Size */
  4.1424 +      #define  XFER_HOST_32BIT   0x18     /*     1 1 32 BIT Transfer Size */
  4.1425 +
  4.1426 +      #define  XFER_DMA_8BIT     0x20     /*     0 1 8 BIT  Transfer Size */
  4.1427 +      #define  XFER_DMA_16BIT    0x40     /*     1 0 16 BIT Transfer Size */
  4.1428 +
  4.1429 +      #define  DISABLE_INT       BIT(7)   /*Do not interrupt at end of cmd. */
  4.1430 +
  4.1431 +      #define  HOST_WRT_CMD      ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
  4.1432 +      #define  HOST_RD_CMD       ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
  4.1433 +      #define  WIDE_HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_16BIT))
  4.1434 +      #define  WIDE_HOST_RD_CMD  ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_16BIT))
  4.1435 +
  4.1436 +   #define  hp_host_addr_lo      0x1C
  4.1437 +   #define  hp_host_addr_lmi     0x1D
  4.1438 +   #define  hp_host_addr_hmi     0x1E
  4.1439 +   #define  hp_host_addr_hi      0x1F
  4.1440 +
  4.1441 +   #define  hp_pio_data          0x20
  4.1442 +   #define  hp_reserved_21       0x21
  4.1443 +   #define  hp_ee_ctrl           0x22
  4.1444 +
  4.1445 +      #define  EXT_ARB_ACK       BIT(7)
  4.1446 +      #define  SCSI_TERM_ENA_H   BIT(6)   /* SCSI high byte terminator */
  4.1447 +      #define  SEE_MS            BIT(5)
  4.1448 +      #define  SEE_CS            BIT(3)
  4.1449 +      #define  SEE_CLK           BIT(2)
  4.1450 +      #define  SEE_DO            BIT(1)
  4.1451 +      #define  SEE_DI            BIT(0)
  4.1452 +
  4.1453 +      #define  EE_READ           0x06
  4.1454 +      #define  EE_WRITE          0x05
  4.1455 +      #define  EWEN              0x04
  4.1456 +      #define  EWEN_ADDR         0x03C0
  4.1457 +      #define  EWDS              0x04
  4.1458 +      #define  EWDS_ADDR         0x0000
  4.1459 +
  4.1460 +   #define  hp_brdctl            0x23
  4.1461 +
  4.1462 +      #define  DAT_7             BIT(7)
  4.1463 +      #define  DAT_6             BIT(6)
  4.1464 +      #define  DAT_5             BIT(5)
  4.1465 +      #define  BRD_STB           BIT(4)
  4.1466 +      #define  BRD_CS            BIT(3)
  4.1467 +      #define  BRD_WR            BIT(2)
  4.1468 +
  4.1469 +   #define  hp_reserved_24       0x24
  4.1470 +   #define  hp_reserved_25       0x25
  4.1471 +
  4.1472 +
  4.1473 +
  4.1474 +
  4.1475 +   #define  hp_bm_ctrl           0x26
  4.1476 +
  4.1477 +      #define  SCSI_TERM_ENA_L   BIT(0)   /*Enable/Disable external terminators */
  4.1478 +      #define  FLUSH_XFER_CNTR   BIT(1)   /*Flush transfer counter */
  4.1479 +      #define  BM_XFER_MIN_8     BIT(2)   /*Enable bus master transfer of 9 */
  4.1480 +      #define  BIOS_ENA          BIT(3)   /*Enable BIOS/FLASH Enable */
  4.1481 +      #define  FORCE1_XFER       BIT(5)   /*Always xfer one byte in byte mode */
  4.1482 +      #define  FAST_SINGLE       BIT(6)   /*?? */
  4.1483 +
  4.1484 +      #define  BMCTRL_DEFAULT    (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
  4.1485 +
  4.1486 +   #define  hp_reserved_27       0x27
  4.1487 +
  4.1488 +   #define  hp_sg_addr           0x28
  4.1489 +   #define  hp_page_ctrl         0x29
  4.1490 +
  4.1491 +      #define  SCATTER_EN        BIT(0)   
  4.1492 +      #define  SGRAM_ARAM        BIT(1)   
  4.1493 +      #define  BIOS_SHADOW       BIT(2)   
  4.1494 +      #define  G_INT_DISABLE     BIT(3)   /* Enable/Disable all Interrupts */
  4.1495 +      #define  NARROW_SCSI_CARD  BIT(4)   /* NARROW/WIDE SCSI config pin */
  4.1496 +
  4.1497 +   #define  hp_reserved_2A       0x2A
  4.1498 +   #define  hp_pci_cmd_cfg       0x2B
  4.1499 +
  4.1500 +      #define  IO_SPACE_ENA      BIT(0)   /*enable I/O space */
  4.1501 +      #define  MEM_SPACE_ENA     BIT(1)   /*enable memory space */
  4.1502 +      #define  BUS_MSTR_ENA      BIT(2)   /*enable bus master operation */
  4.1503 +      #define  MEM_WI_ENA        BIT(4)   /*enable Write and Invalidate */
  4.1504 +      #define  PAR_ERR_RESP      BIT(6)   /*enable parity error responce. */
  4.1505 +
  4.1506 +   #define  hp_reserved_2C       0x2C
  4.1507 +
  4.1508 +   #define  hp_pci_stat_cfg      0x2D
  4.1509 +
  4.1510 +      #define  DATA_PARITY_ERR   BIT(0)   
  4.1511 +      #define  REC_TARGET_ABORT  BIT(4)   /*received Target abort */
  4.1512 +      #define  REC_MASTER_ABORT  BIT(5)   /*received Master abort */
  4.1513 +      #define  SIG_SYSTEM_ERR    BIT(6)   
  4.1514 +      #define  DETECTED_PAR_ERR  BIT(7)   
  4.1515 +
  4.1516 +   #define  hp_reserved_2E       0x2E
  4.1517 +
  4.1518 +   #define  hp_sys_status        0x2F
  4.1519 +
  4.1520 +      #define  SLV_DATA_RDY      BIT(0)   /*Slave data ready */
  4.1521 +      #define  XFER_CNT_ZERO     BIT(1)   /*Transfer counter = 0 */
  4.1522 +      #define  BM_FIFO_EMPTY     BIT(2)   /*FIFO empty */
  4.1523 +      #define  BM_FIFO_FULL      BIT(3)   /*FIFO full */
  4.1524 +      #define  HOST_OP_DONE      BIT(4)   /*host operation done */
  4.1525 +      #define  DMA_OP_DONE       BIT(5)   /*DMA operation done */
  4.1526 +      #define  SLV_OP_DONE       BIT(6)   /*Slave operation done */
  4.1527 +      #define  PWR_ON_FLAG       BIT(7)   /*Power on flag */
  4.1528 +
  4.1529 +   #define  hp_reserved_30       0x30
  4.1530 +
  4.1531 +   #define  hp_host_status0      0x31
  4.1532 +
  4.1533 +      #define  HOST_TERM         BIT(5)   /*Host Terminal Count */
  4.1534 +      #define  HOST_TRSHLD       BIT(6)   /*Host Threshold      */
  4.1535 +      #define  CONNECTED_2_HOST  BIT(7)   /*Connected to Host   */
  4.1536 +
  4.1537 +   #define  hp_reserved_32       0x32
  4.1538 +
  4.1539 +   #define  hp_rev_num           0x33
  4.1540 +
  4.1541 +      #define  REV_A_CONST       0x0E
  4.1542 +      #define  REV_B_CONST       0x0E
  4.1543 +
  4.1544 +   #define  hp_stack_data        0x34
  4.1545 +   #define  hp_stack_addr        0x35
  4.1546 +
  4.1547 +   #define  hp_ext_status        0x36
  4.1548 +
  4.1549 +      #define  BM_FORCE_OFF      BIT(0)   /*Bus Master is forced to get off */
  4.1550 +      #define  PCI_TGT_ABORT     BIT(0)   /*PCI bus master transaction aborted */
  4.1551 +      #define  PCI_DEV_TMOUT     BIT(1)   /*PCI Device Time out */
  4.1552 +      #define  FIFO_TC_NOT_ZERO  BIT(2)   /*FIFO or transfer counter not zero */
  4.1553 +      #define  CHIP_RST_OCCUR    BIT(3)   /*Chip reset occurs */
  4.1554 +      #define  CMD_ABORTED       BIT(4)   /*Command aborted */
  4.1555 +      #define  BM_PARITY_ERR     BIT(5)   /*parity error on data received   */
  4.1556 +      #define  PIO_OVERRUN       BIT(6)   /*Slave data overrun */
  4.1557 +      #define  BM_CMD_BUSY       BIT(7)   /*Bus master transfer command busy */
  4.1558 +      #define  BAD_EXT_STATUS    (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
  4.1559 +                                  BM_PARITY_ERR | PIO_OVERRUN)
  4.1560 +
  4.1561 +   #define  hp_int_status        0x37
  4.1562 +      
  4.1563 +      #define  BM_CMD_CMPL       BIT(0)   /*Bus Master command complete */
  4.1564 +      #define  EXT_STATUS_ON     BIT(1)   /*Extended status is valid */
  4.1565 +      #define  SCSI_INTERRUPT    BIT(2)   /*Global indication of a SCSI int. */
  4.1566 +      #define  BM_FIFO_RDY       BIT(4)   
  4.1567 +      #define  INT_ASSERTED      BIT(5)   /* */
  4.1568 +      #define  SRAM_BUSY         BIT(6)   /*Scatter/Gather RAM busy */
  4.1569 +      #define  CMD_REG_BUSY      BIT(7)                                       
  4.1570 +
  4.1571 +
  4.1572 +   #define  hp_fifo_cnt          0x38
  4.1573 +   #define  hp_curr_host_cnt     0x39
  4.1574 +   #define  hp_reserved_3A       0x3A
  4.1575 +   #define  hp_fifo_in_addr      0x3B
  4.1576 +
  4.1577 +   #define  hp_fifo_out_addr     0x3C
  4.1578 +   #define  hp_reserved_3D       0x3D
  4.1579 +   #define  hp_reserved_3E       0x3E
  4.1580 +   #define  hp_reserved_3F       0x3F
  4.1581 +
  4.1582 +
  4.1583 +
  4.1584 +   extern USHORT default_intena;
  4.1585 +
  4.1586 +   #define  hp_intena		 0x40
  4.1587 +
  4.1588 +      #define  RESET		 BITW(7)
  4.1589 +      #define  PROG_HLT		 BITW(6)  
  4.1590 +      #define  PARITY		 BITW(5)
  4.1591 +      #define  FIFO		 BITW(4)
  4.1592 +      #define  SEL		 BITW(3)
  4.1593 +      #define  SCAM_SEL		 BITW(2) 
  4.1594 +      #define  RSEL		 BITW(1)
  4.1595 +      #define  TIMEOUT		 BITW(0)
  4.1596 +      #define  BUS_FREE		 BITW(15)
  4.1597 +      #define  XFER_CNT_0	 BITW(14)
  4.1598 +      #define  PHASE		 BITW(13)
  4.1599 +      #define  IUNKWN		 BITW(12)
  4.1600 +      #define  ICMD_COMP	 BITW(11)
  4.1601 +      #define  ITICKLE		 BITW(10)
  4.1602 +      #define  IDO_STRT		 BITW(9)
  4.1603 +      #define  ITAR_DISC	 BITW(8)
  4.1604 +      #define  AUTO_INT		 (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
  4.1605 +      #define  CLR_ALL_INT	 0xFFFF
  4.1606 +      #define  CLR_ALL_INT_1	 0xFF00
  4.1607 +
  4.1608 +   #define  hp_intstat		 0x42
  4.1609 +
  4.1610 +   #define  hp_scsisig           0x44
  4.1611 +
  4.1612 +      #define  SCSI_SEL          BIT(7)
  4.1613 +      #define  SCSI_BSY          BIT(6)
  4.1614 +      #define  SCSI_REQ          BIT(5)
  4.1615 +      #define  SCSI_ACK          BIT(4)
  4.1616 +      #define  SCSI_ATN          BIT(3)
  4.1617 +      #define  SCSI_CD           BIT(2)
  4.1618 +      #define  SCSI_MSG          BIT(1)
  4.1619 +      #define  SCSI_IOBIT        BIT(0)
  4.1620 +
  4.1621 +      #define  S_SCSI_PHZ        (BIT(2)+BIT(1)+BIT(0))
  4.1622 +      #define  S_CMD_PH          (BIT(2)              )
  4.1623 +      #define  S_MSGO_PH         (BIT(2)+BIT(1)       )
  4.1624 +      #define  S_STAT_PH         (BIT(2)       +BIT(0))
  4.1625 +      #define  S_MSGI_PH         (BIT(2)+BIT(1)+BIT(0))
  4.1626 +      #define  S_DATAI_PH        (              BIT(0))
  4.1627 +      #define  S_DATAO_PH        0x00
  4.1628 +      #define  S_ILL_PH          (       BIT(1)       )
  4.1629 +
  4.1630 +   #define  hp_scsictrl_0        0x45
  4.1631 +
  4.1632 +      #define  NO_ARB            BIT(7)
  4.1633 +      #define  SEL_TAR           BIT(6)
  4.1634 +      #define  ENA_ATN           BIT(4)
  4.1635 +      #define  ENA_RESEL         BIT(2)
  4.1636 +      #define  SCSI_RST          BIT(1)
  4.1637 +      #define  ENA_SCAM_SEL      BIT(0)
  4.1638 +
  4.1639 +
  4.1640 +
  4.1641 +   #define  hp_portctrl_0        0x46
  4.1642 +
  4.1643 +      #define  SCSI_PORT         BIT(7)
  4.1644 +      #define  SCSI_INBIT        BIT(6)
  4.1645 +      #define  DMA_PORT          BIT(5)
  4.1646 +      #define  DMA_RD            BIT(4)
  4.1647 +      #define  HOST_PORT         BIT(3)
  4.1648 +      #define  HOST_WRT          BIT(2)
  4.1649 +      #define  SCSI_BUS_EN       BIT(1)
  4.1650 +      #define  START_TO          BIT(0)
  4.1651 +
  4.1652 +   #define  hp_scsireset         0x47
  4.1653 +
  4.1654 +      #define  SCSI_TAR          BIT(7)
  4.1655 +      #define  SCSI_INI          BIT(6)
  4.1656 +      #define  SCAM_EN           BIT(5)
  4.1657 +      #define  ACK_HOLD          BIT(4)
  4.1658 +      #define  DMA_RESET         BIT(3)
  4.1659 +      #define  HPSCSI_RESET      BIT(2)
  4.1660 +      #define  PROG_RESET        BIT(1)
  4.1661 +      #define  FIFO_CLR          BIT(0)
  4.1662 +
  4.1663 +   #define  hp_xfercnt_0         0x48
  4.1664 +   #define  hp_xfercnt_1         0x49
  4.1665 +   #define  hp_xfercnt_2         0x4A
  4.1666 +   #define  hp_xfercnt_3         0x4B
  4.1667 +
  4.1668 +   #define  hp_fifodata_0        0x4C
  4.1669 +   #define  hp_fifodata_1        0x4D
  4.1670 +   #define  hp_addstat           0x4E
  4.1671 +
  4.1672 +      #define  SCAM_TIMER        BIT(7)
  4.1673 +      #define  AUTO_RUNNING      BIT(6)
  4.1674 +      #define  FAST_SYNC         BIT(5)
  4.1675 +      #define  SCSI_MODE8        BIT(3)
  4.1676 +      #define  SCSI_PAR_ERR      BIT(0)
  4.1677 +
  4.1678 +   #define  hp_prgmcnt_0         0x4F
  4.1679 +
  4.1680 +      #define  AUTO_PC_MASK      0x3F
  4.1681 +
  4.1682 +   #define  hp_selfid_0          0x50
  4.1683 +   #define  hp_selfid_1          0x51
  4.1684 +   #define  hp_arb_id            0x52
  4.1685 +
  4.1686 +      #define  ARB_ID            (BIT(3) + BIT(2) + BIT(1) + BIT(0))
  4.1687 +
  4.1688 +   #define  hp_select_id         0x53
  4.1689 +
  4.1690 +      #define  RESEL_ID          (BIT(7) + BIT(6) + BIT(5) + BIT(4))
  4.1691 +      #define  SELECT_ID         (BIT(3) + BIT(2) + BIT(1) + BIT(0))
  4.1692 +
  4.1693 +   #define  hp_synctarg_base     0x54
  4.1694 +   #define  hp_synctarg_12       0x54
  4.1695 +   #define  hp_synctarg_13       0x55
  4.1696 +   #define  hp_synctarg_14       0x56
  4.1697 +   #define  hp_synctarg_15       0x57
  4.1698 +
  4.1699 +   #define  hp_synctarg_8        0x58
  4.1700 +   #define  hp_synctarg_9        0x59
  4.1701 +   #define  hp_synctarg_10       0x5A
  4.1702 +   #define  hp_synctarg_11       0x5B
  4.1703 +
  4.1704 +   #define  hp_synctarg_4        0x5C
  4.1705 +   #define  hp_synctarg_5        0x5D
  4.1706 +   #define  hp_synctarg_6        0x5E
  4.1707 +   #define  hp_synctarg_7        0x5F
  4.1708 +
  4.1709 +   #define  hp_synctarg_0        0x60
  4.1710 +   #define  hp_synctarg_1        0x61
  4.1711 +   #define  hp_synctarg_2        0x62
  4.1712 +   #define  hp_synctarg_3        0x63
  4.1713 +
  4.1714 +      #define  RATE_20MB         0x00
  4.1715 +      #define  RATE_10MB         (              BIT(5))
  4.1716 +      #define  RATE_6_6MB        (       BIT(6)       )   
  4.1717 +      #define  RATE_5MB          (       BIT(6)+BIT(5))
  4.1718 +      #define  RATE_4MB          (BIT(7)              )
  4.1719 +      #define  RATE_3_33MB       (BIT(7)       +BIT(5))
  4.1720 +      #define  RATE_2_85MB       (BIT(7)+BIT(6)       )
  4.1721 +      #define  RATE_2_5MB        (BIT(7)+BIT(5)+BIT(6))
  4.1722 +      #define  NEXT_CLK          BIT(5)
  4.1723 +      #define  SLOWEST_SYNC      (BIT(7)+BIT(6)+BIT(5))
  4.1724 +      #define  NARROW_SCSI       BIT(4)
  4.1725 +      #define  SYNC_OFFSET       (BIT(3) + BIT(2) + BIT(1) + BIT(0))
  4.1726 +      #define  DEFAULT_ASYNC     0x00
  4.1727 +      #define  DEFAULT_OFFSET    0x0F
  4.1728 +
  4.1729 +   #define  hp_autostart_0       0x64
  4.1730 +   #define  hp_autostart_1       0x65
  4.1731 +   #define  hp_autostart_2       0x66
  4.1732 +   #define  hp_autostart_3       0x67
  4.1733 +
  4.1734 +
  4.1735 +
  4.1736 +      #define  DISABLE  0x00
  4.1737 +      #define  AUTO_IMMED    BIT(5)
  4.1738 +      #define  SELECT   BIT(6)
  4.1739 +      #define  RESELECT (BIT(6)+BIT(5))
  4.1740 +      #define  BUSFREE  BIT(7)
  4.1741 +      #define  XFER_0   (BIT(7)+BIT(5))
  4.1742 +      #define  END_DATA (BIT(7)+BIT(6))
  4.1743 +      #define  MSG_PHZ  (BIT(7)+BIT(6)+BIT(5))
  4.1744 +
  4.1745 +   #define  hp_gp_reg_0          0x68
  4.1746 +   #define  hp_gp_reg_1          0x69
  4.1747 +   #define  hp_gp_reg_2          0x6A
  4.1748 +   #define  hp_gp_reg_3          0x6B
  4.1749 +
  4.1750 +   #define  hp_seltimeout        0x6C
  4.1751 +
  4.1752 +
  4.1753 +      #define  TO_2ms            0x54      /* 2.0503ms */
  4.1754 +      #define  TO_4ms            0x67      /* 3.9959ms */
  4.1755 +
  4.1756 +      #define  TO_5ms            0x03      /* 4.9152ms */
  4.1757 +      #define  TO_10ms           0x07      /* 11.xxxms */
  4.1758 +      #define  TO_250ms          0x99      /* 250.68ms */
  4.1759 +      #define  TO_290ms          0xB1      /* 289.99ms */
  4.1760 +      #define  TO_350ms          0xD6      /* 350.62ms */
  4.1761 +      #define  TO_417ms          0xFF      /* 417.79ms */
  4.1762 +
  4.1763 +   #define  hp_clkctrl_0         0x6D
  4.1764 +
  4.1765 +      #define  PWR_DWN           BIT(6)
  4.1766 +      #define  ACTdeassert       BIT(4)
  4.1767 +      #define  ATNonErr          BIT(3)
  4.1768 +      #define  CLK_30MHZ         BIT(1)
  4.1769 +      #define  CLK_40MHZ         (BIT(1) + BIT(0))
  4.1770 +      #define  CLK_50MHZ         BIT(2)
  4.1771 +
  4.1772 +      #define  CLKCTRL_DEFAULT   (ACTdeassert | CLK_40MHZ)
  4.1773 +
  4.1774 +   #define  hp_fiforead          0x6E
  4.1775 +   #define  hp_fifowrite         0x6F
  4.1776 +
  4.1777 +   #define  hp_offsetctr         0x70
  4.1778 +   #define  hp_xferstat          0x71
  4.1779 +
  4.1780 +      #define  FIFO_FULL         BIT(7)
  4.1781 +      #define  FIFO_EMPTY        BIT(6)
  4.1782 +      #define  FIFO_MASK         0x3F   /* Mask for the FIFO count value. */
  4.1783 +      #define  FIFO_LEN          0x20
  4.1784 +
  4.1785 +   #define  hp_portctrl_1        0x72
  4.1786 +
  4.1787 +      #define  EVEN_HOST_P       BIT(5)
  4.1788 +      #define  INVT_SCSI         BIT(4)
  4.1789 +      #define  CHK_SCSI_P        BIT(3)
  4.1790 +      #define  HOST_MODE8        BIT(0)
  4.1791 +      #define  HOST_MODE16       0x00
  4.1792 +
  4.1793 +   #define  hp_xfer_pad          0x73
  4.1794 +
  4.1795 +      #define  ID_UNLOCK         BIT(3)
  4.1796 +      #define  XFER_PAD          BIT(2)
  4.1797 +
  4.1798 +   #define  hp_scsidata_0        0x74
  4.1799 +   #define  hp_scsidata_1        0x75
  4.1800 +   #define  hp_timer_0           0x76
  4.1801 +   #define  hp_timer_1           0x77
  4.1802 +
  4.1803 +   #define  hp_reserved_78       0x78
  4.1804 +   #define  hp_reserved_79       0x79
  4.1805 +   #define  hp_reserved_7A       0x7A
  4.1806 +   #define  hp_reserved_7B       0x7B
  4.1807 +
  4.1808 +   #define  hp_reserved_7C       0x7C
  4.1809 +   #define  hp_reserved_7D       0x7D
  4.1810 +   #define  hp_reserved_7E       0x7E
  4.1811 +   #define  hp_reserved_7F       0x7F
  4.1812 +
  4.1813 +   #define  hp_aramBase          0x80
  4.1814 +   #define  BIOS_DATA_OFFSET     0x60
  4.1815 +   #define  BIOS_RELATIVE_CARD   0x64
  4.1816 +
  4.1817 +
  4.1818 +
  4.1819 +
  4.1820 +      #define  AUTO_LEN 0x80
  4.1821 +      #define  AR0      0x00
  4.1822 +      #define  AR1      BITW(8)
  4.1823 +      #define  AR2      BITW(9)
  4.1824 +      #define  AR3      (BITW(9) + BITW(8))
  4.1825 +      #define  SDATA    BITW(10)
  4.1826 +
  4.1827 +      #define  NOP_OP   0x00        /* Nop command */
  4.1828 +
  4.1829 +      #define  CRD_OP   BITW(11)     /* Cmp Reg. w/ Data */
  4.1830 +
  4.1831 +      #define  CRR_OP   BITW(12)     /* Cmp Reg. w. Reg. */
  4.1832 +
  4.1833 +      #define  CBE_OP   (BITW(14)+BITW(12)+BITW(11)) /* Cmp SCSI cmd class & Branch EQ */
  4.1834 +      
  4.1835 +      #define  CBN_OP   (BITW(14)+BITW(13))  /* Cmp SCSI cmd class & Branch NOT EQ */
  4.1836 +      
  4.1837 +      #define  CPE_OP   (BITW(14)+BITW(11))  /* Cmp SCSI phs & Branch EQ */
  4.1838 +
  4.1839 +      #define  CPN_OP   (BITW(14)+BITW(12))  /* Cmp SCSI phs & Branch NOT EQ */
  4.1840 +
  4.1841 +
  4.1842 +      #define  ADATA_OUT   0x00     
  4.1843 +      #define  ADATA_IN    BITW(8)
  4.1844 +      #define  ACOMMAND    BITW(10)
  4.1845 +      #define  ASTATUS     (BITW(10)+BITW(8))
  4.1846 +      #define  AMSG_OUT    (BITW(10)+BITW(9))
  4.1847 +      #define  AMSG_IN     (BITW(10)+BITW(9)+BITW(8))
  4.1848 +      #define  AILLEGAL    (BITW(9)+BITW(8))
  4.1849 +
  4.1850 +
  4.1851 +      #define  BRH_OP   BITW(13)   /* Branch */
  4.1852 +
  4.1853 +      
  4.1854 +      #define  ALWAYS   0x00
  4.1855 +      #define  EQUAL    BITW(8)
  4.1856 +      #define  NOT_EQ   BITW(9)
  4.1857 +
  4.1858 +      #define  TCB_OP   (BITW(13)+BITW(11))    /* Test condition & branch */
  4.1859 +
  4.1860 +      
  4.1861 +      #define  ATN_SET     BITW(8)
  4.1862 +      #define  ATN_RESET   BITW(9)
  4.1863 +      #define  XFER_CNT    (BITW(9)+BITW(8))
  4.1864 +      #define  FIFO_0      BITW(10)
  4.1865 +      #define  FIFO_NOT0   (BITW(10)+BITW(8))
  4.1866 +      #define  T_USE_SYNC0 (BITW(10)+BITW(9))
  4.1867 +
  4.1868 +
  4.1869 +      #define  MPM_OP   BITW(15)        /* Match phase and move data */
  4.1870 +
  4.1871 +      #define  MDR_OP   (BITW(12)+BITW(11)) /* Move data to Reg. */
  4.1872 +
  4.1873 +      #define  MRR_OP   BITW(14)        /* Move DReg. to Reg. */
  4.1874 +
  4.1875 +
  4.1876 +      #define  S_IDREG  (BIT(2)+BIT(1)+BIT(0))
  4.1877 +
  4.1878 +
  4.1879 +      #define  D_AR0    0x00
  4.1880 +      #define  D_AR1    BIT(0)
  4.1881 +      #define  D_AR2    BIT(1)
  4.1882 +      #define  D_AR3    (BIT(1) + BIT(0))
  4.1883 +      #define  D_SDATA  BIT(2)
  4.1884 +      #define  D_BUCKET (BIT(2) + BIT(1) + BIT(0))
  4.1885 +
  4.1886 +
  4.1887 +      #define  ADR_OP   (BITW(13)+BITW(12)) /* Logical AND Reg. w. Data */
  4.1888 +
  4.1889 +      #define  ADS_OP   (BITW(14)+BITW(13)+BITW(12)) 
  4.1890 +
  4.1891 +      #define  ODR_OP   (BITW(13)+BITW(12)+BITW(11))  
  4.1892 +
  4.1893 +      #define  ODS_OP   (BITW(14)+BITW(13)+BITW(12)+BITW(11))  
  4.1894 +
  4.1895 +      #define  STR_OP   (BITW(15)+BITW(14)) /* Store to A_Reg. */
  4.1896 +
  4.1897 +      #define  AINT_ENA1   0x00
  4.1898 +      #define  AINT_STAT1  BITW(8)
  4.1899 +      #define  ASCSI_SIG   BITW(9)
  4.1900 +      #define  ASCSI_CNTL  (BITW(9)+BITW(8))
  4.1901 +      #define  APORT_CNTL  BITW(10)
  4.1902 +      #define  ARST_CNTL   (BITW(10)+BITW(8))
  4.1903 +      #define  AXFERCNT0   (BITW(10)+BITW(9))
  4.1904 +      #define  AXFERCNT1   (BITW(10)+BITW(9)+BITW(8))
  4.1905 +      #define  AXFERCNT2   BITW(11)
  4.1906 +      #define  AFIFO_DATA  (BITW(11)+BITW(8))
  4.1907 +      #define  ASCSISELID  (BITW(11)+BITW(9))
  4.1908 +      #define  ASCSISYNC0  (BITW(11)+BITW(9)+BITW(8))
  4.1909 +
  4.1910 +
  4.1911 +      #define  RAT_OP      (BITW(14)+BITW(13)+BITW(11))
  4.1912 +
  4.1913 +      #define  SSI_OP      (BITW(15)+BITW(11))
  4.1914 +
  4.1915 +
  4.1916 +      #define  SSI_ITAR_DISC	(ITAR_DISC >> 8)
  4.1917 +      #define  SSI_IDO_STRT	(IDO_STRT >> 8)
  4.1918 +      #define  SSI_IDI_STRT	(IDO_STRT >> 8)
  4.1919 +
  4.1920 +      #define  SSI_ICMD_COMP	(ICMD_COMP >> 8)
  4.1921 +      #define  SSI_ITICKLE	(ITICKLE >> 8)
  4.1922 +
  4.1923 +      #define  SSI_IUNKWN	(IUNKWN >> 8)
  4.1924 +      #define  SSI_INO_CC	(IUNKWN >> 8)
  4.1925 +      #define  SSI_IRFAIL	(IUNKWN >> 8)
  4.1926 +
  4.1927 +
  4.1928 +      #define  NP    0x10     /*Next Phase */
  4.1929 +      #define  NTCMD 0x02     /*Non- Tagged Command start */
  4.1930 +      #define  CMDPZ 0x04     /*Command phase */
  4.1931 +      #define  DINT  0x12     /*Data Out/In interrupt */
  4.1932 +      #define  DI    0x13     /*Data Out */
  4.1933 +      #define  MI    0x14     /*Message In */
  4.1934 +      #define  DC    0x19     /*Disconnect Message */
  4.1935 +      #define  ST    0x1D     /*Status Phase */
  4.1936 +      #define  UNKNWN 0x24    /*Unknown bus action */
  4.1937 +      #define  CC    0x25     /*Command Completion failure */
  4.1938 +      #define  TICK  0x26     /*New target reselected us. */
  4.1939 +      #define  RFAIL 0x27     /*Reselection failed */
  4.1940 +      #define  SELCHK 0x28     /*Select & Check SCSI ID latch reg */
  4.1941 +
  4.1942 +
  4.1943 +      #define  ID_MSG_STRT    hp_aramBase + 0x00
  4.1944 +      #define  NON_TAG_ID_MSG hp_aramBase + 0x06
  4.1945 +      #define  CMD_STRT       hp_aramBase + 0x08
  4.1946 +      #define  SYNC_MSGS      hp_aramBase + 0x08
  4.1947 +
  4.1948 +
  4.1949 +
  4.1950 +
  4.1951 +
  4.1952 +      #define  TAG_STRT          0x00
  4.1953 +      #define  SELECTION_START   0x00
  4.1954 +      #define  DISCONNECT_START  0x10/2
  4.1955 +      #define  END_DATA_START    0x14/2
  4.1956 +      #define  NONTAG_STRT       0x02/2
  4.1957 +      #define  CMD_ONLY_STRT     CMDPZ/2
  4.1958 +      #define  TICKLE_STRT     TICK/2
  4.1959 +      #define  SELCHK_STRT     SELCHK/2
  4.1960 +
  4.1961 +
  4.1962 +
  4.1963 +
  4.1964 +#define mEEPROM_CLK_DELAY(port) (RD_HARPOON(port+hp_intstat_1))
  4.1965 +
  4.1966 +#define mWAIT_10MS(port) (RD_HARPOON(port+hp_intstat_1))
  4.1967 +
  4.1968 +
  4.1969 +#define CLR_XFER_CNT(port) (WR_HARPOON(port+hp_xfercnt_0, 0x00))
  4.1970 +
  4.1971 +#define SET_XFER_CNT(port, data) (WR_HARP32(port,hp_xfercnt_0,data))
  4.1972 +
  4.1973 +#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
  4.1974 +/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
  4.1975 +                                 xfercnt <<= 16,\
  4.1976 +                                 xfercnt |= RDW_HARPOON((USHORT)(port+hp_xfercnt_0)))
  4.1977 + */
  4.1978 +#if defined(DOS)
  4.1979 +#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((USHORT)(port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\
  4.1980 +         addr >>= 16,\
  4.1981 +         WRW_HARPOON((USHORT)(port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\
  4.1982 +         WR_HARP32(port,hp_xfercnt_0,count),\
  4.1983 +         WRW_HARPOON((USHORT)(port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\
  4.1984 +         count >>= 16,\
  4.1985 +         WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
  4.1986 +#else
  4.1987 +#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\
  4.1988 +         addr >>= 16,\
  4.1989 +         WRW_HARPOON((port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\
  4.1990 +         WR_HARP32(port,hp_xfercnt_0,count),\
  4.1991 +         WRW_HARPOON((port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\
  4.1992 +         count >>= 16,\
  4.1993 +         WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
  4.1994 +#endif
  4.1995 +
  4.1996 +#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
  4.1997 +                          WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
  4.1998 +
  4.1999 +
  4.2000 +#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
  4.2001 +                          WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
  4.2002 +
  4.2003 +#define ACCEPT_STAT(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
  4.2004 +                          WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
  4.2005 +
  4.2006 +#define ACCEPT_STAT_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
  4.2007 +                          WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
  4.2008 +
  4.2009 +#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
  4.2010 +                        WR_HARPOON(port+hp_scsireset, 0x00))
  4.2011 +
  4.2012 +#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
  4.2013 +                             (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
  4.2014 +
  4.2015 +#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
  4.2016 +                             (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
  4.2017 +
  4.2018 +#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
  4.2019 +                             (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
  4.2020 +
  4.2021 +#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
  4.2022 +                             (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
  4.2023 +
  4.2024 +
  4.2025 +
  4.2026 +#endif
  4.2027 +
  4.2028 +
  4.2029 +#if (FW_TYPE==_UCB_MGR_)
  4.2030 +void ReadNVRam(PSCCBcard pCurrCard,PUCB p_ucb);
  4.2031 +void WriteNVRam(PSCCBcard pCurrCard,PUCB p_ucb);
  4.2032 +void UpdateCheckSum(u32bits baseport);
  4.2033 +#endif // (FW_TYPE==_UCB_MGR_)
  4.2034 +
  4.2035 +#if defined(DOS)
  4.2036 +UCHAR sfm(USHORT port, PSCCB pcurrSCCB);
  4.2037 +void  scsiStartAuto(USHORT port);
  4.2038 +UCHAR sisyncn(USHORT port, UCHAR p_card, UCHAR syncFlag);
  4.2039 +void  ssel(USHORT port, UCHAR p_card);
  4.2040 +void  sres(USHORT port, UCHAR p_card, PSCCBcard pCurrCard);
  4.2041 +void  sdecm(UCHAR message, USHORT port, UCHAR p_card);
  4.2042 +void  shandem(USHORT port, UCHAR p_card,PSCCB pCurrSCCB);
  4.2043 +void  stsyncn(USHORT port, UCHAR p_card);
  4.2044 +void  sisyncr(USHORT port,UCHAR sync_pulse, UCHAR offset);
  4.2045 +void  sssyncv(USHORT p_port, UCHAR p_id, UCHAR p_sync_value, PSCCBMgr_tar_info currTar_Info);
  4.2046 +void  sresb(USHORT port, UCHAR p_card);
  4.2047 +void  sxfrp(USHORT p_port, UCHAR p_card);
  4.2048 +void  schkdd(USHORT port, UCHAR p_card);
  4.2049 +UCHAR RdStack(USHORT port, UCHAR index);
  4.2050 +void  WrStack(USHORT portBase, UCHAR index, UCHAR data);
  4.2051 +UCHAR ChkIfChipInitialized(USHORT ioPort);
  4.2052 +
  4.2053 +#if defined(V302)
  4.2054 +UCHAR GetTarLun(USHORT port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tag, PUCHAR lun);
  4.2055 +#endif
  4.2056 +
  4.2057 +void SendMsg(USHORT port, UCHAR message);
  4.2058 +void  queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg, UCHAR error_code);
  4.2059 +UCHAR scsellDOS(USHORT p_port, UCHAR targ_id);
  4.2060 +#else
  4.2061 +UCHAR sfm(ULONG port, PSCCB pcurrSCCB);
  4.2062 +void  scsiStartAuto(ULONG port);
  4.2063 +UCHAR sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag);
  4.2064 +void  ssel(ULONG port, UCHAR p_card);
  4.2065 +void  sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard);
  4.2066 +void  sdecm(UCHAR message, ULONG port, UCHAR p_card);
  4.2067 +void  shandem(ULONG port, UCHAR p_card,PSCCB pCurrSCCB);
  4.2068 +void  stsyncn(ULONG port, UCHAR p_card);
  4.2069 +void  sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset);
  4.2070 +void  sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value, PSCCBMgr_tar_info currTar_Info);
  4.2071 +void  sresb(ULONG port, UCHAR p_card);
  4.2072 +void  sxfrp(ULONG p_port, UCHAR p_card);
  4.2073 +void  schkdd(ULONG port, UCHAR p_card);
  4.2074 +UCHAR RdStack(ULONG port, UCHAR index);
  4.2075 +void  WrStack(ULONG portBase, UCHAR index, UCHAR data);
  4.2076 +UCHAR ChkIfChipInitialized(ULONG ioPort);
  4.2077 +
  4.2078 +#if defined(V302)
  4.2079 +UCHAR GetTarLun(ULONG port, UCHAR p_card, UCHAR our_target, PSCCBcard pCurrCard, PUCHAR tar, PUCHAR lun);
  4.2080 +#endif
  4.2081 +
  4.2082 +void SendMsg(ULONG port, UCHAR message);
  4.2083 +void  queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg, UCHAR error_code);
  4.2084 +#endif
  4.2085 +
  4.2086 +void  ssenss(PSCCBcard pCurrCard);
  4.2087 +void  sinits(PSCCB p_sccb, UCHAR p_card);
  4.2088 +void  RNVRamData(PNVRamInfo pNvRamInfo);
  4.2089 +
  4.2090 +#if defined(WIDE_SCSI)
  4.2091 +   #if defined(DOS)
  4.2092 +   UCHAR siwidn(USHORT port, UCHAR p_card);
  4.2093 +   void  stwidn(USHORT port, UCHAR p_card);
  4.2094 +   void  siwidr(USHORT port, UCHAR width);
  4.2095 +   #else
  4.2096 +   UCHAR siwidn(ULONG port, UCHAR p_card);
  4.2097 +   void  stwidn(ULONG port, UCHAR p_card);
  4.2098 +   void  siwidr(ULONG port, UCHAR width);
  4.2099 +   #endif
  4.2100 +#endif
  4.2101 +
  4.2102 +
  4.2103 +void  queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card);
  4.2104 +void  queueDisconnect(PSCCB p_SCCB, UCHAR p_card);
  4.2105 +void  queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB, UCHAR p_card);
  4.2106 +void  queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card);
  4.2107 +void  queueFlushSccb(UCHAR p_card, UCHAR error_code);
  4.2108 +void  queueAddSccb(PSCCB p_SCCB, UCHAR card);
  4.2109 +UCHAR queueFindSccb(PSCCB p_SCCB, UCHAR p_card);
  4.2110 +void  utilUpdateResidual(PSCCB p_SCCB);
  4.2111 +USHORT CalcCrc16(UCHAR buffer[]);
  4.2112 +UCHAR  CalcLrc(UCHAR buffer[]);
  4.2113 +
  4.2114 +
  4.2115 +#if defined(DOS)
  4.2116 +void  Wait1Second(USHORT p_port);
  4.2117 +void  Wait(USHORT p_port, UCHAR p_delay);
  4.2118 +void  utilEEWriteOnOff(USHORT p_port,UCHAR p_mode);
  4.2119 +void  utilEEWrite(USHORT p_port, USHORT ee_data, USHORT ee_addr);
  4.2120 +USHORT utilEERead(USHORT p_port, USHORT ee_addr);
  4.2121 +USHORT utilEEReadOrg(USHORT p_port, USHORT ee_addr);
  4.2122 +void  utilEESendCmdAddr(USHORT p_port, UCHAR ee_cmd, USHORT ee_addr);
  4.2123 +#else
  4.2124 +void  Wait1Second(ULONG p_port);
  4.2125 +void  Wait(ULONG p_port, UCHAR p_delay);
  4.2126 +void  utilEEWriteOnOff(ULONG p_port,UCHAR p_mode);
  4.2127 +void  utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr);
  4.2128 +USHORT utilEERead(ULONG p_port, USHORT ee_addr);
  4.2129 +USHORT utilEEReadOrg(ULONG p_port, USHORT ee_addr);
  4.2130 +void  utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr);
  4.2131 +#endif
  4.2132 +
  4.2133 +
  4.2134 +
  4.2135 +#if defined(OS2)
  4.2136 +   void  far phaseDataOut(ULONG port, UCHAR p_card);
  4.2137 +   void  far phaseDataIn(ULONG port, UCHAR p_card);
  4.2138 +   void  far phaseCommand(ULONG port, UCHAR p_card);
  4.2139 +   void  far phaseStatus(ULONG port, UCHAR p_card);
  4.2140 +   void  far phaseMsgOut(ULONG port, UCHAR p_card);
  4.2141 +   void  far phaseMsgIn(ULONG port, UCHAR p_card);
  4.2142 +   void  far phaseIllegal(ULONG port, UCHAR p_card);
  4.2143 +#else
  4.2144 +   #if defined(DOS)
  4.2145 +      void  phaseDataOut(USHORT port, UCHAR p_card);
  4.2146 +      void  phaseDataIn(USHORT port, UCHAR p_card);
  4.2147 +      void  phaseCommand(USHORT port, UCHAR p_card);
  4.2148 +      void  phaseStatus(USHORT port, UCHAR p_card);
  4.2149 +      void  phaseMsgOut(USHORT port, UCHAR p_card);
  4.2150 +      void  phaseMsgIn(USHORT port, UCHAR p_card);
  4.2151 +      void  phaseIllegal(USHORT port, UCHAR p_card);
  4.2152 +   #else
  4.2153 +      void  phaseDataOut(ULONG port, UCHAR p_card);
  4.2154 +      void  phaseDataIn(ULONG port, UCHAR p_card);
  4.2155 +      void  phaseCommand(ULONG port, UCHAR p_card);
  4.2156 +      void  phaseStatus(ULONG port, UCHAR p_card);
  4.2157 +      void  phaseMsgOut(ULONG port, UCHAR p_card);
  4.2158 +      void  phaseMsgIn(ULONG port, UCHAR p_card);
  4.2159 +      void  phaseIllegal(ULONG port, UCHAR p_card);
  4.2160 +   #endif
  4.2161 +#endif
  4.2162 +
  4.2163 +#if defined(DOS)
  4.2164 +void  phaseDecode(USHORT port, UCHAR p_card);
  4.2165 +void  phaseChkFifo(USHORT port, UCHAR p_card);
  4.2166 +void  phaseBusFree(USHORT p_port, UCHAR p_card);
  4.2167 +#else
  4.2168 +void  phaseDecode(ULONG port, UCHAR p_card);
  4.2169 +void  phaseChkFifo(ULONG port, UCHAR p_card);
  4.2170 +void  phaseBusFree(ULONG p_port, UCHAR p_card);
  4.2171 +#endif
  4.2172 +
  4.2173 +
  4.2174 +
  4.2175 +
  4.2176 +#if defined(DOS)
  4.2177 +void  XbowInit(USHORT port, UCHAR scamFlg);
  4.2178 +void  BusMasterInit(USHORT p_port);
  4.2179 +int   DiagXbow(USHORT port);
  4.2180 +int   DiagBusMaster(USHORT port);
  4.2181 +void  DiagEEPROM(USHORT p_port);
  4.2182 +#else
  4.2183 +void  XbowInit(ULONG port, UCHAR scamFlg);
  4.2184 +void  BusMasterInit(ULONG p_port);
  4.2185 +int   DiagXbow(ULONG port);
  4.2186 +int   DiagBusMaster(ULONG port);
  4.2187 +void  DiagEEPROM(ULONG p_port);
  4.2188 +#endif
  4.2189 +
  4.2190 +
  4.2191 +
  4.2192 +
  4.2193 +#if defined(DOS)
  4.2194 +void  busMstrAbort(USHORT port);
  4.2195 +UCHAR busMstrTimeOut(USHORT port);
  4.2196 +void  dataXferProcessor(USHORT port, PSCCBcard pCurrCard);
  4.2197 +void  busMstrSGDataXferStart(USHORT port, PSCCB pCurrSCCB);
  4.2198 +void  busMstrDataXferStart(USHORT port, PSCCB pCurrSCCB);
  4.2199 +void  hostDataXferAbort(USHORT port, UCHAR p_card, PSCCB pCurrSCCB);
  4.2200 +#else
  4.2201 +void  busMstrAbort(ULONG port);
  4.2202 +UCHAR busMstrTimeOut(ULONG port);
  4.2203 +void  dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
  4.2204 +void  busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
  4.2205 +void  busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
  4.2206 +void  hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB);
  4.2207 +#endif
  4.2208 +void  hostDataXferRestart(PSCCB currSCCB);
  4.2209 +
  4.2210 +
  4.2211 +#if defined (DOS)
  4.2212 +UCHAR SccbMgr_bad_isr(USHORT p_port, UCHAR p_card, PSCCBcard pCurrCard, USHORT p_int);
  4.2213 +#else
  4.2214 +UCHAR SccbMgr_bad_isr(ULONG p_port, UCHAR p_card, PSCCBcard pCurrCard, USHORT p_int);
  4.2215 +
  4.2216 +#endif
  4.2217 +
  4.2218 +void  SccbMgrTableInitAll(void);
  4.2219 +void  SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card);
  4.2220 +void  SccbMgrTableInitTarget(UCHAR p_card, UCHAR target);
  4.2221 +
  4.2222 +
  4.2223 +
  4.2224 +void  scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up);
  4.2225 +
  4.2226 +#if defined(DOS)
  4.2227 +int   scarb(USHORT p_port, UCHAR p_sel_type);
  4.2228 +void  scbusf(USHORT p_port);
  4.2229 +void  scsel(USHORT p_port);
  4.2230 +void  scasid(UCHAR p_card, USHORT p_port);
  4.2231 +UCHAR scxferc(USHORT p_port, UCHAR p_data);
  4.2232 +UCHAR scsendi(USHORT p_port, UCHAR p_id_string[]);
  4.2233 +UCHAR sciso(USHORT p_port, UCHAR p_id_string[]);
  4.2234 +void  scwirod(USHORT p_port, UCHAR p_data_bit);
  4.2235 +void  scwiros(USHORT p_port, UCHAR p_data_bit);
  4.2236 +UCHAR scvalq(UCHAR p_quintet);
  4.2237 +UCHAR scsell(USHORT p_port, UCHAR targ_id);
  4.2238 +void  scwtsel(USHORT p_port);
  4.2239 +void  inisci(UCHAR p_card, USHORT p_port, UCHAR p_our_id);
  4.2240 +void  scsavdi(UCHAR p_card, USHORT p_port);
  4.2241 +#else
  4.2242 +int   scarb(ULONG p_port, UCHAR p_sel_type);
  4.2243 +void  scbusf(ULONG p_port);
  4.2244 +void  scsel(ULONG p_port);
  4.2245 +void  scasid(UCHAR p_card, ULONG p_port);
  4.2246 +UCHAR scxferc(ULONG p_port, UCHAR p_data);
  4.2247 +UCHAR scsendi(ULONG p_port, UCHAR p_id_string[]);
  4.2248 +UCHAR sciso(ULONG p_port, UCHAR p_id_string[]);
  4.2249 +void  scwirod(ULONG p_port, UCHAR p_data_bit);
  4.2250 +void  scwiros(ULONG p_port, UCHAR p_data_bit);
  4.2251 +UCHAR scvalq(UCHAR p_quintet);
  4.2252 +UCHAR scsell(ULONG p_port, UCHAR targ_id);
  4.2253 +void  scwtsel(ULONG p_port);
  4.2254 +void  inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id);
  4.2255 +void  scsavdi(UCHAR p_card, ULONG p_port);
  4.2256 +#endif
  4.2257 +UCHAR scmachid(UCHAR p_card, UCHAR p_id_string[]);
  4.2258 +
  4.2259 +
  4.2260 +#if defined(DOS)
  4.2261 +void  autoCmdCmplt(USHORT p_port, UCHAR p_card);
  4.2262 +void  autoLoadDefaultMap(USHORT p_port);
  4.2263 +#else
  4.2264 +void  autoCmdCmplt(ULONG p_port, UCHAR p_card);
  4.2265 +void  autoLoadDefaultMap(ULONG p_port);
  4.2266 +#endif
  4.2267 +
  4.2268 +
  4.2269 +
  4.2270 +#if (FW_TYPE==_SCCB_MGR_)
  4.2271 +	void  OS_start_timer(unsigned long ioport, unsigned long timeout);
  4.2272 +	void  OS_stop_timer(unsigned long ioport, unsigned long timeout);
  4.2273 +	void  OS_disable_int(unsigned char intvec);
  4.2274 +	void  OS_enable_int(unsigned char intvec);
  4.2275 +	void  OS_delay(unsigned long count);
  4.2276 +	int   OS_VirtToPhys(u32bits CardHandle, u32bits *physaddr, u32bits *virtaddr);
  4.2277 +	#if !(defined(UNIX) || defined(OS2) || defined(SOLARIS_REAL_MODE)) 
  4.2278 +	void  OS_Lock(PSCCBMGR_INFO pCardInfo);
  4.2279 +	void  OS_UnLock(PSCCBMGR_INFO pCardInfo);
  4.2280 +#endif // if FW_TYPE == ...
  4.2281 +
  4.2282 +#endif
  4.2283 +
  4.2284 +extern SCCBCARD BL_Card[MAX_CARDS];
  4.2285 +extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
  4.2286 +
  4.2287 +
  4.2288 +#if defined(OS2)
  4.2289 +   extern void (far *s_PhaseTbl[8]) (ULONG, UCHAR);
  4.2290 +#else
  4.2291 +   #if defined(DOS)
  4.2292 +      extern void (*s_PhaseTbl[8]) (USHORT, UCHAR);
  4.2293 +   #else
  4.2294 +      extern void (*s_PhaseTbl[8]) (ULONG, UCHAR);
  4.2295 +   #endif
  4.2296 +#endif
  4.2297 +
  4.2298 +extern SCCBSCAM_INFO scamInfo[MAX_SCSI_TAR];
  4.2299 +extern NVRAMINFO nvRamInfo[MAX_MB_CARDS];
  4.2300 +#if defined(DOS) || defined(OS2)
  4.2301 +extern UCHAR temp_id_string[ID_STRING_LENGTH];
  4.2302 +#endif
  4.2303 +extern UCHAR scamHAString[];
  4.2304 +
  4.2305 +
  4.2306 +extern UCHAR mbCards;
  4.2307 +#if defined(BUGBUG)
  4.2308 +extern UCHAR debug_int[MAX_CARDS][debug_size];
  4.2309 +extern UCHAR debug_index[MAX_CARDS];
  4.2310 +void Debug_Load(UCHAR p_card, UCHAR p_bug_data);
  4.2311 +#endif
  4.2312 +
  4.2313 +#if (FW_TYPE==_SCCB_MGR_)
  4.2314 +#if defined(DOS)
  4.2315 +   extern UCHAR first_time;
  4.2316 +#endif
  4.2317 +#endif /* (FW_TYPE==_SCCB_MGR_) */
  4.2318 +
  4.2319 +#if (FW_TYPE==_UCB_MGR_)
  4.2320 +#if defined(DOS)
  4.2321 +   extern u08bits first_time;
  4.2322 +#endif
  4.2323 +#endif /* (FW_TYPE==_UCB_MGR_) */
  4.2324 +
  4.2325 +#if defined(BUGBUG)
  4.2326 +void Debug_Load(UCHAR p_card, UCHAR p_bug_data);
  4.2327 +#endif
  4.2328 +
  4.2329 +extern unsigned int SccbGlobalFlags;
  4.2330 +
  4.2331 +
  4.2332 +#ident "$Id: sccb.c 1.18 1997/06/10 16:47:04 mohan Exp $"
  4.2333 +/*----------------------------------------------------------------------
  4.2334 + *
  4.2335 + *
  4.2336 + *   Copyright 1995-1996 by Mylex Corporation.  All Rights Reserved
  4.2337 + *
  4.2338 + *   This file is available under both the GNU General Public License
  4.2339 + *   and a BSD-style copyright; see LICENSE.FlashPoint for details.
  4.2340 + *
  4.2341 + *   $Workfile:   sccb.c  $
  4.2342 + *
  4.2343 + *   Description:  Functions relating to handling of the SCCB interface
  4.2344 + *                 between the device driver and the HARPOON.
  4.2345 + *
  4.2346 + *   $Date: 1997/06/10 16:47:04 $
  4.2347 + *
  4.2348 + *   $Revision: 1.18 $
  4.2349 + *
  4.2350 + *----------------------------------------------------------------------*/
  4.2351 +
  4.2352 +/*#include <globals.h>*/
  4.2353 +
  4.2354 +#if (FW_TYPE==_UCB_MGR_)
  4.2355 +	/*#include <budi.h>*/
  4.2356 +	/*#include <budioctl.h>*/
  4.2357 +#endif
  4.2358 +
  4.2359 +/*#include <sccbmgr.h>*/
  4.2360 +/*#include <blx30.h>*/
  4.2361 +/*#include <target.h>*/
  4.2362 +/*#include <eeprom.h>*/
  4.2363 +/*#include <scsi2.h>*/
  4.2364 +/*#include <harpoon.h>*/
  4.2365 +
  4.2366 +
  4.2367 +
  4.2368 +#if (FW_TYPE==_SCCB_MGR_)
  4.2369 +#define mOS_Lock(card)    OS_Lock((PSCCBMGR_INFO)(((PSCCBcard)card)->cardInfo))
  4.2370 +#define mOS_UnLock(card)  OS_UnLock((PSCCBMGR_INFO)(((PSCCBcard)card)->cardInfo))
  4.2371 +#else /* FW_TYPE==_UCB_MGR_ */
  4.2372 +#define mOS_Lock(card)    OS_Lock((u32bits)(((PSCCBcard)card)->ioPort))
  4.2373 +#define mOS_UnLock(card)  OS_UnLock((u32bits)(((PSCCBcard)card)->ioPort))
  4.2374 +#endif
  4.2375 +
  4.2376 +
  4.2377 +/*
  4.2378 +extern SCCBMGR_TAR_INFO sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR];
  4.2379 +extern SCCBCARD BL_Card[MAX_CARDS];
  4.2380 +
  4.2381 +extern NVRAMINFO nvRamInfo[MAX_MB_CARDS];
  4.2382 +extern UCHAR mbCards;
  4.2383 +
  4.2384 +#if defined (OS2)
  4.2385 +   extern void (far *s_PhaseTbl[8]) (ULONG, UCHAR);
  4.2386 +#else
  4.2387 +   #if defined(DOS)
  4.2388 +      extern void (*s_PhaseTbl[8]) (USHORT, UCHAR);
  4.2389 +   #else
  4.2390 +      extern void (*s_PhaseTbl[8]) (ULONG, UCHAR);
  4.2391 +   #endif
  4.2392 +#endif
  4.2393 +
  4.2394 +
  4.2395 +#if defined(BUGBUG)
  4.2396 +extern UCHAR debug_int[MAX_CARDS][debug_size];
  4.2397 +extern UCHAR debug_index[MAX_CARDS];
  4.2398 +void Debug_Load(UCHAR p_card, UCHAR p_bug_data);
  4.2399 +#endif
  4.2400 +*/
  4.2401 +
  4.2402 +#if (FW_TYPE==_SCCB_MGR_)
  4.2403 +
  4.2404 +/*---------------------------------------------------------------------
  4.2405 + *
  4.2406 + * Function: SccbMgr_sense_adapter
  4.2407 + *
  4.2408 + * Description: Setup and/or Search for cards and return info to caller.
  4.2409 + *
  4.2410 + *---------------------------------------------------------------------*/
  4.2411 +
  4.2412 +int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo)
  4.2413 +{
  4.2414 +#if defined(DOS)
  4.2415 +#else
  4.2416 +   static UCHAR first_time = 1;
  4.2417 +#endif
  4.2418 +
  4.2419 +   UCHAR i,j,id,ScamFlg;
  4.2420 +   USHORT temp,temp2,temp3,temp4,temp5,temp6;
  4.2421 +#if defined(DOS)
  4.2422 +   USHORT ioport;
  4.2423 +#else
  4.2424 +   ULONG ioport;
  4.2425 +#endif
  4.2426 +	PNVRamInfo pCurrNvRam;
  4.2427 +
  4.2428 +#if defined(DOS)
  4.2429 +   ioport = (USHORT)pCardInfo->si_baseaddr;
  4.2430 +#else
  4.2431 +   ioport = pCardInfo->si_baseaddr;
  4.2432 +#endif
  4.2433 +
  4.2434 +
  4.2435 +   if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
  4.2436 +      return((int)FAILURE);
  4.2437 +
  4.2438 +   if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
  4.2439 +      return((int)FAILURE);
  4.2440 +
  4.2441 +   if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
  4.2442 +      return((int)FAILURE);
  4.2443 +
  4.2444 +   if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
  4.2445 +      return((int)FAILURE);
  4.2446 +
  4.2447 +
  4.2448 +   if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
  4.2449 +
  4.2450 +/* For new Harpoon then check for sub_device ID LSB
  4.2451 +   the bits(0-3) must be all ZERO for compatible with
  4.2452 +   current version of SCCBMgr, else skip this Harpoon
  4.2453 +	device. */
  4.2454 +
  4.2455 +	   if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
  4.2456 +	      return((int)FAILURE);
  4.2457 +	}
  4.2458 +
  4.2459 +   if (first_time)
  4.2460 +      {
  4.2461 +      SccbMgrTableInitAll();
  4.2462 +      first_time = 0;
  4.2463 +		mbCards = 0;
  4.2464 +      }
  4.2465 +
  4.2466 +	if(RdStack(ioport, 0) != 0x00) {
  4.2467 +		if(ChkIfChipInitialized(ioport) == FALSE)
  4.2468 +		{
  4.2469 +			pCurrNvRam = NULL;
  4.2470 +		   WR_HARPOON(ioport+hp_semaphore, 0x00);
  4.2471 +			XbowInit(ioport, 0);             /*Must Init the SCSI before attempting */
  4.2472 +			DiagEEPROM(ioport);
  4.2473 +		}
  4.2474 +		else
  4.2475 +		{
  4.2476 +			if(mbCards < MAX_MB_CARDS) {
  4.2477 +				pCurrNvRam = &nvRamInfo[mbCards];
  4.2478 +				mbCards++;
  4.2479 +				pCurrNvRam->niBaseAddr = ioport;
  4.2480 +				RNVRamData(pCurrNvRam);
  4.2481 +			}else
  4.2482 +				return((int) FAILURE);
  4.2483 +		}
  4.2484 +	}else
  4.2485 +		pCurrNvRam = NULL;
  4.2486 +#if defined (NO_BIOS_OPTION)
  4.2487 +	pCurrNvRam = NULL;
  4.2488 +   XbowInit(ioport, 0);                /*Must Init the SCSI before attempting */
  4.2489 +   DiagEEPROM(ioport);
  4.2490 +#endif  /* No BIOS Option */
  4.2491 +
  4.2492 +   WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
  4.2493 +   WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
  4.2494 +
  4.2495 +	if(pCurrNvRam)
  4.2496 +		pCardInfo->si_id = pCurrNvRam->niAdapId;
  4.2497 +	else
  4.2498 +	   pCardInfo->si_id = (UCHAR)(utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
  4.2499 +   	   (UCHAR)0x0FF);
  4.2500 +
  4.2501 +   pCardInfo->si_lun = 0x00;
  4.2502 +   pCardInfo->si_fw_revision = ORION_FW_REV;
  4.2503 +   temp2 = 0x0000;
  4.2504 +   temp3 = 0x0000;
  4.2505 +   temp4 = 0x0000;
  4.2506 +   temp5 = 0x0000;
  4.2507 +   temp6 = 0x0000;
  4.2508 +
  4.2509 +   for (id = 0; id < (16/2); id++) {
  4.2510 +
  4.2511 +		if(pCurrNvRam){
  4.2512 +			temp = (USHORT) pCurrNvRam->niSyncTbl[id];
  4.2513 +			temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
  4.2514 +					 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
  4.2515 +		}else
  4.2516 +	      temp = utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
  4.2517 +
  4.2518 +      for (i = 0; i < 2; temp >>=8,i++) {
  4.2519 +
  4.2520 +         temp2 >>= 1;
  4.2521 +         temp3 >>= 1;
  4.2522 +         temp4 >>= 1;
  4.2523 +         temp5 >>= 1;
  4.2524 +         temp6 >>= 1;
  4.2525 +	 switch (temp & 0x3)
  4.2526 +	   {
  4.2527 +	   case AUTO_RATE_20:	/* Synchronous, 20 mega-transfers/second */
  4.2528 +	     temp6 |= 0x8000;	/* Fall through */
  4.2529 +	   case AUTO_RATE_10:	/* Synchronous, 10 mega-transfers/second */
  4.2530 +	     temp5 |= 0x8000;	/* Fall through */
  4.2531 +	   case AUTO_RATE_05:	/* Synchronous, 5 mega-transfers/second */
  4.2532 +	     temp2 |= 0x8000;	/* Fall through */
  4.2533 +	   case AUTO_RATE_00:	/* Asynchronous */
  4.2534 +	     break;
  4.2535 +	   }
  4.2536 +
  4.2537 +         if (temp & DISC_ENABLE_BIT)
  4.2538 +	   temp3 |= 0x8000;
  4.2539 +
  4.2540 +         if (temp & WIDE_NEGO_BIT)
  4.2541 +	   temp4 |= 0x8000;
  4.2542 +
  4.2543 +         }
  4.2544 +      }
  4.2545 +
  4.2546 +   pCardInfo->si_per_targ_init_sync = temp2;
  4.2547 +   pCardInfo->si_per_targ_no_disc = temp3;
  4.2548 +   pCardInfo->si_per_targ_wide_nego = temp4;
  4.2549 +   pCardInfo->si_per_targ_fast_nego = temp5;
  4.2550 +   pCardInfo->si_per_targ_ultra_nego = temp6;
  4.2551 +
  4.2552 +	if(pCurrNvRam)
  4.2553 +		i = pCurrNvRam->niSysConf;
  4.2554 +	else
  4.2555 +	   i = (UCHAR)(utilEERead(ioport, (SYSTEM_CONFIG/2)));
  4.2556 +
  4.2557 +	if(pCurrNvRam)
  4.2558 +		ScamFlg = pCurrNvRam->niScamConf;
  4.2559 +	else
  4.2560 +	   ScamFlg = (UCHAR) utilEERead(ioport, SCAM_CONFIG/2);
  4.2561 +
  4.2562 +   pCardInfo->si_flags = 0x0000;
  4.2563 +
  4.2564 +   if (i & 0x01)
  4.2565 +      pCardInfo->si_flags |= SCSI_PARITY_ENA;
  4.2566 +
  4.2567 +   if (!(i & 0x02))
  4.2568 +      pCardInfo->si_flags |= SOFT_RESET;
  4.2569 +
  4.2570 +   if (i & 0x10)
  4.2571 +      pCardInfo->si_flags |= EXTENDED_TRANSLATION;
  4.2572 +
  4.2573 +   if (ScamFlg & SCAM_ENABLED)
  4.2574 +     pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
  4.2575 +
  4.2576 +   if (ScamFlg & SCAM_LEVEL2)
  4.2577 +     pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
  4.2578 +
  4.2579 +   j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
  4.2580 +   if (i & 0x04) {
  4.2581 +      j |= SCSI_TERM_ENA_L;
  4.2582 +      }
  4.2583 +   WR_HARPOON(ioport+hp_bm_ctrl, j );
  4.2584 +
  4.2585 +   j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
  4.2586 +   if (i & 0x08) {
  4.2587 +      j |= SCSI_TERM_ENA_H;
  4.2588 +      }
  4.2589 +   WR_HARPOON(ioport+hp_ee_ctrl, j );
  4.2590 +
  4.2591 +   if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
  4.2592 +
  4.2593 +      pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
  4.2594 +
  4.2595 +   pCardInfo->si_card_family = HARPOON_FAMILY;
  4.2596 +   pCardInfo->si_bustype = BUSTYPE_PCI;
  4.2597 +
  4.2598 +	if(pCurrNvRam){
  4.2599 +   	pCardInfo->si_card_model[0] = '9';
  4.2600 +		switch(pCurrNvRam->niModel & 0x0f){
  4.2601 +			case MODEL_LT:
  4.2602 +		   	pCardInfo->si_card_model[1] = '3';
  4.2603 +		   	pCardInfo->si_card_model[2] = '0';
  4.2604 +				break;
  4.2605 +			case MODEL_LW:
  4.2606 +		   	pCardInfo->si_card_model[1] = '5';
  4.2607 +		   	pCardInfo->si_card_model[2] = '0';
  4.2608 +				break;
  4.2609 +			case MODEL_DL:
  4.2610 +		   	pCardInfo->si_card_model[1] = '3';
  4.2611 +		   	pCardInfo->si_card_model[2] = '2';
  4.2612 +				break;
  4.2613 +			case MODEL_DW:
  4.2614 +		   	pCardInfo->si_card_model[1] = '5';
  4.2615 +		   	pCardInfo->si_card_model[2] = '2';
  4.2616 +				break;
  4.2617 +		}
  4.2618 +	}else{
  4.2619 +	   temp = utilEERead(ioport, (MODEL_NUMB_0/2));
  4.2620 +   	pCardInfo->si_card_model[0] = (UCHAR)(temp >> 8);
  4.2621 +	   temp = utilEERead(ioport, (MODEL_NUMB_2/2));
  4.2622 +
  4.2623 +   	pCardInfo->si_card_model[1] = (UCHAR)(temp & 0x00FF);
  4.2624 +	   pCardInfo->si_card_model[2] = (UCHAR)(temp >> 8);
  4.2625 +	}
  4.2626 +
  4.2627 +   if (pCardInfo->si_card_model[1] == '3')
  4.2628 +     {
  4.2629