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.
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