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 
BusLogic_AnnounceDriver(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_DriverInfo(SCSI_Host_T * Host)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 
BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_InitializeCCBs(BusLogic_HostAdapter_T * HostAdapter,void * BlockPointer,int BlockSize)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 
BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_DestroyCCBs(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_CreateAdditionalCCBs(BusLogic_HostAdapter_T * HostAdapter,int AdditionalCCBs,boolean SuccessMessageP)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 
BusLogic_AllocateCCB(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_DeallocateCCB(BusLogic_CCB_T * CCB)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 
BusLogic_Command(BusLogic_HostAdapter_T * HostAdapter,BusLogic_OperationCode_T OperationCode,void * ParameterData,int ParameterLength,void * ReplyData,int ReplyLength)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 
BusLogic_AppendProbeAddressISA(BusLogic_IO_Address_T IO_Address)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 
BusLogic_InitializeProbeInfoListISA(BusLogic_HostAdapter_T * PrototypeHostAdapter)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 
BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T * ProbeInfoList,int ProbeInfoCount)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 
BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T * PrototypeHostAdapter)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 
BusLogic_InitializeFlashPointProbeInfo(BusLogic_HostAdapter_T * PrototypeHostAdapter)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 
BusLogic_InitializeProbeInfoList(BusLogic_HostAdapter_T * PrototypeHostAdapter)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 
BusLogic_Failure(BusLogic_HostAdapter_T * HostAdapter,char * ErrorMessage)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 
BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_HardwareResetHostAdapter(BusLogic_HostAdapter_T * HostAdapter,boolean HardReset)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 
BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_AcquireResources(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_ReleaseResources(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_ReportTargetDeviceInfo(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T * HostAdapter,SCSI_Host_T * Host)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 
BusLogic_SelectQueueDepths(SCSI_Host_T * Host,SCSI_Device_T * DeviceList)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 
BusLogic_DetectHostAdapter(SCSI_Host_Template_T * HostTemplate)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 
BusLogic_ReleaseHostAdapter(SCSI_Host_T * Host)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 
BusLogic_QueueCompletedCCB(BusLogic_CCB_T * CCB)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 
BusLogic_ComputeResultCode(BusLogic_HostAdapter_T * HostAdapter,BusLogic_HostAdapterStatus_T HostAdapterStatus,BusLogic_TargetDeviceStatus_T TargetDeviceStatus)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 
BusLogic_ScanIncomingMailboxes(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_ProcessCompletedCCBs(BusLogic_HostAdapter_T * HostAdapter)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 
BusLogic_InterruptHandler(int IRQ_Channel,void * DeviceIdentifier,Registers_T * InterruptRegisters)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 
BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T * HostAdapter,BusLogic_ActionCode_T ActionCode,BusLogic_CCB_T * CCB)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 
BusLogic_QueueCommand(SCSI_Command_T * Command,void (* CompletionRoutine)(SCSI_Command_T *))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 
BusLogic_AbortCommand(SCSI_Command_T * Command)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 
BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T * HostAdapter,SCSI_Command_T * Command,unsigned int ResetFlags)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 
BusLogic_SendBusDeviceReset(BusLogic_HostAdapter_T * HostAdapter,SCSI_Command_T * Command,unsigned int ResetFlags)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 
BusLogic_ResetCommand(SCSI_Command_T * Command,unsigned int ResetFlags)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 
BusLogic_BIOSDiskParameters(SCSI_Disk_T * Disk,KernelDevice_T Device,int * Parameters)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, block_size(Device));
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 
BusLogic_ProcDirectoryInfo(char * ProcBuffer,char ** StartPointer,off_t Offset,int BytesAvailable,int HostNumber,int WriteFlag)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 
BusLogic_Message(BusLogic_MessageLevel_T MessageLevel,char * Format,BusLogic_HostAdapter_T * HostAdapter,...)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 
BusLogic_ParseKeyword(char ** StringPointer,char * Keyword)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 
BusLogic_ParseDriverOptions(char * OptionsString)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
BusLogic_Setup(char * str)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 MODULE_LICENSE("GPL");
4997 
4998 static SCSI_Host_Template_T driver_template = BUSLOGIC;
4999 
5000 #include "scsi_module.c"
5001