File: /usr/src/linux/drivers/scsi/BusLogic.c

1     /*
2     
3       Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters
4     
5       Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>
6     
7       This program is free software; you may redistribute and/or modify it under
8       the terms of the GNU General Public License Version 2 as published by the
9       Free Software Foundation.
10     
11       This program is distributed in the hope that it will be useful, but
12       WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
13       or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14       for complete details.
15     
16       The author respectfully requests that any modifications to this software be
17       sent directly to him for evaluation and testing.
18     
19       Special thanks to Wayne Yen, Jin-Lon Hon, and Alex Win of BusLogic, whose
20       advice has been invaluable, to David Gentzel, for writing the original Linux
21       BusLogic driver, and to Paul Gortmaker, for being such a dedicated test site.
22     
23       Finally, special thanks to Mylex/BusLogic for making the FlashPoint SCCB
24       Manager available as freely redistributable source code.
25     
26     */
27     
28     
29     #define BusLogic_DriverVersion		"2.1.15"
30     #define BusLogic_DriverDate		"17 August 1998"
31     
32     
33     #include <linux/version.h>
34     #include <linux/module.h>
35     #include <linux/config.h>
36     #include <linux/init.h>
37     #include <linux/types.h>
38     #include <linux/blk.h>
39     #include <linux/blkdev.h>
40     #include <linux/delay.h>
41     #include <linux/ioport.h>
42     #include <linux/mm.h>
43     #include <linux/sched.h>
44     #include <linux/stat.h>
45     #include <linux/pci.h>
46     #include <linux/spinlock.h>
47     #include <asm/dma.h>
48     #include <asm/io.h>
49     #include <asm/system.h>
50     #include "scsi.h"
51     #include "hosts.h"
52     #include "sd.h"
53     #include "BusLogic.h"
54     #include "FlashPoint.c"
55     
56     
57     /*
58       BusLogic_DriverOptionsCount is a count of the number of BusLogic Driver
59       Options specifications provided via the Linux Kernel Command Line or via
60       the Loadable Kernel Module Installation Facility.
61     */
62     
63     static int
64       BusLogic_DriverOptionsCount;
65     
66     
67     /*
68       BusLogic_DriverOptions is an array of Driver Options structures representing
69       BusLogic Driver Options specifications provided via the Linux Kernel Command
70       Line or via the Loadable Kernel Module Installation Facility.
71     */
72     
73     static BusLogic_DriverOptions_T
74       BusLogic_DriverOptions[BusLogic_MaxHostAdapters];
75     
76     
77     /*
78       BusLogic can be assigned a string by insmod.
79     */
80     
81     #ifdef MODULE
82     static char *BusLogic;
83     MODULE_PARM(BusLogic, "s");
84     #endif
85     
86     
87     /*
88       BusLogic_ProbeOptions is a set of Probe Options to be applied across
89       all BusLogic Host Adapters.
90     */
91     
92     static BusLogic_ProbeOptions_T
93       BusLogic_ProbeOptions;
94     
95     
96     /*
97       BusLogic_GlobalOptions is a set of Global Options to be applied across
98       all BusLogic Host Adapters.
99     */
100     
101     static BusLogic_GlobalOptions_T
102       BusLogic_GlobalOptions;
103     
104     
105     /*
106       BusLogic_FirstRegisteredHostAdapter and BusLogic_LastRegisteredHostAdapter
107       are pointers to the first and last registered BusLogic Host Adapters.
108     */
109     
110     static BusLogic_HostAdapter_T
111       *BusLogic_FirstRegisteredHostAdapter,
112       *BusLogic_LastRegisteredHostAdapter;
113     
114     
115     /*
116       BusLogic_ProbeInfoCount is the number of entries in BusLogic_ProbeInfoList.
117     */
118     
119     static int
120       BusLogic_ProbeInfoCount;
121     
122     
123     /*
124       BusLogic_ProbeInfoList is the list of I/O Addresses and Bus Probe Information
125       to be checked for potential BusLogic Host Adapters.  It is initialized by
126       interrogating the PCI Configuration Space on PCI machines as well as from the
127       list of standard BusLogic I/O Addresses.
128     */
129     
130     static BusLogic_ProbeInfo_T
131       *BusLogic_ProbeInfoList;
132     
133     
134     /*
135       BusLogic_CommandFailureReason holds a string identifying the reason why a
136       call to BusLogic_Command failed.  It is only non-NULL when BusLogic_Command
137       returns a failure code.
138     */
139     
140     static char
141       *BusLogic_CommandFailureReason;
142     
143     /*
144       BusLogic_AnnounceDriver announces the Driver Version and Date, Author's
145       Name, Copyright Notice, and Electronic Mail Address.
146     */
147     
148     static void BusLogic_AnnounceDriver(BusLogic_HostAdapter_T *HostAdapter)
149     {
150       BusLogic_Announce("***** BusLogic SCSI Driver Version "
151     		    BusLogic_DriverVersion " of "
152     		    BusLogic_DriverDate " *****\n", HostAdapter);
153       BusLogic_Announce("Copyright 1995-1998 by Leonard N. Zubkoff "
154     		    "<lnz@dandelion.com>\n", HostAdapter);
155     }
156     
157     
158     /*
159       BusLogic_DriverInfo returns the Host Adapter Name to identify this SCSI
160       Driver and Host Adapter.
161     */
162     
163     const char *BusLogic_DriverInfo(SCSI_Host_T *Host)
164     {
165       BusLogic_HostAdapter_T *HostAdapter =
166         (BusLogic_HostAdapter_T *) Host->hostdata;
167       return HostAdapter->FullModelName;
168     }
169     
170     
171     /*
172       BusLogic_RegisterHostAdapter adds Host Adapter to the list of registered
173       BusLogic Host Adapters.
174     */
175     
176     static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
177     {
178       HostAdapter->Next = NULL;
179       if (BusLogic_FirstRegisteredHostAdapter == NULL)
180         {
181           BusLogic_FirstRegisteredHostAdapter = HostAdapter;
182           BusLogic_LastRegisteredHostAdapter = HostAdapter;
183         }
184       else
185         {
186           BusLogic_LastRegisteredHostAdapter->Next = HostAdapter;
187           BusLogic_LastRegisteredHostAdapter = HostAdapter;
188         }
189     }
190     
191     
192     /*
193       BusLogic_UnregisterHostAdapter removes Host Adapter from the list of
194       registered BusLogic Host Adapters.
195     */
196     
197     static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
198     {
199       if (HostAdapter == BusLogic_FirstRegisteredHostAdapter)
200         {
201           BusLogic_FirstRegisteredHostAdapter =
202     	BusLogic_FirstRegisteredHostAdapter->Next;
203           if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
204     	BusLogic_LastRegisteredHostAdapter = NULL;
205         }
206       else
207         {
208           BusLogic_HostAdapter_T *PreviousHostAdapter =
209     	BusLogic_FirstRegisteredHostAdapter;
210           while (PreviousHostAdapter != NULL &&
211     	     PreviousHostAdapter->Next != HostAdapter)
212     	PreviousHostAdapter = PreviousHostAdapter->Next;
213           if (PreviousHostAdapter != NULL)
214     	PreviousHostAdapter->Next = HostAdapter->Next;
215         }
216       HostAdapter->Next = NULL;
217     }
218     
219     
220     /*
221       BusLogic_InitializeCCBs initializes a group of Command Control Blocks (CCBs)
222       for Host Adapter from the BlockSize bytes located at BlockPointer.  The newly
223       created CCBs are added to Host Adapter's free list.
224     */
225     
226     static void BusLogic_InitializeCCBs(BusLogic_HostAdapter_T *HostAdapter,
227     				    void *BlockPointer, int BlockSize)
228     {
229       BusLogic_CCB_T *CCB = (BusLogic_CCB_T *) BlockPointer;
230       memset(BlockPointer, 0, BlockSize);
231       CCB->AllocationGroupHead = true;
232       while ((BlockSize -= sizeof(BusLogic_CCB_T)) >= 0)
233         {
234           CCB->Status = BusLogic_CCB_Free;
235           CCB->HostAdapter = HostAdapter;
236           if (BusLogic_FlashPointHostAdapterP(HostAdapter))
237     	{
238     	  CCB->CallbackFunction = BusLogic_QueueCompletedCCB;
239     	  CCB->BaseAddress = HostAdapter->FlashPointInfo.BaseAddress;
240     	}
241           CCB->Next = HostAdapter->Free_CCBs;
242           CCB->NextAll = HostAdapter->All_CCBs;
243           HostAdapter->Free_CCBs = CCB;
244           HostAdapter->All_CCBs = CCB;
245           HostAdapter->AllocatedCCBs++;
246           CCB++;
247         }
248     }
249     
250     
251     /*
252       BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter.
253     */
254     
255     static boolean BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *HostAdapter)
256     {
257       int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(BusLogic_CCB_T);
258       while (HostAdapter->AllocatedCCBs < HostAdapter->InitialCCBs)
259         {
260           void *BlockPointer = kmalloc(BlockSize,
261     				   (HostAdapter->BounceBuffersRequired
262     				    ? GFP_ATOMIC | GFP_DMA
263     				    : GFP_ATOMIC));
264           if (BlockPointer == NULL)
265     	{
266     	  BusLogic_Error("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n",
267     			 HostAdapter);
268     	  return false;
269     	}
270           BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize);
271         }
272       return true;
273     }
274     
275     
276     /*
277       BusLogic_DestroyCCBs deallocates the CCBs for Host Adapter.
278     */
279     
280     static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *HostAdapter)
281     {
282       BusLogic_CCB_T *NextCCB = HostAdapter->All_CCBs, *CCB;
283       HostAdapter->All_CCBs = NULL;
284       HostAdapter->Free_CCBs = NULL;
285       while ((CCB = NextCCB) != NULL)
286         {
287           NextCCB = CCB->NextAll;
288           if (CCB->AllocationGroupHead)
289     	kfree(CCB);
290         }
291     }
292     
293     
294     /*
295       BusLogic_CreateAdditionalCCBs allocates Additional CCBs for Host Adapter.  If
296       allocation fails and there are no remaining CCBs available, the Driver Queue
297       Depth is decreased to a known safe value to avoid potential deadlocks when
298       multiple host adapters share the same IRQ Channel.
299     */
300     
301     static void BusLogic_CreateAdditionalCCBs(BusLogic_HostAdapter_T *HostAdapter,
302     					  int AdditionalCCBs,
303     					  boolean SuccessMessageP)
304     {
305       int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(BusLogic_CCB_T);
306       int PreviouslyAllocated = HostAdapter->AllocatedCCBs;
307       if (AdditionalCCBs <= 0) return;
308       while (HostAdapter->AllocatedCCBs - PreviouslyAllocated < AdditionalCCBs)
309         {
310           void *BlockPointer = kmalloc(BlockSize,
311     				   (HostAdapter->BounceBuffersRequired
312     				    ? GFP_ATOMIC | GFP_DMA
313     				    : GFP_ATOMIC));
314           if (BlockPointer == NULL) break;
315           BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize);
316         }
317       if (HostAdapter->AllocatedCCBs > PreviouslyAllocated)
318         {
319           if (SuccessMessageP)
320     	BusLogic_Notice("Allocated %d additional CCBs (total now %d)\n",
321     			HostAdapter,
322     			HostAdapter->AllocatedCCBs - PreviouslyAllocated,
323     			HostAdapter->AllocatedCCBs);
324           return;
325         }
326       BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter);
327       if (HostAdapter->DriverQueueDepth >
328           HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount)
329         {
330           HostAdapter->DriverQueueDepth =
331     	HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount;
332           HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth;
333         }
334     }
335     
336     
337     /*
338       BusLogic_AllocateCCB allocates a CCB from Host Adapter's free list,
339       allocating more memory from the Kernel if necessary.  The Host Adapter's
340       Lock should already have been acquired by the caller.
341     */
342     
343     static BusLogic_CCB_T *BusLogic_AllocateCCB(BusLogic_HostAdapter_T
344     					    *HostAdapter)
345     {
346       static unsigned long SerialNumber = 0;
347       BusLogic_CCB_T *CCB;
348       CCB = HostAdapter->Free_CCBs;
349       if (CCB != NULL)
350         {
351           CCB->SerialNumber = ++SerialNumber;
352           HostAdapter->Free_CCBs = CCB->Next;
353           CCB->Next = NULL;
354           if (HostAdapter->Free_CCBs == NULL)
355     	BusLogic_CreateAdditionalCCBs(HostAdapter,
356     				      HostAdapter->IncrementalCCBs,
357     				      true);
358           return CCB;
359         }
360       BusLogic_CreateAdditionalCCBs(HostAdapter,
361     				HostAdapter->IncrementalCCBs,
362     				true);
363       CCB = HostAdapter->Free_CCBs;
364       if (CCB == NULL) return NULL;
365       CCB->SerialNumber = ++SerialNumber;
366       HostAdapter->Free_CCBs = CCB->Next;
367       CCB->Next = NULL;
368       return CCB;
369     }
370     
371     
372     /*
373       BusLogic_DeallocateCCB deallocates a CCB, returning it to the Host Adapter's
374       free list.  The Host Adapter's Lock should already have been acquired by the
375       caller.
376     */
377     
378     static void BusLogic_DeallocateCCB(BusLogic_CCB_T *CCB)
379     {
380       BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
381       CCB->Command = NULL;
382       CCB->Status = BusLogic_CCB_Free;
383       CCB->Next = HostAdapter->Free_CCBs;
384       HostAdapter->Free_CCBs = CCB;
385     }
386     
387     
388     /*
389       BusLogic_Command sends the command OperationCode to HostAdapter, optionally
390       providing ParameterLength bytes of ParameterData and receiving at most
391       ReplyLength bytes of ReplyData; any excess reply data is received but
392       discarded.
393     
394       On success, this function returns the number of reply bytes read from
395       the Host Adapter (including any discarded data); on failure, it returns
396       -1 if the command was invalid, or -2 if a timeout occurred.
397     
398       BusLogic_Command is called exclusively during host adapter detection and
399       initialization, so performance and latency are not critical, and exclusive
400       access to the Host Adapter hardware is assumed.  Once the host adapter and
401       driver are initialized, the only Host Adapter command that is issued is the
402       single byte Execute Mailbox Command operation code, which does not require
403       waiting for the Host Adapter Ready bit to be set in the Status Register.
404     */
405     
406     static int BusLogic_Command(BusLogic_HostAdapter_T *HostAdapter,
407     			    BusLogic_OperationCode_T OperationCode,
408     			    void *ParameterData,
409     			    int ParameterLength,
410     			    void *ReplyData,
411     			    int ReplyLength)
412     {
413       unsigned char *ParameterPointer = (unsigned char *) ParameterData;
414       unsigned char *ReplyPointer = (unsigned char *) ReplyData;
415       BusLogic_StatusRegister_T StatusRegister;
416       BusLogic_InterruptRegister_T InterruptRegister;
417       ProcessorFlags_T ProcessorFlags = 0;
418       int ReplyBytes = 0, Result;
419       long TimeoutCounter;
420       /*
421         Clear out the Reply Data if provided.
422       */
423       if (ReplyLength > 0)
424         memset(ReplyData, 0, ReplyLength);
425       /*
426         If the IRQ Channel has not yet been acquired, then interrupts must be
427         disabled while issuing host adapter commands since a Command Complete
428         interrupt could occur if the IRQ Channel was previously enabled by another
429         BusLogic Host Adapter or another driver sharing the same IRQ Channel.
430       */
431       if (!HostAdapter->IRQ_ChannelAcquired)
432         {
433           save_flags(ProcessorFlags);
434           cli();
435         }
436       /*
437         Wait for the Host Adapter Ready bit to be set and the Command/Parameter
438         Register Busy bit to be reset in the Status Register.
439       */
440       TimeoutCounter = 10000;
441       while (--TimeoutCounter >= 0)
442         {
443           StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
444           if (StatusRegister.Bits.HostAdapterReady &&
445     	  !StatusRegister.Bits.CommandParameterRegisterBusy)
446     	break;
447           udelay(100);
448         }
449       if (TimeoutCounter < 0)
450         {
451           BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
452           Result = -2;
453           goto Done;
454         }
455       /*
456         Write the OperationCode to the Command/Parameter Register.
457       */
458       HostAdapter->HostAdapterCommandCompleted = false;
459       BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
460       /*
461         Write any additional Parameter Bytes.
462       */
463       TimeoutCounter = 10000;
464       while (ParameterLength > 0 && --TimeoutCounter >= 0)
465         {
466           /*
467     	Wait 100 microseconds to give the Host Adapter enough time to determine
468     	whether the last value written to the Command/Parameter Register was
469     	valid or not.  If the Command Complete bit is set in the Interrupt
470     	Register, then the Command Invalid bit in the Status Register will be
471     	reset if the Operation Code or Parameter was valid and the command
472     	has completed, or set if the Operation Code or Parameter was invalid.
473     	If the Data In Register Ready bit is set in the Status Register, then
474     	the Operation Code was valid, and data is waiting to be read back
475     	from the Host Adapter.  Otherwise, wait for the Command/Parameter
476     	Register Busy bit in the Status Register to be reset.
477           */
478           udelay(100);
479           InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
480           StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
481           if (InterruptRegister.Bits.CommandComplete) break;
482           if (HostAdapter->HostAdapterCommandCompleted) break;
483           if (StatusRegister.Bits.DataInRegisterReady) break;
484           if (StatusRegister.Bits.CommandParameterRegisterBusy) continue;
485           BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
486           ParameterLength--;
487         }
488       if (TimeoutCounter < 0)
489         {
490           BusLogic_CommandFailureReason =
491     	"Timeout waiting for Parameter Acceptance";
492           Result = -2;
493           goto Done;
494         }
495       /*
496         The Modify I/O Address command does not cause a Command Complete Interrupt.
497       */
498       if (OperationCode == BusLogic_ModifyIOAddress)
499         {
500           StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
501           if (StatusRegister.Bits.CommandInvalid)
502     	{
503     	  BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
504     	  Result = -1;
505     	  goto Done;
506     	}
507           if (BusLogic_GlobalOptions.TraceConfiguration)
508     	BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: "
509     			"(Modify I/O Address)\n", HostAdapter,
510     			OperationCode, StatusRegister.All);
511           Result = 0;
512           goto Done;
513         }
514       /*
515         Select an appropriate timeout value for awaiting command completion.
516       */
517       switch (OperationCode)
518         {
519         case BusLogic_InquireInstalledDevicesID0to7:
520         case BusLogic_InquireInstalledDevicesID8to15:
521         case BusLogic_InquireTargetDevices:
522           /* Approximately 60 seconds. */
523           TimeoutCounter = 60*10000;
524           break;
525         default:
526           /* Approximately 1 second. */
527           TimeoutCounter = 10000;
528           break;
529         }
530       /*
531         Receive any Reply Bytes, waiting for either the Command Complete bit to
532         be set in the Interrupt Register, or for the Interrupt Handler to set the
533         Host Adapter Command Completed bit in the Host Adapter structure.
534       */
535       while (--TimeoutCounter >= 0)
536         {
537           InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
538           StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
539           if (InterruptRegister.Bits.CommandComplete) break;
540           if (HostAdapter->HostAdapterCommandCompleted) break;
541           if (StatusRegister.Bits.DataInRegisterReady)
542     	{
543     	  if (++ReplyBytes <= ReplyLength)
544     	    *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
545     	  else BusLogic_ReadDataInRegister(HostAdapter);
546     	}
547           if (OperationCode == BusLogic_FetchHostAdapterLocalRAM &&
548     	  StatusRegister.Bits.HostAdapterReady) break;
549           udelay(100);
550         }
551       if (TimeoutCounter < 0)
552         {
553           BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
554           Result = -2;
555           goto Done;
556         }
557       /*
558         Clear any pending Command Complete Interrupt.
559       */
560       BusLogic_InterruptReset(HostAdapter);
561       /*
562         Provide tracing information if requested.
563       */
564       if (BusLogic_GlobalOptions.TraceConfiguration)
565         {
566           int i;
567           BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:",
568     		      HostAdapter, OperationCode,
569     		      StatusRegister.All, ReplyLength, ReplyBytes);
570           if (ReplyLength > ReplyBytes) ReplyLength = ReplyBytes;
571           for (i = 0; i < ReplyLength; i++)
572     	BusLogic_Notice(" %02X", HostAdapter,
573     			((unsigned char *) ReplyData)[i]);
574           BusLogic_Notice("\n", HostAdapter);
575         }
576       /*
577         Process Command Invalid conditions.
578       */
579       if (StatusRegister.Bits.CommandInvalid)
580         {
581           /*
582     	Some early BusLogic Host Adapters may not recover properly from
583     	a Command Invalid condition, so if this appears to be the case,
584     	a Soft Reset is issued to the Host Adapter.  Potentially invalid
585     	commands are never attempted after Mailbox Initialization is
586     	performed, so there should be no Host Adapter state lost by a
587     	Soft Reset in response to a Command Invalid condition.
588           */
589           udelay(1000);
590           StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
591           if (StatusRegister.Bits.CommandInvalid ||
592     	  StatusRegister.Bits.Reserved ||
593     	  StatusRegister.Bits.DataInRegisterReady ||
594     	  StatusRegister.Bits.CommandParameterRegisterBusy ||
595     	  !StatusRegister.Bits.HostAdapterReady ||
596     	  !StatusRegister.Bits.InitializationRequired ||
597     	  StatusRegister.Bits.DiagnosticActive ||
598     	  StatusRegister.Bits.DiagnosticFailure)
599     	{
600     	  BusLogic_SoftReset(HostAdapter);
601     	  udelay(1000);
602     	}
603           BusLogic_CommandFailureReason = "Command Invalid";
604           Result = -1;
605           goto Done;
606         }
607       /*
608         Handle Excess Parameters Supplied conditions.
609       */
610       if (ParameterLength > 0)
611         {
612           BusLogic_CommandFailureReason = "Excess Parameters Supplied";
613           Result = -1;
614           goto Done;
615         }
616       /*
617         Indicate the command completed successfully.
618       */
619       BusLogic_CommandFailureReason = NULL;
620       Result = ReplyBytes;
621       /*
622         Restore the interrupt status if necessary and return.
623       */
624     Done:
625       if (!HostAdapter->IRQ_ChannelAcquired)
626         restore_flags(ProcessorFlags);
627       return Result;
628     }
629     
630     
631     /*
632       BusLogic_AppendProbeAddressISA appends a single ISA I/O Address to the list
633       of I/O Address and Bus Probe Information to be checked for potential BusLogic
634       Host Adapters.
635     */
636     
637     static void BusLogic_AppendProbeAddressISA(BusLogic_IO_Address_T IO_Address)
638     {
639       BusLogic_ProbeInfo_T *ProbeInfo;
640       if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return;
641       ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
642       ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
643       ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
644       ProbeInfo->IO_Address = IO_Address;
645     }
646     
647     
648     /*
649       BusLogic_InitializeProbeInfoListISA initializes the list of I/O Address and
650       Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters
651       only from the list of standard BusLogic MultiMaster ISA I/O Addresses.
652     */
653     
654     static void BusLogic_InitializeProbeInfoListISA(BusLogic_HostAdapter_T
655     						*PrototypeHostAdapter)
656     {
657       /*
658         If BusLogic Driver Options specifications requested that ISA Bus Probes
659         be inhibited, do not proceed further.
660       */
661       if (BusLogic_ProbeOptions.NoProbeISA) return;
662       /*
663         Append the list of standard BusLogic MultiMaster ISA I/O Addresses.
664       */
665       if (BusLogic_ProbeOptions.LimitedProbeISA
666           ? BusLogic_ProbeOptions.Probe330
667           : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)
668         BusLogic_AppendProbeAddressISA(0x330);
669       if (BusLogic_ProbeOptions.LimitedProbeISA
670           ? BusLogic_ProbeOptions.Probe334
671           : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0)
672         BusLogic_AppendProbeAddressISA(0x334);
673       if (BusLogic_ProbeOptions.LimitedProbeISA
674           ? BusLogic_ProbeOptions.Probe230
675           : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0)
676         BusLogic_AppendProbeAddressISA(0x230);
677       if (BusLogic_ProbeOptions.LimitedProbeISA
678           ? BusLogic_ProbeOptions.Probe234
679           : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0)
680         BusLogic_AppendProbeAddressISA(0x234);
681       if (BusLogic_ProbeOptions.LimitedProbeISA
682           ? BusLogic_ProbeOptions.Probe130
683           : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0)
684         BusLogic_AppendProbeAddressISA(0x130);
685       if (BusLogic_ProbeOptions.LimitedProbeISA
686           ? BusLogic_ProbeOptions.Probe134
687           : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0)
688         BusLogic_AppendProbeAddressISA(0x134);
689     }
690     
691     
692     #ifdef CONFIG_PCI
693     
694     
695     /*
696       BusLogic_SortProbeInfo sorts a section of BusLogic_ProbeInfoList in order
697       of increasing PCI Bus and Device Number.
698     */
699     
700     static void BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *ProbeInfoList,
701     				   int ProbeInfoCount)
702     {
703       int LastInterchange = ProbeInfoCount-1, Bound, j;
704       while (LastInterchange > 0)
705         {
706           Bound = LastInterchange;
707           LastInterchange = 0;
708           for (j = 0; j < Bound; j++)
709     	{
710     	  BusLogic_ProbeInfo_T *ProbeInfo1 = &ProbeInfoList[j];
711     	  BusLogic_ProbeInfo_T *ProbeInfo2 = &ProbeInfoList[j+1];
712     	  if (ProbeInfo1->Bus > ProbeInfo2->Bus ||
713     	      (ProbeInfo1->Bus == ProbeInfo2->Bus &&
714     	       (ProbeInfo1->Device > ProbeInfo2->Device)))
715     	    {
716     	      BusLogic_ProbeInfo_T TempProbeInfo;
717     	      memcpy(&TempProbeInfo, ProbeInfo1, sizeof(BusLogic_ProbeInfo_T));
718     	      memcpy(ProbeInfo1, ProbeInfo2, sizeof(BusLogic_ProbeInfo_T));
719     	      memcpy(ProbeInfo2, &TempProbeInfo, sizeof(BusLogic_ProbeInfo_T));
720     	      LastInterchange = j;
721     	    }
722     	}
723         }
724     }
725     
726     
727     /*
728       BusLogic_InitializeMultiMasterProbeInfo initializes the list of I/O Address
729       and Bus Probe Information to be checked for potential BusLogic MultiMaster
730       SCSI Host Adapters by interrogating the PCI Configuration Space on PCI
731       machines as well as from the list of standard BusLogic MultiMaster ISA
732       I/O Addresses.  It returns the number of PCI MultiMaster Host Adapters found.
733     */
734     
735     static int BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T
736     						   *PrototypeHostAdapter)
737     {
738       BusLogic_ProbeInfo_T *PrimaryProbeInfo =
739         &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount];
740       int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1;
741       int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0;
742       boolean ForceBusDeviceScanningOrder = false;
743       boolean ForceBusDeviceScanningOrderChecked = false;
744       boolean StandardAddressSeen[6];
745       PCI_Device_T *PCI_Device = NULL;
746       int i;
747       if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return 0;
748       BusLogic_ProbeInfoCount++;
749       for (i = 0; i < 6; i++)
750         StandardAddressSeen[i] = false;
751       /*
752         Iterate over the MultiMaster PCI Host Adapters.  For each enumerated host
753         adapter, determine whether its ISA Compatible I/O Port is enabled and if
754         so, whether it is assigned the Primary I/O Address.  A host adapter that is
755         assigned the Primary I/O Address will always be the preferred boot device.
756         The MultiMaster BIOS will first recognize a host adapter at the Primary I/O
757         Address, then any other PCI host adapters, and finally any host adapters
758         located at the remaining standard ISA I/O Addresses.  When a PCI host
759         adapter is found with its ISA Compatible I/O Port enabled, a command is
760         issued to disable the ISA Compatible I/O Port, and it is noted that the
761         particular standard ISA I/O Address need not be probed.
762       */
763       PrimaryProbeInfo->IO_Address = 0;
764       while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
765     				       PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
766     				       PCI_Device)) != NULL)
767         {
768           BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
769           BusLogic_PCIHostAdapterInformation_T PCIHostAdapterInformation;
770           BusLogic_ModifyIOAddressRequest_T ModifyIOAddressRequest;
771           unsigned char Bus = PCI_Device->bus->number;
772           unsigned char Device = PCI_Device->devfn >> 3;
773           unsigned int IRQ_Channel;
774           unsigned long BaseAddress0;
775           unsigned long BaseAddress1;
776           BusLogic_IO_Address_T IO_Address;
777           BusLogic_PCI_Address_T PCI_Address;
778     
779           if (pci_enable_device(PCI_Device))
780           	continue;
781           
782           IRQ_Channel = PCI_Device->irq;
783           IO_Address  = BaseAddress0 = pci_resource_start(PCI_Device, 0);
784           PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
785     
786           if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM)
787     	{
788     	  BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
789     			 "MultiMaster Host Adapter\n", NULL, BaseAddress0);
790     	  BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
791     			 NULL, Bus, Device, IO_Address);
792     	  continue;
793     	}
794           if (pci_resource_flags(PCI_Device,1) & IORESOURCE_IO)
795     	{
796     	  BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
797     			 "MultiMaster Host Adapter\n", NULL, BaseAddress1);
798     	  BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n",
799     			 NULL, Bus, Device, PCI_Address);
800     	  continue;
801     	}
802           if (IRQ_Channel == 0)
803     	{
804     	  BusLogic_Error("BusLogic: IRQ Channel %d illegal for "
805     			 "MultiMaster Host Adapter\n", NULL, IRQ_Channel);
806     	  BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
807     			 NULL, Bus, Device, IO_Address);
808     	  continue;
809     	}
810           if (BusLogic_GlobalOptions.TraceProbe)
811     	{
812     	  BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter "
813     			  "detected at\n", NULL);
814     	  BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address "
815     			  "0x%X PCI Address 0x%X\n", NULL,
816     			  Bus, Device, IO_Address, PCI_Address);
817     	}
818           /*
819     	Issue the Inquire PCI Host Adapter Information command to determine
820     	the ISA Compatible I/O Port.  If the ISA Compatible I/O Port is
821     	known and enabled, note that the particular Standard ISA I/O
822     	Address should not be probed.
823           */
824           HostAdapter->IO_Address = IO_Address;
825           BusLogic_InterruptReset(HostAdapter);
826           if (BusLogic_Command(HostAdapter,
827     			   BusLogic_InquirePCIHostAdapterInformation,
828     			   NULL, 0, &PCIHostAdapterInformation,
829     			   sizeof(PCIHostAdapterInformation))
830     	  == sizeof(PCIHostAdapterInformation))
831     	{
832     	  if (PCIHostAdapterInformation.ISACompatibleIOPort < 6)
833     	    StandardAddressSeen[PCIHostAdapterInformation
834     				.ISACompatibleIOPort] = true;
835     	}
836           else PCIHostAdapterInformation.ISACompatibleIOPort =
837     	     BusLogic_IO_Disable;
838           /*
839     	Issue the Modify I/O Address command to disable the ISA Compatible
840     	I/O Port.
841           */
842           ModifyIOAddressRequest = BusLogic_IO_Disable;
843           BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress,
844     		       &ModifyIOAddressRequest,
845     		       sizeof(ModifyIOAddressRequest), NULL, 0);
846           /*
847     	For the first MultiMaster Host Adapter enumerated, issue the Fetch
848     	Host Adapter Local RAM command to read byte 45 of the AutoSCSI area,
849     	for the setting of the "Use Bus And Device # For PCI Scanning Seq."
850     	option.  Issue the Inquire Board ID command since this option is
851     	only valid for the BT-948/958/958D.
852           */
853           if (!ForceBusDeviceScanningOrderChecked)
854     	{
855     	  BusLogic_FetchHostAdapterLocalRAMRequest_T
856     	    FetchHostAdapterLocalRAMRequest;
857     	  BusLogic_AutoSCSIByte45_T AutoSCSIByte45;
858     	  BusLogic_BoardID_T BoardID;
859     	  FetchHostAdapterLocalRAMRequest.ByteOffset =
860     	    BusLogic_AutoSCSI_BaseOffset + 45;
861     	  FetchHostAdapterLocalRAMRequest.ByteCount =
862     	    sizeof(AutoSCSIByte45);
863     	  BusLogic_Command(HostAdapter,
864     			   BusLogic_FetchHostAdapterLocalRAM,
865     			   &FetchHostAdapterLocalRAMRequest,
866     			   sizeof(FetchHostAdapterLocalRAMRequest),
867     			   &AutoSCSIByte45, sizeof(AutoSCSIByte45));
868     	  BusLogic_Command(HostAdapter, BusLogic_InquireBoardID,
869     			   NULL, 0, &BoardID, sizeof(BoardID));
870     	  if (BoardID.FirmwareVersion1stDigit == '5')
871     	    ForceBusDeviceScanningOrder =
872     	      AutoSCSIByte45.ForceBusDeviceScanningOrder;
873     	  ForceBusDeviceScanningOrderChecked = true;
874     	}
875           /*
876     	Determine whether this MultiMaster Host Adapter has its ISA
877     	Compatible I/O Port enabled and is assigned the Primary I/O Address.
878     	If it does, then it is the Primary MultiMaster Host Adapter and must
879     	be recognized first.  If it does not, then it is added to the list
880     	for probing after any Primary MultiMaster Host Adapter is probed.
881           */
882           if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330)
883     	{
884     	  PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
885     	  PrimaryProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
886     	  PrimaryProbeInfo->IO_Address = IO_Address;
887     	  PrimaryProbeInfo->PCI_Address = PCI_Address;
888     	  PrimaryProbeInfo->Bus = Bus;
889     	  PrimaryProbeInfo->Device = Device;
890     	  PrimaryProbeInfo->IRQ_Channel = IRQ_Channel;
891     	  PCIMultiMasterCount++;
892     	}
893           else if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
894     	{
895     	  BusLogic_ProbeInfo_T *ProbeInfo =
896     	    &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
897     	  ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
898     	  ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
899     	  ProbeInfo->IO_Address = IO_Address;
900     	  ProbeInfo->PCI_Address = PCI_Address;
901     	  ProbeInfo->Bus = Bus;
902     	  ProbeInfo->Device = Device;
903     	  ProbeInfo->IRQ_Channel = IRQ_Channel;
904     	  NonPrimaryPCIMultiMasterCount++;
905     	  PCIMultiMasterCount++;
906     	}
907           else BusLogic_Warning("BusLogic: Too many Host Adapters "
908     			    "detected\n", NULL);
909         }
910       /*
911         If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option is ON
912         for the first enumerated MultiMaster Host Adapter, and if that host adapter
913         is a BT-948/958/958D, then the MultiMaster BIOS will recognize MultiMaster
914         Host Adapters in the order of increasing PCI Bus and Device Number.  In
915         that case, sort the probe information into the same order the BIOS uses.
916         If this option is OFF, then the MultiMaster BIOS will recognize MultiMaster
917         Host Adapters in the order they are enumerated by the PCI BIOS, and hence
918         no sorting is necessary.
919       */
920       if (ForceBusDeviceScanningOrder)
921         BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[
922     			      NonPrimaryPCIMultiMasterIndex],
923     			   NonPrimaryPCIMultiMasterCount);
924       /*
925         If no PCI MultiMaster Host Adapter is assigned the Primary I/O Address,
926         then the Primary I/O Address must be probed explicitly before any PCI
927         host adapters are probed.
928       */
929       if (!BusLogic_ProbeOptions.NoProbeISA)
930         if (PrimaryProbeInfo->IO_Address == 0 &&
931     	(BusLogic_ProbeOptions.LimitedProbeISA
932     	 ? BusLogic_ProbeOptions.Probe330
933     	 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0))
934           {
935     	PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
936     	PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
937     	PrimaryProbeInfo->IO_Address = 0x330;
938           }
939       /*
940         Append the list of standard BusLogic MultiMaster ISA I/O Addresses,
941         omitting the Primary I/O Address which has already been handled.
942       */
943       if (!BusLogic_ProbeOptions.NoProbeISA)
944         {
945           if (!StandardAddressSeen[1] &&
946     	  (BusLogic_ProbeOptions.LimitedProbeISA
947     	   ? BusLogic_ProbeOptions.Probe334
948     	   : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0))
949     	BusLogic_AppendProbeAddressISA(0x334);
950           if (!StandardAddressSeen[2] &&
951     	  (BusLogic_ProbeOptions.LimitedProbeISA
952     	   ? BusLogic_ProbeOptions.Probe230
953     	   : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0))
954     	BusLogic_AppendProbeAddressISA(0x230);
955           if (!StandardAddressSeen[3] &&
956     	  (BusLogic_ProbeOptions.LimitedProbeISA
957     	   ? BusLogic_ProbeOptions.Probe234
958     	   : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0))
959     	BusLogic_AppendProbeAddressISA(0x234);
960           if (!StandardAddressSeen[4] &&
961     	  (BusLogic_ProbeOptions.LimitedProbeISA
962     	   ? BusLogic_ProbeOptions.Probe130
963     	   : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0))
964     	BusLogic_AppendProbeAddressISA(0x130);
965           if (!StandardAddressSeen[5] &&
966     	  (BusLogic_ProbeOptions.LimitedProbeISA
967     	   ? BusLogic_ProbeOptions.Probe134
968     	   : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0))
969     	BusLogic_AppendProbeAddressISA(0x134);
970         }
971       /*
972         Iterate over the older non-compliant MultiMaster PCI Host Adapters,
973         noting the PCI bus location and assigned IRQ Channel.
974       */
975       PCI_Device = NULL;
976       while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
977     				       PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
978     				       PCI_Device)) != NULL)
979         {
980           unsigned char Bus = PCI_Device->bus->number;
981           unsigned char Device = PCI_Device->devfn >> 3;
982           unsigned int IRQ_Channel = PCI_Device->irq;
983           BusLogic_IO_Address_T IO_Address = pci_resource_start(PCI_Device, 0);
984     
985           if (pci_enable_device(PCI_Device))
986     		continue;
987     
988           if (IO_Address == 0 || IRQ_Channel == 0) continue;
989           for (i = 0; i < BusLogic_ProbeInfoCount; i++)
990     	{
991     	  BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[i];
992     	  if (ProbeInfo->IO_Address == IO_Address &&
993     	      ProbeInfo->HostAdapterType == BusLogic_MultiMaster)
994     	    {
995     	      ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
996     	      ProbeInfo->PCI_Address = 0;
997     	      ProbeInfo->Bus = Bus;
998     	      ProbeInfo->Device = Device;
999     	      ProbeInfo->IRQ_Channel = IRQ_Channel;
1000     	      break;
1001     	    }
1002     	}
1003         }
1004       return PCIMultiMasterCount;
1005     }
1006     
1007     
1008     /*
1009       BusLogic_InitializeFlashPointProbeInfo initializes the list of I/O Address
1010       and Bus Probe Information to be checked for potential BusLogic FlashPoint
1011       Host Adapters by interrogating the PCI Configuration Space.  It returns the
1012       number of FlashPoint Host Adapters found.
1013     */
1014     
1015     static int BusLogic_InitializeFlashPointProbeInfo(BusLogic_HostAdapter_T
1016     						  *PrototypeHostAdapter)
1017     {
1018       int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0;
1019       PCI_Device_T *PCI_Device = NULL;
1020       /*
1021         Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
1022       */
1023       while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
1024     				       PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
1025     				       PCI_Device)) != NULL)
1026         {
1027           unsigned char Bus = PCI_Device->bus->number;
1028           unsigned char Device = PCI_Device->devfn >> 3;
1029           unsigned int IRQ_Channel = PCI_Device->irq;
1030           unsigned long BaseAddress0 = pci_resource_start(PCI_Device, 0);
1031           unsigned long BaseAddress1 = pci_resource_start(PCI_Device, 1);
1032           BusLogic_IO_Address_T IO_Address = BaseAddress0;
1033           BusLogic_PCI_Address_T PCI_Address = BaseAddress1;
1034     
1035           if (pci_enable_device(PCI_Device))
1036     		continue;
1037     
1038     #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
1039           if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM)
1040     	{
1041     	  BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
1042     			 "FlashPoint Host Adapter\n", NULL, BaseAddress0);
1043     	  BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
1044     			 NULL, Bus, Device, IO_Address);
1045     	  continue;
1046     	}
1047           if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO)
1048     	{
1049     	  BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
1050     			 "FlashPoint Host Adapter\n", NULL, BaseAddress1);
1051     	  BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n",
1052     			 NULL, Bus, Device, PCI_Address);
1053     	  continue;
1054     	}
1055           if (IRQ_Channel == 0)
1056     	{
1057     	  BusLogic_Error("BusLogic: IRQ Channel %d illegal for "
1058     			 "FlashPoint Host Adapter\n", NULL, IRQ_Channel);
1059     	  BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
1060     			 NULL, Bus, Device, IO_Address);
1061     	  continue;
1062     	}
1063           if (BusLogic_GlobalOptions.TraceProbe)
1064     	{
1065     	  BusLogic_Notice("BusLogic: FlashPoint Host Adapter "
1066     			  "detected at\n", NULL);
1067     	  BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address "
1068     			  "0x%X PCI Address 0x%X\n", NULL,
1069     			  Bus, Device, IO_Address, PCI_Address);
1070     	}
1071           if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
1072     	{
1073     	  BusLogic_ProbeInfo_T *ProbeInfo =
1074     	    &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
1075     	  ProbeInfo->HostAdapterType = BusLogic_FlashPoint;
1076     	  ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
1077     	  ProbeInfo->IO_Address = IO_Address;
1078     	  ProbeInfo->PCI_Address = PCI_Address;
1079     	  ProbeInfo->Bus = Bus;
1080     	  ProbeInfo->Device = Device;
1081     	  ProbeInfo->IRQ_Channel = IRQ_Channel;
1082     	  FlashPointCount++;
1083     	}
1084           else BusLogic_Warning("BusLogic: Too many Host Adapters "
1085     			    "detected\n", NULL);
1086     #else
1087           BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
1088     		     "PCI Bus %d Device %d\n", NULL, Bus, Device);
1089           BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, "
1090     		     "but FlashPoint\n", NULL, IO_Address, PCI_Address, IRQ_Channel);
1091           BusLogic_Error("BusLogic: support was omitted in this kernel "
1092     		     "configuration.\n", NULL);
1093     #endif
1094         }
1095       /*
1096         The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of
1097         increasing PCI Bus and Device Number, so sort the probe information into
1098         the same order the BIOS uses.
1099       */
1100       BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[FlashPointIndex],
1101     			 FlashPointCount);
1102       return FlashPointCount;
1103     }
1104     
1105     
1106     /*
1107       BusLogic_InitializeProbeInfoList initializes the list of I/O Address and Bus
1108       Probe Information to be checked for potential BusLogic SCSI Host Adapters by
1109       interrogating the PCI Configuration Space on PCI machines as well as from the
1110       list of standard BusLogic MultiMaster ISA I/O Addresses.  By default, if both
1111       FlashPoint and PCI MultiMaster Host Adapters are present, this driver will
1112       probe for FlashPoint Host Adapters first unless the BIOS primary disk is
1113       controlled by the first PCI MultiMaster Host Adapter, in which case
1114       MultiMaster Host Adapters will be probed first.  The BusLogic Driver Options
1115       specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force
1116       a particular probe order.
1117     */
1118     
1119     static void BusLogic_InitializeProbeInfoList(BusLogic_HostAdapter_T
1120     					     *PrototypeHostAdapter)
1121     {
1122       /*
1123         If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint
1124         Host Adapters; otherwise, default to the standard ISA MultiMaster probe.
1125       */
1126       if (!BusLogic_ProbeOptions.NoProbePCI && pci_present())
1127         {
1128           if (BusLogic_ProbeOptions.MultiMasterFirst)
1129     	{
1130     	  BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1131     	  BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1132     	}
1133           else if (BusLogic_ProbeOptions.FlashPointFirst)
1134     	{
1135     	  BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1136     	  BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1137     	}
1138           else
1139     	{
1140     	  int FlashPointCount =
1141     	    BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1142     	  int PCIMultiMasterCount =
1143     	    BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1144     	  if (FlashPointCount > 0 && PCIMultiMasterCount > 0)
1145     	    {
1146     	      BusLogic_ProbeInfo_T *ProbeInfo =
1147     		&BusLogic_ProbeInfoList[FlashPointCount];
1148     	      BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
1149     	      BusLogic_FetchHostAdapterLocalRAMRequest_T
1150     		FetchHostAdapterLocalRAMRequest;
1151     	      BusLogic_BIOSDriveMapByte_T Drive0MapByte;
1152     	      while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus)
1153     		ProbeInfo++;
1154     	      HostAdapter->IO_Address = ProbeInfo->IO_Address;
1155     	      FetchHostAdapterLocalRAMRequest.ByteOffset =
1156     		BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0;
1157     	      FetchHostAdapterLocalRAMRequest.ByteCount =
1158     		sizeof(Drive0MapByte);
1159     	      BusLogic_Command(HostAdapter,
1160     			       BusLogic_FetchHostAdapterLocalRAM,
1161     			       &FetchHostAdapterLocalRAMRequest,
1162     			       sizeof(FetchHostAdapterLocalRAMRequest),
1163     			       &Drive0MapByte, sizeof(Drive0MapByte));
1164     	      /*
1165     		If the Map Byte for BIOS Drive 0 indicates that BIOS Drive 0
1166     		is controlled by this PCI MultiMaster Host Adapter, then
1167     		reverse the probe order so that MultiMaster Host Adapters are
1168     		probed before FlashPoint Host Adapters.
1169     	      */
1170     	      if (Drive0MapByte.DiskGeometry !=
1171     		  BusLogic_BIOS_Disk_Not_Installed)
1172     		{
1173     		  BusLogic_ProbeInfo_T
1174     		    SavedProbeInfo[BusLogic_MaxHostAdapters];
1175     		  int MultiMasterCount =
1176     		    BusLogic_ProbeInfoCount - FlashPointCount;
1177     		  memcpy(SavedProbeInfo,
1178     			 BusLogic_ProbeInfoList,
1179     			 BusLogic_ProbeInfoCount
1180     			 * sizeof(BusLogic_ProbeInfo_T));
1181     		  memcpy(&BusLogic_ProbeInfoList[0],
1182     			 &SavedProbeInfo[FlashPointCount],
1183     			 MultiMasterCount * sizeof(BusLogic_ProbeInfo_T));
1184     		  memcpy(&BusLogic_ProbeInfoList[MultiMasterCount],
1185     			 &SavedProbeInfo[0],
1186     			 FlashPointCount * sizeof(BusLogic_ProbeInfo_T));
1187     		}
1188     	    }
1189     	}
1190         }
1191       else BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter);
1192     }
1193     
1194     
1195     #endif  /* CONFIG_PCI */
1196     
1197     
1198     /*
1199       BusLogic_Failure prints a standardized error message, and then returns false.
1200     */
1201     
1202     static boolean BusLogic_Failure(BusLogic_HostAdapter_T *HostAdapter,
1203     				char *ErrorMessage)
1204     {
1205       BusLogic_AnnounceDriver(HostAdapter);
1206       if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus)
1207         {
1208           BusLogic_Error("While configuring BusLogic PCI Host Adapter at\n",
1209     		     HostAdapter);
1210           BusLogic_Error("Bus %d Device %d I/O Address 0x%X PCI Address 0x%X:\n",
1211     		     HostAdapter, HostAdapter->Bus, HostAdapter->Device,
1212     		     HostAdapter->IO_Address, HostAdapter->PCI_Address);
1213         }
1214       else BusLogic_Error("While configuring BusLogic Host Adapter at "
1215     		      "I/O Address 0x%X:\n", HostAdapter,
1216     		      HostAdapter->IO_Address);
1217       BusLogic_Error("%s FAILED - DETACHING\n", HostAdapter, ErrorMessage);
1218       if (BusLogic_CommandFailureReason != NULL)
1219         BusLogic_Error("ADDITIONAL FAILURE INFO - %s\n", HostAdapter,
1220     		   BusLogic_CommandFailureReason);
1221       return false;
1222     }
1223     
1224     
1225     /*
1226       BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
1227     */
1228     
1229     static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
1230     {
1231       BusLogic_StatusRegister_T StatusRegister;
1232       BusLogic_InterruptRegister_T InterruptRegister;
1233       BusLogic_GeometryRegister_T GeometryRegister;
1234       /*
1235         FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
1236       */
1237       if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1238         {
1239           FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
1240           FlashPointInfo->BaseAddress =
1241     	(BusLogic_Base_Address_T) HostAdapter->IO_Address;
1242           FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel;
1243           FlashPointInfo->Present = false;
1244           if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 &&
1245     	    FlashPointInfo->Present))
1246     	{
1247     	  BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
1248     			 "PCI Bus %d Device %d\n", HostAdapter,
1249     			 HostAdapter->Bus, HostAdapter->Device);
1250     	  BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, "
1251     			 "but FlashPoint\n", HostAdapter,
1252     			 HostAdapter->IO_Address, HostAdapter->PCI_Address);
1253     	  BusLogic_Error("BusLogic: Probe Function failed to validate it.\n",
1254     			 HostAdapter);
1255     	  return false;
1256     	}
1257           if (BusLogic_GlobalOptions.TraceProbe)
1258     	BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n",
1259     			HostAdapter, HostAdapter->IO_Address);
1260           /*
1261     	Indicate the Host Adapter Probe completed successfully.
1262           */
1263           return true;
1264         }
1265       /*
1266         Read the Status, Interrupt, and Geometry Registers to test if there are I/O
1267         ports that respond, and to check the values to determine if they are from a
1268         BusLogic Host Adapter.  A nonexistent I/O port will return 0xFF, in which
1269         case there is definitely no BusLogic Host Adapter at this base I/O Address.
1270         The test here is a subset of that used by the BusLogic Host Adapter BIOS.
1271       */
1272       StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1273       InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
1274       GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1275       if (BusLogic_GlobalOptions.TraceProbe)
1276         BusLogic_Notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, "
1277     		    "Geometry 0x%02X\n", HostAdapter,
1278     		    HostAdapter->IO_Address, StatusRegister.All,
1279     		    InterruptRegister.All, GeometryRegister.All);
1280       if (StatusRegister.All == 0 ||
1281           StatusRegister.Bits.DiagnosticActive ||
1282           StatusRegister.Bits.CommandParameterRegisterBusy ||
1283           StatusRegister.Bits.Reserved ||
1284           StatusRegister.Bits.CommandInvalid ||
1285           InterruptRegister.Bits.Reserved != 0)
1286         return false;
1287       /*
1288         Check the undocumented Geometry Register to test if there is an I/O port
1289         that responded.  Adaptec Host Adapters do not implement the Geometry
1290         Register, so this test helps serve to avoid incorrectly recognizing an
1291         Adaptec 1542A or 1542B as a BusLogic.  Unfortunately, the Adaptec 1542C
1292         series does respond to the Geometry Register I/O port, but it will be
1293         rejected later when the Inquire Extended Setup Information command is
1294         issued in BusLogic_CheckHostAdapter.  The AMI FastDisk Host Adapter is a
1295         BusLogic clone that implements the same interface as earlier BusLogic
1296         Host Adapters, including the undocumented commands, and is therefore
1297         supported by this driver.  However, the AMI FastDisk always returns 0x00
1298         upon reading the Geometry Register, so the extended translation option
1299         should always be left disabled on the AMI FastDisk.
1300       */
1301       if (GeometryRegister.All == 0xFF) return false;
1302       /*
1303         Indicate the Host Adapter Probe completed successfully.
1304       */
1305       return true;
1306     }
1307     
1308     
1309     /*
1310       BusLogic_HardwareResetHostAdapter issues a Hardware Reset to the Host Adapter
1311       and waits for Host Adapter Diagnostics to complete.  If HardReset is true, a
1312       Hard Reset is performed which also initiates a SCSI Bus Reset.  Otherwise, a
1313       Soft Reset is performed which only resets the Host Adapter without forcing a
1314       SCSI Bus Reset.
1315     */
1316     
1317     static boolean BusLogic_HardwareResetHostAdapter(BusLogic_HostAdapter_T
1318     						   *HostAdapter,
1319     						 boolean HardReset)
1320     {
1321       BusLogic_StatusRegister_T StatusRegister;
1322       int TimeoutCounter;
1323       /*
1324         FlashPoint Host Adapters are Hard Reset by the FlashPoint SCCB Manager.
1325       */
1326       if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1327         {
1328           FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
1329           FlashPointInfo->HostSoftReset = !HardReset;
1330           FlashPointInfo->ReportDataUnderrun = true;
1331           HostAdapter->CardHandle =
1332     	FlashPoint_HardwareResetHostAdapter(FlashPointInfo);
1333           if (HostAdapter->CardHandle == FlashPoint_BadCardHandle) return false;
1334           /*
1335     	Indicate the Host Adapter Hard Reset completed successfully.
1336           */
1337           return true;
1338         }
1339       /*
1340         Issue a Hard Reset or Soft Reset Command to the Host Adapter.  The Host
1341         Adapter should respond by setting Diagnostic Active in the Status Register.
1342       */
1343       if (HardReset)
1344         BusLogic_HardReset(HostAdapter);
1345       else BusLogic_SoftReset(HostAdapter);
1346       /*
1347         Wait until Diagnostic Active is set in the Status Register.
1348       */
1349       TimeoutCounter = 5*10000;
1350       while (--TimeoutCounter >= 0)
1351         {
1352           StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1353           if (StatusRegister.Bits.DiagnosticActive) break;
1354           udelay(100);
1355         }
1356       if (BusLogic_GlobalOptions.TraceHardwareReset)
1357         BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, "
1358     		    "Status 0x%02X\n", HostAdapter,
1359     		    HostAdapter->IO_Address, StatusRegister.All);
1360       if (TimeoutCounter < 0) return false;
1361       /*
1362         Wait 100 microseconds to allow completion of any initial diagnostic
1363         activity which might leave the contents of the Status Register
1364         unpredictable.
1365       */
1366       udelay(100);
1367       /*
1368         Wait until Diagnostic Active is reset in the Status Register.
1369       */
1370       TimeoutCounter = 10*10000;
1371       while (--TimeoutCounter >= 0)
1372         {
1373           StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1374           if (!StatusRegister.Bits.DiagnosticActive) break;
1375           udelay(100);
1376         }
1377       if (BusLogic_GlobalOptions.TraceHardwareReset)
1378         BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, "
1379     		    "Status 0x%02X\n", HostAdapter,
1380     		    HostAdapter->IO_Address, StatusRegister.All);
1381       if (TimeoutCounter < 0) return false;
1382       /*
1383         Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
1384         or Data In Register Ready bits is set in the Status Register.
1385       */
1386       TimeoutCounter = 10000;
1387       while (--TimeoutCounter >= 0)
1388         {
1389           StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1390           if (StatusRegister.Bits.DiagnosticFailure ||
1391     	  StatusRegister.Bits.HostAdapterReady ||
1392     	  StatusRegister.Bits.DataInRegisterReady)
1393     	break;
1394           udelay(100);
1395         }
1396       if (BusLogic_GlobalOptions.TraceHardwareReset)
1397         BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, "
1398     		    "Status 0x%02X\n", HostAdapter,
1399     		    HostAdapter->IO_Address, StatusRegister.All);
1400       if (TimeoutCounter < 0) return false;
1401       /*
1402         If Diagnostic Failure is set or Host Adapter Ready is reset, then an
1403         error occurred during the Host Adapter diagnostics.  If Data In Register
1404         Ready is set, then there is an Error Code available.
1405       */
1406       if (StatusRegister.Bits.DiagnosticFailure ||
1407           !StatusRegister.Bits.HostAdapterReady)
1408         {
1409           BusLogic_CommandFailureReason = NULL;
1410           BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
1411           BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n",
1412     		     HostAdapter, StatusRegister.All);
1413           if (StatusRegister.Bits.DataInRegisterReady)
1414     	{
1415     	  unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
1416     	  BusLogic_Error("HOST ADAPTER ERROR CODE = %d\n",
1417     			 HostAdapter, ErrorCode);
1418     	}
1419           return false;
1420         }
1421       /*
1422         Indicate the Host Adapter Hard Reset completed successfully.
1423       */
1424       return true;
1425     }
1426     
1427     
1428     /*
1429       BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
1430       Host Adapter.
1431     */
1432     
1433     static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
1434     {
1435       BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
1436       BusLogic_RequestedReplyLength_T RequestedReplyLength;
1437       boolean Result = true;
1438       /*
1439         FlashPoint Host Adapters do not require this protection.
1440       */
1441       if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
1442       /*
1443         Issue the Inquire Extended Setup Information command.  Only genuine
1444         BusLogic Host Adapters and true clones support this command.  Adaptec 1542C
1445         series Host Adapters that respond to the Geometry Register I/O port will
1446         fail this command.
1447       */
1448       RequestedReplyLength = sizeof(ExtendedSetupInformation);
1449       if (BusLogic_Command(HostAdapter,
1450     		       BusLogic_InquireExtendedSetupInformation,
1451     		       &RequestedReplyLength,
1452     		       sizeof(RequestedReplyLength),
1453     		       &ExtendedSetupInformation,
1454     		       sizeof(ExtendedSetupInformation))
1455           != sizeof(ExtendedSetupInformation))
1456         Result = false;
1457       /*
1458         Provide tracing information if requested and return.
1459       */
1460       if (BusLogic_GlobalOptions.TraceProbe)
1461         BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter,
1462     		    HostAdapter->IO_Address, (Result ? "Found" : "Not Found"));
1463       return Result;
1464     }
1465     
1466     
1467     /*
1468       BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
1469       from Host Adapter and initializes the Host Adapter structure.
1470     */
1471     
1472     static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T
1473     						     *HostAdapter)
1474     {
1475       BusLogic_BoardID_T BoardID;
1476       BusLogic_Configuration_T Configuration;
1477       BusLogic_SetupInformation_T SetupInformation;
1478       BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
1479       BusLogic_HostAdapterModelNumber_T HostAdapterModelNumber;
1480       BusLogic_FirmwareVersion3rdDigit_T FirmwareVersion3rdDigit;
1481       BusLogic_FirmwareVersionLetter_T FirmwareVersionLetter;
1482       BusLogic_PCIHostAdapterInformation_T PCIHostAdapterInformation;
1483       BusLogic_FetchHostAdapterLocalRAMRequest_T FetchHostAdapterLocalRAMRequest;
1484       BusLogic_AutoSCSIData_T AutoSCSIData;
1485       BusLogic_GeometryRegister_T GeometryRegister;
1486       BusLogic_RequestedReplyLength_T RequestedReplyLength;
1487       unsigned char *TargetPointer, Character;
1488       int TargetID, i;
1489       /*
1490         Configuration Information for FlashPoint Host Adapters is provided in the
1491         FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function.
1492         Initialize fields in the Host Adapter structure from the FlashPoint_Info
1493         structure.
1494       */
1495       if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1496         {
1497           FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
1498           TargetPointer = HostAdapter->ModelName;
1499           *TargetPointer++ = 'B';
1500           *TargetPointer++ = 'T';
1501           *TargetPointer++ = '-';
1502           for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++)
1503     	*TargetPointer++ = FlashPointInfo->ModelNumber[i];
1504           *TargetPointer++ = '\0';
1505           strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion);
1506           HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID;
1507           HostAdapter->ExtendedTranslationEnabled =
1508     	FlashPointInfo->ExtendedTranslationEnabled;
1509           HostAdapter->ParityCheckingEnabled =
1510     	FlashPointInfo->ParityCheckingEnabled;
1511           HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset;
1512           HostAdapter->LevelSensitiveInterrupt = true;
1513           HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI;
1514           HostAdapter->HostDifferentialSCSI = false;
1515           HostAdapter->HostSupportsSCAM = true;
1516           HostAdapter->HostUltraSCSI = true;
1517           HostAdapter->ExtendedLUNSupport = true;
1518           HostAdapter->TerminationInfoValid = true;
1519           HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated;
1520           HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated;
1521           HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled;
1522           HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2;
1523           HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1524           HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1525           HostAdapter->MaxLogicalUnits = 32;
1526           HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1527           HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1528           HostAdapter->DriverQueueDepth = 255;
1529           HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth;
1530           HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted;
1531           HostAdapter->FastPermitted = FlashPointInfo->FastPermitted;
1532           HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted;
1533           HostAdapter->WidePermitted = FlashPointInfo->WidePermitted;
1534           HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted;
1535           HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1536           goto Common;
1537         }
1538       /*
1539         Issue the Inquire Board ID command.
1540       */
1541       if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0,
1542     		       &BoardID, sizeof(BoardID)) != sizeof(BoardID))
1543         return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
1544       /*
1545         Issue the Inquire Configuration command.
1546       */
1547       if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0,
1548     		       &Configuration, sizeof(Configuration))
1549           != sizeof(Configuration))
1550         return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
1551       /*
1552         Issue the Inquire Setup Information command.
1553       */
1554       RequestedReplyLength = sizeof(SetupInformation);
1555       if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
1556     		       &RequestedReplyLength, sizeof(RequestedReplyLength),
1557     		       &SetupInformation, sizeof(SetupInformation))
1558           != sizeof(SetupInformation))
1559         return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
1560       /*
1561         Issue the Inquire Extended Setup Information command.
1562       */
1563       RequestedReplyLength = sizeof(ExtendedSetupInformation);
1564       if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation,
1565     		       &RequestedReplyLength, sizeof(RequestedReplyLength),
1566     		       &ExtendedSetupInformation,
1567     		       sizeof(ExtendedSetupInformation))
1568           != sizeof(ExtendedSetupInformation))
1569         return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
1570       /*
1571         Issue the Inquire Firmware Version 3rd Digit command.
1572       */
1573       FirmwareVersion3rdDigit = '\0';
1574       if (BoardID.FirmwareVersion1stDigit > '0')
1575         if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit,
1576     			 NULL, 0, &FirmwareVersion3rdDigit,
1577     			 sizeof(FirmwareVersion3rdDigit))
1578     	!= sizeof(FirmwareVersion3rdDigit))
1579           return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
1580       /*
1581         Issue the Inquire Host Adapter Model Number command.
1582       */
1583       if (ExtendedSetupInformation.BusType == 'A' &&
1584           BoardID.FirmwareVersion1stDigit == '2')
1585         /* BusLogic BT-542B ISA 2.xx */
1586         strcpy(HostAdapterModelNumber, "542B");
1587       else if (ExtendedSetupInformation.BusType == 'E' &&
1588     	   BoardID.FirmwareVersion1stDigit == '2' &&
1589     	   (BoardID.FirmwareVersion2ndDigit <= '1' ||
1590     	    (BoardID.FirmwareVersion2ndDigit == '2' &&
1591     	     FirmwareVersion3rdDigit == '0')))
1592         /* BusLogic BT-742A EISA 2.1x or 2.20 */
1593         strcpy(HostAdapterModelNumber, "742A");
1594       else if (ExtendedSetupInformation.BusType == 'E' &&
1595     	   BoardID.FirmwareVersion1stDigit == '0')
1596         /* AMI FastDisk EISA Series 441 0.x */
1597         strcpy(HostAdapterModelNumber, "747A");
1598       else
1599         {
1600           RequestedReplyLength = sizeof(HostAdapterModelNumber);
1601           if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber,
1602     			   &RequestedReplyLength, sizeof(RequestedReplyLength),
1603     			   &HostAdapterModelNumber,
1604     			   sizeof(HostAdapterModelNumber))
1605     	  != sizeof(HostAdapterModelNumber))
1606     	return BusLogic_Failure(HostAdapter,
1607     				"INQUIRE HOST ADAPTER MODEL NUMBER");
1608         }
1609       /*
1610         BusLogic MultiMaster Host Adapters can be identified by their model number
1611         and the major version number of their firmware as follows:
1612     
1613         5.xx	BusLogic "W" Series Host Adapters:
1614     		  BT-948/958/958D
1615         4.xx	BusLogic "C" Series Host Adapters:
1616     		  BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
1617         3.xx	BusLogic "S" Series Host Adapters:
1618     		  BT-747S/747D/757S/757D/445S/545S/542D
1619     		  BT-542B/742A (revision H)
1620         2.xx	BusLogic "A" Series Host Adapters:
1621     		  BT-542B/742A (revision G and below)
1622         0.xx	AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
1623       */
1624       /*
1625         Save the Model Name and Host Adapter Name in the Host Adapter structure.
1626       */
1627       TargetPointer = HostAdapter->ModelName;
1628       *TargetPointer++ = 'B';
1629       *TargetPointer++ = 'T';
1630       *TargetPointer++ = '-';
1631       for (i = 0; i < sizeof(HostAdapterModelNumber); i++)
1632         {
1633           Character = HostAdapterModelNumber[i];
1634           if (Character == ' ' || Character == '\0') break;
1635           *TargetPointer++ = Character;
1636         }
1637       *TargetPointer++ = '\0';
1638       /*
1639         Save the Firmware Version in the Host Adapter structure.
1640       */
1641       TargetPointer = HostAdapter->FirmwareVersion;
1642       *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
1643       *TargetPointer++ = '.';
1644       *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
1645       if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
1646         *TargetPointer++ = FirmwareVersion3rdDigit;
1647       *TargetPointer = '\0';
1648       /*
1649         Issue the Inquire Firmware Version Letter command.
1650       */
1651       if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0)
1652         {
1653           if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter,
1654     			   NULL, 0, &FirmwareVersionLetter,
1655     			   sizeof(FirmwareVersionLetter))
1656     	  != sizeof(FirmwareVersionLetter))
1657     	return BusLogic_Failure(HostAdapter,
1658     				"INQUIRE FIRMWARE VERSION LETTER");
1659           if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
1660     	*TargetPointer++ = FirmwareVersionLetter;
1661           *TargetPointer = '\0';
1662         }
1663       /*
1664         Save the Host Adapter SCSI ID in the Host Adapter structure.
1665       */
1666       HostAdapter->SCSI_ID = Configuration.HostAdapterID;
1667       /*
1668         Determine the Bus Type and save it in the Host Adapter structure, determine
1669         and save the IRQ Channel if necessary, and determine and save the DMA
1670         Channel for ISA Host Adapters.
1671       */
1672       HostAdapter->HostAdapterBusType =
1673         BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4'];
1674       if (HostAdapter->IRQ_Channel == 0)
1675         {
1676           if (Configuration.IRQ_Channel9)
1677     	HostAdapter->IRQ_Channel = 9;
1678           else if (Configuration.IRQ_Channel10)
1679     	HostAdapter->IRQ_Channel = 10;
1680           else if (Configuration.IRQ_Channel11)
1681     	HostAdapter->IRQ_Channel = 11;
1682           else if (Configuration.IRQ_Channel12)
1683     	HostAdapter->IRQ_Channel = 12;
1684           else if (Configuration.IRQ_Channel14)
1685     	HostAdapter->IRQ_Channel = 14;
1686           else if (Configuration.IRQ_Channel15)
1687     	HostAdapter->IRQ_Channel = 15;
1688         }
1689       if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus)
1690         {
1691           if (Configuration.DMA_Channel5)
1692     	HostAdapter->DMA_Channel = 5;
1693           else if (Configuration.DMA_Channel6)
1694     	HostAdapter->DMA_Channel = 6;
1695           else if (Configuration.DMA_Channel7)
1696     	HostAdapter->DMA_Channel = 7;
1697         }
1698       /*
1699         Determine whether Extended Translation is enabled and save it in
1700         the Host Adapter structure.
1701       */
1702       GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1703       HostAdapter->ExtendedTranslationEnabled =
1704         GeometryRegister.Bits.ExtendedTranslationEnabled;
1705       /*
1706         Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
1707         SCSI flag, Differential SCSI flag, SCAM Supported flag, and
1708         Ultra SCSI flag in the Host Adapter structure.
1709       */
1710       HostAdapter->HostAdapterScatterGatherLimit =
1711         ExtendedSetupInformation.ScatterGatherLimit;
1712       HostAdapter->DriverScatterGatherLimit =
1713         HostAdapter->HostAdapterScatterGatherLimit;
1714       if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
1715         HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1716       if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt)
1717         HostAdapter->LevelSensitiveInterrupt = true;
1718       HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI;
1719       HostAdapter->HostDifferentialSCSI =
1720         ExtendedSetupInformation.HostDifferentialSCSI;
1721       HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM;
1722       HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
1723       /*
1724         Determine whether Extended LUN Format CCBs are supported and save the
1725         information in the Host Adapter structure.
1726       */
1727       if (HostAdapter->FirmwareVersion[0] == '5' ||
1728           (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
1729         HostAdapter->ExtendedLUNSupport = true;
1730       /*
1731         Issue the Inquire PCI Host Adapter Information command to read the
1732         Termination Information from "W" series MultiMaster Host Adapters.
1733       */
1734       if (HostAdapter->FirmwareVersion[0] == '5')
1735         {
1736           if (BusLogic_Command(HostAdapter,
1737     			   BusLogic_InquirePCIHostAdapterInformation,
1738     			   NULL, 0, &PCIHostAdapterInformation,
1739     			   sizeof(PCIHostAdapterInformation))
1740     	  != sizeof(PCIHostAdapterInformation))
1741     	return BusLogic_Failure(HostAdapter,
1742     				"INQUIRE PCI HOST ADAPTER INFORMATION");
1743           /*
1744     	Save the Termination Information in the Host Adapter structure.
1745           */
1746           if (PCIHostAdapterInformation.GenericInfoValid)
1747     	{
1748     	  HostAdapter->TerminationInfoValid = true;
1749     	  HostAdapter->LowByteTerminated =
1750     	    PCIHostAdapterInformation.LowByteTerminated;
1751     	  HostAdapter->HighByteTerminated =
1752     	    PCIHostAdapterInformation.HighByteTerminated;
1753     	}
1754         }
1755       /*
1756         Issue the Fetch Host Adapter Local RAM command to read the AutoSCSI data
1757         from "W" and "C" series MultiMaster Host Adapters.
1758       */
1759       if (HostAdapter->FirmwareVersion[0] >= '4')
1760         {
1761           FetchHostAdapterLocalRAMRequest.ByteOffset =
1762     	BusLogic_AutoSCSI_BaseOffset;
1763           FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData);
1764           if (BusLogic_Command(HostAdapter,
1765     			   BusLogic_FetchHostAdapterLocalRAM,
1766     			   &FetchHostAdapterLocalRAMRequest,
1767     			   sizeof(FetchHostAdapterLocalRAMRequest),
1768     			   &AutoSCSIData, sizeof(AutoSCSIData))
1769     	  != sizeof(AutoSCSIData))
1770     	return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM");
1771           /*
1772     	Save the Parity Checking Enabled, Bus Reset Enabled, and Termination
1773     	Information in the Host Adapter structure.
1774           */
1775           HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled;
1776           HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled;
1777           if (HostAdapter->FirmwareVersion[0] == '4')
1778     	{
1779     	  HostAdapter->TerminationInfoValid = true;
1780     	  HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated;
1781     	  HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated;
1782     	}
1783           /*
1784     	Save the Wide Permitted, Fast Permitted, Synchronous Permitted,
1785     	Disconnect Permitted, Ultra Permitted, and SCAM Information in the
1786     	Host Adapter structure.
1787           */
1788           HostAdapter->WidePermitted = AutoSCSIData.WidePermitted;
1789           HostAdapter->FastPermitted = AutoSCSIData.FastPermitted;
1790           HostAdapter->SynchronousPermitted =
1791     	AutoSCSIData.SynchronousPermitted;
1792           HostAdapter->DisconnectPermitted =
1793     	AutoSCSIData.DisconnectPermitted;
1794           if (HostAdapter->HostUltraSCSI)
1795     	HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted;
1796           if (HostAdapter->HostSupportsSCAM)
1797     	{
1798     	  HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled;
1799     	  HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2;
1800     	}
1801         }
1802       /*
1803         Initialize fields in the Host Adapter structure for "S" and "A" series
1804         MultiMaster Host Adapters.
1805       */
1806       if (HostAdapter->FirmwareVersion[0] < '4')
1807         {
1808           if (SetupInformation.SynchronousInitiationEnabled)
1809     	{
1810     	  HostAdapter->SynchronousPermitted = 0xFF;
1811     	  if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)
1812     	    {
1813     	      if (ExtendedSetupInformation.Misc.FastOnEISA)
1814     		HostAdapter->FastPermitted = 0xFF;
1815     	      if (strcmp(HostAdapter->ModelName, "BT-757") == 0)
1816     		HostAdapter->WidePermitted = 0xFF;
1817     	    }
1818     	}
1819           HostAdapter->DisconnectPermitted = 0xFF;
1820           HostAdapter->ParityCheckingEnabled =
1821     	SetupInformation.ParityCheckingEnabled;
1822           HostAdapter->BusResetEnabled = true;
1823         }
1824       /*
1825         Determine the maximum number of Target IDs and Logical Units supported by
1826         this driver for Wide and Narrow Host Adapters.
1827       */
1828       HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1829       HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8);
1830       /*
1831         Select appropriate values for the Mailbox Count, Driver Queue Depth,
1832         Initial CCBs, and Incremental CCBs variables based on whether or not Strict
1833         Round Robin Mode is supported.  If Strict Round Robin Mode is supported,
1834         then there is no performance degradation in using the maximum possible
1835         number of Outgoing and Incoming Mailboxes and allowing the Tagged and
1836         Untagged Queue Depths to determine the actual utilization.  If Strict Round
1837         Robin Mode is not supported, then the Host Adapter must scan all the
1838         Outgoing Mailboxes whenever an Outgoing Mailbox entry is made, which can
1839         cause a substantial performance penalty.  The host adapters actually have
1840         room to store the following number of CCBs internally; that is, they can
1841         internally queue and manage this many active commands on the SCSI bus
1842         simultaneously.  Performance measurements demonstrate that the Driver Queue
1843         Depth should be set to the Mailbox Count, rather than the Host Adapter
1844         Queue Depth (internal CCB capacity), as it is more efficient to have the
1845         queued commands waiting in Outgoing Mailboxes if necessary than to block
1846         the process in the higher levels of the SCSI Subsystem.
1847     
1848     	192	  BT-948/958/958D
1849     	100	  BT-946C/956C/956CD/747C/757C/757CD/445C
1850     	 50	  BT-545C/540CF
1851     	 30	  BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
1852       */
1853       if (HostAdapter->FirmwareVersion[0] == '5')
1854         HostAdapter->HostAdapterQueueDepth = 192;
1855       else if (HostAdapter->FirmwareVersion[0] == '4')
1856         HostAdapter->HostAdapterQueueDepth =
1857           (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50);
1858       else HostAdapter->HostAdapterQueueDepth = 30;
1859       if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0)
1860         {
1861           HostAdapter->StrictRoundRobinModeSupport = true;
1862           HostAdapter->MailboxCount = BusLogic_MaxMailboxes;
1863         }
1864       else
1865         {
1866           HostAdapter->StrictRoundRobinModeSupport = false;
1867           HostAdapter->MailboxCount = 32;
1868         }
1869       HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount;
1870       HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1871       HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1872       /*
1873         Tagged Queuing support is available and operates properly on all "W" series
1874         MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with
1875         firmware version 4.22 and above, and on "S" series MultiMaster Host
1876         Adapters with firmware version 3.35 and above.
1877       */
1878       HostAdapter->TaggedQueuingPermitted = 0;
1879       switch (HostAdapter->FirmwareVersion[0])
1880         {
1881         case '5':
1882           HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1883           break;
1884         case '4':
1885           if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
1886     	HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1887           break;
1888         case '3':
1889           if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
1890     	HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1891           break;
1892         }
1893       /*
1894         Determine the Host Adapter BIOS Address if the BIOS is enabled and
1895         save it in the Host Adapter structure.  The BIOS is disabled if the
1896         BIOS_Address is 0.
1897       */
1898       HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
1899       /*
1900         ISA Host Adapters require Bounce Buffers if there is more than 16MB memory.
1901       */
1902       if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus &&
1903           (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1904         HostAdapter->BounceBuffersRequired = true;
1905       /*
1906         BusLogic BT-445S Host Adapters prior to board revision E have a hardware
1907         bug whereby when the BIOS is enabled, transfers to/from the same address
1908         range the BIOS occupies modulo 16MB are handled incorrectly.  Only properly
1909         functioning BT-445S Host Adapters have firmware version 3.37, so require
1910         that ISA Bounce Buffers be used for the buggy BT-445S models if there is
1911         more than 16MB memory.
1912       */
1913       if (HostAdapter->BIOS_Address > 0 &&
1914           strcmp(HostAdapter->ModelName, "BT-445S") == 0 &&
1915           strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 &&
1916           (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1917         HostAdapter->BounceBuffersRequired = true;
1918       /*
1919         Initialize parameters common to MultiMaster and FlashPoint Host Adapters.
1920       */
1921     Common:
1922       /*
1923         Initialize the Host Adapter Full Model Name from the Model Name.
1924       */
1925       strcpy(HostAdapter->FullModelName, "BusLogic ");
1926       strcat(HostAdapter->FullModelName, HostAdapter->ModelName);
1927       /*
1928         Select an appropriate value for the Tagged Queue Depth either from a
1929         BusLogic Driver Options specification, or based on whether this Host
1930         Adapter requires that ISA Bounce Buffers be used.  The Tagged Queue Depth
1931         is left at 0 for automatic determination in BusLogic_SelectQueueDepths.
1932         Initialize the Untagged Queue Depth.
1933       */
1934       for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
1935         {
1936           unsigned char QueueDepth = 0;
1937           if (HostAdapter->DriverOptions != NULL &&
1938     	  HostAdapter->DriverOptions->QueueDepth[TargetID] > 0)
1939     	QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID];
1940           else if (HostAdapter->BounceBuffersRequired)
1941     	QueueDepth = BusLogic_TaggedQueueDepthBB;
1942           HostAdapter->QueueDepth[TargetID] = QueueDepth;
1943         }
1944       if (HostAdapter->BounceBuffersRequired)
1945         HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB;
1946       else HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
1947       if (HostAdapter->DriverOptions != NULL)
1948         HostAdapter->CommonQueueDepth =
1949           HostAdapter->DriverOptions->CommonQueueDepth;
1950       if (HostAdapter->CommonQueueDepth > 0 &&
1951           HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth)
1952         HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth;
1953       /*
1954         Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
1955         Therefore, mask the Tagged Queuing Permitted Default bits with the
1956         Disconnect/Reconnect Permitted bits.
1957       */
1958       HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted;
1959       /*
1960         Combine the default Tagged Queuing Permitted bits with any BusLogic Driver
1961         Options Tagged Queuing specification.
1962       */
1963       if (HostAdapter->DriverOptions != NULL)
1964         HostAdapter->TaggedQueuingPermitted =
1965           (HostAdapter->DriverOptions->TaggedQueuingPermitted &
1966            HostAdapter->DriverOptions->TaggedQueuingPermittedMask) |
1967           (HostAdapter->TaggedQueuingPermitted &
1968            ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask);
1969       /*
1970         Select appropriate values for the Error Recovery Strategy array
1971         either from a BusLogic Driver Options specification, or using
1972         BusLogic_ErrorRecovery_Default.
1973       */
1974       for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
1975         if (HostAdapter->DriverOptions != NULL)
1976           HostAdapter->ErrorRecoveryStrategy[TargetID] =
1977     	HostAdapter->DriverOptions->ErrorRecoveryStrategy[TargetID];
1978         else HostAdapter->ErrorRecoveryStrategy[TargetID] =
1979     	   BusLogic_ErrorRecovery_Default;
1980       /*
1981         Select an appropriate value for Bus Settle Time either from a BusLogic
1982         Driver Options specification, or from BusLogic_DefaultBusSettleTime.
1983       */
1984       if (HostAdapter->DriverOptions != NULL &&
1985           HostAdapter->DriverOptions->BusSettleTime > 0)
1986         HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime;
1987       else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
1988       /*
1989         Indicate reading the Host Adapter Configuration completed successfully.
1990       */
1991       return true;
1992     }
1993     
1994     
1995     /*
1996       BusLogic_ReportHostAdapterConfiguration reports the configuration of
1997       Host Adapter.
1998     */
1999     
2000     static boolean BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T
2001     						       *HostAdapter)
2002     {
2003       unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
2004       unsigned short SynchronousPermitted, FastPermitted;
2005       unsigned short UltraPermitted, WidePermitted;
2006       unsigned short DisconnectPermitted, TaggedQueuingPermitted;
2007       boolean CommonSynchronousNegotiation, CommonTaggedQueueDepth;
2008       boolean CommonErrorRecovery;
2009       char SynchronousString[BusLogic_MaxTargetDevices+1];
2010       char WideString[BusLogic_MaxTargetDevices+1];
2011       char DisconnectString[BusLogic_MaxTargetDevices+1];
2012       char TaggedQueuingString[BusLogic_MaxTargetDevices+1];
2013       char ErrorRecoveryString[BusLogic_MaxTargetDevices+1];
2014       char *SynchronousMessage = SynchronousString;
2015       char *WideMessage = WideString;
2016       char *DisconnectMessage = DisconnectString;
2017       char *TaggedQueuingMessage = TaggedQueuingString;
2018       char *ErrorRecoveryMessage = ErrorRecoveryString;
2019       int TargetID;
2020       BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n",
2021     		HostAdapter, HostAdapter->ModelName,
2022     		BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType],
2023     		(HostAdapter->HostWideSCSI ? " Wide" : ""),
2024     		(HostAdapter->HostDifferentialSCSI ? " Differential" : ""),
2025     		(HostAdapter->HostUltraSCSI ? " Ultra" : ""));
2026       BusLogic_Info("  Firmware Version: %s, I/O Address: 0x%X, "
2027     		"IRQ Channel: %d/%s\n", HostAdapter,
2028     		HostAdapter->FirmwareVersion,
2029     		HostAdapter->IO_Address, HostAdapter->IRQ_Channel,
2030     		(HostAdapter->LevelSensitiveInterrupt ? "Level" : "Edge"));
2031       if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus)
2032         {
2033           BusLogic_Info("  DMA Channel: ", HostAdapter);
2034           if (HostAdapter->DMA_Channel > 0)
2035     	BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel);
2036           else BusLogic_Info("None, ", HostAdapter);
2037           if (HostAdapter->BIOS_Address > 0)
2038     	BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter,
2039     		      HostAdapter->BIOS_Address);
2040           else BusLogic_Info("BIOS Address: None, ", HostAdapter);
2041         }
2042       else
2043         {
2044           BusLogic_Info("  PCI Bus: %d, Device: %d, Address: ",
2045     		    HostAdapter, HostAdapter->Bus, HostAdapter->Device);
2046           if (HostAdapter->PCI_Address > 0)
2047     	BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address);
2048           else BusLogic_Info("Unassigned, ", HostAdapter);
2049         }
2050       BusLogic_Info("Host Adapter SCSI ID: %d\n", HostAdapter,
2051     		HostAdapter->SCSI_ID);
2052       BusLogic_Info("  Parity Checking: %s, Extended Translation: %s\n",
2053     		HostAdapter,
2054     		(HostAdapter->ParityCheckingEnabled
2055     		 ? "Enabled" : "Disabled"),
2056     		(HostAdapter->ExtendedTranslationEnabled
2057     		 ? "Enabled" : "Disabled"));
2058       AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID);
2059       SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask;
2060       FastPermitted = HostAdapter->FastPermitted & AllTargetsMask;
2061       UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask;
2062       if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) &&
2063            (HostAdapter->FirmwareVersion[0] >= '4' ||
2064     	HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) ||
2065           BusLogic_FlashPointHostAdapterP(HostAdapter))
2066         {
2067           CommonSynchronousNegotiation = false;
2068           if (SynchronousPermitted == 0)
2069     	{
2070     	  SynchronousMessage = "Disabled";
2071     	  CommonSynchronousNegotiation = true;
2072     	}
2073           else if (SynchronousPermitted == AllTargetsMask)
2074     	{
2075     	  if (FastPermitted == 0)
2076     	    {
2077     	      SynchronousMessage = "Slow";
2078     	      CommonSynchronousNegotiation = true;
2079     	    }
2080     	  else if (FastPermitted == AllTargetsMask)
2081     	    {
2082     	      if (UltraPermitted == 0)
2083     		{
2084     		  SynchronousMessage = "Fast";
2085     		  CommonSynchronousNegotiation = true;
2086     		}
2087     	      else if (UltraPermitted == AllTargetsMask)
2088     		{
2089     		  SynchronousMessage = "Ultra";
2090     		  CommonSynchronousNegotiation = true;
2091     		}
2092     	    }
2093     	}
2094           if (!CommonSynchronousNegotiation)
2095     	{
2096     	  for (TargetID = 0;
2097     	       TargetID < HostAdapter->MaxTargetDevices;
2098     	       TargetID++)
2099     	    SynchronousString[TargetID] =
2100     	      ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' :
2101     	       (!(FastPermitted & (1 << TargetID)) ? 'S' :
2102     		(!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U')));
2103     	  SynchronousString[HostAdapter->SCSI_ID] = '#';
2104     	  SynchronousString[HostAdapter->MaxTargetDevices] = '\0';
2105     	}
2106         }
2107       else SynchronousMessage =
2108     	 (SynchronousPermitted == 0 ? "Disabled" : "Enabled");
2109       WidePermitted = HostAdapter->WidePermitted & AllTargetsMask;
2110       if (WidePermitted == 0)
2111         WideMessage = "Disabled";
2112       else if (WidePermitted == AllTargetsMask)
2113         WideMessage = "Enabled";
2114       else
2115         {
2116           for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2117     	 WideString[TargetID] =
2118     	   ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N');
2119           WideString[HostAdapter->SCSI_ID] = '#';
2120           WideString[HostAdapter->MaxTargetDevices] = '\0';
2121         }
2122       DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
2123       if (DisconnectPermitted == 0)
2124         DisconnectMessage = "Disabled";
2125       else if (DisconnectPermitted == AllTargetsMask)
2126         DisconnectMessage = "Enabled";
2127       else
2128         {
2129           for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2130     	DisconnectString[TargetID] =
2131     	  ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
2132           DisconnectString[HostAdapter->SCSI_ID] = '#';
2133           DisconnectString[HostAdapter->MaxTargetDevices] = '\0';
2134         }
2135       TaggedQueuingPermitted =
2136         HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
2137       if (TaggedQueuingPermitted == 0)
2138         TaggedQueuingMessage = "Disabled";
2139       else if (TaggedQueuingPermitted == AllTargetsMask)
2140         TaggedQueuingMessage = "Enabled";
2141       else
2142         {
2143           for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2144     	TaggedQueuingString[TargetID] =
2145     	  ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
2146           TaggedQueuingString[HostAdapter->SCSI_ID] = '#';
2147           TaggedQueuingString[HostAdapter->MaxTargetDevices] = '\0';
2148         }
2149       BusLogic_Info("  Synchronous Negotiation: %s, Wide Negotiation: %s\n",
2150     		HostAdapter, SynchronousMessage, WideMessage);
2151       BusLogic_Info("  Disconnect/Reconnect: %s, Tagged Queuing: %s\n",
2152     		HostAdapter, DisconnectMessage, TaggedQueuingMessage);
2153       if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
2154         {
2155           BusLogic_Info("  Scatter/Gather Limit: %d of %d segments, "
2156     		    "Mailboxes: %d\n", HostAdapter,
2157     		    HostAdapter->DriverScatterGatherLimit,
2158     		    HostAdapter->HostAdapterScatterGatherLimit,
2159     		    HostAdapter->MailboxCount);
2160           BusLogic_Info("  Driver Queue Depth: %d, "
2161     		    "Host Adapter Queue Depth: %d\n",
2162     		    HostAdapter, HostAdapter->DriverQueueDepth,
2163     		    HostAdapter->HostAdapterQueueDepth);
2164         }
2165       else BusLogic_Info("  Driver Queue Depth: %d, "
2166     		     "Scatter/Gather Limit: %d segments\n",
2167     		     HostAdapter, HostAdapter->DriverQueueDepth,
2168     		     HostAdapter->DriverScatterGatherLimit);
2169       BusLogic_Info("  Tagged Queue Depth: ", HostAdapter);
2170       CommonTaggedQueueDepth = true;
2171       for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2172         if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0])
2173           {
2174     	CommonTaggedQueueDepth = false;
2175     	break;
2176           }
2177       if (CommonTaggedQueueDepth)
2178         {
2179           if (HostAdapter->QueueDepth[0] > 0)
2180     	BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]);
2181           else BusLogic_Info("Automatic", HostAdapter);
2182         }
2183       else BusLogic_Info("Individual", HostAdapter);
2184       BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter,
2185     		HostAdapter->UntaggedQueueDepth);
2186       CommonErrorRecovery = true;
2187       for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2188         if (HostAdapter->ErrorRecoveryStrategy[TargetID] !=
2189     	HostAdapter->ErrorRecoveryStrategy[0])
2190           {
2191     	CommonErrorRecovery = false;
2192     	break;
2193           }
2194       if (CommonErrorRecovery)
2195         ErrorRecoveryMessage =
2196           BusLogic_ErrorRecoveryStrategyNames[
2197     	HostAdapter->ErrorRecoveryStrategy[0]];
2198       else
2199         {
2200           for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2201     	ErrorRecoveryString[TargetID] =
2202     	  BusLogic_ErrorRecoveryStrategyLetters[
2203     	    HostAdapter->ErrorRecoveryStrategy[TargetID]];
2204           ErrorRecoveryString[HostAdapter->SCSI_ID] = '#';
2205           ErrorRecoveryString[HostAdapter->MaxTargetDevices] = '\0';
2206         }
2207       BusLogic_Info("  Error Recovery Strategy: %s, SCSI Bus Reset: %s\n",
2208     		HostAdapter, ErrorRecoveryMessage,
2209     		(HostAdapter->BusResetEnabled ? "Enabled" : "Disabled"));
2210       if (HostAdapter->TerminationInfoValid)
2211         {
2212           if (HostAdapter->HostWideSCSI)
2213     	BusLogic_Info("  SCSI Bus Termination: %s", HostAdapter,
2214     		      (HostAdapter->LowByteTerminated
2215     		       ? (HostAdapter->HighByteTerminated
2216     			  ? "Both Enabled" : "Low Enabled")
2217     		       : (HostAdapter->HighByteTerminated
2218     			  ? "High Enabled" : "Both Disabled")));
2219           else BusLogic_Info("  SCSI Bus Termination: %s", HostAdapter,
2220     			 (HostAdapter->LowByteTerminated ?
2221     			  "Enabled" : "Disabled"));
2222           if (HostAdapter->HostSupportsSCAM)
2223     	BusLogic_Info(", SCAM: %s", HostAdapter,
2224     		      (HostAdapter->SCAM_Enabled
2225     		       ? (HostAdapter->SCAM_Level2
2226     			  ? "Enabled, Level 2" : "Enabled, Level 1")
2227     		       : "Disabled"));
2228           BusLogic_Info("\n", HostAdapter);
2229         }
2230       /*
2231         Indicate reporting the Host Adapter configuration completed successfully.
2232       */
2233       return true;
2234     }
2235     
2236     
2237     /*
2238       BusLogic_AcquireResources acquires the system resources necessary to use
2239       Host Adapter.
2240     */
2241     
2242     static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter)
2243     {
2244       if (HostAdapter->IRQ_Channel == 0)
2245         {
2246           BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
2247     		     HostAdapter);
2248           return false;
2249         }
2250       /*
2251         Acquire shared access to the IRQ Channel.
2252       */
2253       if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
2254     		  SA_SHIRQ, HostAdapter->FullModelName, HostAdapter) < 0)
2255         {
2256           BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
2257     		     HostAdapter, HostAdapter->IRQ_Channel);
2258           return false;
2259         }
2260       HostAdapter->IRQ_ChannelAcquired = true;
2261       /*
2262         Acquire exclusive access to the DMA Channel.
2263       */
2264       if (HostAdapter->DMA_Channel > 0)
2265         {
2266           if (request_dma(HostAdapter->DMA_Channel,
2267     		      HostAdapter->FullModelName) < 0)
2268     	{
2269     	  BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n",
2270     			 HostAdapter, HostAdapter->DMA_Channel);
2271     	  return false;
2272     	}
2273           set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
2274           enable_dma(HostAdapter->DMA_Channel);
2275           HostAdapter->DMA_ChannelAcquired = true;
2276         }
2277       /*
2278         Indicate the System Resource Acquisition completed successfully,
2279       */
2280       return true;
2281     }
2282     
2283     
2284     /*
2285       BusLogic_ReleaseResources releases any system resources previously acquired
2286       by BusLogic_AcquireResources.
2287     */
2288     
2289     static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter)
2290     {
2291       /*
2292         Release shared access to the IRQ Channel.
2293       */
2294       if (HostAdapter->IRQ_ChannelAcquired)
2295         free_irq(HostAdapter->IRQ_Channel, HostAdapter);
2296       /*
2297         Release exclusive access to the DMA Channel.
2298       */
2299       if (HostAdapter->DMA_ChannelAcquired)
2300         free_dma(HostAdapter->DMA_Channel);
2301     }
2302     
2303     
2304     /*
2305       BusLogic_InitializeHostAdapter initializes Host Adapter.  This is the only
2306       function called during SCSI Host Adapter detection which modifies the state
2307       of the Host Adapter from its initial power on or hard reset state.
2308     */
2309     
2310     static boolean BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T
2311     					      *HostAdapter)
2312     {
2313       BusLogic_ExtendedMailboxRequest_T ExtendedMailboxRequest;
2314       BusLogic_RoundRobinModeRequest_T RoundRobinModeRequest;
2315       BusLogic_SetCCBFormatRequest_T SetCCBFormatRequest;
2316       int TargetID;
2317       /*
2318         Initialize the pointers to the first and last CCBs that are queued for
2319         completion processing.
2320       */
2321       HostAdapter->FirstCompletedCCB = NULL;
2322       HostAdapter->LastCompletedCCB = NULL;
2323       /*
2324         Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
2325         Command Successful Flag, Active Commands, and Commands Since Reset
2326         for each Target Device.
2327       */
2328       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2329         {
2330           HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
2331           HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
2332           HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
2333           HostAdapter->ActiveCommands[TargetID] = 0;
2334           HostAdapter->CommandsSinceReset[TargetID] = 0;
2335         }
2336       /*
2337         FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
2338       */
2339       if (BusLogic_FlashPointHostAdapterP(HostAdapter)) goto Done;
2340       /*
2341         Initialize the Outgoing and Incoming Mailbox pointers.
2342       */
2343       HostAdapter->FirstOutgoingMailbox =
2344         (BusLogic_OutgoingMailbox_T *) HostAdapter->MailboxSpace;
2345       HostAdapter->LastOutgoingMailbox =
2346         HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
2347       HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
2348       HostAdapter->FirstIncomingMailbox =
2349         (BusLogic_IncomingMailbox_T *) (HostAdapter->LastOutgoingMailbox + 1);
2350       HostAdapter->LastIncomingMailbox =
2351         HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
2352       HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
2353       /*
2354         Initialize the Outgoing and Incoming Mailbox structures.
2355       */
2356       memset(HostAdapter->FirstOutgoingMailbox, 0,
2357     	 HostAdapter->MailboxCount * sizeof(BusLogic_OutgoingMailbox_T));
2358       memset(HostAdapter->FirstIncomingMailbox, 0,
2359     	 HostAdapter->MailboxCount * sizeof(BusLogic_IncomingMailbox_T));
2360       /*
2361         Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
2362       */
2363       ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
2364       ExtendedMailboxRequest.BaseMailboxAddress =
2365         Virtual_to_Bus(HostAdapter->FirstOutgoingMailbox);
2366       if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox,
2367     		       &ExtendedMailboxRequest,
2368     		       sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
2369         return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
2370       /*
2371         Enable Strict Round Robin Mode if supported by the Host Adapter.  In
2372         Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing
2373         Mailbox for each new command, rather than scanning through all the
2374         Outgoing Mailboxes to find any that have new commands in them.  Strict
2375         Round Robin Mode is significantly more efficient.
2376       */
2377       if (HostAdapter->StrictRoundRobinModeSupport)
2378         {
2379           RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
2380           if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode,
2381     			   &RoundRobinModeRequest,
2382     			   sizeof(RoundRobinModeRequest), NULL, 0) < 0)
2383     	return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
2384         }
2385       /*
2386         For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB
2387         Format command to allow 32 Logical Units per Target Device.
2388       */
2389       if (HostAdapter->ExtendedLUNSupport)
2390         {
2391           SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB;
2392           if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat,
2393     			   &SetCCBFormatRequest, sizeof(SetCCBFormatRequest),
2394     			   NULL, 0) < 0)
2395     	return BusLogic_Failure(HostAdapter, "SET CCB FORMAT");
2396         }
2397       /*
2398         Announce Successful Initialization.
2399       */
2400     Done:
2401       if (!HostAdapter->HostAdapterInitialized)
2402         {
2403           BusLogic_Info("*** %s Initialized Successfully ***\n",
2404     		    HostAdapter, HostAdapter->FullModelName);
2405           BusLogic_Info("\n", HostAdapter);
2406         }
2407       else BusLogic_Warning("*** %s Initialized Successfully ***\n",
2408     			HostAdapter, HostAdapter->FullModelName);
2409       HostAdapter->HostAdapterInitialized = true;
2410       /*
2411         Indicate the Host Adapter Initialization completed successfully.
2412       */
2413       return true;
2414     }
2415     
2416     
2417     /*
2418       BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
2419       through Host Adapter.
2420     */
2421     
2422     static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T
2423     					    *HostAdapter)
2424     {
2425       BusLogic_InstalledDevices_T InstalledDevices;
2426       BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
2427       BusLogic_SetupInformation_T SetupInformation;
2428       BusLogic_SynchronousPeriod_T SynchronousPeriod;
2429       BusLogic_RequestedReplyLength_T RequestedReplyLength;
2430       int TargetID;
2431       /*
2432         Wait a few seconds between the Host Adapter Hard Reset which initiates
2433         a SCSI Bus Reset and issuing any SCSI Commands.  Some SCSI devices get
2434         confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
2435       */
2436       BusLogic_Delay(HostAdapter->BusSettleTime);
2437       /*
2438         FlashPoint Host Adapters do not provide for Target Device Inquiry.
2439       */
2440       if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
2441       /*
2442         Inhibit the Target Device Inquiry if requested.
2443       */
2444       if (HostAdapter->DriverOptions != NULL &&
2445           HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
2446         return true;
2447       /*
2448         Issue the Inquire Target Devices command for host adapters with firmware
2449         version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command
2450         for older host adapters.  This is necessary to force Synchronous Transfer
2451         Negotiation so that the Inquire Setup Information and Inquire Synchronous
2452         Period commands will return valid data.  The Inquire Target Devices command
2453         is preferable to Inquire Installed Devices ID 0 to 7 since it only probes
2454         Logical Unit 0 of each Target Device.
2455       */
2456       if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0)
2457         {
2458           if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0,
2459     			   &InstalledDevices, sizeof(InstalledDevices))
2460     	  != sizeof(InstalledDevices))
2461     	return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES");
2462           for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2463     	HostAdapter->TargetFlags[TargetID].TargetExists =
2464     	  (InstalledDevices & (1 << TargetID) ? true : false);
2465         }
2466       else
2467         {
2468           if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7,
2469     			   NULL, 0, &InstalledDevicesID0to7,
2470     			   sizeof(InstalledDevicesID0to7))
2471     	  != sizeof(InstalledDevicesID0to7))
2472     	return BusLogic_Failure(HostAdapter,
2473     				"INQUIRE INSTALLED DEVICES ID 0 TO 7");
2474           for (TargetID = 0; TargetID < 8; TargetID++)
2475     	HostAdapter->TargetFlags[TargetID].TargetExists =
2476     	  (InstalledDevicesID0to7[TargetID] != 0 ? true : false);
2477         }
2478       /*
2479         Issue the Inquire Setup Information command.
2480       */
2481       RequestedReplyLength = sizeof(SetupInformation);
2482       if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
2483     		       &RequestedReplyLength, sizeof(RequestedReplyLength),
2484     		       &SetupInformation, sizeof(SetupInformation))
2485           != sizeof(SetupInformation))
2486         return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
2487       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2488           HostAdapter->SynchronousOffset[TargetID] =
2489     	(TargetID < 8
2490     	 ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset
2491     	 : SetupInformation.SynchronousValuesID8to15[TargetID-8].Offset);
2492       if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0)
2493         for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2494           HostAdapter->TargetFlags[TargetID].WideTransfersActive =
2495     	(TargetID < 8
2496     	 ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID)
2497     	    ? true : false)
2498     	 : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID-8))
2499     	    ? true : false));
2500       /*
2501         Issue the Inquire Synchronous Period command.
2502       */
2503       if (HostAdapter->FirmwareVersion[0] >= '3')
2504         {
2505           RequestedReplyLength = sizeof(SynchronousPeriod);
2506           if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod,
2507     			   &RequestedReplyLength, sizeof(RequestedReplyLength),
2508     			   &SynchronousPeriod, sizeof(SynchronousPeriod))
2509     	  != sizeof(SynchronousPeriod))
2510     	return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
2511           for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2512     	HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
2513         }
2514       else
2515         for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2516           if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
2517     	HostAdapter->SynchronousPeriod[TargetID] =
2518     	  20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
2519     				   .TransferPeriod;
2520       /*
2521         Indicate the Target Device Inquiry completed successfully.
2522       */
2523       return true;
2524     }
2525     
2526     
2527     /*
2528       BusLogic_ReportTargetDeviceInfo reports about the Target Devices accessible
2529       through Host Adapter.
2530     */
2531     
2532     static void BusLogic_ReportTargetDeviceInfo(BusLogic_HostAdapter_T
2533     					    *HostAdapter)
2534     {
2535       int TargetID;
2536       /*
2537         Inhibit the Target Device Inquiry and Reporting if requested.
2538       */
2539       if (BusLogic_MultiMasterHostAdapterP(HostAdapter) &&
2540           HostAdapter->DriverOptions != NULL &&
2541           HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
2542         return;
2543       /*
2544         Report on the Target Devices found.
2545       */
2546       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2547         {
2548           BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
2549           if (TargetFlags->TargetExists && !TargetFlags->TargetInfoReported)
2550     	{
2551     	  int SynchronousTransferRate = 0;
2552     	  if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2553     	    {
2554     	      unsigned char WideTransfersActive;
2555     	      FlashPoint_InquireTargetInfo(
2556     		HostAdapter->CardHandle, TargetID,
2557     		&HostAdapter->SynchronousPeriod[TargetID],
2558     		&HostAdapter->SynchronousOffset[TargetID],
2559     		&WideTransfersActive);
2560     	      TargetFlags->WideTransfersActive = WideTransfersActive;
2561     	    }
2562     	  else if (TargetFlags->WideTransfersSupported &&
2563     		   (HostAdapter->WidePermitted & (1 << TargetID)) &&
2564     		   strcmp(HostAdapter->FirmwareVersion, "5.06L") < 0)
2565     	    TargetFlags->WideTransfersActive = true;
2566     	  if (HostAdapter->SynchronousPeriod[TargetID] > 0)
2567     	    SynchronousTransferRate =
2568     	      100000 / HostAdapter->SynchronousPeriod[TargetID];
2569     	  if (TargetFlags->WideTransfersActive)
2570     	    SynchronousTransferRate <<= 1;
2571     	  if (SynchronousTransferRate >= 9950)
2572     	    {
2573     	      SynchronousTransferRate = (SynchronousTransferRate + 50) / 100;
2574     	      BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at "
2575     			    "%d.%01d MB/sec, offset %d\n",
2576     			    HostAdapter, TargetID,
2577     			    HostAdapter->QueueDepth[TargetID],
2578     			    (TargetFlags->WideTransfersActive ? "Wide " : ""),
2579     			    SynchronousTransferRate / 10,
2580     			    SynchronousTransferRate % 10,
2581     			    HostAdapter->SynchronousOffset[TargetID]);
2582     	    }
2583     	  else if (SynchronousTransferRate > 0)
2584     	    {
2585     	      SynchronousTransferRate = (SynchronousTransferRate + 5) / 10;
2586     	      BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at "
2587     			    "%d.%02d MB/sec, offset %d\n",
2588     			    HostAdapter, TargetID,
2589     			    HostAdapter->QueueDepth[TargetID],
2590     			    (TargetFlags->WideTransfersActive ? "Wide " : ""),
2591     			    SynchronousTransferRate / 100,
2592     			    SynchronousTransferRate % 100,
2593     			    HostAdapter->SynchronousOffset[TargetID]);
2594     	    }
2595     	  else BusLogic_Info("Target %d: Queue Depth %d, Asynchronous\n",
2596     			     HostAdapter, TargetID,
2597     			     HostAdapter->QueueDepth[TargetID]);
2598     	  TargetFlags->TargetInfoReported = true;
2599     	}
2600         }
2601     }
2602     
2603     
2604     /*
2605       BusLogic_InitializeHostStructure initializes the fields in the SCSI Host
2606       structure.  The base, io_port, n_io_ports, irq, and dma_channel fields in the
2607       SCSI Host structure are intentionally left uninitialized, as this driver
2608       handles acquisition and release of these resources explicitly, as well as
2609       ensuring exclusive access to the Host Adapter hardware and data structures
2610       through explicit acquisition and release of the Host Adapter's Lock.
2611     */
2612     
2613     static void BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T
2614     					       *HostAdapter,
2615     					     SCSI_Host_T *Host)
2616     {
2617       Host->max_id = HostAdapter->MaxTargetDevices;
2618       Host->max_lun = HostAdapter->MaxLogicalUnits;
2619       Host->max_channel = 0;
2620       Host->unique_id = HostAdapter->IO_Address;
2621       Host->this_id = HostAdapter->SCSI_ID;
2622       Host->can_queue = HostAdapter->DriverQueueDepth;
2623       Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
2624       Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
2625       Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
2626     }
2627     
2628     
2629     /*
2630       BusLogic_SelectQueueDepths selects Queue Depths for each Target Device based
2631       on the Host Adapter's Total Queue Depth and the number, type, speed, and
2632       capabilities of the Target Devices.  When called for the last Host Adapter,
2633       it reports on the Target Device Information for all BusLogic Host Adapters
2634       since all the Target Devices have now been probed.
2635     */
2636     
2637     static void BusLogic_SelectQueueDepths(SCSI_Host_T *Host,
2638     				       SCSI_Device_T *DeviceList)
2639     {
2640       BusLogic_HostAdapter_T *HostAdapter =
2641         (BusLogic_HostAdapter_T *) Host->hostdata;
2642       int TaggedDeviceCount = 0, AutomaticTaggedDeviceCount = 0;
2643       int UntaggedDeviceCount = 0, AutomaticTaggedQueueDepth = 0;
2644       int AllocatedQueueDepth = 0;
2645       SCSI_Device_T *Device;
2646       int TargetID;
2647       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2648         if (HostAdapter->TargetFlags[TargetID].TargetExists)
2649           {
2650     	int QueueDepth = HostAdapter->QueueDepth[TargetID];
2651     	if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported &&
2652     	    (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
2653     	  {
2654     	    TaggedDeviceCount++;
2655     	    if (QueueDepth == 0) AutomaticTaggedDeviceCount++;
2656     	  }
2657     	else
2658     	  {
2659     	    UntaggedDeviceCount++;
2660     	    if (QueueDepth == 0 ||
2661     		QueueDepth > HostAdapter->UntaggedQueueDepth)
2662     	      {
2663     		QueueDepth = HostAdapter->UntaggedQueueDepth;
2664     		HostAdapter->QueueDepth[TargetID] = QueueDepth;
2665     	      }
2666     	  }
2667     	AllocatedQueueDepth += QueueDepth;
2668     	if (QueueDepth == 1)
2669     	  HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
2670           }
2671       HostAdapter->TargetDeviceCount = TaggedDeviceCount + UntaggedDeviceCount;
2672       if (AutomaticTaggedDeviceCount > 0)
2673         {
2674           AutomaticTaggedQueueDepth =
2675     	(HostAdapter->HostAdapterQueueDepth - AllocatedQueueDepth)
2676     	/ AutomaticTaggedDeviceCount;
2677           if (AutomaticTaggedQueueDepth > BusLogic_MaxAutomaticTaggedQueueDepth)
2678     	AutomaticTaggedQueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth;
2679           if (AutomaticTaggedQueueDepth < BusLogic_MinAutomaticTaggedQueueDepth)
2680     	AutomaticTaggedQueueDepth = BusLogic_MinAutomaticTaggedQueueDepth;
2681           for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2682     	if (HostAdapter->TargetFlags[TargetID].TargetExists &&
2683     	    HostAdapter->QueueDepth[TargetID] == 0)
2684     	  {
2685     	    AllocatedQueueDepth += AutomaticTaggedQueueDepth;
2686     	    HostAdapter->QueueDepth[TargetID] = AutomaticTaggedQueueDepth;
2687     	  }
2688         }
2689       for (Device = DeviceList; Device != NULL; Device = Device->next)
2690         if (Device->host == Host)
2691           Device->queue_depth = HostAdapter->QueueDepth[Device->id];
2692       /* Allocate an extra CCB for each Target Device for a Bus Device Reset. */
2693       AllocatedQueueDepth += HostAdapter->TargetDeviceCount;
2694       if (AllocatedQueueDepth > HostAdapter->DriverQueueDepth)
2695         AllocatedQueueDepth = HostAdapter->DriverQueueDepth;
2696       BusLogic_CreateAdditionalCCBs(HostAdapter,
2697     				AllocatedQueueDepth
2698     				- HostAdapter->AllocatedCCBs,
2699     				false);
2700       if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
2701         for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
2702     	 HostAdapter != NULL;
2703     	 HostAdapter = HostAdapter->Next)
2704           BusLogic_ReportTargetDeviceInfo(HostAdapter);
2705     }
2706     
2707     
2708     /*
2709       BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
2710       I/O Addresses where they may be located, initializing, registering, and
2711       reporting the configuration of each BusLogic Host Adapter it finds.  It
2712       returns the number of BusLogic Host Adapters successfully initialized and
2713       registered.
2714     */
2715     
2716     int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate)
2717     {
2718       int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex;
2719       BusLogic_HostAdapter_T *PrototypeHostAdapter;
2720       if (BusLogic_ProbeOptions.NoProbe) return 0;
2721       BusLogic_ProbeInfoList = (BusLogic_ProbeInfo_T *)
2722         kmalloc(BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T),
2723     	    GFP_ATOMIC);
2724       if (BusLogic_ProbeInfoList == NULL)
2725         {
2726           BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL);
2727           return 0;
2728         }
2729       memset(BusLogic_ProbeInfoList, 0,
2730     	 BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T));
2731       PrototypeHostAdapter = (BusLogic_HostAdapter_T *)
2732         kmalloc(sizeof(BusLogic_HostAdapter_T), GFP_ATOMIC);
2733       if (PrototypeHostAdapter == NULL)
2734         {
2735           kfree(BusLogic_ProbeInfoList);
2736           BusLogic_Error("BusLogic: Unable to allocate Prototype "
2737     		     "Host Adapter\n", NULL);
2738           return 0;
2739         }
2740       memset(PrototypeHostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
2741     #ifdef MODULE
2742       if (BusLogic != NULL)
2743         BusLogic_Setup(BusLogic);
2744     #endif
2745       BusLogic_InitializeProbeInfoList(PrototypeHostAdapter);
2746       for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++)
2747         {
2748           BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex];
2749           BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
2750           SCSI_Host_T *Host;
2751           if (ProbeInfo->IO_Address == 0) continue;
2752           memset(HostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
2753           HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType;
2754           HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType;
2755           HostAdapter->IO_Address = ProbeInfo->IO_Address;
2756           HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
2757           HostAdapter->Bus = ProbeInfo->Bus;
2758           HostAdapter->Device = ProbeInfo->Device;
2759           HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
2760           HostAdapter->AddressCount =
2761     	BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
2762           /*
2763     	Probe the Host Adapter.  If unsuccessful, abort further initialization.
2764           */
2765           if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue;
2766           /*
2767     	Hard Reset the Host Adapter.  If unsuccessful, abort further
2768     	initialization.
2769           */
2770           if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) continue;
2771           /*
2772     	Check the Host Adapter.  If unsuccessful, abort further initialization.
2773           */
2774           if (!BusLogic_CheckHostAdapter(HostAdapter)) continue;
2775           /*
2776     	Initialize the Driver Options field if provided.
2777           */
2778           if (DriverOptionsIndex < BusLogic_DriverOptionsCount)
2779     	HostAdapter->DriverOptions =
2780     	  &BusLogic_DriverOptions[DriverOptionsIndex++];
2781           /*
2782     	Announce the Driver Version and Date, Author's Name, Copyright Notice,
2783     	and Electronic Mail Address.
2784           */
2785           BusLogic_AnnounceDriver(HostAdapter);
2786           /*
2787     	Register usage of the I/O Address range.  From this point onward, any
2788     	failure will be assumed to be due to a problem with the Host Adapter,
2789     	rather than due to having mistakenly identified this port as belonging
2790     	to a BusLogic Host Adapter.  The I/O Address range will not be
2791     	released, thereby preventing it from being incorrectly identified as
2792     	any other type of Host Adapter.
2793           */
2794           request_region(HostAdapter->IO_Address, HostAdapter->AddressCount,
2795     		     "BusLogic");
2796           /*
2797     	Register the SCSI Host structure.
2798           */
2799           Host = scsi_register(HostTemplate, sizeof(BusLogic_HostAdapter_T));
2800           if(Host==NULL)
2801           {
2802           	release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2803           	continue;
2804           }
2805           HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata;
2806           memcpy(HostAdapter, PrototypeHostAdapter, sizeof(BusLogic_HostAdapter_T));
2807           HostAdapter->SCSI_Host = Host;
2808           HostAdapter->HostNumber = Host->host_no;
2809           Host->select_queue_depths = BusLogic_SelectQueueDepths;
2810           /*
2811     	Add Host Adapter to the end of the list of registered BusLogic
2812     	Host Adapters.
2813           */
2814           BusLogic_RegisterHostAdapter(HostAdapter);
2815           /*
2816     	Read the Host Adapter Configuration, Configure the Host Adapter,
2817     	Acquire the System Resources necessary to use the Host Adapter, then
2818     	Create the Initial CCBs, Initialize the Host Adapter, and finally
2819     	perform Target Device Inquiry.
2820           */
2821           if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
2822     	  BusLogic_ReportHostAdapterConfiguration(HostAdapter) &&
2823     	  BusLogic_AcquireResources(HostAdapter) &&
2824     	  BusLogic_CreateInitialCCBs(HostAdapter) &&
2825     	  BusLogic_InitializeHostAdapter(HostAdapter) &&
2826     	  BusLogic_TargetDeviceInquiry(HostAdapter))
2827     	{
2828     	  /*
2829     	    Initialization has been completed successfully.  Release and
2830     	    re-register usage of the I/O Address range so that the Model
2831     	    Name of the Host Adapter will appear, and initialize the SCSI
2832     	    Host structure.
2833     	  */
2834     	  release_region(HostAdapter->IO_Address,
2835     			 HostAdapter->AddressCount);
2836     	  request_region(HostAdapter->IO_Address,
2837     			 HostAdapter->AddressCount,
2838     			 HostAdapter->FullModelName);
2839     	  BusLogic_InitializeHostStructure(HostAdapter, Host);
2840     	  BusLogicHostAdapterCount++;
2841     	}
2842           else
2843     	{
2844     	  /*
2845     	    An error occurred during Host Adapter Configuration Querying, Host
2846     	    Adapter Configuration, Resource Acquisition, CCB Creation, Host
2847     	    Adapter Initialization, or Target Device Inquiry, so remove Host
2848     	    Adapter from the list of registered BusLogic Host Adapters, destroy
2849     	    the CCBs, Release the System Resources, and Unregister the SCSI
2850     	    Host.
2851     	  */
2852     	  BusLogic_DestroyCCBs(HostAdapter);
2853     	  BusLogic_ReleaseResources(HostAdapter);
2854     	  BusLogic_UnregisterHostAdapter(HostAdapter);
2855     	  scsi_unregister(Host);
2856     	}
2857         }
2858       kfree(PrototypeHostAdapter);
2859       kfree(BusLogic_ProbeInfoList);
2860       BusLogic_ProbeInfoList = NULL;
2861       return BusLogicHostAdapterCount;
2862     }
2863     
2864     
2865     /*
2866       BusLogic_ReleaseHostAdapter releases all resources previously acquired to
2867       support a specific Host Adapter, including the I/O Address range, and
2868       unregisters the BusLogic Host Adapter.
2869     */
2870     
2871     int BusLogic_ReleaseHostAdapter(SCSI_Host_T *Host)
2872     {
2873       BusLogic_HostAdapter_T *HostAdapter =
2874         (BusLogic_HostAdapter_T *) Host->hostdata;
2875       /*
2876         FlashPoint Host Adapters must first be released by the FlashPoint
2877         SCCB Manager.
2878       */
2879       if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2880         FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle);
2881       /*
2882         Destroy the CCBs and release any system resources acquired to
2883         support Host Adapter.
2884       */
2885       BusLogic_DestroyCCBs(HostAdapter);
2886       BusLogic_ReleaseResources(HostAdapter);
2887       /*
2888         Release usage of the I/O Address range.
2889       */
2890       release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2891       /*
2892         Remove Host Adapter from the list of registered BusLogic Host Adapters.
2893       */
2894       BusLogic_UnregisterHostAdapter(HostAdapter);
2895       return 0;
2896     }
2897     
2898     
2899     /*
2900       BusLogic_QueueCompletedCCB queues CCB for completion processing.
2901     */
2902     
2903     static void BusLogic_QueueCompletedCCB(BusLogic_CCB_T *CCB)
2904     {
2905       BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
2906       CCB->Status = BusLogic_CCB_Completed;
2907       CCB->Next = NULL;
2908       if (HostAdapter->FirstCompletedCCB == NULL)
2909         {
2910           HostAdapter->FirstCompletedCCB = CCB;
2911           HostAdapter->LastCompletedCCB = CCB;
2912         }
2913       else
2914         {
2915           HostAdapter->LastCompletedCCB->Next = CCB;
2916           HostAdapter->LastCompletedCCB = CCB;
2917         }
2918       HostAdapter->ActiveCommands[CCB->TargetID]--;
2919     }
2920     
2921     
2922     /*
2923       BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from
2924       the Host Adapter Status and Target Device Status.
2925     */
2926     
2927     static int BusLogic_ComputeResultCode(BusLogic_HostAdapter_T *HostAdapter,
2928     				      BusLogic_HostAdapterStatus_T
2929     					HostAdapterStatus,
2930     				      BusLogic_TargetDeviceStatus_T
2931     					TargetDeviceStatus)
2932     {
2933       int HostStatus;
2934       switch (HostAdapterStatus)
2935         {
2936         case BusLogic_CommandCompletedNormally:
2937         case BusLogic_LinkedCommandCompleted:
2938         case BusLogic_LinkedCommandCompletedWithFlag:
2939           HostStatus = DID_OK;
2940           break;
2941         case BusLogic_SCSISelectionTimeout:
2942           HostStatus = DID_TIME_OUT;
2943           break;
2944         case BusLogic_InvalidOutgoingMailboxActionCode:
2945         case BusLogic_InvalidCommandOperationCode:
2946         case BusLogic_InvalidCommandParameter:
2947           BusLogic_Warning("BusLogic Driver Protocol Error 0x%02X\n",
2948     		       HostAdapter, HostAdapterStatus);
2949         case BusLogic_DataUnderRun:
2950         case BusLogic_DataOverRun:
2951         case BusLogic_UnexpectedBusFree:
2952         case BusLogic_LinkedCCBhasInvalidLUN:
2953         case BusLogic_AutoRequestSenseFailed:
2954         case BusLogic_TaggedQueuingMessageRejected:
2955         case BusLogic_UnsupportedMessageReceived:
2956         case BusLogic_HostAdapterHardwareFailed:
2957         case BusLogic_TargetDeviceReconnectedImproperly:
2958         case BusLogic_AbortQueueGenerated:
2959         case BusLogic_HostAdapterSoftwareError:
2960         case BusLogic_HostAdapterHardwareTimeoutError:
2961         case BusLogic_SCSIParityErrorDetected:
2962           HostStatus = DID_ERROR;
2963           break;
2964         case BusLogic_InvalidBusPhaseRequested:
2965         case BusLogic_TargetFailedResponseToATN:
2966         case BusLogic_HostAdapterAssertedRST:
2967         case BusLogic_OtherDeviceAssertedRST:
2968         case BusLogic_HostAdapterAssertedBusDeviceReset:
2969           HostStatus = DID_RESET;
2970           break;
2971         default:
2972           BusLogic_Warning("Unknown Host Adapter Status 0x%02X\n",
2973     		       HostAdapter, HostAdapterStatus);
2974           HostStatus = DID_ERROR;
2975           break;
2976         }
2977       return (HostStatus << 16) | TargetDeviceStatus;
2978     }
2979     
2980     
2981     /*
2982       BusLogic_ScanIncomingMailboxes scans the Incoming Mailboxes saving any
2983       Incoming Mailbox entries for completion processing.
2984     */
2985     
2986     static void BusLogic_ScanIncomingMailboxes(BusLogic_HostAdapter_T *HostAdapter)
2987     {
2988       /*
2989         Scan through the Incoming Mailboxes in Strict Round Robin fashion, saving
2990         any completed CCBs for further processing.  It is essential that for each
2991         CCB and SCSI Command issued, command completion processing is performed
2992         exactly once.  Therefore, only Incoming Mailboxes with completion code
2993         Command Completed Without Error, Command Completed With Error, or Command
2994         Aborted At Host Request are saved for completion processing.  When an
2995         Incoming Mailbox has a completion code of Aborted Command Not Found, the
2996         CCB had already completed or been aborted before the current Abort request
2997         was processed, and so completion processing has already occurred and no
2998         further action should be taken.
2999       */
3000       BusLogic_IncomingMailbox_T *NextIncomingMailbox =
3001         HostAdapter->NextIncomingMailbox;
3002       BusLogic_CompletionCode_T CompletionCode;
3003       while ((CompletionCode = NextIncomingMailbox->CompletionCode) !=
3004     	 BusLogic_IncomingMailboxFree)
3005         {
3006           BusLogic_CCB_T *CCB = (BusLogic_CCB_T *)
3007     	Bus_to_Virtual(NextIncomingMailbox->CCB);
3008           if (CompletionCode != BusLogic_AbortedCommandNotFound)
3009     	{
3010     	  if (CCB->Status == BusLogic_CCB_Active ||
3011     	      CCB->Status == BusLogic_CCB_Reset)
3012     	    {
3013     	      /*
3014     		Save the Completion Code for this CCB and queue the CCB
3015     		for completion processing.
3016     	      */
3017     	      CCB->CompletionCode = CompletionCode;
3018     	      BusLogic_QueueCompletedCCB(CCB);
3019     	    }
3020     	  else
3021     	    {
3022     	      /*
3023     		If a CCB ever appears in an Incoming Mailbox and is not marked
3024     		as status Active or Reset, then there is most likely a bug in
3025     		the Host Adapter firmware.
3026     	      */
3027     	      BusLogic_Warning("Illegal CCB #%ld status %d in "
3028     			       "Incoming Mailbox\n", HostAdapter,
3029     			       CCB->SerialNumber, CCB->Status);
3030     	    }
3031     	}
3032           NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree;
3033           if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
3034     	NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
3035         }
3036       HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
3037     }
3038     
3039     
3040     /*
3041       BusLogic_ProcessCompletedCCBs iterates over the completed CCBs for Host
3042       Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
3043       calling the SCSI Subsystem Completion Routines.  The Host Adapter's Lock
3044       should already have been acquired by the caller.
3045     */
3046     
3047     static void BusLogic_ProcessCompletedCCBs(BusLogic_HostAdapter_T *HostAdapter)
3048     {
3049       if (HostAdapter->ProcessCompletedCCBsActive) return;
3050       HostAdapter->ProcessCompletedCCBsActive = true;
3051       while (HostAdapter->FirstCompletedCCB != NULL)
3052         {
3053           BusLogic_CCB_T *CCB = HostAdapter->FirstCompletedCCB;
3054           SCSI_Command_T *Command = CCB->Command;
3055           HostAdapter->FirstCompletedCCB = CCB->Next;
3056           if (HostAdapter->FirstCompletedCCB == NULL)
3057     	HostAdapter->LastCompletedCCB = NULL;
3058           /*
3059     	Process the Completed CCB.
3060           */
3061           if (CCB->Opcode == BusLogic_BusDeviceReset)
3062     	{
3063     	  int TargetID = CCB->TargetID;
3064     	  BusLogic_Warning("Bus Device Reset CCB #%ld to Target "
3065     			   "%d Completed\n", HostAdapter,
3066     			   CCB->SerialNumber, TargetID);
3067     	  BusLogic_IncrementErrorCounter(
3068     	    &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted);
3069     	  HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
3070     	  HostAdapter->CommandsSinceReset[TargetID] = 0;
3071     	  HostAdapter->LastResetCompleted[TargetID] = jiffies;
3072     	  /*
3073     	    Place CCB back on the Host Adapter's free list.
3074     	  */
3075     	  BusLogic_DeallocateCCB(CCB);
3076     	  /*
3077     	    Bus Device Reset CCBs have the Command field non-NULL only when a
3078     	    Bus Device Reset was requested for a Command that did not have a
3079     	    currently active CCB in the Host Adapter (i.e., a Synchronous
3080     	    Bus Device Reset), and hence would not have its Completion Routine
3081     	    called otherwise.
3082     	  */
3083     	  while (Command != NULL)
3084     	    {
3085     	      SCSI_Command_T *NextCommand = Command->reset_chain;
3086     	      Command->reset_chain = NULL;
3087     	      Command->result = DID_RESET << 16;
3088     	      Command->scsi_done(Command);
3089     	      Command = NextCommand;
3090     	    }
3091     	  /*
3092     	    Iterate over the CCBs for this Host Adapter performing completion
3093     	    processing for any CCBs marked as Reset for this Target.
3094     	  */
3095     	  for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3096     	    if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID)
3097     	      {
3098     		Command = CCB->Command;
3099     		BusLogic_DeallocateCCB(CCB);
3100     		HostAdapter->ActiveCommands[TargetID]--;
3101     		Command->result = DID_RESET << 16;
3102     		Command->scsi_done(Command);
3103     	      }
3104     	  HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
3105     	}
3106           else
3107     	{
3108     	  /*
3109     	    Translate the Completion Code, Host Adapter Status, and Target
3110     	    Device Status into a SCSI Subsystem Result Code.
3111     	  */
3112     	  switch (CCB->CompletionCode)
3113     	    {
3114     	    case BusLogic_IncomingMailboxFree:
3115     	    case BusLogic_AbortedCommandNotFound:
3116     	    case BusLogic_InvalidCCB:
3117     	      BusLogic_Warning("CCB #%ld to Target %d Impossible State\n",
3118     			       HostAdapter, CCB->SerialNumber, CCB->TargetID);
3119     	      break;
3120     	    case BusLogic_CommandCompletedWithoutError:
3121     	      HostAdapter->TargetStatistics[CCB->TargetID]
3122     			   .CommandsCompleted++;
3123     	      HostAdapter->TargetFlags[CCB->TargetID]
3124     			   .CommandSuccessfulFlag = true;
3125     	      Command->result = DID_OK << 16;
3126     	      break;
3127     	    case BusLogic_CommandAbortedAtHostRequest:
3128     	      BusLogic_Warning("CCB #%ld to Target %d Aborted\n",
3129     			       HostAdapter, CCB->SerialNumber, CCB->TargetID);
3130     	      BusLogic_IncrementErrorCounter(
3131     		&HostAdapter->TargetStatistics[CCB->TargetID]
3132     			      .CommandAbortsCompleted);
3133     	      Command->result = DID_ABORT << 16;
3134     	      break;
3135     	    case BusLogic_CommandCompletedWithError:
3136     	      Command->result =
3137     		BusLogic_ComputeResultCode(HostAdapter,
3138     					   CCB->HostAdapterStatus,
3139     					   CCB->TargetDeviceStatus);
3140     	      if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
3141     		{
3142     		  HostAdapter->TargetStatistics[CCB->TargetID]
3143     			       .CommandsCompleted++;
3144     		  if (BusLogic_GlobalOptions.TraceErrors)
3145     		    {
3146     		      int i;
3147     		      BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
3148     				      "Adapter Status %02X "
3149     				      "Target Status %02X\n",
3150     				      HostAdapter, CCB->SerialNumber,
3151     				      CCB->TargetID, Command->result,
3152     				      CCB->HostAdapterStatus,
3153     				      CCB->TargetDeviceStatus);
3154     		      BusLogic_Notice("CDB   ", HostAdapter);
3155     		      for (i = 0; i < CCB->CDB_Length; i++)
3156     			BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]);
3157     		      BusLogic_Notice("\n", HostAdapter);
3158     		      BusLogic_Notice("Sense ", HostAdapter);
3159     		      for (i = 0; i < CCB->SenseDataLength; i++)
3160     			BusLogic_Notice(" %02X", HostAdapter,
3161     					Command->sense_buffer[i]);
3162     		      BusLogic_Notice("\n", HostAdapter);
3163     		    }
3164     		}
3165     	      break;
3166     	    }
3167     	  /*
3168     	    When an INQUIRY command completes normally, save the
3169     	    CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
3170     	    Wide Data Transfers Supported) bits.
3171     	  */
3172     	  if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 &&
3173     	      CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally)
3174     	    {
3175     	      BusLogic_TargetFlags_T *TargetFlags =
3176     		&HostAdapter->TargetFlags[CCB->TargetID];
3177     	      SCSI_Inquiry_T *InquiryResult =
3178     		(SCSI_Inquiry_T *) Command->request_buffer;
3179     	      TargetFlags->TargetExists = true;
3180     	      TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
3181     	      TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
3182     	    }
3183     	  /*
3184     	    Place CCB back on the Host Adapter's free list.
3185     	  */
3186     	  BusLogic_DeallocateCCB(CCB);
3187     	  /*
3188     	    Call the SCSI Command Completion Routine.
3189     	  */
3190     	  Command->scsi_done(Command);
3191     	}
3192         }
3193       HostAdapter->ProcessCompletedCCBsActive = false;
3194     }
3195     
3196     
3197     /*
3198       BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
3199       Adapters.
3200     */
3201     
3202     static void BusLogic_InterruptHandler(int IRQ_Channel,
3203     				      void *DeviceIdentifier,
3204     				      Registers_T *InterruptRegisters)
3205     {
3206       BusLogic_HostAdapter_T *HostAdapter =
3207         (BusLogic_HostAdapter_T *) DeviceIdentifier;
3208       ProcessorFlags_T ProcessorFlags;
3209       /*
3210         Acquire exclusive access to Host Adapter.
3211       */
3212       BusLogic_AcquireHostAdapterLockIH(HostAdapter, &ProcessorFlags);
3213       /*
3214         Handle Interrupts appropriately for each Host Adapter type.
3215       */
3216       if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3217         {
3218           BusLogic_InterruptRegister_T InterruptRegister;
3219           /*
3220     	Read the Host Adapter Interrupt Register.
3221           */
3222           InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
3223           if (InterruptRegister.Bits.InterruptValid)
3224     	{
3225     	  /*
3226     	    Acknowledge the interrupt and reset the Host Adapter
3227     	    Interrupt Register.
3228     	  */
3229     	  BusLogic_InterruptReset(HostAdapter);
3230     	  /*
3231     	    Process valid External SCSI Bus Reset and Incoming Mailbox
3232     	    Loaded Interrupts.  Command Complete Interrupts are noted,
3233     	    and Outgoing Mailbox Available Interrupts are ignored, as
3234     	    they are never enabled.
3235     	  */
3236     	  if (InterruptRegister.Bits.ExternalBusReset)
3237     	    HostAdapter->HostAdapterExternalReset = true;
3238     	  else if (InterruptRegister.Bits.IncomingMailboxLoaded)
3239     	    BusLogic_ScanIncomingMailboxes(HostAdapter);
3240     	  else if (InterruptRegister.Bits.CommandComplete)
3241     	    HostAdapter->HostAdapterCommandCompleted = true;
3242     	}
3243         }
3244       else
3245         {
3246           /*
3247     	Check if there is a pending interrupt for this Host Adapter.
3248           */
3249           if (FlashPoint_InterruptPending(HostAdapter->CardHandle))
3250     	switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle))
3251     	  {
3252     	  case FlashPoint_NormalInterrupt:
3253     	    break;
3254     	  case FlashPoint_ExternalBusReset:
3255     	    HostAdapter->HostAdapterExternalReset = true;
3256     	    break;
3257     	  case FlashPoint_InternalError:
3258     	    BusLogic_Warning("Internal FlashPoint Error detected"
3259     			     " - Resetting Host Adapter\n", HostAdapter);
3260     	    HostAdapter->HostAdapterInternalError = true;
3261     	    break;
3262     	  }
3263         }
3264       /*
3265         Process any completed CCBs.
3266       */
3267       if (HostAdapter->FirstCompletedCCB != NULL)
3268         BusLogic_ProcessCompletedCCBs(HostAdapter);
3269       /*
3270         Reset the Host Adapter if requested.
3271       */
3272       if (HostAdapter->HostAdapterExternalReset ||
3273           HostAdapter->HostAdapterInternalError)
3274         {
3275           BusLogic_ResetHostAdapter(HostAdapter, NULL, 0);
3276           HostAdapter->HostAdapterExternalReset = false;
3277           HostAdapter->HostAdapterInternalError = false;
3278           scsi_mark_host_reset(HostAdapter->SCSI_Host);
3279         }
3280       /*
3281         Release exclusive access to Host Adapter.
3282       */
3283       BusLogic_ReleaseHostAdapterLockIH(HostAdapter, &ProcessorFlags);
3284     }
3285     
3286     
3287     /*
3288       BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
3289       Mailbox for execution by Host Adapter.  The Host Adapter's Lock should
3290       already have been acquired by the caller.
3291     */
3292     
3293     static boolean BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T
3294     					       *HostAdapter,
3295     					     BusLogic_ActionCode_T ActionCode,
3296     					     BusLogic_CCB_T *CCB)
3297     {
3298       BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
3299       NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
3300       if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
3301         {
3302           CCB->Status = BusLogic_CCB_Active;
3303           /*
3304     	The CCB field must be written before the Action Code field since
3305     	the Host Adapter is operating asynchronously and the locking code
3306     	does not protect against simultaneous access by the Host Adapter.
3307           */
3308           NextOutgoingMailbox->CCB = Virtual_to_Bus(CCB);
3309           NextOutgoingMailbox->ActionCode = ActionCode;
3310           BusLogic_StartMailboxCommand(HostAdapter);
3311           if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
3312     	NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
3313           HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
3314           if (ActionCode == BusLogic_MailboxStartCommand)
3315     	{
3316     	  HostAdapter->ActiveCommands[CCB->TargetID]++;
3317     	  if (CCB->Opcode != BusLogic_BusDeviceReset)
3318     	    HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++;
3319     	}
3320           return true;
3321         }
3322       return false;
3323     }
3324     
3325     
3326     /*
3327       BusLogic_QueueCommand creates a CCB for Command and places it into an
3328       Outgoing Mailbox for execution by the associated Host Adapter.
3329     */
3330     
3331     int BusLogic_QueueCommand(SCSI_Command_T *Command,
3332     			  void (*CompletionRoutine)(SCSI_Command_T *))
3333     {
3334       BusLogic_HostAdapter_T *HostAdapter =
3335         (BusLogic_HostAdapter_T *) Command->host->hostdata;
3336       BusLogic_TargetFlags_T *TargetFlags =
3337         &HostAdapter->TargetFlags[Command->target];
3338       BusLogic_TargetStatistics_T *TargetStatistics =
3339         HostAdapter->TargetStatistics;
3340       unsigned char *CDB = Command->cmnd;
3341       int CDB_Length = Command->cmd_len;
3342       int TargetID = Command->target;
3343       int LogicalUnit = Command->lun;
3344       void *BufferPointer = Command->request_buffer;
3345       int BufferLength = Command->request_bufflen;
3346       int SegmentCount = Command->use_sg;
3347       ProcessorFlags_T ProcessorFlags;
3348       BusLogic_CCB_T *CCB;
3349       /*
3350         SCSI REQUEST_SENSE commands will be executed automatically by the Host
3351         Adapter for any errors, so they should not be executed explicitly unless
3352         the Sense Data is zero indicating that no error occurred.
3353       */
3354       if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0)
3355         {
3356           Command->result = DID_OK << 16;
3357           CompletionRoutine(Command);
3358           return 0;
3359         }
3360       /*
3361         Acquire exclusive access to Host Adapter.
3362       */
3363       BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
3364       /*
3365         Allocate a CCB from the Host Adapter's free list.  In the unlikely event
3366         that there are none available and memory allocation fails, wait 1 second
3367         and try again.  If that fails, the Host Adapter is probably hung so signal
3368         an error as a Host Adapter Hard Reset should be initiated soon.
3369       */
3370       CCB = BusLogic_AllocateCCB(HostAdapter);
3371       if (CCB == NULL)
3372         {
3373           BusLogic_Delay(1);
3374           CCB = BusLogic_AllocateCCB(HostAdapter);
3375           if (CCB == NULL)
3376     	{
3377     	  Command->result = DID_ERROR << 16;
3378     	  CompletionRoutine(Command);
3379     	  goto Done;
3380     	}
3381         }
3382       /*
3383         Initialize the fields in the BusLogic Command Control Block (CCB).
3384       */
3385       if (SegmentCount == 0)
3386         {
3387           CCB->Opcode = BusLogic_InitiatorCCB;
3388           CCB->DataLength = BufferLength;
3389           CCB->DataPointer = Virtual_to_Bus(BufferPointer);
3390         }
3391       else
3392         {
3393           SCSI_ScatterList_T *ScatterList = (SCSI_ScatterList_T *) BufferPointer;
3394           int Segment;
3395           CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
3396           CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T);
3397           if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3398     	CCB->DataPointer = Virtual_to_Bus(CCB->ScatterGatherList);
3399           else CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
3400           for (Segment = 0; Segment < SegmentCount; Segment++)
3401     	{
3402     	  CCB->ScatterGatherList[Segment].SegmentByteCount =
3403     	    ScatterList[Segment].length;
3404     	  CCB->ScatterGatherList[Segment].SegmentDataPointer =
3405     	    Virtual_to_Bus(ScatterList[Segment].address);
3406     	}
3407         }
3408       switch (CDB[0])
3409         {
3410         case READ_6:
3411         case READ_10:
3412           CCB->DataDirection = BusLogic_DataInLengthChecked;
3413           TargetStatistics[TargetID].ReadCommands++;
3414           BusLogic_IncrementByteCounter(
3415     	&TargetStatistics[TargetID].TotalBytesRead, BufferLength);
3416           BusLogic_IncrementSizeBucket(
3417     	TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength);
3418           break;
3419         case WRITE_6:
3420         case WRITE_10:
3421           CCB->DataDirection = BusLogic_DataOutLengthChecked;
3422           TargetStatistics[TargetID].WriteCommands++;
3423           BusLogic_IncrementByteCounter(
3424     	&TargetStatistics[TargetID].TotalBytesWritten, BufferLength);
3425           BusLogic_IncrementSizeBucket(
3426     	TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength);
3427           break;
3428         default:
3429           CCB->DataDirection = BusLogic_UncheckedDataTransfer;
3430           break;
3431         }
3432       CCB->CDB_Length = CDB_Length;
3433       CCB->SenseDataLength = sizeof(Command->sense_buffer);
3434       CCB->HostAdapterStatus = 0;
3435       CCB->TargetDeviceStatus = 0;
3436       CCB->TargetID = TargetID;
3437       CCB->LogicalUnit = LogicalUnit;
3438       CCB->TagEnable = false;
3439       CCB->LegacyTagEnable = false;
3440       /*
3441         BusLogic recommends that after a Reset the first couple of commands that
3442         are sent to a Target Device be sent in a non Tagged Queue fashion so that
3443         the Host Adapter and Target Device can establish Synchronous and Wide
3444         Transfer before Queue Tag messages can interfere with the Synchronous and
3445         Wide Negotiation messages.  By waiting to enable Tagged Queuing until after
3446         the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is
3447         assured that after a Reset any pending commands are requeued before Tagged
3448         Queuing is enabled and that the Tagged Queuing message will not occur while
3449         the partition table is being printed.  In addition, some devices do not
3450         properly handle the transition from non-tagged to tagged commands, so it is
3451         necessary to wait until there are no pending commands for a target device
3452         before queuing tagged commands.
3453       */
3454       if (HostAdapter->CommandsSinceReset[TargetID]++ >=
3455     	BusLogic_MaxTaggedQueueDepth &&
3456           !TargetFlags->TaggedQueuingActive &&
3457           HostAdapter->ActiveCommands[TargetID] == 0 &&
3458           TargetFlags->TaggedQueuingSupported &&
3459           (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
3460         {
3461           TargetFlags->TaggedQueuingActive = true;
3462           BusLogic_Notice("Tagged Queuing now active for Target %d\n",
3463     		      HostAdapter, TargetID);
3464         }
3465       if (TargetFlags->TaggedQueuingActive)
3466         {
3467           BusLogic_QueueTag_T QueueTag = BusLogic_SimpleQueueTag;
3468           /*
3469     	When using Tagged Queuing with Simple Queue Tags, it appears that disk
3470     	drive controllers do not guarantee that a queued command will not
3471     	remain in a disconnected state indefinitely if commands that read or
3472     	write nearer the head position continue to arrive without interruption.
3473     	Therefore, for each Target Device this driver keeps track of the last
3474     	time either the queue was empty or an Ordered Queue Tag was issued.  If
3475     	more than 4 seconds (one fifth of the 20 second disk timeout) have
3476     	elapsed since this last sequence point, this command will be issued
3477     	with an Ordered Queue Tag rather than a Simple Queue Tag, which forces
3478     	the Target Device to complete all previously queued commands before
3479     	this command may be executed.
3480           */
3481           if (HostAdapter->ActiveCommands[TargetID] == 0)
3482     	HostAdapter->LastSequencePoint[TargetID] = jiffies;
3483           else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 4*HZ)
3484     	{
3485     	  HostAdapter->LastSequencePoint[TargetID] = jiffies;
3486     	  QueueTag = BusLogic_OrderedQueueTag;
3487     	}
3488           if (HostAdapter->ExtendedLUNSupport)
3489     	{
3490     	  CCB->TagEnable = true;
3491     	  CCB->QueueTag = QueueTag;
3492     	}
3493           else
3494     	{
3495     	  CCB->LegacyTagEnable = true;
3496     	  CCB->LegacyQueueTag = QueueTag;
3497     	}
3498         }
3499       memcpy(CCB->CDB, CDB, CDB_Length);
3500       CCB->SenseDataPointer = Virtual_to_Bus(&Command->sense_buffer);
3501       CCB->Command = Command;
3502       Command->scsi_done = CompletionRoutine;
3503       if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3504         {
3505           /*
3506     	Place the CCB in an Outgoing Mailbox.  The higher levels of the SCSI
3507     	Subsystem should not attempt to queue more commands than can be placed
3508     	in Outgoing Mailboxes, so there should always be one free.  In the
3509     	unlikely event that there are none available, wait 1 second and try
3510     	again.  If that fails, the Host Adapter is probably hung so signal an
3511     	error as a Host Adapter Hard Reset should be initiated soon.
3512           */
3513           if (!BusLogic_WriteOutgoingMailbox(
3514     	     HostAdapter, BusLogic_MailboxStartCommand, CCB))
3515     	{
3516     	  BusLogic_Warning("Unable to write Outgoing Mailbox - "
3517     			   "Pausing for 1 second\n", HostAdapter);
3518     	  BusLogic_Delay(1);
3519     	  if (!BusLogic_WriteOutgoingMailbox(
3520     		 HostAdapter, BusLogic_MailboxStartCommand, CCB))
3521     	    {
3522     	      BusLogic_Warning("Still unable to write Outgoing Mailbox - "
3523     			       "Host Adapter Dead?\n", HostAdapter);
3524     	      BusLogic_DeallocateCCB(CCB);
3525     	      Command->result = DID_ERROR << 16;
3526     	      Command->scsi_done(Command);
3527     	    }
3528     	}
3529         }
3530       else
3531         {
3532           /*
3533     	Call the FlashPoint SCCB Manager to start execution of the CCB.
3534           */
3535           CCB->Status = BusLogic_CCB_Active;
3536           HostAdapter->ActiveCommands[TargetID]++;
3537           TargetStatistics[TargetID].CommandsAttempted++;
3538           FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
3539           /*
3540     	The Command may have already completed and BusLogic_QueueCompletedCCB
3541     	been called, or it may still be pending.
3542           */
3543           if (CCB->Status == BusLogic_CCB_Completed)
3544     	BusLogic_ProcessCompletedCCBs(HostAdapter);
3545         }
3546       /*
3547         Release exclusive access to Host Adapter.
3548       */
3549     Done:
3550       BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
3551       return 0;
3552     }
3553     
3554     
3555     /*
3556       BusLogic_AbortCommand aborts Command if possible.
3557     */
3558     
3559     int BusLogic_AbortCommand(SCSI_Command_T *Command)
3560     {
3561       BusLogic_HostAdapter_T *HostAdapter =
3562         (BusLogic_HostAdapter_T *) Command->host->hostdata;
3563       int TargetID = Command->target;
3564       ProcessorFlags_T ProcessorFlags;
3565       BusLogic_CCB_T *CCB;
3566       int Result;
3567       BusLogic_IncrementErrorCounter(
3568         &HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested);
3569       /*
3570         Acquire exclusive access to Host Adapter.
3571       */
3572       BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
3573       /*
3574         If this Command has already completed, then no Abort is necessary.
3575       */
3576       if (Command->serial_number != Command->serial_number_at_timeout)
3577         {
3578           BusLogic_Warning("Unable to Abort Command to Target %d - "
3579     		       "Already Completed\n", HostAdapter, TargetID);
3580           Result = SCSI_ABORT_NOT_RUNNING;
3581           goto Done;
3582         }
3583       /*
3584         Attempt to find an Active CCB for this Command.  If no Active CCB for this
3585         Command is found, then no Abort is necessary.
3586       */
3587       for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3588         if (CCB->Command == Command) break;
3589       if (CCB == NULL)
3590         {
3591           BusLogic_Warning("Unable to Abort Command to Target %d - "
3592     		       "No CCB Found\n", HostAdapter, TargetID);
3593           Result = SCSI_ABORT_NOT_RUNNING;
3594           goto Done;
3595         }
3596       else if (CCB->Status == BusLogic_CCB_Completed)
3597         {
3598           BusLogic_Warning("Unable to Abort Command to Target %d - "
3599     		       "CCB Completed\n", HostAdapter, TargetID);
3600           Result = SCSI_ABORT_NOT_RUNNING;
3601           goto Done;
3602         }
3603       else if (CCB->Status == BusLogic_CCB_Reset)
3604         {
3605           BusLogic_Warning("Unable to Abort Command to Target %d - "
3606     		       "CCB Reset\n", HostAdapter, TargetID);
3607           Result = SCSI_ABORT_PENDING;
3608           goto Done;
3609         }
3610       if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3611         {
3612           /*
3613     	Attempt to Abort this CCB.  MultiMaster Firmware versions prior to 5.xx
3614     	do not generate Abort Tag messages, but only generate the non-tagged
3615     	Abort message.  Since non-tagged commands are not sent by the Host
3616     	Adapter until the queue of outstanding tagged commands has completed,
3617     	and the Abort message is treated as a non-tagged command, it is
3618     	effectively impossible to abort commands when Tagged Queuing is active.
3619     	Firmware version 5.xx does generate Abort Tag messages, so it is
3620     	possible to abort commands when Tagged Queuing is active.
3621           */
3622           if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
3623     	  HostAdapter->FirmwareVersion[0] < '5')
3624     	{
3625     	  BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
3626     			   "Abort Tag Not Supported\n",
3627     			   HostAdapter, CCB->SerialNumber, TargetID);
3628     	  Result = SCSI_ABORT_SNOOZE;
3629     	}
3630           else if (BusLogic_WriteOutgoingMailbox(
3631     		 HostAdapter, BusLogic_MailboxAbortCommand, CCB))
3632     	{
3633     	  BusLogic_Warning("Aborting CCB #%ld to Target %d\n",
3634     			   HostAdapter, CCB->SerialNumber, TargetID);
3635     	  BusLogic_IncrementErrorCounter(
3636     	    &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3637     	  Result = SCSI_ABORT_PENDING;
3638     	}
3639           else
3640     	{
3641     	  BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
3642     			   "No Outgoing Mailboxes\n",
3643     			    HostAdapter, CCB->SerialNumber, TargetID);
3644     	  Result = SCSI_ABORT_BUSY;
3645     	}
3646         }
3647       else
3648         {
3649           /*
3650     	Call the FlashPoint SCCB Manager to abort execution of the CCB.
3651           */
3652           BusLogic_Warning("Aborting CCB #%ld to Target %d\n",
3653     		       HostAdapter, CCB->SerialNumber, TargetID);
3654           BusLogic_IncrementErrorCounter(
3655     	&HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3656           FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB);
3657           /*
3658     	The Abort may have already been completed and
3659     	BusLogic_QueueCompletedCCB been called, or it
3660     	may still be pending.
3661           */
3662           Result = SCSI_ABORT_PENDING;
3663           if (CCB->Status == BusLogic_CCB_Completed)
3664     	{
3665     	  BusLogic_ProcessCompletedCCBs(HostAdapter);
3666     	  Result = SCSI_ABORT_SUCCESS;
3667     	}
3668         }
3669       /*
3670         Release exclusive access to Host Adapter.
3671       */
3672     Done:
3673       BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
3674       return Result;
3675     }
3676     
3677     
3678     /*
3679       BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
3680       currently executing SCSI Commands as having been Reset.
3681     */
3682     
3683     static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter,
3684     				     SCSI_Command_T *Command,
3685     				     unsigned int ResetFlags)
3686     {
3687       ProcessorFlags_T ProcessorFlags;
3688       BusLogic_CCB_T *CCB;
3689       int TargetID, Result;
3690       boolean HardReset;
3691       if (HostAdapter->HostAdapterExternalReset)
3692         {
3693           BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets);
3694           HardReset = false;
3695         }
3696       else if (HostAdapter->HostAdapterInternalError)
3697         {
3698           BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors);
3699           HardReset = true;
3700         }
3701       else
3702         {
3703           BusLogic_IncrementErrorCounter(
3704     	&HostAdapter->TargetStatistics[Command->target]
3705     		      .HostAdapterResetsRequested);
3706           HardReset = true;
3707         }
3708       /*
3709         Acquire exclusive access to Host Adapter.
3710       */
3711       BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
3712       /*
3713         If this is an Asynchronous Reset and this Command has already completed,
3714         then no Reset is necessary.
3715       */
3716       if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
3717         {
3718           TargetID = Command->target;
3719           if (Command->serial_number != Command->serial_number_at_timeout)
3720     	{
3721     	  BusLogic_Warning("Unable to Reset Command to Target %d - "
3722     			   "Already Completed or Reset\n",
3723     			   HostAdapter, TargetID);
3724     	  Result = SCSI_RESET_NOT_RUNNING;
3725     	  goto Done;
3726           }
3727           for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3728     	if (CCB->Command == Command) break;
3729           if (CCB == NULL)
3730     	{
3731     	  BusLogic_Warning("Unable to Reset Command to Target %d - "
3732     			   "No CCB Found\n", HostAdapter, TargetID);
3733     	  Result = SCSI_RESET_NOT_RUNNING;
3734     	  goto Done;
3735     	}
3736           else if (CCB->Status == BusLogic_CCB_Completed)
3737     	{
3738     	  BusLogic_Warning("Unable to Reset Command to Target %d - "
3739     			   "CCB Completed\n", HostAdapter, TargetID);
3740     	  Result = SCSI_RESET_NOT_RUNNING;
3741     	  goto Done;
3742     	}
3743           else if (CCB->Status == BusLogic_CCB_Reset &&
3744     	       HostAdapter->BusDeviceResetPendingCCB[TargetID] == NULL)
3745     	{
3746     	  BusLogic_Warning("Unable to Reset Command to Target %d - "
3747     			   "Reset Pending\n", HostAdapter, TargetID);
3748     	  Result = SCSI_RESET_PENDING;
3749     	  goto Done;
3750     	}
3751         }
3752       if (Command == NULL)
3753         {
3754           if (HostAdapter->HostAdapterInternalError)
3755     	BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n",
3756     			 HostAdapter, HostAdapter->FullModelName);
3757           else BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n",
3758     			    HostAdapter, HostAdapter->FullModelName);
3759         }
3760       else
3761         {
3762           BusLogic_Warning("Resetting %s due to Target %d\n", HostAdapter,
3763     		       HostAdapter->FullModelName, Command->target);
3764           BusLogic_IncrementErrorCounter(
3765     	&HostAdapter->TargetStatistics[Command->target]
3766     		      .HostAdapterResetsAttempted);
3767         }
3768       /*
3769         Attempt to Reset and Reinitialize the Host Adapter.
3770       */
3771       if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) &&
3772     	BusLogic_InitializeHostAdapter(HostAdapter)))
3773         {
3774           BusLogic_Error("Resetting %s Failed\n", HostAdapter,
3775     		     HostAdapter->FullModelName);
3776           Result = SCSI_RESET_ERROR;
3777           goto Done;
3778         }
3779       if (Command != NULL)
3780         BusLogic_IncrementErrorCounter(
3781           &HostAdapter->TargetStatistics[Command->target]
3782     		    .HostAdapterResetsCompleted);
3783       /*
3784         Mark all currently executing CCBs as having been Reset.
3785       */
3786       for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3787         if (CCB->Status == BusLogic_CCB_Active)
3788           CCB->Status = BusLogic_CCB_Reset;
3789       /*
3790         Wait a few seconds between the Host Adapter Hard Reset which initiates
3791         a SCSI Bus Reset and issuing any SCSI Commands.  Some SCSI devices get
3792         confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
3793         Note that a timer interrupt may occur here, but all active CCBs have
3794         already been marked Reset and so a reentrant call will return Pending.
3795       */
3796       if (HardReset)
3797         BusLogic_Delay(HostAdapter->BusSettleTime);
3798       /*
3799         If this is a Synchronous Reset, perform completion processing for
3800         the Command being Reset.
3801       */
3802       if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
3803         {
3804           Command->result = DID_RESET << 16;
3805           Command->scsi_done(Command);
3806         }
3807       /*
3808         Perform completion processing for all CCBs marked as Reset.
3809       */
3810       for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3811         if (CCB->Status == BusLogic_CCB_Reset)
3812           {
3813     	Command = CCB->Command;
3814     	BusLogic_DeallocateCCB(CCB);
3815     	while (Command != NULL)
3816     	  {
3817     	    SCSI_Command_T *NextCommand = Command->reset_chain;
3818     	    Command->reset_chain = NULL;
3819     	    Command->result = DID_RESET << 16;
3820     	    Command->scsi_done(Command);
3821     	    Command = NextCommand;
3822     	  }
3823           }
3824       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
3825         {
3826           HostAdapter->LastResetAttempted[TargetID] = jiffies;
3827           HostAdapter->LastResetCompleted[TargetID] = jiffies;
3828         }
3829       Result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET;
3830       /*
3831         Release exclusive access to Host Adapter.
3832       */
3833     Done:
3834       BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
3835       return Result;
3836     }
3837     
3838     
3839     /*
3840       BusLogic_SendBusDeviceReset sends a Bus Device Reset to the Target
3841       Device associated with Command.
3842     */
3843     
3844     static int BusLogic_SendBusDeviceReset(BusLogic_HostAdapter_T *HostAdapter,
3845     				       SCSI_Command_T *Command,
3846     				       unsigned int ResetFlags)
3847     {
3848       int TargetID = Command->target;
3849       BusLogic_CCB_T *CCB, *XCCB;
3850       ProcessorFlags_T ProcessorFlags;
3851       int Result = -1;
3852       BusLogic_IncrementErrorCounter(
3853         &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsRequested);
3854       /*
3855         Acquire exclusive access to Host Adapter.
3856       */
3857       BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
3858       /*
3859         If this is an Asynchronous Reset and this Command has already completed,
3860         then no Reset is necessary.
3861       */
3862       if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
3863         {
3864           if (Command->serial_number != Command->serial_number_at_timeout)
3865     	{
3866     	  BusLogic_Warning("Unable to Reset Command to Target %d - "
3867     			   "Already Completed\n", HostAdapter, TargetID);
3868     	  Result = SCSI_RESET_NOT_RUNNING;
3869     	  goto Done;
3870     	}
3871           for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3872     	if (CCB->Command == Command) break;
3873           if (CCB == NULL)
3874     	{
3875     	  BusLogic_Warning("Unable to Reset Command to Target %d - "
3876     			   "No CCB Found\n", HostAdapter, TargetID);
3877     	  Result = SCSI_RESET_NOT_RUNNING;
3878     	  goto Done;
3879     	}
3880           else if (CCB->Status == BusLogic_CCB_Completed)
3881     	{
3882     	  BusLogic_Warning("Unable to Reset Command to Target %d - "
3883     			   "CCB Completed\n", HostAdapter, TargetID);
3884     	  Result = SCSI_RESET_NOT_RUNNING;
3885     	  goto Done;
3886     	}
3887           else if (CCB->Status == BusLogic_CCB_Reset)
3888     	{
3889     	  BusLogic_Warning("Unable to Reset Command to Target %d - "
3890     			   "Reset Pending\n", HostAdapter, TargetID);
3891     	  Result = SCSI_RESET_PENDING;
3892     	  goto Done;
3893     	}
3894           else if (HostAdapter->BusDeviceResetPendingCCB[TargetID] != NULL)
3895     	{
3896     	  BusLogic_Warning("Bus Device Reset already pending to Target %d\n",
3897     			   HostAdapter, TargetID);
3898     	  goto Done;
3899     	}
3900         }
3901       /*
3902         If this is a Synchronous Reset and a Bus Device Reset is already pending
3903         for this Target Device, do not send a second one.  Add this Command to
3904         the list of Commands for which completion processing must be performed
3905         when the Bus Device Reset CCB completes.
3906       */
3907       if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
3908         if ((CCB = HostAdapter->BusDeviceResetPendingCCB[TargetID]) != NULL)
3909           {
3910     	Command->reset_chain = CCB->Command;
3911     	CCB->Command = Command;
3912     	BusLogic_Warning("Unable to Reset Command to Target %d - "
3913     			 "Reset Pending\n", HostAdapter, TargetID);
3914     	Result = SCSI_RESET_PENDING;
3915     	goto Done;
3916           }
3917       if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3918         {
3919           /*
3920     	MultiMaster Firmware versions prior to 5.xx treat a Bus Device Reset as
3921     	a non-tagged command.  Since non-tagged commands are not sent by the
3922     	Host Adapter until the queue of outstanding tagged commands has
3923     	completed, it is effectively impossible to send a Bus Device Reset
3924     	while there are tagged commands outstanding.  Therefore, in that case a
3925     	full Host Adapter Hard Reset and SCSI Bus Reset must be done.
3926           */
3927           if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
3928     	  HostAdapter->ActiveCommands[TargetID] > 0 &&
3929     	  HostAdapter->FirmwareVersion[0] < '5')
3930     	goto Done;
3931         }
3932       /*
3933         Allocate a CCB from the Host Adapter's free list.  In the unlikely event
3934         that there are none available and memory allocation fails, attempt a full
3935         Host Adapter Hard Reset and SCSI Bus Reset.
3936       */
3937       CCB = BusLogic_AllocateCCB(HostAdapter);
3938       if (CCB == NULL) goto Done;
3939       BusLogic_Warning("Sending Bus Device Reset CCB #%ld to Target %d\n",
3940     		   HostAdapter, CCB->SerialNumber, TargetID);
3941       CCB->Opcode = BusLogic_BusDeviceReset;
3942       CCB->TargetID = TargetID;
3943       /*
3944         For Synchronous Resets, arrange for the interrupt handler to perform
3945         completion processing for the Command being Reset.
3946       */
3947       if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
3948         {
3949           Command->reset_chain = NULL;
3950           CCB->Command = Command;
3951         }
3952       if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3953         {
3954           /*
3955     	Attempt to write an Outgoing Mailbox with the Bus Device Reset CCB.
3956     	If sending a Bus Device Reset is impossible, attempt a full Host
3957     	Adapter Hard Reset and SCSI Bus Reset.
3958           */
3959           if (!(BusLogic_WriteOutgoingMailbox(
3960     	      HostAdapter, BusLogic_MailboxStartCommand, CCB)))
3961     	{
3962     	  BusLogic_Warning("Unable to write Outgoing Mailbox for "
3963     			   "Bus Device Reset\n", HostAdapter);
3964     	  BusLogic_DeallocateCCB(CCB);
3965     	  goto Done;
3966     	}
3967         }
3968       else
3969         {
3970           /*
3971     	Call the FlashPoint SCCB Manager to start execution of the CCB.
3972           */
3973           CCB->Status = BusLogic_CCB_Active;
3974           HostAdapter->ActiveCommands[TargetID]++;
3975           FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
3976         }
3977       /*
3978         If there is a currently executing CCB in the Host Adapter for this Command
3979         (i.e. this is an Asynchronous Reset), then an Incoming Mailbox entry may be
3980         made with a completion code of BusLogic_HostAdapterAssertedBusDeviceReset.
3981         If there is no active CCB for this Command (i.e. this is a Synchronous
3982         Reset), then the Bus Device Reset CCB's Command field will have been set
3983         to the Command so that the interrupt for the completion of the Bus Device
3984         Reset can call the Completion Routine for the Command.  On successful
3985         execution of a Bus Device Reset, older firmware versions did return the
3986         pending CCBs with the appropriate completion code, but more recent firmware
3987         versions only return the Bus Device Reset CCB itself.  This driver handles
3988         both cases by marking all the currently executing CCBs to this Target
3989         Device as Reset.  When the Bus Device Reset CCB is processed by the
3990         interrupt handler, any remaining CCBs marked as Reset will have completion
3991         processing performed.
3992       */
3993       BusLogic_IncrementErrorCounter(
3994         &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsAttempted);
3995       HostAdapter->BusDeviceResetPendingCCB[TargetID] = CCB;
3996       HostAdapter->LastResetAttempted[TargetID] = jiffies;
3997       for (XCCB = HostAdapter->All_CCBs; XCCB != NULL; XCCB = XCCB->NextAll)
3998         if (XCCB->Status == BusLogic_CCB_Active && XCCB->TargetID == TargetID)
3999           XCCB->Status = BusLogic_CCB_Reset;
4000       /*
4001         FlashPoint Host Adapters may have already completed the Bus Device
4002         Reset and BusLogic_QueueCompletedCCB been called, or it may still be
4003         pending.
4004       */
4005       Result = SCSI_RESET_PENDING;
4006       if (BusLogic_FlashPointHostAdapterP(HostAdapter))
4007         if (CCB->Status == BusLogic_CCB_Completed)
4008           {
4009     	BusLogic_ProcessCompletedCCBs(HostAdapter);
4010     	Result = SCSI_RESET_SUCCESS;
4011           }
4012       /*
4013         If a Bus Device Reset was not possible for some reason, force a full
4014         Host Adapter Hard Reset and SCSI Bus Reset.
4015       */
4016     Done:
4017       if (Result < 0)
4018         Result = BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
4019       /*
4020         Release exclusive access to Host Adapter.
4021       */
4022       BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
4023       return Result;
4024     }
4025     
4026     
4027     /*
4028       BusLogic_ResetCommand takes appropriate action to reset Command.
4029     */
4030     
4031     int BusLogic_ResetCommand(SCSI_Command_T *Command, unsigned int ResetFlags)
4032     {
4033       BusLogic_HostAdapter_T *HostAdapter =
4034         (BusLogic_HostAdapter_T *) Command->host->hostdata;
4035       int TargetID = Command->target;
4036       BusLogic_ErrorRecoveryStrategy_T
4037         ErrorRecoveryStrategy = HostAdapter->ErrorRecoveryStrategy[TargetID];
4038       /*
4039         Disable Tagged Queuing if it is active for this Target Device and if
4040         it has been less than 10 minutes since the last reset occurred, or since
4041         the system was initialized if no prior resets have occurred.
4042       */
4043       if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
4044           jiffies - HostAdapter->LastResetCompleted[TargetID] < 10*60*HZ)
4045         {
4046           HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
4047           HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
4048           BusLogic_Warning("Tagged Queuing now disabled for Target %d\n",
4049     		       HostAdapter, TargetID);
4050         }
4051       switch (ErrorRecoveryStrategy)
4052         {
4053         case BusLogic_ErrorRecovery_Default:
4054           if (ResetFlags & SCSI_RESET_SUGGEST_HOST_RESET)
4055     	return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
4056           else if (ResetFlags & SCSI_RESET_SUGGEST_BUS_RESET)
4057     	return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
4058           /* Fall through to Bus Device Reset case. */
4059         case BusLogic_ErrorRecovery_BusDeviceReset:
4060           /*
4061     	The Bus Device Reset Error Recovery Strategy only graduates to a Hard
4062     	Reset when no commands have completed successfully since the last Bus
4063     	Device Reset and it has been at least 100 milliseconds.  This prevents
4064     	a sequence of commands that all timeout together from immediately
4065     	forcing a Hard Reset before the Bus Device Reset has had a chance to
4066     	clear the error condition.
4067           */
4068           if (HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag ||
4069     	  jiffies - HostAdapter->LastResetAttempted[TargetID] < HZ/10)
4070     	{
4071     	  HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
4072     	  return BusLogic_SendBusDeviceReset(HostAdapter, Command, ResetFlags);
4073     	}
4074           /* Fall through to Hard Reset case. */
4075         case BusLogic_ErrorRecovery_HardReset:
4076           return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
4077         case BusLogic_ErrorRecovery_None:
4078           BusLogic_Warning("Error Recovery for Target %d Suppressed\n",
4079     		       HostAdapter, TargetID);
4080           break;
4081         }
4082       return SCSI_RESET_PUNT;
4083     }
4084     
4085     
4086     /*
4087       BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
4088       Parameters for Disk.  The default disk geometry is 64 heads, 32 sectors, and
4089       the appropriate number of cylinders so as not to exceed drive capacity.  In
4090       order for disks equal to or larger than 1 GB to be addressable by the BIOS
4091       without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
4092       may be enabled in AutoSCSI on FlashPoint Host Adapters and on "W" and "C"
4093       series MultiMaster Host Adapters, or by a dip switch setting on "S" and "A"
4094       series MultiMaster Host Adapters.  With Extended Translation enabled, drives
4095       between 1 GB inclusive and 2 GB exclusive are given a disk geometry of 128
4096       heads and 32 sectors, and drives above 2 GB inclusive are given a disk
4097       geometry of 255 heads and 63 sectors.  However, if the BIOS detects that the
4098       Extended Translation setting does not match the geometry in the partition
4099       table, then the translation inferred from the partition table will be used by
4100       the BIOS, and a warning may be displayed.
4101     */
4102     
4103     int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
4104     				int *Parameters)
4105     {
4106       BusLogic_HostAdapter_T *HostAdapter =
4107         (BusLogic_HostAdapter_T *) Disk->device->host->hostdata;
4108       BIOS_DiskParameters_T *DiskParameters = (BIOS_DiskParameters_T *) Parameters;
4109       struct buffer_head *BufferHead;
4110       if (HostAdapter->ExtendedTranslationEnabled &&
4111           Disk->capacity >= 2*1024*1024 /* 1 GB in 512 byte sectors */)
4112         {
4113           if (Disk->capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */)
4114     	{
4115     	  DiskParameters->Heads = 255;
4116     	  DiskParameters->Sectors = 63;
4117     	}
4118           else
4119     	{
4120     	  DiskParameters->Heads = 128;
4121     	  DiskParameters->Sectors = 32;
4122     	}
4123         }
4124       else
4125         {
4126           DiskParameters->Heads = 64;
4127           DiskParameters->Sectors = 32;
4128         }
4129       DiskParameters->Cylinders =
4130         Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
4131       /*
4132         Attempt to read the first 1024 bytes from the disk device.
4133       */
4134       BufferHead = bread(MKDEV(MAJOR(Device), MINOR(Device) & ~0x0F), 0, 1024);
4135       if (BufferHead == NULL) return 0;
4136       /*
4137         If the boot sector partition table flag is valid, search for a partition
4138         table entry whose end_head matches one of the standard BusLogic geometry
4139         translations (64/32, 128/32, or 255/63).
4140       */
4141       if (*(unsigned short *) (BufferHead->b_data + 0x1FE) == 0xAA55)
4142         {
4143           PartitionTable_T *FirstPartitionEntry =
4144     	(PartitionTable_T *) (BufferHead->b_data + 0x1BE);
4145           PartitionTable_T *PartitionEntry = FirstPartitionEntry;
4146           int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
4147           unsigned char PartitionEntryEndHead, PartitionEntryEndSector;
4148           for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++)
4149     	{
4150     	  PartitionEntryEndHead = PartitionEntry->end_head;
4151     	  PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F;
4152     	  if (PartitionEntryEndHead == 64-1)
4153     	    {
4154     	      DiskParameters->Heads = 64;
4155     	      DiskParameters->Sectors = 32;
4156     	      break;
4157     	    }
4158     	  else if (PartitionEntryEndHead == 128-1)
4159     	    {
4160     	      DiskParameters->Heads = 128;
4161     	      DiskParameters->Sectors = 32;
4162     	      break;
4163     	    }
4164     	  else if (PartitionEntryEndHead == 255-1)
4165     	    {
4166     	      DiskParameters->Heads = 255;
4167     	      DiskParameters->Sectors = 63;
4168     	      break;
4169     	    }
4170     	  PartitionEntry++;
4171     	}
4172           if (PartitionNumber == 4)
4173     	{
4174     	  PartitionEntryEndHead = FirstPartitionEntry->end_head;
4175     	  PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F;
4176     	}
4177           DiskParameters->Cylinders =
4178     	Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
4179           if (PartitionNumber < 4 &&
4180     	  PartitionEntryEndSector == DiskParameters->Sectors)
4181     	{
4182     	  if (DiskParameters->Cylinders != SavedCylinders)
4183     	    BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n",
4184     			     HostAdapter,
4185     			     DiskParameters->Heads, DiskParameters->Sectors);
4186     	}
4187           else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0)
4188     	{
4189     	  BusLogic_Warning("Warning: Partition Table appears to "
4190     			   "have Geometry %d/%d which is\n", HostAdapter,
4191     			   PartitionEntryEndHead + 1,
4192     			   PartitionEntryEndSector);
4193     	  BusLogic_Warning("not compatible with current BusLogic "
4194     			   "Host Adapter Geometry %d/%d\n", HostAdapter,
4195     			   DiskParameters->Heads, DiskParameters->Sectors);
4196     	}
4197         }
4198       brelse(BufferHead);
4199       return 0;
4200     }
4201     
4202     
4203     /*
4204       BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
4205     */
4206     
4207     int BusLogic_ProcDirectoryInfo(char *ProcBuffer, char **StartPointer,
4208     			       off_t Offset, int BytesAvailable,
4209     			       int HostNumber, int WriteFlag)
4210     {
4211       BusLogic_HostAdapter_T *HostAdapter;
4212       BusLogic_TargetStatistics_T *TargetStatistics;
4213       int TargetID, Length;
4214       char *Buffer;
4215       for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
4216            HostAdapter != NULL;
4217            HostAdapter = HostAdapter->Next)
4218         if (HostAdapter->HostNumber == HostNumber) break;
4219       if (HostAdapter == NULL)
4220         {
4221           BusLogic_Error("Cannot find Host Adapter for SCSI Host %d\n",
4222     		     NULL, HostNumber);
4223           return 0;
4224         }
4225       TargetStatistics = HostAdapter->TargetStatistics;
4226       if (WriteFlag)
4227         {
4228           HostAdapter->ExternalHostAdapterResets = 0;
4229           HostAdapter->HostAdapterInternalErrors = 0;
4230           memset(TargetStatistics, 0,
4231     	     BusLogic_MaxTargetDevices * sizeof(BusLogic_TargetStatistics_T));
4232           return 0;
4233         }
4234       Buffer = HostAdapter->MessageBuffer;
4235       Length = HostAdapter->MessageBufferLength;
4236       Length += sprintf(&Buffer[Length], "\n\
4237     Current Driver Queue Depth:	%d\n\
4238     Currently Allocated CCBs:	%d\n",
4239     		    HostAdapter->DriverQueueDepth,
4240     		    HostAdapter->AllocatedCCBs);
4241       Length += sprintf(&Buffer[Length], "\n\n\
4242     			   DATA TRANSFER STATISTICS\n\
4243     \n\
4244     Target	Tagged Queuing	Queue Depth  Active  Attempted	Completed\n\
4245     ======	==============	===========  ======  =========	=========\n");
4246       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4247         {
4248           BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4249           if (!TargetFlags->TargetExists) continue;
4250           Length +=
4251     	sprintf(&Buffer[Length], "  %2d	%s", TargetID,
4252     		(TargetFlags->TaggedQueuingSupported
4253     		 ? (TargetFlags->TaggedQueuingActive
4254     		    ? "    Active"
4255     		    : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
4256     		       ? "  Permitted" : "   Disabled"))
4257     		 : "Not Supported"));
4258           Length += sprintf(&Buffer[Length],
4259     			"	    %3d       %3u    %9u	%9u\n",
4260     			HostAdapter->QueueDepth[TargetID],
4261     			HostAdapter->ActiveCommands[TargetID],
4262     			TargetStatistics[TargetID].CommandsAttempted,
4263     			TargetStatistics[TargetID].CommandsCompleted);
4264         }
4265       Length += sprintf(&Buffer[Length], "\n\
4266     Target  Read Commands  Write Commands   Total Bytes Read    Total Bytes Written\n\
4267     ======  =============  ==============  ===================  ===================\n");
4268       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4269         {
4270           BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4271           if (!TargetFlags->TargetExists) continue;
4272           Length +=
4273     	sprintf(&Buffer[Length], "  %2d	  %9u	 %9u", TargetID,
4274     		TargetStatistics[TargetID].ReadCommands,
4275     		TargetStatistics[TargetID].WriteCommands);
4276           if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0)
4277     	Length +=
4278     	  sprintf(&Buffer[Length], "     %9u%09u",
4279     		  TargetStatistics[TargetID].TotalBytesRead.Billions,
4280     		  TargetStatistics[TargetID].TotalBytesRead.Units);
4281           else
4282     	Length +=
4283     	  sprintf(&Buffer[Length], "		%9u",
4284     		  TargetStatistics[TargetID].TotalBytesRead.Units);
4285           if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0)
4286     	Length +=
4287     	  sprintf(&Buffer[Length], "   %9u%09u\n",
4288     		  TargetStatistics[TargetID].TotalBytesWritten.Billions,
4289     		  TargetStatistics[TargetID].TotalBytesWritten.Units);
4290           else
4291     	Length +=
4292     	  sprintf(&Buffer[Length], "	     %9u\n",
4293     		  TargetStatistics[TargetID].TotalBytesWritten.Units);
4294         }
4295       Length += sprintf(&Buffer[Length], "\n\
4296     Target  Command    0-1KB      1-2KB      2-4KB      4-8KB     8-16KB\n\
4297     ======  =======  =========  =========  =========  =========  =========\n");
4298       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4299         {
4300           BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4301           if (!TargetFlags->TargetExists) continue;
4302           Length +=
4303     	sprintf(&Buffer[Length],
4304     		"  %2d	 Read	 %9u  %9u  %9u  %9u  %9u\n", TargetID,
4305     		TargetStatistics[TargetID].ReadCommandSizeBuckets[0],
4306     		TargetStatistics[TargetID].ReadCommandSizeBuckets[1],
4307     		TargetStatistics[TargetID].ReadCommandSizeBuckets[2],
4308     		TargetStatistics[TargetID].ReadCommandSizeBuckets[3],
4309     		TargetStatistics[TargetID].ReadCommandSizeBuckets[4]);
4310           Length +=
4311     	sprintf(&Buffer[Length],
4312     		"  %2d	 Write	 %9u  %9u  %9u  %9u  %9u\n", TargetID,
4313     		TargetStatistics[TargetID].WriteCommandSizeBuckets[0],
4314     		TargetStatistics[TargetID].WriteCommandSizeBuckets[1],
4315     		TargetStatistics[TargetID].WriteCommandSizeBuckets[2],
4316     		TargetStatistics[TargetID].WriteCommandSizeBuckets[3],
4317     		TargetStatistics[TargetID].WriteCommandSizeBuckets[4]);
4318         }
4319       Length += sprintf(&Buffer[Length], "\n\
4320     Target  Command   16-32KB    32-64KB   64-128KB   128-256KB   256KB+\n\
4321     ======  =======  =========  =========  =========  =========  =========\n");
4322       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4323         {
4324           BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4325           if (!TargetFlags->TargetExists) continue;
4326           Length +=
4327     	sprintf(&Buffer[Length],
4328     		"  %2d	 Read	 %9u  %9u  %9u  %9u  %9u\n", TargetID,
4329     		TargetStatistics[TargetID].ReadCommandSizeBuckets[5],
4330     		TargetStatistics[TargetID].ReadCommandSizeBuckets[6],
4331     		TargetStatistics[TargetID].ReadCommandSizeBuckets[7],
4332     		TargetStatistics[TargetID].ReadCommandSizeBuckets[8],
4333     		TargetStatistics[TargetID].ReadCommandSizeBuckets[9]);
4334           Length +=
4335     	sprintf(&Buffer[Length],
4336     		"  %2d	 Write	 %9u  %9u  %9u  %9u  %9u\n", TargetID,
4337     		TargetStatistics[TargetID].WriteCommandSizeBuckets[5],
4338     		TargetStatistics[TargetID].WriteCommandSizeBuckets[6],
4339     		TargetStatistics[TargetID].WriteCommandSizeBuckets[7],
4340     		TargetStatistics[TargetID].WriteCommandSizeBuckets[8],
4341     		TargetStatistics[TargetID].WriteCommandSizeBuckets[9]);
4342         }
4343       Length += sprintf(&Buffer[Length], "\n\n\
4344     			   ERROR RECOVERY STATISTICS\n\
4345     \n\
4346     	  Command Aborts      Bus Device Resets	  Host Adapter Resets\n\
4347     Target	Requested Completed  Requested Completed  Requested Completed\n\
4348       ID	\\\\\\\\ Attempted ////  \\\\\\\\ Attempted ////  \\\\\\\\ Attempted ////\n\
4349     ======	 ===== ===== =====    ===== ===== =====	   ===== ===== =====\n");
4350       for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4351         {
4352           BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4353           if (!TargetFlags->TargetExists) continue;
4354           Length +=
4355     	sprintf(&Buffer[Length], "\
4356       %2d	 %5d %5d %5d    %5d %5d %5d	   %5d %5d %5d\n", TargetID,
4357     		TargetStatistics[TargetID].CommandAbortsRequested,
4358     		TargetStatistics[TargetID].CommandAbortsAttempted,
4359     		TargetStatistics[TargetID].CommandAbortsCompleted,
4360     		TargetStatistics[TargetID].BusDeviceResetsRequested,
4361     		TargetStatistics[TargetID].BusDeviceResetsAttempted,
4362     		TargetStatistics[TargetID].BusDeviceResetsCompleted,
4363     		TargetStatistics[TargetID].HostAdapterResetsRequested,
4364     		TargetStatistics[TargetID].HostAdapterResetsAttempted,
4365     		TargetStatistics[TargetID].HostAdapterResetsCompleted);
4366         }
4367       Length += sprintf(&Buffer[Length], "\nExternal Host Adapter Resets: %d\n",
4368     		    HostAdapter->ExternalHostAdapterResets);
4369       Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %d\n",
4370     		    HostAdapter->HostAdapterInternalErrors);
4371       if (Length >= BusLogic_MessageBufferSize)
4372         BusLogic_Error("Message Buffer length %d exceeds size %d\n",
4373     		   HostAdapter, Length, BusLogic_MessageBufferSize);
4374       if ((Length -= Offset) <= 0) return 0;
4375       if (Length >= BytesAvailable) Length = BytesAvailable;
4376       memcpy(ProcBuffer, HostAdapter->MessageBuffer + Offset, Length);
4377       *StartPointer = ProcBuffer;
4378       return Length;
4379     }
4380     
4381     
4382     /*
4383       BusLogic_Message prints Driver Messages.
4384     */
4385     
4386     static void BusLogic_Message(BusLogic_MessageLevel_T MessageLevel,
4387     			     char *Format,
4388     			     BusLogic_HostAdapter_T *HostAdapter,
4389     			     ...)
4390     {
4391       static char Buffer[BusLogic_LineBufferSize];
4392       static boolean BeginningOfLine = true;
4393       va_list Arguments;
4394       int Length = 0;
4395       va_start(Arguments, HostAdapter);
4396       Length = vsprintf(Buffer, Format, Arguments);
4397       va_end(Arguments);
4398       if (MessageLevel == BusLogic_AnnounceLevel)
4399         {
4400           static int AnnouncementLines = 0;
4401           strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength],
4402     	     Buffer);
4403           HostAdapter->MessageBufferLength += Length;
4404           if (++AnnouncementLines <= 2)
4405     	printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
4406         }
4407       else if (MessageLevel == BusLogic_InfoLevel)
4408         {
4409           strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength],
4410     	     Buffer);
4411           HostAdapter->MessageBufferLength += Length;
4412           if (BeginningOfLine)
4413     	{
4414     	  if (Buffer[0] != '\n' || Length > 1)
4415     	    printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
4416     		   HostAdapter->HostNumber, Buffer);
4417     	}
4418           else printk("%s", Buffer);
4419         }
4420       else
4421         {
4422           if (BeginningOfLine)
4423     	{
4424     	  if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized)
4425     	    printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
4426     		   HostAdapter->HostNumber, Buffer);
4427     	  else printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
4428     	}
4429           else printk("%s", Buffer);
4430         }
4431       BeginningOfLine = (Buffer[Length-1] == '\n');
4432     }
4433     
4434     
4435     /*
4436       BusLogic_ParseKeyword parses an individual option keyword.  It returns true
4437       and updates the pointer if the keyword is recognized and false otherwise.
4438     */
4439     
4440     static boolean BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
4441     {
4442       char *Pointer = *StringPointer;
4443       while (*Keyword != '\0')
4444         {
4445           char StringChar = *Pointer++;
4446           char KeywordChar = *Keyword++;
4447           if (StringChar >= 'A' && StringChar <= 'Z')
4448     	StringChar += 'a' - 'Z';
4449           if (KeywordChar >= 'A' && KeywordChar <= 'Z')
4450     	KeywordChar += 'a' - 'Z';
4451           if (StringChar != KeywordChar) return false;
4452         }
4453       *StringPointer = Pointer;
4454       return true;
4455     }
4456     
4457     
4458     /*
4459       BusLogic_ParseDriverOptions handles processing of BusLogic Driver Options
4460       specifications.
4461     
4462       BusLogic Driver Options may be specified either via the Linux Kernel Command
4463       Line or via the Loadable Kernel Module Installation Facility.  Driver Options
4464       for multiple host adapters may be specified either by separating the option
4465       strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
4466       command line.  Individual option specifications for a single host adapter are
4467       separated by commas.  The Probing and Debugging Options apply to all host
4468       adapters whereas the remaining options apply individually only to the
4469       selected host adapter.
4470     
4471       The BusLogic Driver Probing Options comprise the following:
4472     
4473       IO:<integer>
4474     
4475         The "IO:" option specifies an ISA I/O Address to be probed for a non-PCI
4476         MultiMaster Host Adapter.  If neither "IO:" nor "NoProbeISA" options are
4477         specified, then the standard list of BusLogic MultiMaster ISA I/O Addresses
4478         will be probed (0x330, 0x334, 0x230, 0x234, 0x130, and 0x134).  Multiple
4479         "IO:" options may be specified to precisely determine the I/O Addresses to
4480         be probed, but the probe order will always follow the standard list.
4481     
4482       NoProbe
4483     
4484         The "NoProbe" option disables all probing and therefore no BusLogic Host
4485         Adapters will be detected.
4486     
4487       NoProbeISA
4488     
4489         The "NoProbeISA" option disables probing of the standard BusLogic ISA I/O
4490         Addresses and therefore only PCI MultiMaster and FlashPoint Host Adapters
4491         will be detected.
4492     
4493       NoProbePCI
4494     
4495         The "NoProbePCI" options disables the interrogation of PCI Configuration
4496         Space and therefore only ISA Multimaster Host Adapters will be detected, as
4497         well as PCI Multimaster Host Adapters that have their ISA Compatible I/O
4498         Port set to "Primary" or "Alternate".
4499     
4500       NoSortPCI
4501     
4502         The "NoSortPCI" option forces PCI MultiMaster Host Adapters to be
4503         enumerated in the order provided by the PCI BIOS, ignoring any setting of
4504         the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option.
4505     
4506       MultiMasterFirst
4507     
4508         The "MultiMasterFirst" option forces MultiMaster Host Adapters to be probed
4509         before FlashPoint Host Adapters.  By default, if both FlashPoint and PCI
4510         MultiMaster Host Adapters are present, this driver will probe for
4511         FlashPoint Host Adapters first unless the BIOS primary disk is controlled
4512         by the first PCI MultiMaster Host Adapter, in which case MultiMaster Host
4513         Adapters will be probed first.
4514     
4515       FlashPointFirst
4516     
4517         The "FlashPointFirst" option forces FlashPoint Host Adapters to be probed
4518         before MultiMaster Host Adapters.
4519     
4520       The BusLogic Driver Tagged Queuing Options allow for explicitly specifying
4521       the Queue Depth and whether Tagged Queuing is permitted for each Target
4522       Device (assuming that the Target Device supports Tagged Queuing).  The Queue
4523       Depth is the number of SCSI Commands that are allowed to be concurrently
4524       presented for execution (either to the Host Adapter or Target Device).  Note
4525       that explicitly enabling Tagged Queuing may lead to problems; the option to
4526       enable or disable Tagged Queuing is provided primarily to allow disabling
4527       Tagged Queuing on Target Devices that do not implement it correctly.  The
4528       following options are available:
4529     
4530       QueueDepth:<integer>
4531     
4532         The "QueueDepth:" or QD:" option specifies the Queue Depth to use for all
4533         Target Devices that support Tagged Queuing, as well as the maximum Queue
4534         Depth for devices that do not support Tagged Queuing.  If no Queue Depth
4535         option is provided, the Queue Depth will be determined automatically based
4536         on the Host Adapter's Total Queue Depth and the number, type, speed, and
4537         capabilities of the detected Target Devices.  For Host Adapters that
4538         require ISA Bounce Buffers, the Queue Depth is automatically set by default
4539         to BusLogic_TaggedQueueDepthBB or BusLogic_UntaggedQueueDepthBB to avoid
4540         excessive preallocation of DMA Bounce Buffer memory.  Target Devices that
4541         do not support Tagged Queuing always have their Queue Depth set to
4542         BusLogic_UntaggedQueueDepth or BusLogic_UntaggedQueueDepthBB, unless a
4543         lower Queue Depth option is provided.  A Queue Depth of 1 automatically
4544         disables Tagged Queuing.
4545     
4546       QueueDepth:[<integer>,<integer>...]
4547     
4548         The "QueueDepth:[...]" or "QD:[...]" option specifies the Queue Depth
4549         individually for each Target Device.  If an <integer> is omitted, the
4550         associated Target Device will have its Queue Depth selected automatically.
4551     
4552       TaggedQueuing:Default
4553     
4554         The "TaggedQueuing:Default" or "TQ:Default" option permits Tagged Queuing
4555         based on the firmware version of the BusLogic Host Adapter and based on
4556         whether the Queue Depth allows queuing multiple commands.
4557     
4558       TaggedQueuing:Enable
4559     
4560         The "TaggedQueuing:Enable" or "TQ:Enable" option enables Tagged Queuing for
4561         all Target Devices on this Host Adapter, overriding any limitation that
4562         would otherwise be imposed based on the Host Adapter firmware version.
4563     
4564       TaggedQueuing:Disable
4565     
4566         The "TaggedQueuing:Disable" or "TQ:Disable" option disables Tagged Queuing
4567         for all Target Devices on this Host Adapter.
4568     
4569       TaggedQueuing:<Target-Spec>
4570     
4571         The "TaggedQueuing:<Target-Spec>" or "TQ:<Target-Spec>" option controls
4572         Tagged Queuing individually for each Target Device.  <Target-Spec> is a
4573         sequence of "Y", "N", and "X" characters.  "Y" enables Tagged Queuing, "N"
4574         disables Tagged Queuing, and "X" accepts the default based on the firmware
4575         version.  The first character refers to Target Device 0, the second to
4576         Target Device 1, and so on; if the sequence of "Y", "N", and "X" characters
4577         does not cover all the Target Devices, unspecified characters are assumed
4578         to be "X".
4579     
4580       The BusLogic Driver Error Recovery Option allows for explicitly specifying
4581       the Error Recovery action to be performed when BusLogic_ResetCommand is
4582       called due to a SCSI Command failing to complete successfully.  The following
4583       options are available:
4584     
4585       ErrorRecovery:Default
4586     
4587         The "ErrorRecovery:Default" or "ER:Default" option selects between the Hard
4588         Reset and Bus Device Reset options based on the recommendation of the SCSI
4589         Subsystem.
4590     
4591       ErrorRecovery:HardReset
4592     
4593         The "ErrorRecovery:HardReset" or "ER:HardReset" option will initiate a Host
4594         Adapter Hard Reset which also causes a SCSI Bus Reset.
4595     
4596       ErrorRecovery:BusDeviceReset
4597     
4598         The "ErrorRecovery:BusDeviceReset" or "ER:BusDeviceReset" option will send
4599         a Bus Device Reset message to the individual Target Device causing the
4600         error.  If Error Recovery is again initiated for this Target Device and no
4601         SCSI Command to this Target Device has completed successfully since the Bus
4602         Device Reset message was sent, then a Hard Reset will be attempted.
4603     
4604       ErrorRecovery:None
4605     
4606         The "ErrorRecovery:None" or "ER:None" option suppresses Error Recovery.
4607         This option should only be selected if a SCSI Bus Reset or Bus Device Reset
4608         will cause the Target Device or a critical operation to suffer a complete
4609         and unrecoverable failure.
4610     
4611       ErrorRecovery:<Target-Spec>
4612     
4613         The "ErrorRecovery:<Target-Spec>" or "ER:<Target-Spec>" option controls
4614         Error Recovery individually for each Target Device.  <Target-Spec> is a
4615         sequence of "D", "H", "B", and "N" characters.  "D" selects Default, "H"
4616         selects Hard Reset, "B" selects Bus Device Reset, and "N" selects None.
4617         The first character refers to Target Device 0, the second to Target Device
4618         1, and so on; if the sequence of "D", "H", "B", and "N" characters does not
4619         cover all the possible Target Devices, unspecified characters are assumed
4620         to be "D".
4621     
4622       The BusLogic Driver Miscellaneous Options comprise the following:
4623     
4624       BusSettleTime:<seconds>
4625     
4626         The "BusSettleTime:" or "BST:" option specifies the Bus Settle Time in
4627         seconds.  The Bus Settle Time is the amount of time to wait between a Host
4628         Adapter Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI
4629         Commands.  If unspecified, it defaults to BusLogic_DefaultBusSettleTime.
4630     
4631       InhibitTargetInquiry
4632     
4633         The "InhibitTargetInquiry" option inhibits the execution of an Inquire
4634         Target Devices or Inquire Installed Devices command on MultiMaster Host
4635         Adapters.  This may be necessary with some older Target Devices that do not
4636         respond correctly when Logical Units above 0 are addressed.
4637     
4638       The BusLogic Driver Debugging Options comprise the following:
4639     
4640       TraceProbe
4641     
4642         The "TraceProbe" option enables tracing of Host Adapter Probing.
4643     
4644       TraceHardwareReset
4645     
4646         The "TraceHardwareReset" option enables tracing of Host Adapter Hardware
4647         Reset.
4648     
4649       TraceConfiguration
4650     
4651         The "TraceConfiguration" option enables tracing of Host Adapter
4652         Configuration.
4653     
4654       TraceErrors
4655     
4656         The "TraceErrors" option enables tracing of SCSI Commands that return an
4657         error from the Target Device.  The CDB and Sense Data will be printed for
4658         each SCSI Command that fails.
4659     
4660       Debug
4661     
4662         The "Debug" option enables all debugging options.
4663     
4664       The following examples demonstrate setting the Queue Depth for Target Devices
4665       1 and 2 on the first host adapter to 7 and 15, the Queue Depth for all Target
4666       Devices on the second host adapter to 31, and the Bus Settle Time on the
4667       second host adapter to 30 seconds.
4668     
4669       Linux Kernel Command Line:
4670     
4671         linux BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30
4672     
4673       LILO Linux Boot Loader (in /etc/lilo.conf):
4674     
4675         append = "BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"
4676     
4677       INSMOD Loadable Kernel Module Installation Facility:
4678     
4679         insmod BusLogic.o \
4680     	'BusLogic="QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"'
4681     
4682       NOTE: Module Utilities 2.1.71 or later is required for correct parsing
4683     	of driver options containing commas.
4684     
4685     */
4686     
4687     static int __init BusLogic_ParseDriverOptions(char *OptionsString)
4688     {
4689       while (true)
4690         {
4691           BusLogic_DriverOptions_T *DriverOptions =
4692     	&BusLogic_DriverOptions[BusLogic_DriverOptionsCount++];
4693           int TargetID;
4694           memset(DriverOptions, 0, sizeof(BusLogic_DriverOptions_T));
4695           for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
4696     	DriverOptions->ErrorRecoveryStrategy[TargetID] =
4697     	  BusLogic_ErrorRecovery_Default;
4698           while (*OptionsString != '\0' && *OptionsString != ';')
4699     	{
4700     	  /* Probing Options. */
4701     	  if (BusLogic_ParseKeyword(&OptionsString, "IO:"))
4702     	    {
4703     	      BusLogic_IO_Address_T IO_Address =
4704     		simple_strtoul(OptionsString, &OptionsString, 0);
4705     	      BusLogic_ProbeOptions.LimitedProbeISA = true;
4706     	      switch (IO_Address)
4707     		{
4708     		case 0x330:
4709     		  BusLogic_ProbeOptions.Probe330 = true;
4710     		  break;
4711     		case 0x334:
4712     		  BusLogic_ProbeOptions.Probe334 = true;
4713     		  break;
4714     		case 0x230:
4715     		  BusLogic_ProbeOptions.Probe230 = true;
4716     		  break;
4717     		case 0x234:
4718     		  BusLogic_ProbeOptions.Probe234 = true;
4719     		  break;
4720     		case 0x130:
4721     		  BusLogic_ProbeOptions.Probe130 = true;
4722     		  break;
4723     		case 0x134:
4724     		  BusLogic_ProbeOptions.Probe134 = true;
4725     		  break;
4726     		default:
4727     		  BusLogic_Error("BusLogic: Invalid Driver Options "
4728     				 "(illegal I/O Address 0x%X)\n",
4729     				 NULL, IO_Address);
4730     		  return 0;
4731     		}
4732     	    }
4733     	  else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA"))
4734     	    BusLogic_ProbeOptions.NoProbeISA = true;
4735     	  else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI"))
4736     	    BusLogic_ProbeOptions.NoProbePCI = true;
4737     	  else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe"))
4738     	    BusLogic_ProbeOptions.NoProbe = true;
4739     	  else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI"))
4740     	    BusLogic_ProbeOptions.NoSortPCI = true;
4741     	  else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst"))
4742     	    BusLogic_ProbeOptions.MultiMasterFirst = true;
4743     	  else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst"))
4744     	    BusLogic_ProbeOptions.FlashPointFirst = true;
4745     	  /* Tagged Queuing Options. */
4746     	  else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") ||
4747     		   BusLogic_ParseKeyword(&OptionsString, "QD:["))
4748     	    {
4749     	      for (TargetID = 0;
4750     		   TargetID < BusLogic_MaxTargetDevices;
4751     		   TargetID++)
4752     		{
4753     		  unsigned short QueueDepth =
4754     		    simple_strtoul(OptionsString, &OptionsString, 0);
4755     		  if (QueueDepth > BusLogic_MaxTaggedQueueDepth)
4756     		    {
4757     		      BusLogic_Error("BusLogic: Invalid Driver Options "
4758     				     "(illegal Queue Depth %d)\n",
4759     				     NULL, QueueDepth);
4760     		      return 0;
4761     		    }
4762     		  DriverOptions->QueueDepth[TargetID] = QueueDepth;
4763     		  if (*OptionsString == ',')
4764     		    OptionsString++;
4765     		  else if (*OptionsString == ']')
4766     		    break;
4767     		  else
4768     		    {
4769     		      BusLogic_Error("BusLogic: Invalid Driver Options "
4770     				     "(',' or ']' expected at '%s')\n",
4771     				     NULL, OptionsString);
4772     		      return 0;
4773     		    }
4774     		}
4775     	      if (*OptionsString != ']')
4776     		{
4777     		  BusLogic_Error("BusLogic: Invalid Driver Options "
4778     				 "(']' expected at '%s')\n",
4779     				 NULL, OptionsString);
4780     		  return 0;
4781     		}
4782     	      else OptionsString++;
4783     	    }
4784     	  else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") ||
4785     		   BusLogic_ParseKeyword(&OptionsString, "QD:"))
4786     	    {
4787     	      unsigned short QueueDepth =
4788     		simple_strtoul(OptionsString, &OptionsString, 0);
4789     	      if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth)
4790     		{
4791     		  BusLogic_Error("BusLogic: Invalid Driver Options "
4792     				 "(illegal Queue Depth %d)\n",
4793     				 NULL, QueueDepth);
4794     		  return 0;
4795     		}
4796     	      DriverOptions->CommonQueueDepth = QueueDepth;
4797     	      for (TargetID = 0;
4798     		   TargetID < BusLogic_MaxTargetDevices;
4799     		   TargetID++)
4800     		DriverOptions->QueueDepth[TargetID] = QueueDepth;
4801     	    }
4802     	  else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") ||
4803     		   BusLogic_ParseKeyword(&OptionsString, "TQ:"))
4804     	    {
4805     	      if (BusLogic_ParseKeyword(&OptionsString, "Default"))
4806     		{
4807     		  DriverOptions->TaggedQueuingPermitted = 0x0000;
4808     		  DriverOptions->TaggedQueuingPermittedMask = 0x0000;
4809     		}
4810     	      else if (BusLogic_ParseKeyword(&OptionsString, "Enable"))
4811     		{
4812     		  DriverOptions->TaggedQueuingPermitted = 0xFFFF;
4813     		  DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
4814     		}
4815     	      else if (BusLogic_ParseKeyword(&OptionsString, "Disable"))
4816     		{
4817     		  DriverOptions->TaggedQueuingPermitted = 0x0000;
4818     		  DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
4819     		}
4820     	      else
4821     		{
4822     		  unsigned short TargetBit;
4823     		  for (TargetID = 0, TargetBit = 1;
4824     		       TargetID < BusLogic_MaxTargetDevices;
4825     		       TargetID++, TargetBit <<= 1)
4826     		    switch (*OptionsString++)
4827     		      {
4828     		      case 'Y':
4829     			DriverOptions->TaggedQueuingPermitted |= TargetBit;
4830     			DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
4831     			break;
4832     		      case 'N':
4833     			DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
4834     			DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
4835     			break;
4836     		      case 'X':
4837     			break;
4838     		      default:
4839     			OptionsString--;
4840     			TargetID = BusLogic_MaxTargetDevices;
4841     			break;
4842     		      }
4843     		}
4844     	    }
4845     	  /* Error Recovery Option. */
4846     	  else if (BusLogic_ParseKeyword(&OptionsString, "ErrorRecovery:") ||
4847     		   BusLogic_ParseKeyword(&OptionsString, "ER:"))
4848     	    {
4849     	      if (BusLogic_ParseKeyword(&OptionsString, "Default"))
4850     		for (TargetID = 0;
4851     		     TargetID < BusLogic_MaxTargetDevices;
4852     		     TargetID++)
4853     		  DriverOptions->ErrorRecoveryStrategy[TargetID] =
4854     		    BusLogic_ErrorRecovery_Default;
4855     	      else if (BusLogic_ParseKeyword(&OptionsString, "HardReset"))
4856     		for (TargetID = 0;
4857     		     TargetID < BusLogic_MaxTargetDevices;
4858     		     TargetID++)
4859     		  DriverOptions->ErrorRecoveryStrategy[TargetID] =
4860     		    BusLogic_ErrorRecovery_HardReset;
4861     	      else if (BusLogic_ParseKeyword(&OptionsString, "BusDeviceReset"))
4862     		for (TargetID = 0;
4863     		     TargetID < BusLogic_MaxTargetDevices;
4864     		     TargetID++)
4865     		  DriverOptions->ErrorRecoveryStrategy[TargetID] =
4866     		    BusLogic_ErrorRecovery_BusDeviceReset;
4867     	      else if (BusLogic_ParseKeyword(&OptionsString, "None"))
4868     		for (TargetID = 0;
4869     		     TargetID < BusLogic_MaxTargetDevices;
4870     		     TargetID++)
4871     		  DriverOptions->ErrorRecoveryStrategy[TargetID] =
4872     		    BusLogic_ErrorRecovery_None;
4873     	      else
4874     		for (TargetID = 0;
4875     		     TargetID < BusLogic_MaxTargetDevices;
4876     		     TargetID++)
4877     		  switch (*OptionsString++)
4878     		    {
4879     		    case 'D':
4880     		      DriverOptions->ErrorRecoveryStrategy[TargetID] =
4881     			BusLogic_ErrorRecovery_Default;
4882     		      break;
4883     		    case 'H':
4884     		      DriverOptions->ErrorRecoveryStrategy[TargetID] =
4885     			BusLogic_ErrorRecovery_HardReset;
4886     		      break;
4887     		    case 'B':
4888     		      DriverOptions->ErrorRecoveryStrategy[TargetID] =
4889     			BusLogic_ErrorRecovery_BusDeviceReset;
4890     		      break;
4891     		    case 'N':
4892     		      DriverOptions->ErrorRecoveryStrategy[TargetID] =
4893     			BusLogic_ErrorRecovery_None;
4894     		      break;
4895     		    default:
4896     		      OptionsString--;
4897     		      TargetID = BusLogic_MaxTargetDevices;
4898     		      break;
4899     		    }
4900     	    }
4901     	  /* Miscellaneous Options. */
4902     	  else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") ||
4903     		   BusLogic_ParseKeyword(&OptionsString, "BST:"))
4904     	    {
4905     	      unsigned short BusSettleTime =
4906     		simple_strtoul(OptionsString, &OptionsString, 0);
4907     	      if (BusSettleTime > 5 * 60)
4908     		{
4909     		  BusLogic_Error("BusLogic: Invalid Driver Options "
4910     				 "(illegal Bus Settle Time %d)\n",
4911     				 NULL, BusSettleTime);
4912     		  return 0;
4913     		}
4914     	      DriverOptions->BusSettleTime = BusSettleTime;
4915     	    }
4916     	  else if (BusLogic_ParseKeyword(&OptionsString,
4917     					 "InhibitTargetInquiry"))
4918     	    DriverOptions->LocalOptions.InhibitTargetInquiry = true;
4919     	  /* Debugging Options. */
4920     	  else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe"))
4921     	      BusLogic_GlobalOptions.TraceProbe = true;
4922     	  else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset"))
4923     	      BusLogic_GlobalOptions.TraceHardwareReset = true;
4924     	  else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration"))
4925     	      BusLogic_GlobalOptions.TraceConfiguration = true;
4926     	  else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors"))
4927     	      BusLogic_GlobalOptions.TraceErrors = true;
4928     	  else if (BusLogic_ParseKeyword(&OptionsString, "Debug"))
4929     	    {
4930     	      BusLogic_GlobalOptions.TraceProbe = true;
4931     	      BusLogic_GlobalOptions.TraceHardwareReset = true;
4932     	      BusLogic_GlobalOptions.TraceConfiguration = true;
4933     	      BusLogic_GlobalOptions.TraceErrors = true;
4934     	    }
4935     	  if (*OptionsString == ',')
4936     	    OptionsString++;
4937     	  else if (*OptionsString != ';' && *OptionsString != '\0')
4938     	    {
4939     	      BusLogic_Error("BusLogic: Unexpected Driver Option '%s' "
4940     			     "ignored\n", NULL, OptionsString);
4941     	      *OptionsString = '\0';
4942     	    }
4943     	}
4944           if (!(BusLogic_DriverOptionsCount == 0 ||
4945     	    BusLogic_ProbeInfoCount == 0 ||
4946     	    BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount))
4947     	{
4948     	  BusLogic_Error("BusLogic: Invalid Driver Options "
4949     			 "(all or no I/O Addresses must be specified)\n", NULL);
4950     	  return 0;
4951     	}
4952           /*
4953     	Tagged Queuing is disabled when the Queue Depth is 1 since queuing
4954     	multiple commands is not possible.
4955           */
4956           for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
4957     	if (DriverOptions->QueueDepth[TargetID] == 1)
4958     	  {
4959     	    unsigned short TargetBit = 1 << TargetID;
4960     	    DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
4961     	    DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
4962     	  }
4963           if (*OptionsString == ';') OptionsString++;
4964           if (*OptionsString == '\0') return 0;
4965         }
4966         return 1;
4967     }
4968     
4969     
4970     /*
4971       BusLogic_Setup handles processing of Kernel Command Line Arguments.
4972     */
4973     
4974     static int __init 
4975     BusLogic_Setup(char *str)
4976     {
4977     	int ints[3];
4978     
4979     	(void)get_options(str, ARRAY_SIZE(ints), ints);
4980     
4981     	if (ints[0] != 0) {
4982     		BusLogic_Error("BusLogic: Obsolete Command Line Entry "
4983     				"Format Ignored\n", NULL);
4984     		return 0;
4985     	}
4986     	if (str == NULL || *str == '\0')
4987     		return 0;
4988     	return BusLogic_ParseDriverOptions(str);
4989     }
4990     
4991     __setup("BusLogic=", BusLogic_Setup);
4992     
4993     /*
4994       Get it all started
4995     */
4996     
4997     static SCSI_Host_Template_T driver_template = BUSLOGIC;
4998     
4999     #include "scsi_module.c"
5000