- pre4:
[davej-history.git] / drivers / scsi / BusLogic.c
blob9c3429b4fd6db0f9793a9354122b9a2a11080f8c
1 /*
3 Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters
5 Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>
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.
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.
16 The author respectfully requests that any modifications to this software be
17 sent directly to him for evaluation and testing.
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.
23 Finally, special thanks to Mylex/BusLogic for making the FlashPoint SCCB
24 Manager available as freely redistributable source code.
29 #define BusLogic_DriverVersion "2.1.15"
30 #define BusLogic_DriverDate "17 August 1998"
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"
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.
63 static int
64 BusLogic_DriverOptionsCount = 0;
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.
73 static BusLogic_DriverOptions_T
74 BusLogic_DriverOptions[BusLogic_MaxHostAdapters];
78 BusLogic can be assigned a string by insmod.
81 #ifdef MODULE
82 static char *BusLogic = NULL;
83 MODULE_PARM(BusLogic, "s");
84 #endif
88 BusLogic_ProbeOptions is a set of Probe Options to be applied across
89 all BusLogic Host Adapters.
92 static BusLogic_ProbeOptions_T
93 BusLogic_ProbeOptions = { 0 };
97 BusLogic_GlobalOptions is a set of Global Options to be applied across
98 all BusLogic Host Adapters.
101 static BusLogic_GlobalOptions_T
102 BusLogic_GlobalOptions = { 0 };
106 BusLogic_FirstRegisteredHostAdapter and BusLogic_LastRegisteredHostAdapter
107 are pointers to the first and last registered BusLogic Host Adapters.
110 static BusLogic_HostAdapter_T
111 *BusLogic_FirstRegisteredHostAdapter = NULL,
112 *BusLogic_LastRegisteredHostAdapter = NULL;
116 BusLogic_ProbeInfoCount is the number of entries in BusLogic_ProbeInfoList.
119 static int
120 BusLogic_ProbeInfoCount = 0;
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.
130 static BusLogic_ProbeInfo_T
131 *BusLogic_ProbeInfoList = NULL;
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.
140 static char
141 *BusLogic_CommandFailureReason;
144 BusLogic_AnnounceDriver announces the Driver Version and Date, Author's
145 Name, Copyright Notice, and Electronic Mail Address.
148 static void BusLogic_AnnounceDriver(BusLogic_HostAdapter_T *HostAdapter)
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);
159 BusLogic_DriverInfo returns the Host Adapter Name to identify this SCSI
160 Driver and Host Adapter.
163 const char *BusLogic_DriverInfo(SCSI_Host_T *Host)
165 BusLogic_HostAdapter_T *HostAdapter =
166 (BusLogic_HostAdapter_T *) Host->hostdata;
167 return HostAdapter->FullModelName;
172 BusLogic_RegisterHostAdapter adds Host Adapter to the list of registered
173 BusLogic Host Adapters.
176 static void BusLogic_RegisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
178 HostAdapter->Next = NULL;
179 if (BusLogic_FirstRegisteredHostAdapter == NULL)
181 BusLogic_FirstRegisteredHostAdapter = HostAdapter;
182 BusLogic_LastRegisteredHostAdapter = HostAdapter;
184 else
186 BusLogic_LastRegisteredHostAdapter->Next = HostAdapter;
187 BusLogic_LastRegisteredHostAdapter = HostAdapter;
193 BusLogic_UnregisterHostAdapter removes Host Adapter from the list of
194 registered BusLogic Host Adapters.
197 static void BusLogic_UnregisterHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
199 if (HostAdapter == BusLogic_FirstRegisteredHostAdapter)
201 BusLogic_FirstRegisteredHostAdapter =
202 BusLogic_FirstRegisteredHostAdapter->Next;
203 if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
204 BusLogic_LastRegisteredHostAdapter = NULL;
206 else
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;
216 HostAdapter->Next = NULL;
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.
226 static void BusLogic_InitializeCCBs(BusLogic_HostAdapter_T *HostAdapter,
227 void *BlockPointer, int BlockSize)
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)
234 CCB->Status = BusLogic_CCB_Free;
235 CCB->HostAdapter = HostAdapter;
236 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
238 CCB->CallbackFunction = BusLogic_QueueCompletedCCB;
239 CCB->BaseAddress = HostAdapter->FlashPointInfo.BaseAddress;
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++;
252 BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter.
255 static boolean BusLogic_CreateInitialCCBs(BusLogic_HostAdapter_T *HostAdapter)
257 int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(BusLogic_CCB_T);
258 while (HostAdapter->AllocatedCCBs < HostAdapter->InitialCCBs)
260 void *BlockPointer = kmalloc(BlockSize,
261 (HostAdapter->BounceBuffersRequired
262 ? GFP_ATOMIC | GFP_DMA
263 : GFP_ATOMIC));
264 if (BlockPointer == NULL)
266 BusLogic_Error("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n",
267 HostAdapter);
268 return false;
270 BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize);
272 return true;
277 BusLogic_DestroyCCBs deallocates the CCBs for Host Adapter.
280 static void BusLogic_DestroyCCBs(BusLogic_HostAdapter_T *HostAdapter)
282 BusLogic_CCB_T *NextCCB = HostAdapter->All_CCBs, *CCB;
283 HostAdapter->All_CCBs = NULL;
284 HostAdapter->Free_CCBs = NULL;
285 while ((CCB = NextCCB) != NULL)
287 NextCCB = CCB->NextAll;
288 if (CCB->AllocationGroupHead)
289 kfree(CCB);
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.
301 static void BusLogic_CreateAdditionalCCBs(BusLogic_HostAdapter_T *HostAdapter,
302 int AdditionalCCBs,
303 boolean SuccessMessageP)
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)
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);
317 if (HostAdapter->AllocatedCCBs > PreviouslyAllocated)
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;
326 BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter);
327 if (HostAdapter->DriverQueueDepth >
328 HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount)
330 HostAdapter->DriverQueueDepth =
331 HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount;
332 HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth;
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.
343 static BusLogic_CCB_T *BusLogic_AllocateCCB(BusLogic_HostAdapter_T
344 *HostAdapter)
346 static unsigned long SerialNumber = 0;
347 BusLogic_CCB_T *CCB;
348 CCB = HostAdapter->Free_CCBs;
349 if (CCB != NULL)
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;
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;
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.
378 static void BusLogic_DeallocateCCB(BusLogic_CCB_T *CCB)
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;
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.
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.
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.
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)
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;
421 Clear out the Reply Data if provided.
423 if (ReplyLength > 0)
424 memset(ReplyData, 0, ReplyLength);
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.
431 if (!HostAdapter->IRQ_ChannelAcquired)
433 save_flags(ProcessorFlags);
434 cli();
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.
440 TimeoutCounter = 10000;
441 while (--TimeoutCounter >= 0)
443 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
444 if (StatusRegister.Bits.HostAdapterReady &&
445 !StatusRegister.Bits.CommandParameterRegisterBusy)
446 break;
447 udelay(100);
449 if (TimeoutCounter < 0)
451 BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
452 Result = -2;
453 goto Done;
456 Write the OperationCode to the Command/Parameter Register.
458 HostAdapter->HostAdapterCommandCompleted = false;
459 BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
461 Write any additional Parameter Bytes.
463 TimeoutCounter = 10000;
464 while (ParameterLength > 0 && --TimeoutCounter >= 0)
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.
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--;
488 if (TimeoutCounter < 0)
490 BusLogic_CommandFailureReason =
491 "Timeout waiting for Parameter Acceptance";
492 Result = -2;
493 goto Done;
496 The Modify I/O Address command does not cause a Command Complete Interrupt.
498 if (OperationCode == BusLogic_ModifyIOAddress)
500 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
501 if (StatusRegister.Bits.CommandInvalid)
503 BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
504 Result = -1;
505 goto Done;
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;
515 Select an appropriate timeout value for awaiting command completion.
517 switch (OperationCode)
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;
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.
535 while (--TimeoutCounter >= 0)
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)
543 if (++ReplyBytes <= ReplyLength)
544 *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
545 else BusLogic_ReadDataInRegister(HostAdapter);
547 if (OperationCode == BusLogic_FetchHostAdapterLocalRAM &&
548 StatusRegister.Bits.HostAdapterReady) break;
549 udelay(100);
551 if (TimeoutCounter < 0)
553 BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
554 Result = -2;
555 goto Done;
558 Clear any pending Command Complete Interrupt.
560 BusLogic_InterruptReset(HostAdapter);
562 Provide tracing information if requested.
564 if (BusLogic_GlobalOptions.TraceConfiguration)
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);
577 Process Command Invalid conditions.
579 if (StatusRegister.Bits.CommandInvalid)
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.
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)
600 BusLogic_SoftReset(HostAdapter);
601 udelay(1000);
603 BusLogic_CommandFailureReason = "Command Invalid";
604 Result = -1;
605 goto Done;
608 Handle Excess Parameters Supplied conditions.
610 if (ParameterLength > 0)
612 BusLogic_CommandFailureReason = "Excess Parameters Supplied";
613 Result = -1;
614 goto Done;
617 Indicate the command completed successfully.
619 BusLogic_CommandFailureReason = NULL;
620 Result = ReplyBytes;
622 Restore the interrupt status if necessary and return.
624 Done:
625 if (!HostAdapter->IRQ_ChannelAcquired)
626 restore_flags(ProcessorFlags);
627 return Result;
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.
637 static void BusLogic_AppendProbeAddressISA(BusLogic_IO_Address_T IO_Address)
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;
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.
654 static void BusLogic_InitializeProbeInfoListISA(BusLogic_HostAdapter_T
655 *PrototypeHostAdapter)
658 If BusLogic Driver Options specifications requested that ISA Bus Probes
659 be inhibited, do not proceed further.
661 if (BusLogic_ProbeOptions.NoProbeISA) return;
663 Append the list of standard BusLogic MultiMaster ISA I/O Addresses.
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);
692 #ifdef CONFIG_PCI
696 BusLogic_SortProbeInfo sorts a section of BusLogic_ProbeInfoList in order
697 of increasing PCI Bus and Device Number.
700 static void BusLogic_SortProbeInfo(BusLogic_ProbeInfo_T *ProbeInfoList,
701 int ProbeInfoCount)
703 int LastInterchange = ProbeInfoCount-1, Bound, j;
704 while (LastInterchange > 0)
706 Bound = LastInterchange;
707 LastInterchange = 0;
708 for (j = 0; j < Bound; j++)
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)))
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;
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.
735 static int BusLogic_InitializeMultiMasterProbeInfo(BusLogic_HostAdapter_T
736 *PrototypeHostAdapter)
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;
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.
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)
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 = PCI_Device->irq;
774 unsigned long BaseAddress0 = pci_resource_start(PCI_Device, 0);
775 unsigned long BaseAddress1 = pci_resource_start(PCI_Device, 1);
776 BusLogic_IO_Address_T IO_Address = BaseAddress0;
777 BusLogic_PCI_Address_T PCI_Address = BaseAddress1;
779 if (pci_enable_device(PCI_Device))
780 continue;
782 if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM)
784 BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
785 "MultiMaster Host Adapter\n", NULL, BaseAddress0);
786 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
787 NULL, Bus, Device, IO_Address);
788 continue;
790 if (pci_resource_flags(PCI_Device,1) & IORESOURCE_IO)
792 BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
793 "MultiMaster Host Adapter\n", NULL, BaseAddress1);
794 BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n",
795 NULL, Bus, Device, PCI_Address);
796 continue;
798 if (IRQ_Channel == 0)
800 BusLogic_Error("BusLogic: IRQ Channel %d illegal for "
801 "MultiMaster Host Adapter\n", NULL, IRQ_Channel);
802 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
803 NULL, Bus, Device, IO_Address);
804 continue;
806 if (BusLogic_GlobalOptions.TraceProbe)
808 BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter "
809 "detected at\n", NULL);
810 BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address "
811 "0x%X PCI Address 0x%X\n", NULL,
812 Bus, Device, IO_Address, PCI_Address);
815 Issue the Inquire PCI Host Adapter Information command to determine
816 the ISA Compatible I/O Port. If the ISA Compatible I/O Port is
817 known and enabled, note that the particular Standard ISA I/O
818 Address should not be probed.
820 HostAdapter->IO_Address = IO_Address;
821 BusLogic_InterruptReset(HostAdapter);
822 if (BusLogic_Command(HostAdapter,
823 BusLogic_InquirePCIHostAdapterInformation,
824 NULL, 0, &PCIHostAdapterInformation,
825 sizeof(PCIHostAdapterInformation))
826 == sizeof(PCIHostAdapterInformation))
828 if (PCIHostAdapterInformation.ISACompatibleIOPort < 6)
829 StandardAddressSeen[PCIHostAdapterInformation
830 .ISACompatibleIOPort] = true;
832 else PCIHostAdapterInformation.ISACompatibleIOPort =
833 BusLogic_IO_Disable;
835 Issue the Modify I/O Address command to disable the ISA Compatible
836 I/O Port.
838 ModifyIOAddressRequest = BusLogic_IO_Disable;
839 BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress,
840 &ModifyIOAddressRequest,
841 sizeof(ModifyIOAddressRequest), NULL, 0);
843 For the first MultiMaster Host Adapter enumerated, issue the Fetch
844 Host Adapter Local RAM command to read byte 45 of the AutoSCSI area,
845 for the setting of the "Use Bus And Device # For PCI Scanning Seq."
846 option. Issue the Inquire Board ID command since this option is
847 only valid for the BT-948/958/958D.
849 if (!ForceBusDeviceScanningOrderChecked)
851 BusLogic_FetchHostAdapterLocalRAMRequest_T
852 FetchHostAdapterLocalRAMRequest;
853 BusLogic_AutoSCSIByte45_T AutoSCSIByte45;
854 BusLogic_BoardID_T BoardID;
855 FetchHostAdapterLocalRAMRequest.ByteOffset =
856 BusLogic_AutoSCSI_BaseOffset + 45;
857 FetchHostAdapterLocalRAMRequest.ByteCount =
858 sizeof(AutoSCSIByte45);
859 BusLogic_Command(HostAdapter,
860 BusLogic_FetchHostAdapterLocalRAM,
861 &FetchHostAdapterLocalRAMRequest,
862 sizeof(FetchHostAdapterLocalRAMRequest),
863 &AutoSCSIByte45, sizeof(AutoSCSIByte45));
864 BusLogic_Command(HostAdapter, BusLogic_InquireBoardID,
865 NULL, 0, &BoardID, sizeof(BoardID));
866 if (BoardID.FirmwareVersion1stDigit == '5')
867 ForceBusDeviceScanningOrder =
868 AutoSCSIByte45.ForceBusDeviceScanningOrder;
869 ForceBusDeviceScanningOrderChecked = true;
872 Determine whether this MultiMaster Host Adapter has its ISA
873 Compatible I/O Port enabled and is assigned the Primary I/O Address.
874 If it does, then it is the Primary MultiMaster Host Adapter and must
875 be recognized first. If it does not, then it is added to the list
876 for probing after any Primary MultiMaster Host Adapter is probed.
878 if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330)
880 PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
881 PrimaryProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
882 PrimaryProbeInfo->IO_Address = IO_Address;
883 PrimaryProbeInfo->PCI_Address = PCI_Address;
884 PrimaryProbeInfo->Bus = Bus;
885 PrimaryProbeInfo->Device = Device;
886 PrimaryProbeInfo->IRQ_Channel = IRQ_Channel;
887 PCIMultiMasterCount++;
889 else if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
891 BusLogic_ProbeInfo_T *ProbeInfo =
892 &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
893 ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
894 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
895 ProbeInfo->IO_Address = IO_Address;
896 ProbeInfo->PCI_Address = PCI_Address;
897 ProbeInfo->Bus = Bus;
898 ProbeInfo->Device = Device;
899 ProbeInfo->IRQ_Channel = IRQ_Channel;
900 NonPrimaryPCIMultiMasterCount++;
901 PCIMultiMasterCount++;
903 else BusLogic_Warning("BusLogic: Too many Host Adapters "
904 "detected\n", NULL);
907 If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option is ON
908 for the first enumerated MultiMaster Host Adapter, and if that host adapter
909 is a BT-948/958/958D, then the MultiMaster BIOS will recognize MultiMaster
910 Host Adapters in the order of increasing PCI Bus and Device Number. In
911 that case, sort the probe information into the same order the BIOS uses.
912 If this option is OFF, then the MultiMaster BIOS will recognize MultiMaster
913 Host Adapters in the order they are enumerated by the PCI BIOS, and hence
914 no sorting is necessary.
916 if (ForceBusDeviceScanningOrder)
917 BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[
918 NonPrimaryPCIMultiMasterIndex],
919 NonPrimaryPCIMultiMasterCount);
921 If no PCI MultiMaster Host Adapter is assigned the Primary I/O Address,
922 then the Primary I/O Address must be probed explicitly before any PCI
923 host adapters are probed.
925 if (!BusLogic_ProbeOptions.NoProbeISA)
926 if (PrimaryProbeInfo->IO_Address == 0 &&
927 (BusLogic_ProbeOptions.LimitedProbeISA
928 ? BusLogic_ProbeOptions.Probe330
929 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0))
931 PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
932 PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
933 PrimaryProbeInfo->IO_Address = 0x330;
936 Append the list of standard BusLogic MultiMaster ISA I/O Addresses,
937 omitting the Primary I/O Address which has already been handled.
939 if (!BusLogic_ProbeOptions.NoProbeISA)
941 if (!StandardAddressSeen[1] &&
942 (BusLogic_ProbeOptions.LimitedProbeISA
943 ? BusLogic_ProbeOptions.Probe334
944 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0))
945 BusLogic_AppendProbeAddressISA(0x334);
946 if (!StandardAddressSeen[2] &&
947 (BusLogic_ProbeOptions.LimitedProbeISA
948 ? BusLogic_ProbeOptions.Probe230
949 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0))
950 BusLogic_AppendProbeAddressISA(0x230);
951 if (!StandardAddressSeen[3] &&
952 (BusLogic_ProbeOptions.LimitedProbeISA
953 ? BusLogic_ProbeOptions.Probe234
954 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0))
955 BusLogic_AppendProbeAddressISA(0x234);
956 if (!StandardAddressSeen[4] &&
957 (BusLogic_ProbeOptions.LimitedProbeISA
958 ? BusLogic_ProbeOptions.Probe130
959 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0))
960 BusLogic_AppendProbeAddressISA(0x130);
961 if (!StandardAddressSeen[5] &&
962 (BusLogic_ProbeOptions.LimitedProbeISA
963 ? BusLogic_ProbeOptions.Probe134
964 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0))
965 BusLogic_AppendProbeAddressISA(0x134);
968 Iterate over the older non-compliant MultiMaster PCI Host Adapters,
969 noting the PCI bus location and assigned IRQ Channel.
971 PCI_Device = NULL;
972 while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
973 PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
974 PCI_Device)) != NULL)
976 unsigned char Bus = PCI_Device->bus->number;
977 unsigned char Device = PCI_Device->devfn >> 3;
978 unsigned int IRQ_Channel = PCI_Device->irq;
979 BusLogic_IO_Address_T IO_Address = pci_resource_start(PCI_Device, 0);
981 if (pci_enable_device(PCI_Device))
982 continue;
984 if (IO_Address == 0 || IRQ_Channel == 0) continue;
985 for (i = 0; i < BusLogic_ProbeInfoCount; i++)
987 BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[i];
988 if (ProbeInfo->IO_Address == IO_Address &&
989 ProbeInfo->HostAdapterType == BusLogic_MultiMaster)
991 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
992 ProbeInfo->PCI_Address = 0;
993 ProbeInfo->Bus = Bus;
994 ProbeInfo->Device = Device;
995 ProbeInfo->IRQ_Channel = IRQ_Channel;
996 break;
1000 return PCIMultiMasterCount;
1005 BusLogic_InitializeFlashPointProbeInfo initializes the list of I/O Address
1006 and Bus Probe Information to be checked for potential BusLogic FlashPoint
1007 Host Adapters by interrogating the PCI Configuration Space. It returns the
1008 number of FlashPoint Host Adapters found.
1011 static int BusLogic_InitializeFlashPointProbeInfo(BusLogic_HostAdapter_T
1012 *PrototypeHostAdapter)
1014 int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0;
1015 PCI_Device_T *PCI_Device = NULL;
1017 Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
1019 while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
1020 PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
1021 PCI_Device)) != NULL)
1023 unsigned char Bus = PCI_Device->bus->number;
1024 unsigned char Device = PCI_Device->devfn >> 3;
1025 unsigned int IRQ_Channel = PCI_Device->irq;
1026 unsigned long BaseAddress0 = pci_resource_start(PCI_Device, 0);
1027 unsigned long BaseAddress1 = pci_resource_start(PCI_Device, 1);
1028 BusLogic_IO_Address_T IO_Address = BaseAddress0;
1029 BusLogic_PCI_Address_T PCI_Address = BaseAddress1;
1031 if (pci_enable_device(PCI_Device))
1032 continue;
1034 #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
1035 if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM)
1037 BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
1038 "FlashPoint Host Adapter\n", NULL, BaseAddress0);
1039 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
1040 NULL, Bus, Device, IO_Address);
1041 continue;
1043 if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO)
1045 BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
1046 "FlashPoint Host Adapter\n", NULL, BaseAddress1);
1047 BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n",
1048 NULL, Bus, Device, PCI_Address);
1049 continue;
1051 if (IRQ_Channel == 0)
1053 BusLogic_Error("BusLogic: IRQ Channel %d illegal for "
1054 "FlashPoint Host Adapter\n", NULL, IRQ_Channel);
1055 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
1056 NULL, Bus, Device, IO_Address);
1057 continue;
1059 if (BusLogic_GlobalOptions.TraceProbe)
1061 BusLogic_Notice("BusLogic: FlashPoint Host Adapter "
1062 "detected at\n", NULL);
1063 BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address "
1064 "0x%X PCI Address 0x%X\n", NULL,
1065 Bus, Device, IO_Address, PCI_Address);
1067 if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
1069 BusLogic_ProbeInfo_T *ProbeInfo =
1070 &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
1071 ProbeInfo->HostAdapterType = BusLogic_FlashPoint;
1072 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
1073 ProbeInfo->IO_Address = IO_Address;
1074 ProbeInfo->PCI_Address = PCI_Address;
1075 ProbeInfo->Bus = Bus;
1076 ProbeInfo->Device = Device;
1077 ProbeInfo->IRQ_Channel = IRQ_Channel;
1078 FlashPointCount++;
1080 else BusLogic_Warning("BusLogic: Too many Host Adapters "
1081 "detected\n", NULL);
1082 #else
1083 BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
1084 "PCI Bus %d Device %d\n", NULL, Bus, Device);
1085 BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, "
1086 "but FlashPoint\n", NULL, IO_Address, PCI_Address, IRQ_Channel);
1087 BusLogic_Error("BusLogic: support was omitted in this kernel "
1088 "configuration.\n", NULL);
1089 #endif
1092 The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of
1093 increasing PCI Bus and Device Number, so sort the probe information into
1094 the same order the BIOS uses.
1096 BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[FlashPointIndex],
1097 FlashPointCount);
1098 return FlashPointCount;
1103 BusLogic_InitializeProbeInfoList initializes the list of I/O Address and Bus
1104 Probe Information to be checked for potential BusLogic SCSI Host Adapters by
1105 interrogating the PCI Configuration Space on PCI machines as well as from the
1106 list of standard BusLogic MultiMaster ISA I/O Addresses. By default, if both
1107 FlashPoint and PCI MultiMaster Host Adapters are present, this driver will
1108 probe for FlashPoint Host Adapters first unless the BIOS primary disk is
1109 controlled by the first PCI MultiMaster Host Adapter, in which case
1110 MultiMaster Host Adapters will be probed first. The BusLogic Driver Options
1111 specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force
1112 a particular probe order.
1115 static void BusLogic_InitializeProbeInfoList(BusLogic_HostAdapter_T
1116 *PrototypeHostAdapter)
1119 If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint
1120 Host Adapters; otherwise, default to the standard ISA MultiMaster probe.
1122 if (!BusLogic_ProbeOptions.NoProbePCI && pci_present())
1124 if (BusLogic_ProbeOptions.MultiMasterFirst)
1126 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1127 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1129 else if (BusLogic_ProbeOptions.FlashPointFirst)
1131 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1132 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1134 else
1136 int FlashPointCount =
1137 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1138 int PCIMultiMasterCount =
1139 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1140 if (FlashPointCount > 0 && PCIMultiMasterCount > 0)
1142 BusLogic_ProbeInfo_T *ProbeInfo =
1143 &BusLogic_ProbeInfoList[FlashPointCount];
1144 BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
1145 BusLogic_FetchHostAdapterLocalRAMRequest_T
1146 FetchHostAdapterLocalRAMRequest;
1147 BusLogic_BIOSDriveMapByte_T Drive0MapByte;
1148 while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus)
1149 ProbeInfo++;
1150 HostAdapter->IO_Address = ProbeInfo->IO_Address;
1151 FetchHostAdapterLocalRAMRequest.ByteOffset =
1152 BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0;
1153 FetchHostAdapterLocalRAMRequest.ByteCount =
1154 sizeof(Drive0MapByte);
1155 BusLogic_Command(HostAdapter,
1156 BusLogic_FetchHostAdapterLocalRAM,
1157 &FetchHostAdapterLocalRAMRequest,
1158 sizeof(FetchHostAdapterLocalRAMRequest),
1159 &Drive0MapByte, sizeof(Drive0MapByte));
1161 If the Map Byte for BIOS Drive 0 indicates that BIOS Drive 0
1162 is controlled by this PCI MultiMaster Host Adapter, then
1163 reverse the probe order so that MultiMaster Host Adapters are
1164 probed before FlashPoint Host Adapters.
1166 if (Drive0MapByte.DiskGeometry !=
1167 BusLogic_BIOS_Disk_Not_Installed)
1169 BusLogic_ProbeInfo_T
1170 SavedProbeInfo[BusLogic_MaxHostAdapters];
1171 int MultiMasterCount =
1172 BusLogic_ProbeInfoCount - FlashPointCount;
1173 memcpy(SavedProbeInfo,
1174 BusLogic_ProbeInfoList,
1175 BusLogic_ProbeInfoCount
1176 * sizeof(BusLogic_ProbeInfo_T));
1177 memcpy(&BusLogic_ProbeInfoList[0],
1178 &SavedProbeInfo[FlashPointCount],
1179 MultiMasterCount * sizeof(BusLogic_ProbeInfo_T));
1180 memcpy(&BusLogic_ProbeInfoList[MultiMasterCount],
1181 &SavedProbeInfo[0],
1182 FlashPointCount * sizeof(BusLogic_ProbeInfo_T));
1187 else BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter);
1191 #endif /* CONFIG_PCI */
1195 BusLogic_Failure prints a standardized error message, and then returns false.
1198 static boolean BusLogic_Failure(BusLogic_HostAdapter_T *HostAdapter,
1199 char *ErrorMessage)
1201 BusLogic_AnnounceDriver(HostAdapter);
1202 if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus)
1204 BusLogic_Error("While configuring BusLogic PCI Host Adapter at\n",
1205 HostAdapter);
1206 BusLogic_Error("Bus %d Device %d I/O Address 0x%X PCI Address 0x%X:\n",
1207 HostAdapter, HostAdapter->Bus, HostAdapter->Device,
1208 HostAdapter->IO_Address, HostAdapter->PCI_Address);
1210 else BusLogic_Error("While configuring BusLogic Host Adapter at "
1211 "I/O Address 0x%X:\n", HostAdapter,
1212 HostAdapter->IO_Address);
1213 BusLogic_Error("%s FAILED - DETACHING\n", HostAdapter, ErrorMessage);
1214 if (BusLogic_CommandFailureReason != NULL)
1215 BusLogic_Error("ADDITIONAL FAILURE INFO - %s\n", HostAdapter,
1216 BusLogic_CommandFailureReason);
1217 return false;
1222 BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
1225 static boolean BusLogic_ProbeHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
1227 BusLogic_StatusRegister_T StatusRegister;
1228 BusLogic_InterruptRegister_T InterruptRegister;
1229 BusLogic_GeometryRegister_T GeometryRegister;
1231 FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
1233 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1235 FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
1236 FlashPointInfo->BaseAddress =
1237 (BusLogic_Base_Address_T) HostAdapter->IO_Address;
1238 FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel;
1239 FlashPointInfo->Present = false;
1240 if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 &&
1241 FlashPointInfo->Present))
1243 BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
1244 "PCI Bus %d Device %d\n", HostAdapter,
1245 HostAdapter->Bus, HostAdapter->Device);
1246 BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, "
1247 "but FlashPoint\n", HostAdapter,
1248 HostAdapter->IO_Address, HostAdapter->PCI_Address);
1249 BusLogic_Error("BusLogic: Probe Function failed to validate it.\n",
1250 HostAdapter);
1251 return false;
1253 if (BusLogic_GlobalOptions.TraceProbe)
1254 BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n",
1255 HostAdapter, HostAdapter->IO_Address);
1257 Indicate the Host Adapter Probe completed successfully.
1259 return true;
1262 Read the Status, Interrupt, and Geometry Registers to test if there are I/O
1263 ports that respond, and to check the values to determine if they are from a
1264 BusLogic Host Adapter. A nonexistent I/O port will return 0xFF, in which
1265 case there is definitely no BusLogic Host Adapter at this base I/O Address.
1266 The test here is a subset of that used by the BusLogic Host Adapter BIOS.
1268 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1269 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
1270 GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1271 if (BusLogic_GlobalOptions.TraceProbe)
1272 BusLogic_Notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, "
1273 "Geometry 0x%02X\n", HostAdapter,
1274 HostAdapter->IO_Address, StatusRegister.All,
1275 InterruptRegister.All, GeometryRegister.All);
1276 if (StatusRegister.All == 0 ||
1277 StatusRegister.Bits.DiagnosticActive ||
1278 StatusRegister.Bits.CommandParameterRegisterBusy ||
1279 StatusRegister.Bits.Reserved ||
1280 StatusRegister.Bits.CommandInvalid ||
1281 InterruptRegister.Bits.Reserved != 0)
1282 return false;
1284 Check the undocumented Geometry Register to test if there is an I/O port
1285 that responded. Adaptec Host Adapters do not implement the Geometry
1286 Register, so this test helps serve to avoid incorrectly recognizing an
1287 Adaptec 1542A or 1542B as a BusLogic. Unfortunately, the Adaptec 1542C
1288 series does respond to the Geometry Register I/O port, but it will be
1289 rejected later when the Inquire Extended Setup Information command is
1290 issued in BusLogic_CheckHostAdapter. The AMI FastDisk Host Adapter is a
1291 BusLogic clone that implements the same interface as earlier BusLogic
1292 Host Adapters, including the undocumented commands, and is therefore
1293 supported by this driver. However, the AMI FastDisk always returns 0x00
1294 upon reading the Geometry Register, so the extended translation option
1295 should always be left disabled on the AMI FastDisk.
1297 if (GeometryRegister.All == 0xFF) return false;
1299 Indicate the Host Adapter Probe completed successfully.
1301 return true;
1306 BusLogic_HardwareResetHostAdapter issues a Hardware Reset to the Host Adapter
1307 and waits for Host Adapter Diagnostics to complete. If HardReset is true, a
1308 Hard Reset is performed which also initiates a SCSI Bus Reset. Otherwise, a
1309 Soft Reset is performed which only resets the Host Adapter without forcing a
1310 SCSI Bus Reset.
1313 static boolean BusLogic_HardwareResetHostAdapter(BusLogic_HostAdapter_T
1314 *HostAdapter,
1315 boolean HardReset)
1317 BusLogic_StatusRegister_T StatusRegister;
1318 int TimeoutCounter;
1320 FlashPoint Host Adapters are Hard Reset by the FlashPoint SCCB Manager.
1322 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1324 FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
1325 FlashPointInfo->HostSoftReset = !HardReset;
1326 FlashPointInfo->ReportDataUnderrun = true;
1327 HostAdapter->CardHandle =
1328 FlashPoint_HardwareResetHostAdapter(FlashPointInfo);
1329 if (HostAdapter->CardHandle == FlashPoint_BadCardHandle) return false;
1331 Indicate the Host Adapter Hard Reset completed successfully.
1333 return true;
1336 Issue a Hard Reset or Soft Reset Command to the Host Adapter. The Host
1337 Adapter should respond by setting Diagnostic Active in the Status Register.
1339 if (HardReset)
1340 BusLogic_HardReset(HostAdapter);
1341 else BusLogic_SoftReset(HostAdapter);
1343 Wait until Diagnostic Active is set in the Status Register.
1345 TimeoutCounter = 5*10000;
1346 while (--TimeoutCounter >= 0)
1348 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1349 if (StatusRegister.Bits.DiagnosticActive) break;
1350 udelay(100);
1352 if (BusLogic_GlobalOptions.TraceHardwareReset)
1353 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, "
1354 "Status 0x%02X\n", HostAdapter,
1355 HostAdapter->IO_Address, StatusRegister.All);
1356 if (TimeoutCounter < 0) return false;
1358 Wait 100 microseconds to allow completion of any initial diagnostic
1359 activity which might leave the contents of the Status Register
1360 unpredictable.
1362 udelay(100);
1364 Wait until Diagnostic Active is reset in the Status Register.
1366 TimeoutCounter = 10*10000;
1367 while (--TimeoutCounter >= 0)
1369 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1370 if (!StatusRegister.Bits.DiagnosticActive) break;
1371 udelay(100);
1373 if (BusLogic_GlobalOptions.TraceHardwareReset)
1374 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, "
1375 "Status 0x%02X\n", HostAdapter,
1376 HostAdapter->IO_Address, StatusRegister.All);
1377 if (TimeoutCounter < 0) return false;
1379 Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
1380 or Data In Register Ready bits is set in the Status Register.
1382 TimeoutCounter = 10000;
1383 while (--TimeoutCounter >= 0)
1385 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1386 if (StatusRegister.Bits.DiagnosticFailure ||
1387 StatusRegister.Bits.HostAdapterReady ||
1388 StatusRegister.Bits.DataInRegisterReady)
1389 break;
1390 udelay(100);
1392 if (BusLogic_GlobalOptions.TraceHardwareReset)
1393 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, "
1394 "Status 0x%02X\n", HostAdapter,
1395 HostAdapter->IO_Address, StatusRegister.All);
1396 if (TimeoutCounter < 0) return false;
1398 If Diagnostic Failure is set or Host Adapter Ready is reset, then an
1399 error occurred during the Host Adapter diagnostics. If Data In Register
1400 Ready is set, then there is an Error Code available.
1402 if (StatusRegister.Bits.DiagnosticFailure ||
1403 !StatusRegister.Bits.HostAdapterReady)
1405 BusLogic_CommandFailureReason = NULL;
1406 BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
1407 BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n",
1408 HostAdapter, StatusRegister.All);
1409 if (StatusRegister.Bits.DataInRegisterReady)
1411 unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
1412 BusLogic_Error("HOST ADAPTER ERROR CODE = %d\n",
1413 HostAdapter, ErrorCode);
1415 return false;
1418 Indicate the Host Adapter Hard Reset completed successfully.
1420 return true;
1425 BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
1426 Host Adapter.
1429 static boolean BusLogic_CheckHostAdapter(BusLogic_HostAdapter_T *HostAdapter)
1431 BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
1432 BusLogic_RequestedReplyLength_T RequestedReplyLength;
1433 boolean Result = true;
1435 FlashPoint Host Adapters do not require this protection.
1437 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
1439 Issue the Inquire Extended Setup Information command. Only genuine
1440 BusLogic Host Adapters and true clones support this command. Adaptec 1542C
1441 series Host Adapters that respond to the Geometry Register I/O port will
1442 fail this command.
1444 RequestedReplyLength = sizeof(ExtendedSetupInformation);
1445 if (BusLogic_Command(HostAdapter,
1446 BusLogic_InquireExtendedSetupInformation,
1447 &RequestedReplyLength,
1448 sizeof(RequestedReplyLength),
1449 &ExtendedSetupInformation,
1450 sizeof(ExtendedSetupInformation))
1451 != sizeof(ExtendedSetupInformation))
1452 Result = false;
1454 Provide tracing information if requested and return.
1456 if (BusLogic_GlobalOptions.TraceProbe)
1457 BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter,
1458 HostAdapter->IO_Address, (Result ? "Found" : "Not Found"));
1459 return Result;
1464 BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
1465 from Host Adapter and initializes the Host Adapter structure.
1468 static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T
1469 *HostAdapter)
1471 BusLogic_BoardID_T BoardID;
1472 BusLogic_Configuration_T Configuration;
1473 BusLogic_SetupInformation_T SetupInformation;
1474 BusLogic_ExtendedSetupInformation_T ExtendedSetupInformation;
1475 BusLogic_HostAdapterModelNumber_T HostAdapterModelNumber;
1476 BusLogic_FirmwareVersion3rdDigit_T FirmwareVersion3rdDigit;
1477 BusLogic_FirmwareVersionLetter_T FirmwareVersionLetter;
1478 BusLogic_PCIHostAdapterInformation_T PCIHostAdapterInformation;
1479 BusLogic_FetchHostAdapterLocalRAMRequest_T FetchHostAdapterLocalRAMRequest;
1480 BusLogic_AutoSCSIData_T AutoSCSIData;
1481 BusLogic_GeometryRegister_T GeometryRegister;
1482 BusLogic_RequestedReplyLength_T RequestedReplyLength;
1483 unsigned char *TargetPointer, Character;
1484 int TargetID, i;
1486 Configuration Information for FlashPoint Host Adapters is provided in the
1487 FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function.
1488 Initialize fields in the Host Adapter structure from the FlashPoint_Info
1489 structure.
1491 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1493 FlashPoint_Info_T *FlashPointInfo = &HostAdapter->FlashPointInfo;
1494 TargetPointer = HostAdapter->ModelName;
1495 *TargetPointer++ = 'B';
1496 *TargetPointer++ = 'T';
1497 *TargetPointer++ = '-';
1498 for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++)
1499 *TargetPointer++ = FlashPointInfo->ModelNumber[i];
1500 *TargetPointer++ = '\0';
1501 strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion);
1502 HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID;
1503 HostAdapter->ExtendedTranslationEnabled =
1504 FlashPointInfo->ExtendedTranslationEnabled;
1505 HostAdapter->ParityCheckingEnabled =
1506 FlashPointInfo->ParityCheckingEnabled;
1507 HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset;
1508 HostAdapter->LevelSensitiveInterrupt = true;
1509 HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI;
1510 HostAdapter->HostDifferentialSCSI = false;
1511 HostAdapter->HostSupportsSCAM = true;
1512 HostAdapter->HostUltraSCSI = true;
1513 HostAdapter->ExtendedLUNSupport = true;
1514 HostAdapter->TerminationInfoValid = true;
1515 HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated;
1516 HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated;
1517 HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled;
1518 HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2;
1519 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1520 HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1521 HostAdapter->MaxLogicalUnits = 32;
1522 HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1523 HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1524 HostAdapter->DriverQueueDepth = 255;
1525 HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth;
1526 HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted;
1527 HostAdapter->FastPermitted = FlashPointInfo->FastPermitted;
1528 HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted;
1529 HostAdapter->WidePermitted = FlashPointInfo->WidePermitted;
1530 HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted;
1531 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1532 goto Common;
1535 Issue the Inquire Board ID command.
1537 if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0,
1538 &BoardID, sizeof(BoardID)) != sizeof(BoardID))
1539 return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
1541 Issue the Inquire Configuration command.
1543 if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0,
1544 &Configuration, sizeof(Configuration))
1545 != sizeof(Configuration))
1546 return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
1548 Issue the Inquire Setup Information command.
1550 RequestedReplyLength = sizeof(SetupInformation);
1551 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
1552 &RequestedReplyLength, sizeof(RequestedReplyLength),
1553 &SetupInformation, sizeof(SetupInformation))
1554 != sizeof(SetupInformation))
1555 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
1557 Issue the Inquire Extended Setup Information command.
1559 RequestedReplyLength = sizeof(ExtendedSetupInformation);
1560 if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation,
1561 &RequestedReplyLength, sizeof(RequestedReplyLength),
1562 &ExtendedSetupInformation,
1563 sizeof(ExtendedSetupInformation))
1564 != sizeof(ExtendedSetupInformation))
1565 return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
1567 Issue the Inquire Firmware Version 3rd Digit command.
1569 FirmwareVersion3rdDigit = '\0';
1570 if (BoardID.FirmwareVersion1stDigit > '0')
1571 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit,
1572 NULL, 0, &FirmwareVersion3rdDigit,
1573 sizeof(FirmwareVersion3rdDigit))
1574 != sizeof(FirmwareVersion3rdDigit))
1575 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
1577 Issue the Inquire Host Adapter Model Number command.
1579 if (ExtendedSetupInformation.BusType == 'A' &&
1580 BoardID.FirmwareVersion1stDigit == '2')
1581 /* BusLogic BT-542B ISA 2.xx */
1582 strcpy(HostAdapterModelNumber, "542B");
1583 else if (ExtendedSetupInformation.BusType == 'E' &&
1584 BoardID.FirmwareVersion1stDigit == '2' &&
1585 (BoardID.FirmwareVersion2ndDigit <= '1' ||
1586 (BoardID.FirmwareVersion2ndDigit == '2' &&
1587 FirmwareVersion3rdDigit == '0')))
1588 /* BusLogic BT-742A EISA 2.1x or 2.20 */
1589 strcpy(HostAdapterModelNumber, "742A");
1590 else if (ExtendedSetupInformation.BusType == 'E' &&
1591 BoardID.FirmwareVersion1stDigit == '0')
1592 /* AMI FastDisk EISA Series 441 0.x */
1593 strcpy(HostAdapterModelNumber, "747A");
1594 else
1596 RequestedReplyLength = sizeof(HostAdapterModelNumber);
1597 if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber,
1598 &RequestedReplyLength, sizeof(RequestedReplyLength),
1599 &HostAdapterModelNumber,
1600 sizeof(HostAdapterModelNumber))
1601 != sizeof(HostAdapterModelNumber))
1602 return BusLogic_Failure(HostAdapter,
1603 "INQUIRE HOST ADAPTER MODEL NUMBER");
1606 BusLogic MultiMaster Host Adapters can be identified by their model number
1607 and the major version number of their firmware as follows:
1609 5.xx BusLogic "W" Series Host Adapters:
1610 BT-948/958/958D
1611 4.xx BusLogic "C" Series Host Adapters:
1612 BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
1613 3.xx BusLogic "S" Series Host Adapters:
1614 BT-747S/747D/757S/757D/445S/545S/542D
1615 BT-542B/742A (revision H)
1616 2.xx BusLogic "A" Series Host Adapters:
1617 BT-542B/742A (revision G and below)
1618 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
1621 Save the Model Name and Host Adapter Name in the Host Adapter structure.
1623 TargetPointer = HostAdapter->ModelName;
1624 *TargetPointer++ = 'B';
1625 *TargetPointer++ = 'T';
1626 *TargetPointer++ = '-';
1627 for (i = 0; i < sizeof(HostAdapterModelNumber); i++)
1629 Character = HostAdapterModelNumber[i];
1630 if (Character == ' ' || Character == '\0') break;
1631 *TargetPointer++ = Character;
1633 *TargetPointer++ = '\0';
1635 Save the Firmware Version in the Host Adapter structure.
1637 TargetPointer = HostAdapter->FirmwareVersion;
1638 *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
1639 *TargetPointer++ = '.';
1640 *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
1641 if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
1642 *TargetPointer++ = FirmwareVersion3rdDigit;
1643 *TargetPointer = '\0';
1645 Issue the Inquire Firmware Version Letter command.
1647 if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0)
1649 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter,
1650 NULL, 0, &FirmwareVersionLetter,
1651 sizeof(FirmwareVersionLetter))
1652 != sizeof(FirmwareVersionLetter))
1653 return BusLogic_Failure(HostAdapter,
1654 "INQUIRE FIRMWARE VERSION LETTER");
1655 if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
1656 *TargetPointer++ = FirmwareVersionLetter;
1657 *TargetPointer = '\0';
1660 Save the Host Adapter SCSI ID in the Host Adapter structure.
1662 HostAdapter->SCSI_ID = Configuration.HostAdapterID;
1664 Determine the Bus Type and save it in the Host Adapter structure, determine
1665 and save the IRQ Channel if necessary, and determine and save the DMA
1666 Channel for ISA Host Adapters.
1668 HostAdapter->HostAdapterBusType =
1669 BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4'];
1670 if (HostAdapter->IRQ_Channel == 0)
1672 if (Configuration.IRQ_Channel9)
1673 HostAdapter->IRQ_Channel = 9;
1674 else if (Configuration.IRQ_Channel10)
1675 HostAdapter->IRQ_Channel = 10;
1676 else if (Configuration.IRQ_Channel11)
1677 HostAdapter->IRQ_Channel = 11;
1678 else if (Configuration.IRQ_Channel12)
1679 HostAdapter->IRQ_Channel = 12;
1680 else if (Configuration.IRQ_Channel14)
1681 HostAdapter->IRQ_Channel = 14;
1682 else if (Configuration.IRQ_Channel15)
1683 HostAdapter->IRQ_Channel = 15;
1685 if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus)
1687 if (Configuration.DMA_Channel5)
1688 HostAdapter->DMA_Channel = 5;
1689 else if (Configuration.DMA_Channel6)
1690 HostAdapter->DMA_Channel = 6;
1691 else if (Configuration.DMA_Channel7)
1692 HostAdapter->DMA_Channel = 7;
1695 Determine whether Extended Translation is enabled and save it in
1696 the Host Adapter structure.
1698 GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1699 HostAdapter->ExtendedTranslationEnabled =
1700 GeometryRegister.Bits.ExtendedTranslationEnabled;
1702 Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
1703 SCSI flag, Differential SCSI flag, SCAM Supported flag, and
1704 Ultra SCSI flag in the Host Adapter structure.
1706 HostAdapter->HostAdapterScatterGatherLimit =
1707 ExtendedSetupInformation.ScatterGatherLimit;
1708 HostAdapter->DriverScatterGatherLimit =
1709 HostAdapter->HostAdapterScatterGatherLimit;
1710 if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
1711 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1712 if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt)
1713 HostAdapter->LevelSensitiveInterrupt = true;
1714 HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI;
1715 HostAdapter->HostDifferentialSCSI =
1716 ExtendedSetupInformation.HostDifferentialSCSI;
1717 HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM;
1718 HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
1720 Determine whether Extended LUN Format CCBs are supported and save the
1721 information in the Host Adapter structure.
1723 if (HostAdapter->FirmwareVersion[0] == '5' ||
1724 (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
1725 HostAdapter->ExtendedLUNSupport = true;
1727 Issue the Inquire PCI Host Adapter Information command to read the
1728 Termination Information from "W" series MultiMaster Host Adapters.
1730 if (HostAdapter->FirmwareVersion[0] == '5')
1732 if (BusLogic_Command(HostAdapter,
1733 BusLogic_InquirePCIHostAdapterInformation,
1734 NULL, 0, &PCIHostAdapterInformation,
1735 sizeof(PCIHostAdapterInformation))
1736 != sizeof(PCIHostAdapterInformation))
1737 return BusLogic_Failure(HostAdapter,
1738 "INQUIRE PCI HOST ADAPTER INFORMATION");
1740 Save the Termination Information in the Host Adapter structure.
1742 if (PCIHostAdapterInformation.GenericInfoValid)
1744 HostAdapter->TerminationInfoValid = true;
1745 HostAdapter->LowByteTerminated =
1746 PCIHostAdapterInformation.LowByteTerminated;
1747 HostAdapter->HighByteTerminated =
1748 PCIHostAdapterInformation.HighByteTerminated;
1752 Issue the Fetch Host Adapter Local RAM command to read the AutoSCSI data
1753 from "W" and "C" series MultiMaster Host Adapters.
1755 if (HostAdapter->FirmwareVersion[0] >= '4')
1757 FetchHostAdapterLocalRAMRequest.ByteOffset =
1758 BusLogic_AutoSCSI_BaseOffset;
1759 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData);
1760 if (BusLogic_Command(HostAdapter,
1761 BusLogic_FetchHostAdapterLocalRAM,
1762 &FetchHostAdapterLocalRAMRequest,
1763 sizeof(FetchHostAdapterLocalRAMRequest),
1764 &AutoSCSIData, sizeof(AutoSCSIData))
1765 != sizeof(AutoSCSIData))
1766 return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM");
1768 Save the Parity Checking Enabled, Bus Reset Enabled, and Termination
1769 Information in the Host Adapter structure.
1771 HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled;
1772 HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled;
1773 if (HostAdapter->FirmwareVersion[0] == '4')
1775 HostAdapter->TerminationInfoValid = true;
1776 HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated;
1777 HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated;
1780 Save the Wide Permitted, Fast Permitted, Synchronous Permitted,
1781 Disconnect Permitted, Ultra Permitted, and SCAM Information in the
1782 Host Adapter structure.
1784 HostAdapter->WidePermitted = AutoSCSIData.WidePermitted;
1785 HostAdapter->FastPermitted = AutoSCSIData.FastPermitted;
1786 HostAdapter->SynchronousPermitted =
1787 AutoSCSIData.SynchronousPermitted;
1788 HostAdapter->DisconnectPermitted =
1789 AutoSCSIData.DisconnectPermitted;
1790 if (HostAdapter->HostUltraSCSI)
1791 HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted;
1792 if (HostAdapter->HostSupportsSCAM)
1794 HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled;
1795 HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2;
1799 Initialize fields in the Host Adapter structure for "S" and "A" series
1800 MultiMaster Host Adapters.
1802 if (HostAdapter->FirmwareVersion[0] < '4')
1804 if (SetupInformation.SynchronousInitiationEnabled)
1806 HostAdapter->SynchronousPermitted = 0xFF;
1807 if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)
1809 if (ExtendedSetupInformation.Misc.FastOnEISA)
1810 HostAdapter->FastPermitted = 0xFF;
1811 if (strcmp(HostAdapter->ModelName, "BT-757") == 0)
1812 HostAdapter->WidePermitted = 0xFF;
1815 HostAdapter->DisconnectPermitted = 0xFF;
1816 HostAdapter->ParityCheckingEnabled =
1817 SetupInformation.ParityCheckingEnabled;
1818 HostAdapter->BusResetEnabled = true;
1821 Determine the maximum number of Target IDs and Logical Units supported by
1822 this driver for Wide and Narrow Host Adapters.
1824 HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1825 HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8);
1827 Select appropriate values for the Mailbox Count, Driver Queue Depth,
1828 Initial CCBs, and Incremental CCBs variables based on whether or not Strict
1829 Round Robin Mode is supported. If Strict Round Robin Mode is supported,
1830 then there is no performance degradation in using the maximum possible
1831 number of Outgoing and Incoming Mailboxes and allowing the Tagged and
1832 Untagged Queue Depths to determine the actual utilization. If Strict Round
1833 Robin Mode is not supported, then the Host Adapter must scan all the
1834 Outgoing Mailboxes whenever an Outgoing Mailbox entry is made, which can
1835 cause a substantial performance penalty. The host adapters actually have
1836 room to store the following number of CCBs internally; that is, they can
1837 internally queue and manage this many active commands on the SCSI bus
1838 simultaneously. Performance measurements demonstrate that the Driver Queue
1839 Depth should be set to the Mailbox Count, rather than the Host Adapter
1840 Queue Depth (internal CCB capacity), as it is more efficient to have the
1841 queued commands waiting in Outgoing Mailboxes if necessary than to block
1842 the process in the higher levels of the SCSI Subsystem.
1844 192 BT-948/958/958D
1845 100 BT-946C/956C/956CD/747C/757C/757CD/445C
1846 50 BT-545C/540CF
1847 30 BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
1849 if (HostAdapter->FirmwareVersion[0] == '5')
1850 HostAdapter->HostAdapterQueueDepth = 192;
1851 else if (HostAdapter->FirmwareVersion[0] == '4')
1852 HostAdapter->HostAdapterQueueDepth =
1853 (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50);
1854 else HostAdapter->HostAdapterQueueDepth = 30;
1855 if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0)
1857 HostAdapter->StrictRoundRobinModeSupport = true;
1858 HostAdapter->MailboxCount = BusLogic_MaxMailboxes;
1860 else
1862 HostAdapter->StrictRoundRobinModeSupport = false;
1863 HostAdapter->MailboxCount = 32;
1865 HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount;
1866 HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1867 HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1869 Tagged Queuing support is available and operates properly on all "W" series
1870 MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with
1871 firmware version 4.22 and above, and on "S" series MultiMaster Host
1872 Adapters with firmware version 3.35 and above.
1874 HostAdapter->TaggedQueuingPermitted = 0;
1875 switch (HostAdapter->FirmwareVersion[0])
1877 case '5':
1878 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1879 break;
1880 case '4':
1881 if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
1882 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1883 break;
1884 case '3':
1885 if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
1886 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1887 break;
1890 Determine the Host Adapter BIOS Address if the BIOS is enabled and
1891 save it in the Host Adapter structure. The BIOS is disabled if the
1892 BIOS_Address is 0.
1894 HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
1896 ISA Host Adapters require Bounce Buffers if there is more than 16MB memory.
1898 if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus &&
1899 (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1900 HostAdapter->BounceBuffersRequired = true;
1902 BusLogic BT-445S Host Adapters prior to board revision E have a hardware
1903 bug whereby when the BIOS is enabled, transfers to/from the same address
1904 range the BIOS occupies modulo 16MB are handled incorrectly. Only properly
1905 functioning BT-445S Host Adapters have firmware version 3.37, so require
1906 that ISA Bounce Buffers be used for the buggy BT-445S models if there is
1907 more than 16MB memory.
1909 if (HostAdapter->BIOS_Address > 0 &&
1910 strcmp(HostAdapter->ModelName, "BT-445S") == 0 &&
1911 strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 &&
1912 (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1913 HostAdapter->BounceBuffersRequired = true;
1915 Initialize parameters common to MultiMaster and FlashPoint Host Adapters.
1917 Common:
1919 Initialize the Host Adapter Full Model Name from the Model Name.
1921 strcpy(HostAdapter->FullModelName, "BusLogic ");
1922 strcat(HostAdapter->FullModelName, HostAdapter->ModelName);
1924 Select an appropriate value for the Tagged Queue Depth either from a
1925 BusLogic Driver Options specification, or based on whether this Host
1926 Adapter requires that ISA Bounce Buffers be used. The Tagged Queue Depth
1927 is left at 0 for automatic determination in BusLogic_SelectQueueDepths.
1928 Initialize the Untagged Queue Depth.
1930 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
1932 unsigned char QueueDepth = 0;
1933 if (HostAdapter->DriverOptions != NULL &&
1934 HostAdapter->DriverOptions->QueueDepth[TargetID] > 0)
1935 QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID];
1936 else if (HostAdapter->BounceBuffersRequired)
1937 QueueDepth = BusLogic_TaggedQueueDepthBB;
1938 HostAdapter->QueueDepth[TargetID] = QueueDepth;
1940 if (HostAdapter->BounceBuffersRequired)
1941 HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB;
1942 else HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
1943 if (HostAdapter->DriverOptions != NULL)
1944 HostAdapter->CommonQueueDepth =
1945 HostAdapter->DriverOptions->CommonQueueDepth;
1946 if (HostAdapter->CommonQueueDepth > 0 &&
1947 HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth)
1948 HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth;
1950 Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
1951 Therefore, mask the Tagged Queuing Permitted Default bits with the
1952 Disconnect/Reconnect Permitted bits.
1954 HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted;
1956 Combine the default Tagged Queuing Permitted bits with any BusLogic Driver
1957 Options Tagged Queuing specification.
1959 if (HostAdapter->DriverOptions != NULL)
1960 HostAdapter->TaggedQueuingPermitted =
1961 (HostAdapter->DriverOptions->TaggedQueuingPermitted &
1962 HostAdapter->DriverOptions->TaggedQueuingPermittedMask) |
1963 (HostAdapter->TaggedQueuingPermitted &
1964 ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask);
1966 Select appropriate values for the Error Recovery Strategy array
1967 either from a BusLogic Driver Options specification, or using
1968 BusLogic_ErrorRecovery_Default.
1970 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
1971 if (HostAdapter->DriverOptions != NULL)
1972 HostAdapter->ErrorRecoveryStrategy[TargetID] =
1973 HostAdapter->DriverOptions->ErrorRecoveryStrategy[TargetID];
1974 else HostAdapter->ErrorRecoveryStrategy[TargetID] =
1975 BusLogic_ErrorRecovery_Default;
1977 Select an appropriate value for Bus Settle Time either from a BusLogic
1978 Driver Options specification, or from BusLogic_DefaultBusSettleTime.
1980 if (HostAdapter->DriverOptions != NULL &&
1981 HostAdapter->DriverOptions->BusSettleTime > 0)
1982 HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime;
1983 else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
1985 Indicate reading the Host Adapter Configuration completed successfully.
1987 return true;
1992 BusLogic_ReportHostAdapterConfiguration reports the configuration of
1993 Host Adapter.
1996 static boolean BusLogic_ReportHostAdapterConfiguration(BusLogic_HostAdapter_T
1997 *HostAdapter)
1999 unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
2000 unsigned short SynchronousPermitted, FastPermitted;
2001 unsigned short UltraPermitted, WidePermitted;
2002 unsigned short DisconnectPermitted, TaggedQueuingPermitted;
2003 boolean CommonSynchronousNegotiation, CommonTaggedQueueDepth;
2004 boolean CommonErrorRecovery;
2005 char SynchronousString[BusLogic_MaxTargetDevices+1];
2006 char WideString[BusLogic_MaxTargetDevices+1];
2007 char DisconnectString[BusLogic_MaxTargetDevices+1];
2008 char TaggedQueuingString[BusLogic_MaxTargetDevices+1];
2009 char ErrorRecoveryString[BusLogic_MaxTargetDevices+1];
2010 char *SynchronousMessage = SynchronousString;
2011 char *WideMessage = WideString;
2012 char *DisconnectMessage = DisconnectString;
2013 char *TaggedQueuingMessage = TaggedQueuingString;
2014 char *ErrorRecoveryMessage = ErrorRecoveryString;
2015 int TargetID;
2016 BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n",
2017 HostAdapter, HostAdapter->ModelName,
2018 BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType],
2019 (HostAdapter->HostWideSCSI ? " Wide" : ""),
2020 (HostAdapter->HostDifferentialSCSI ? " Differential" : ""),
2021 (HostAdapter->HostUltraSCSI ? " Ultra" : ""));
2022 BusLogic_Info(" Firmware Version: %s, I/O Address: 0x%X, "
2023 "IRQ Channel: %d/%s\n", HostAdapter,
2024 HostAdapter->FirmwareVersion,
2025 HostAdapter->IO_Address, HostAdapter->IRQ_Channel,
2026 (HostAdapter->LevelSensitiveInterrupt ? "Level" : "Edge"));
2027 if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus)
2029 BusLogic_Info(" DMA Channel: ", HostAdapter);
2030 if (HostAdapter->DMA_Channel > 0)
2031 BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel);
2032 else BusLogic_Info("None, ", HostAdapter);
2033 if (HostAdapter->BIOS_Address > 0)
2034 BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter,
2035 HostAdapter->BIOS_Address);
2036 else BusLogic_Info("BIOS Address: None, ", HostAdapter);
2038 else
2040 BusLogic_Info(" PCI Bus: %d, Device: %d, Address: ",
2041 HostAdapter, HostAdapter->Bus, HostAdapter->Device);
2042 if (HostAdapter->PCI_Address > 0)
2043 BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address);
2044 else BusLogic_Info("Unassigned, ", HostAdapter);
2046 BusLogic_Info("Host Adapter SCSI ID: %d\n", HostAdapter,
2047 HostAdapter->SCSI_ID);
2048 BusLogic_Info(" Parity Checking: %s, Extended Translation: %s\n",
2049 HostAdapter,
2050 (HostAdapter->ParityCheckingEnabled
2051 ? "Enabled" : "Disabled"),
2052 (HostAdapter->ExtendedTranslationEnabled
2053 ? "Enabled" : "Disabled"));
2054 AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID);
2055 SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask;
2056 FastPermitted = HostAdapter->FastPermitted & AllTargetsMask;
2057 UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask;
2058 if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) &&
2059 (HostAdapter->FirmwareVersion[0] >= '4' ||
2060 HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) ||
2061 BusLogic_FlashPointHostAdapterP(HostAdapter))
2063 CommonSynchronousNegotiation = false;
2064 if (SynchronousPermitted == 0)
2066 SynchronousMessage = "Disabled";
2067 CommonSynchronousNegotiation = true;
2069 else if (SynchronousPermitted == AllTargetsMask)
2071 if (FastPermitted == 0)
2073 SynchronousMessage = "Slow";
2074 CommonSynchronousNegotiation = true;
2076 else if (FastPermitted == AllTargetsMask)
2078 if (UltraPermitted == 0)
2080 SynchronousMessage = "Fast";
2081 CommonSynchronousNegotiation = true;
2083 else if (UltraPermitted == AllTargetsMask)
2085 SynchronousMessage = "Ultra";
2086 CommonSynchronousNegotiation = true;
2090 if (!CommonSynchronousNegotiation)
2092 for (TargetID = 0;
2093 TargetID < HostAdapter->MaxTargetDevices;
2094 TargetID++)
2095 SynchronousString[TargetID] =
2096 ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' :
2097 (!(FastPermitted & (1 << TargetID)) ? 'S' :
2098 (!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U')));
2099 SynchronousString[HostAdapter->SCSI_ID] = '#';
2100 SynchronousString[HostAdapter->MaxTargetDevices] = '\0';
2103 else SynchronousMessage =
2104 (SynchronousPermitted == 0 ? "Disabled" : "Enabled");
2105 WidePermitted = HostAdapter->WidePermitted & AllTargetsMask;
2106 if (WidePermitted == 0)
2107 WideMessage = "Disabled";
2108 else if (WidePermitted == AllTargetsMask)
2109 WideMessage = "Enabled";
2110 else
2112 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2113 WideString[TargetID] =
2114 ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N');
2115 WideString[HostAdapter->SCSI_ID] = '#';
2116 WideString[HostAdapter->MaxTargetDevices] = '\0';
2118 DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
2119 if (DisconnectPermitted == 0)
2120 DisconnectMessage = "Disabled";
2121 else if (DisconnectPermitted == AllTargetsMask)
2122 DisconnectMessage = "Enabled";
2123 else
2125 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2126 DisconnectString[TargetID] =
2127 ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
2128 DisconnectString[HostAdapter->SCSI_ID] = '#';
2129 DisconnectString[HostAdapter->MaxTargetDevices] = '\0';
2131 TaggedQueuingPermitted =
2132 HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
2133 if (TaggedQueuingPermitted == 0)
2134 TaggedQueuingMessage = "Disabled";
2135 else if (TaggedQueuingPermitted == AllTargetsMask)
2136 TaggedQueuingMessage = "Enabled";
2137 else
2139 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2140 TaggedQueuingString[TargetID] =
2141 ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
2142 TaggedQueuingString[HostAdapter->SCSI_ID] = '#';
2143 TaggedQueuingString[HostAdapter->MaxTargetDevices] = '\0';
2145 BusLogic_Info(" Synchronous Negotiation: %s, Wide Negotiation: %s\n",
2146 HostAdapter, SynchronousMessage, WideMessage);
2147 BusLogic_Info(" Disconnect/Reconnect: %s, Tagged Queuing: %s\n",
2148 HostAdapter, DisconnectMessage, TaggedQueuingMessage);
2149 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
2151 BusLogic_Info(" Scatter/Gather Limit: %d of %d segments, "
2152 "Mailboxes: %d\n", HostAdapter,
2153 HostAdapter->DriverScatterGatherLimit,
2154 HostAdapter->HostAdapterScatterGatherLimit,
2155 HostAdapter->MailboxCount);
2156 BusLogic_Info(" Driver Queue Depth: %d, "
2157 "Host Adapter Queue Depth: %d\n",
2158 HostAdapter, HostAdapter->DriverQueueDepth,
2159 HostAdapter->HostAdapterQueueDepth);
2161 else BusLogic_Info(" Driver Queue Depth: %d, "
2162 "Scatter/Gather Limit: %d segments\n",
2163 HostAdapter, HostAdapter->DriverQueueDepth,
2164 HostAdapter->DriverScatterGatherLimit);
2165 BusLogic_Info(" Tagged Queue Depth: ", HostAdapter);
2166 CommonTaggedQueueDepth = true;
2167 for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2168 if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0])
2170 CommonTaggedQueueDepth = false;
2171 break;
2173 if (CommonTaggedQueueDepth)
2175 if (HostAdapter->QueueDepth[0] > 0)
2176 BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]);
2177 else BusLogic_Info("Automatic", HostAdapter);
2179 else BusLogic_Info("Individual", HostAdapter);
2180 BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter,
2181 HostAdapter->UntaggedQueueDepth);
2182 CommonErrorRecovery = true;
2183 for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2184 if (HostAdapter->ErrorRecoveryStrategy[TargetID] !=
2185 HostAdapter->ErrorRecoveryStrategy[0])
2187 CommonErrorRecovery = false;
2188 break;
2190 if (CommonErrorRecovery)
2191 ErrorRecoveryMessage =
2192 BusLogic_ErrorRecoveryStrategyNames[
2193 HostAdapter->ErrorRecoveryStrategy[0]];
2194 else
2196 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2197 ErrorRecoveryString[TargetID] =
2198 BusLogic_ErrorRecoveryStrategyLetters[
2199 HostAdapter->ErrorRecoveryStrategy[TargetID]];
2200 ErrorRecoveryString[HostAdapter->SCSI_ID] = '#';
2201 ErrorRecoveryString[HostAdapter->MaxTargetDevices] = '\0';
2203 BusLogic_Info(" Error Recovery Strategy: %s, SCSI Bus Reset: %s\n",
2204 HostAdapter, ErrorRecoveryMessage,
2205 (HostAdapter->BusResetEnabled ? "Enabled" : "Disabled"));
2206 if (HostAdapter->TerminationInfoValid)
2208 if (HostAdapter->HostWideSCSI)
2209 BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter,
2210 (HostAdapter->LowByteTerminated
2211 ? (HostAdapter->HighByteTerminated
2212 ? "Both Enabled" : "Low Enabled")
2213 : (HostAdapter->HighByteTerminated
2214 ? "High Enabled" : "Both Disabled")));
2215 else BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter,
2216 (HostAdapter->LowByteTerminated ?
2217 "Enabled" : "Disabled"));
2218 if (HostAdapter->HostSupportsSCAM)
2219 BusLogic_Info(", SCAM: %s", HostAdapter,
2220 (HostAdapter->SCAM_Enabled
2221 ? (HostAdapter->SCAM_Level2
2222 ? "Enabled, Level 2" : "Enabled, Level 1")
2223 : "Disabled"));
2224 BusLogic_Info("\n", HostAdapter);
2227 Indicate reporting the Host Adapter configuration completed successfully.
2229 return true;
2234 BusLogic_AcquireResources acquires the system resources necessary to use
2235 Host Adapter.
2238 static boolean BusLogic_AcquireResources(BusLogic_HostAdapter_T *HostAdapter)
2240 if (HostAdapter->IRQ_Channel == 0)
2242 BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
2243 HostAdapter);
2244 return false;
2247 Acquire shared access to the IRQ Channel.
2249 if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
2250 SA_SHIRQ, HostAdapter->FullModelName, HostAdapter) < 0)
2252 BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
2253 HostAdapter, HostAdapter->IRQ_Channel);
2254 return false;
2256 HostAdapter->IRQ_ChannelAcquired = true;
2258 Acquire exclusive access to the DMA Channel.
2260 if (HostAdapter->DMA_Channel > 0)
2262 if (request_dma(HostAdapter->DMA_Channel,
2263 HostAdapter->FullModelName) < 0)
2265 BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n",
2266 HostAdapter, HostAdapter->DMA_Channel);
2267 return false;
2269 set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
2270 enable_dma(HostAdapter->DMA_Channel);
2271 HostAdapter->DMA_ChannelAcquired = true;
2274 Indicate the System Resource Acquisition completed successfully,
2276 return true;
2281 BusLogic_ReleaseResources releases any system resources previously acquired
2282 by BusLogic_AcquireResources.
2285 static void BusLogic_ReleaseResources(BusLogic_HostAdapter_T *HostAdapter)
2288 Release shared access to the IRQ Channel.
2290 if (HostAdapter->IRQ_ChannelAcquired)
2291 free_irq(HostAdapter->IRQ_Channel, HostAdapter);
2293 Release exclusive access to the DMA Channel.
2295 if (HostAdapter->DMA_ChannelAcquired)
2296 free_dma(HostAdapter->DMA_Channel);
2301 BusLogic_InitializeHostAdapter initializes Host Adapter. This is the only
2302 function called during SCSI Host Adapter detection which modifies the state
2303 of the Host Adapter from its initial power on or hard reset state.
2306 static boolean BusLogic_InitializeHostAdapter(BusLogic_HostAdapter_T
2307 *HostAdapter)
2309 BusLogic_ExtendedMailboxRequest_T ExtendedMailboxRequest;
2310 BusLogic_RoundRobinModeRequest_T RoundRobinModeRequest;
2311 BusLogic_SetCCBFormatRequest_T SetCCBFormatRequest;
2312 int TargetID;
2314 Initialize the pointers to the first and last CCBs that are queued for
2315 completion processing.
2317 HostAdapter->FirstCompletedCCB = NULL;
2318 HostAdapter->LastCompletedCCB = NULL;
2320 Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
2321 Command Successful Flag, Active Commands, and Commands Since Reset
2322 for each Target Device.
2324 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2326 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
2327 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
2328 HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
2329 HostAdapter->ActiveCommands[TargetID] = 0;
2330 HostAdapter->CommandsSinceReset[TargetID] = 0;
2333 FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
2335 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) goto Done;
2337 Initialize the Outgoing and Incoming Mailbox pointers.
2339 HostAdapter->FirstOutgoingMailbox =
2340 (BusLogic_OutgoingMailbox_T *) HostAdapter->MailboxSpace;
2341 HostAdapter->LastOutgoingMailbox =
2342 HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
2343 HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
2344 HostAdapter->FirstIncomingMailbox =
2345 (BusLogic_IncomingMailbox_T *) (HostAdapter->LastOutgoingMailbox + 1);
2346 HostAdapter->LastIncomingMailbox =
2347 HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
2348 HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
2350 Initialize the Outgoing and Incoming Mailbox structures.
2352 memset(HostAdapter->FirstOutgoingMailbox, 0,
2353 HostAdapter->MailboxCount * sizeof(BusLogic_OutgoingMailbox_T));
2354 memset(HostAdapter->FirstIncomingMailbox, 0,
2355 HostAdapter->MailboxCount * sizeof(BusLogic_IncomingMailbox_T));
2357 Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
2359 ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
2360 ExtendedMailboxRequest.BaseMailboxAddress =
2361 Virtual_to_Bus(HostAdapter->FirstOutgoingMailbox);
2362 if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox,
2363 &ExtendedMailboxRequest,
2364 sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
2365 return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
2367 Enable Strict Round Robin Mode if supported by the Host Adapter. In
2368 Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing
2369 Mailbox for each new command, rather than scanning through all the
2370 Outgoing Mailboxes to find any that have new commands in them. Strict
2371 Round Robin Mode is significantly more efficient.
2373 if (HostAdapter->StrictRoundRobinModeSupport)
2375 RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
2376 if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode,
2377 &RoundRobinModeRequest,
2378 sizeof(RoundRobinModeRequest), NULL, 0) < 0)
2379 return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
2382 For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB
2383 Format command to allow 32 Logical Units per Target Device.
2385 if (HostAdapter->ExtendedLUNSupport)
2387 SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB;
2388 if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat,
2389 &SetCCBFormatRequest, sizeof(SetCCBFormatRequest),
2390 NULL, 0) < 0)
2391 return BusLogic_Failure(HostAdapter, "SET CCB FORMAT");
2394 Announce Successful Initialization.
2396 Done:
2397 if (!HostAdapter->HostAdapterInitialized)
2399 BusLogic_Info("*** %s Initialized Successfully ***\n",
2400 HostAdapter, HostAdapter->FullModelName);
2401 BusLogic_Info("\n", HostAdapter);
2403 else BusLogic_Warning("*** %s Initialized Successfully ***\n",
2404 HostAdapter, HostAdapter->FullModelName);
2405 HostAdapter->HostAdapterInitialized = true;
2407 Indicate the Host Adapter Initialization completed successfully.
2409 return true;
2414 BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
2415 through Host Adapter.
2418 static boolean BusLogic_TargetDeviceInquiry(BusLogic_HostAdapter_T
2419 *HostAdapter)
2421 BusLogic_InstalledDevices_T InstalledDevices;
2422 BusLogic_InstalledDevices8_T InstalledDevicesID0to7;
2423 BusLogic_SetupInformation_T SetupInformation;
2424 BusLogic_SynchronousPeriod_T SynchronousPeriod;
2425 BusLogic_RequestedReplyLength_T RequestedReplyLength;
2426 int TargetID;
2428 Wait a few seconds between the Host Adapter Hard Reset which initiates
2429 a SCSI Bus Reset and issuing any SCSI Commands. Some SCSI devices get
2430 confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
2432 BusLogic_Delay(HostAdapter->BusSettleTime);
2434 FlashPoint Host Adapters do not provide for Target Device Inquiry.
2436 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
2438 Inhibit the Target Device Inquiry if requested.
2440 if (HostAdapter->DriverOptions != NULL &&
2441 HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
2442 return true;
2444 Issue the Inquire Target Devices command for host adapters with firmware
2445 version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command
2446 for older host adapters. This is necessary to force Synchronous Transfer
2447 Negotiation so that the Inquire Setup Information and Inquire Synchronous
2448 Period commands will return valid data. The Inquire Target Devices command
2449 is preferable to Inquire Installed Devices ID 0 to 7 since it only probes
2450 Logical Unit 0 of each Target Device.
2452 if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0)
2454 if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0,
2455 &InstalledDevices, sizeof(InstalledDevices))
2456 != sizeof(InstalledDevices))
2457 return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES");
2458 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2459 HostAdapter->TargetFlags[TargetID].TargetExists =
2460 (InstalledDevices & (1 << TargetID) ? true : false);
2462 else
2464 if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7,
2465 NULL, 0, &InstalledDevicesID0to7,
2466 sizeof(InstalledDevicesID0to7))
2467 != sizeof(InstalledDevicesID0to7))
2468 return BusLogic_Failure(HostAdapter,
2469 "INQUIRE INSTALLED DEVICES ID 0 TO 7");
2470 for (TargetID = 0; TargetID < 8; TargetID++)
2471 HostAdapter->TargetFlags[TargetID].TargetExists =
2472 (InstalledDevicesID0to7[TargetID] != 0 ? true : false);
2475 Issue the Inquire Setup Information command.
2477 RequestedReplyLength = sizeof(SetupInformation);
2478 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
2479 &RequestedReplyLength, sizeof(RequestedReplyLength),
2480 &SetupInformation, sizeof(SetupInformation))
2481 != sizeof(SetupInformation))
2482 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
2483 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2484 HostAdapter->SynchronousOffset[TargetID] =
2485 (TargetID < 8
2486 ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset
2487 : SetupInformation.SynchronousValuesID8to15[TargetID-8].Offset);
2488 if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0)
2489 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2490 HostAdapter->TargetFlags[TargetID].WideTransfersActive =
2491 (TargetID < 8
2492 ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID)
2493 ? true : false)
2494 : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID-8))
2495 ? true : false));
2497 Issue the Inquire Synchronous Period command.
2499 if (HostAdapter->FirmwareVersion[0] >= '3')
2501 RequestedReplyLength = sizeof(SynchronousPeriod);
2502 if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod,
2503 &RequestedReplyLength, sizeof(RequestedReplyLength),
2504 &SynchronousPeriod, sizeof(SynchronousPeriod))
2505 != sizeof(SynchronousPeriod))
2506 return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
2507 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2508 HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
2510 else
2511 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2512 if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
2513 HostAdapter->SynchronousPeriod[TargetID] =
2514 20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
2515 .TransferPeriod;
2517 Indicate the Target Device Inquiry completed successfully.
2519 return true;
2524 BusLogic_ReportTargetDeviceInfo reports about the Target Devices accessible
2525 through Host Adapter.
2528 static void BusLogic_ReportTargetDeviceInfo(BusLogic_HostAdapter_T
2529 *HostAdapter)
2531 int TargetID;
2533 Inhibit the Target Device Inquiry and Reporting if requested.
2535 if (BusLogic_MultiMasterHostAdapterP(HostAdapter) &&
2536 HostAdapter->DriverOptions != NULL &&
2537 HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
2538 return;
2540 Report on the Target Devices found.
2542 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2544 BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
2545 if (TargetFlags->TargetExists && !TargetFlags->TargetInfoReported)
2547 int SynchronousTransferRate = 0;
2548 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2550 boolean WideTransfersActive;
2551 FlashPoint_InquireTargetInfo(
2552 HostAdapter->CardHandle, TargetID,
2553 &HostAdapter->SynchronousPeriod[TargetID],
2554 &HostAdapter->SynchronousOffset[TargetID],
2555 &WideTransfersActive);
2556 TargetFlags->WideTransfersActive = WideTransfersActive;
2558 else if (TargetFlags->WideTransfersSupported &&
2559 (HostAdapter->WidePermitted & (1 << TargetID)) &&
2560 strcmp(HostAdapter->FirmwareVersion, "5.06L") < 0)
2561 TargetFlags->WideTransfersActive = true;
2562 if (HostAdapter->SynchronousPeriod[TargetID] > 0)
2563 SynchronousTransferRate =
2564 100000 / HostAdapter->SynchronousPeriod[TargetID];
2565 if (TargetFlags->WideTransfersActive)
2566 SynchronousTransferRate <<= 1;
2567 if (SynchronousTransferRate >= 9950)
2569 SynchronousTransferRate = (SynchronousTransferRate + 50) / 100;
2570 BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at "
2571 "%d.%01d MB/sec, offset %d\n",
2572 HostAdapter, TargetID,
2573 HostAdapter->QueueDepth[TargetID],
2574 (TargetFlags->WideTransfersActive ? "Wide " : ""),
2575 SynchronousTransferRate / 10,
2576 SynchronousTransferRate % 10,
2577 HostAdapter->SynchronousOffset[TargetID]);
2579 else if (SynchronousTransferRate > 0)
2581 SynchronousTransferRate = (SynchronousTransferRate + 5) / 10;
2582 BusLogic_Info("Target %d: Queue Depth %d, %sSynchronous at "
2583 "%d.%02d MB/sec, offset %d\n",
2584 HostAdapter, TargetID,
2585 HostAdapter->QueueDepth[TargetID],
2586 (TargetFlags->WideTransfersActive ? "Wide " : ""),
2587 SynchronousTransferRate / 100,
2588 SynchronousTransferRate % 100,
2589 HostAdapter->SynchronousOffset[TargetID]);
2591 else BusLogic_Info("Target %d: Queue Depth %d, Asynchronous\n",
2592 HostAdapter, TargetID,
2593 HostAdapter->QueueDepth[TargetID]);
2594 TargetFlags->TargetInfoReported = true;
2601 BusLogic_InitializeHostStructure initializes the fields in the SCSI Host
2602 structure. The base, io_port, n_io_ports, irq, and dma_channel fields in the
2603 SCSI Host structure are intentionally left uninitialized, as this driver
2604 handles acquisition and release of these resources explicitly, as well as
2605 ensuring exclusive access to the Host Adapter hardware and data structures
2606 through explicit acquisition and release of the Host Adapter's Lock.
2609 static void BusLogic_InitializeHostStructure(BusLogic_HostAdapter_T
2610 *HostAdapter,
2611 SCSI_Host_T *Host)
2613 Host->max_id = HostAdapter->MaxTargetDevices;
2614 Host->max_lun = HostAdapter->MaxLogicalUnits;
2615 Host->max_channel = 0;
2616 Host->unique_id = HostAdapter->IO_Address;
2617 Host->this_id = HostAdapter->SCSI_ID;
2618 Host->can_queue = HostAdapter->DriverQueueDepth;
2619 Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
2620 Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
2621 Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
2626 BusLogic_SelectQueueDepths selects Queue Depths for each Target Device based
2627 on the Host Adapter's Total Queue Depth and the number, type, speed, and
2628 capabilities of the Target Devices. When called for the last Host Adapter,
2629 it reports on the Target Device Information for all BusLogic Host Adapters
2630 since all the Target Devices have now been probed.
2633 static void BusLogic_SelectQueueDepths(SCSI_Host_T *Host,
2634 SCSI_Device_T *DeviceList)
2636 BusLogic_HostAdapter_T *HostAdapter =
2637 (BusLogic_HostAdapter_T *) Host->hostdata;
2638 int TaggedDeviceCount = 0, AutomaticTaggedDeviceCount = 0;
2639 int UntaggedDeviceCount = 0, AutomaticTaggedQueueDepth = 0;
2640 int AllocatedQueueDepth = 0;
2641 SCSI_Device_T *Device;
2642 int TargetID;
2643 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2644 if (HostAdapter->TargetFlags[TargetID].TargetExists)
2646 int QueueDepth = HostAdapter->QueueDepth[TargetID];
2647 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported &&
2648 (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
2650 TaggedDeviceCount++;
2651 if (QueueDepth == 0) AutomaticTaggedDeviceCount++;
2653 else
2655 UntaggedDeviceCount++;
2656 if (QueueDepth == 0 ||
2657 QueueDepth > HostAdapter->UntaggedQueueDepth)
2659 QueueDepth = HostAdapter->UntaggedQueueDepth;
2660 HostAdapter->QueueDepth[TargetID] = QueueDepth;
2663 AllocatedQueueDepth += QueueDepth;
2664 if (QueueDepth == 1)
2665 HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
2667 HostAdapter->TargetDeviceCount = TaggedDeviceCount + UntaggedDeviceCount;
2668 if (AutomaticTaggedDeviceCount > 0)
2670 AutomaticTaggedQueueDepth =
2671 (HostAdapter->HostAdapterQueueDepth - AllocatedQueueDepth)
2672 / AutomaticTaggedDeviceCount;
2673 if (AutomaticTaggedQueueDepth > BusLogic_MaxAutomaticTaggedQueueDepth)
2674 AutomaticTaggedQueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth;
2675 if (AutomaticTaggedQueueDepth < BusLogic_MinAutomaticTaggedQueueDepth)
2676 AutomaticTaggedQueueDepth = BusLogic_MinAutomaticTaggedQueueDepth;
2677 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2678 if (HostAdapter->TargetFlags[TargetID].TargetExists &&
2679 HostAdapter->QueueDepth[TargetID] == 0)
2681 AllocatedQueueDepth += AutomaticTaggedQueueDepth;
2682 HostAdapter->QueueDepth[TargetID] = AutomaticTaggedQueueDepth;
2685 for (Device = DeviceList; Device != NULL; Device = Device->next)
2686 if (Device->host == Host)
2687 Device->queue_depth = HostAdapter->QueueDepth[Device->id];
2688 /* Allocate an extra CCB for each Target Device for a Bus Device Reset. */
2689 AllocatedQueueDepth += HostAdapter->TargetDeviceCount;
2690 if (AllocatedQueueDepth > HostAdapter->DriverQueueDepth)
2691 AllocatedQueueDepth = HostAdapter->DriverQueueDepth;
2692 BusLogic_CreateAdditionalCCBs(HostAdapter,
2693 AllocatedQueueDepth
2694 - HostAdapter->AllocatedCCBs,
2695 false);
2696 if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
2697 for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
2698 HostAdapter != NULL;
2699 HostAdapter = HostAdapter->Next)
2700 BusLogic_ReportTargetDeviceInfo(HostAdapter);
2705 BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
2706 I/O Addresses where they may be located, initializing, registering, and
2707 reporting the configuration of each BusLogic Host Adapter it finds. It
2708 returns the number of BusLogic Host Adapters successfully initialized and
2709 registered.
2712 int BusLogic_DetectHostAdapter(SCSI_Host_Template_T *HostTemplate)
2714 int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex;
2715 BusLogic_HostAdapter_T *PrototypeHostAdapter;
2716 if (BusLogic_ProbeOptions.NoProbe) return 0;
2717 BusLogic_ProbeInfoList = (BusLogic_ProbeInfo_T *)
2718 kmalloc(BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T),
2719 GFP_ATOMIC);
2720 if (BusLogic_ProbeInfoList == NULL)
2722 BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL);
2723 return 0;
2725 memset(BusLogic_ProbeInfoList, 0,
2726 BusLogic_MaxHostAdapters * sizeof(BusLogic_ProbeInfo_T));
2727 PrototypeHostAdapter = (BusLogic_HostAdapter_T *)
2728 kmalloc(sizeof(BusLogic_HostAdapter_T), GFP_ATOMIC);
2729 if (PrototypeHostAdapter == NULL)
2731 kfree(BusLogic_ProbeInfoList);
2732 BusLogic_Error("BusLogic: Unable to allocate Prototype "
2733 "Host Adapter\n", NULL);
2734 return 0;
2736 memset(PrototypeHostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
2737 #ifdef MODULE
2738 if (BusLogic != NULL)
2739 BusLogic_Setup(BusLogic);
2740 #endif
2741 BusLogic_InitializeProbeInfoList(PrototypeHostAdapter);
2742 for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++)
2744 BusLogic_ProbeInfo_T *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex];
2745 BusLogic_HostAdapter_T *HostAdapter = PrototypeHostAdapter;
2746 SCSI_Host_T *Host;
2747 if (ProbeInfo->IO_Address == 0) continue;
2748 memset(HostAdapter, 0, sizeof(BusLogic_HostAdapter_T));
2749 HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType;
2750 HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType;
2751 HostAdapter->IO_Address = ProbeInfo->IO_Address;
2752 HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
2753 HostAdapter->Bus = ProbeInfo->Bus;
2754 HostAdapter->Device = ProbeInfo->Device;
2755 HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
2756 HostAdapter->AddressCount =
2757 BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
2759 Probe the Host Adapter. If unsuccessful, abort further initialization.
2761 if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue;
2763 Hard Reset the Host Adapter. If unsuccessful, abort further
2764 initialization.
2766 if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) continue;
2768 Check the Host Adapter. If unsuccessful, abort further initialization.
2770 if (!BusLogic_CheckHostAdapter(HostAdapter)) continue;
2772 Initialize the Driver Options field if provided.
2774 if (DriverOptionsIndex < BusLogic_DriverOptionsCount)
2775 HostAdapter->DriverOptions =
2776 &BusLogic_DriverOptions[DriverOptionsIndex++];
2778 Announce the Driver Version and Date, Author's Name, Copyright Notice,
2779 and Electronic Mail Address.
2781 BusLogic_AnnounceDriver(HostAdapter);
2783 Register usage of the I/O Address range. From this point onward, any
2784 failure will be assumed to be due to a problem with the Host Adapter,
2785 rather than due to having mistakenly identified this port as belonging
2786 to a BusLogic Host Adapter. The I/O Address range will not be
2787 released, thereby preventing it from being incorrectly identified as
2788 any other type of Host Adapter.
2790 request_region(HostAdapter->IO_Address, HostAdapter->AddressCount,
2791 "BusLogic");
2793 Register the SCSI Host structure.
2795 Host = scsi_register(HostTemplate, sizeof(BusLogic_HostAdapter_T));
2796 HostAdapter = (BusLogic_HostAdapter_T *) Host->hostdata;
2797 memcpy(HostAdapter, PrototypeHostAdapter, sizeof(BusLogic_HostAdapter_T));
2798 HostAdapter->SCSI_Host = Host;
2799 HostAdapter->HostNumber = Host->host_no;
2800 Host->select_queue_depths = BusLogic_SelectQueueDepths;
2802 Add Host Adapter to the end of the list of registered BusLogic
2803 Host Adapters.
2805 BusLogic_RegisterHostAdapter(HostAdapter);
2807 Read the Host Adapter Configuration, Configure the Host Adapter,
2808 Acquire the System Resources necessary to use the Host Adapter, then
2809 Create the Initial CCBs, Initialize the Host Adapter, and finally
2810 perform Target Device Inquiry.
2812 if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
2813 BusLogic_ReportHostAdapterConfiguration(HostAdapter) &&
2814 BusLogic_AcquireResources(HostAdapter) &&
2815 BusLogic_CreateInitialCCBs(HostAdapter) &&
2816 BusLogic_InitializeHostAdapter(HostAdapter) &&
2817 BusLogic_TargetDeviceInquiry(HostAdapter))
2820 Initialization has been completed successfully. Release and
2821 re-register usage of the I/O Address range so that the Model
2822 Name of the Host Adapter will appear, and initialize the SCSI
2823 Host structure.
2825 release_region(HostAdapter->IO_Address,
2826 HostAdapter->AddressCount);
2827 request_region(HostAdapter->IO_Address,
2828 HostAdapter->AddressCount,
2829 HostAdapter->FullModelName);
2830 BusLogic_InitializeHostStructure(HostAdapter, Host);
2831 BusLogicHostAdapterCount++;
2833 else
2836 An error occurred during Host Adapter Configuration Querying, Host
2837 Adapter Configuration, Resource Acquisition, CCB Creation, Host
2838 Adapter Initialization, or Target Device Inquiry, so remove Host
2839 Adapter from the list of registered BusLogic Host Adapters, destroy
2840 the CCBs, Release the System Resources, and Unregister the SCSI
2841 Host.
2843 BusLogic_DestroyCCBs(HostAdapter);
2844 BusLogic_ReleaseResources(HostAdapter);
2845 BusLogic_UnregisterHostAdapter(HostAdapter);
2846 scsi_unregister(Host);
2849 kfree(PrototypeHostAdapter);
2850 kfree(BusLogic_ProbeInfoList);
2851 BusLogic_ProbeInfoList = NULL;
2852 return BusLogicHostAdapterCount;
2857 BusLogic_ReleaseHostAdapter releases all resources previously acquired to
2858 support a specific Host Adapter, including the I/O Address range, and
2859 unregisters the BusLogic Host Adapter.
2862 int BusLogic_ReleaseHostAdapter(SCSI_Host_T *Host)
2864 BusLogic_HostAdapter_T *HostAdapter =
2865 (BusLogic_HostAdapter_T *) Host->hostdata;
2867 FlashPoint Host Adapters must first be released by the FlashPoint
2868 SCCB Manager.
2870 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2871 FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle);
2873 Destroy the CCBs and release any system resources acquired to
2874 support Host Adapter.
2876 BusLogic_DestroyCCBs(HostAdapter);
2877 BusLogic_ReleaseResources(HostAdapter);
2879 Release usage of the I/O Address range.
2881 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2883 Remove Host Adapter from the list of registered BusLogic Host Adapters.
2885 BusLogic_UnregisterHostAdapter(HostAdapter);
2886 return 0;
2891 BusLogic_QueueCompletedCCB queues CCB for completion processing.
2894 static void BusLogic_QueueCompletedCCB(BusLogic_CCB_T *CCB)
2896 BusLogic_HostAdapter_T *HostAdapter = CCB->HostAdapter;
2897 CCB->Status = BusLogic_CCB_Completed;
2898 CCB->Next = NULL;
2899 if (HostAdapter->FirstCompletedCCB == NULL)
2901 HostAdapter->FirstCompletedCCB = CCB;
2902 HostAdapter->LastCompletedCCB = CCB;
2904 else
2906 HostAdapter->LastCompletedCCB->Next = CCB;
2907 HostAdapter->LastCompletedCCB = CCB;
2909 HostAdapter->ActiveCommands[CCB->TargetID]--;
2914 BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from
2915 the Host Adapter Status and Target Device Status.
2918 static int BusLogic_ComputeResultCode(BusLogic_HostAdapter_T *HostAdapter,
2919 BusLogic_HostAdapterStatus_T
2920 HostAdapterStatus,
2921 BusLogic_TargetDeviceStatus_T
2922 TargetDeviceStatus)
2924 int HostStatus;
2925 switch (HostAdapterStatus)
2927 case BusLogic_CommandCompletedNormally:
2928 case BusLogic_LinkedCommandCompleted:
2929 case BusLogic_LinkedCommandCompletedWithFlag:
2930 HostStatus = DID_OK;
2931 break;
2932 case BusLogic_SCSISelectionTimeout:
2933 HostStatus = DID_TIME_OUT;
2934 break;
2935 case BusLogic_InvalidOutgoingMailboxActionCode:
2936 case BusLogic_InvalidCommandOperationCode:
2937 case BusLogic_InvalidCommandParameter:
2938 BusLogic_Warning("BusLogic Driver Protocol Error 0x%02X\n",
2939 HostAdapter, HostAdapterStatus);
2940 case BusLogic_DataUnderRun:
2941 case BusLogic_DataOverRun:
2942 case BusLogic_UnexpectedBusFree:
2943 case BusLogic_LinkedCCBhasInvalidLUN:
2944 case BusLogic_AutoRequestSenseFailed:
2945 case BusLogic_TaggedQueuingMessageRejected:
2946 case BusLogic_UnsupportedMessageReceived:
2947 case BusLogic_HostAdapterHardwareFailed:
2948 case BusLogic_TargetDeviceReconnectedImproperly:
2949 case BusLogic_AbortQueueGenerated:
2950 case BusLogic_HostAdapterSoftwareError:
2951 case BusLogic_HostAdapterHardwareTimeoutError:
2952 case BusLogic_SCSIParityErrorDetected:
2953 HostStatus = DID_ERROR;
2954 break;
2955 case BusLogic_InvalidBusPhaseRequested:
2956 case BusLogic_TargetFailedResponseToATN:
2957 case BusLogic_HostAdapterAssertedRST:
2958 case BusLogic_OtherDeviceAssertedRST:
2959 case BusLogic_HostAdapterAssertedBusDeviceReset:
2960 HostStatus = DID_RESET;
2961 break;
2962 default:
2963 BusLogic_Warning("Unknown Host Adapter Status 0x%02X\n",
2964 HostAdapter, HostAdapterStatus);
2965 HostStatus = DID_ERROR;
2966 break;
2968 return (HostStatus << 16) | TargetDeviceStatus;
2973 BusLogic_ScanIncomingMailboxes scans the Incoming Mailboxes saving any
2974 Incoming Mailbox entries for completion processing.
2977 static void BusLogic_ScanIncomingMailboxes(BusLogic_HostAdapter_T *HostAdapter)
2980 Scan through the Incoming Mailboxes in Strict Round Robin fashion, saving
2981 any completed CCBs for further processing. It is essential that for each
2982 CCB and SCSI Command issued, command completion processing is performed
2983 exactly once. Therefore, only Incoming Mailboxes with completion code
2984 Command Completed Without Error, Command Completed With Error, or Command
2985 Aborted At Host Request are saved for completion processing. When an
2986 Incoming Mailbox has a completion code of Aborted Command Not Found, the
2987 CCB had already completed or been aborted before the current Abort request
2988 was processed, and so completion processing has already occurred and no
2989 further action should be taken.
2991 BusLogic_IncomingMailbox_T *NextIncomingMailbox =
2992 HostAdapter->NextIncomingMailbox;
2993 BusLogic_CompletionCode_T CompletionCode;
2994 while ((CompletionCode = NextIncomingMailbox->CompletionCode) !=
2995 BusLogic_IncomingMailboxFree)
2997 BusLogic_CCB_T *CCB = (BusLogic_CCB_T *)
2998 Bus_to_Virtual(NextIncomingMailbox->CCB);
2999 if (CompletionCode != BusLogic_AbortedCommandNotFound)
3001 if (CCB->Status == BusLogic_CCB_Active ||
3002 CCB->Status == BusLogic_CCB_Reset)
3005 Save the Completion Code for this CCB and queue the CCB
3006 for completion processing.
3008 CCB->CompletionCode = CompletionCode;
3009 BusLogic_QueueCompletedCCB(CCB);
3011 else
3014 If a CCB ever appears in an Incoming Mailbox and is not marked
3015 as status Active or Reset, then there is most likely a bug in
3016 the Host Adapter firmware.
3018 BusLogic_Warning("Illegal CCB #%ld status %d in "
3019 "Incoming Mailbox\n", HostAdapter,
3020 CCB->SerialNumber, CCB->Status);
3023 NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree;
3024 if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
3025 NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
3027 HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
3032 BusLogic_ProcessCompletedCCBs iterates over the completed CCBs for Host
3033 Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
3034 calling the SCSI Subsystem Completion Routines. The Host Adapter's Lock
3035 should already have been acquired by the caller.
3038 static void BusLogic_ProcessCompletedCCBs(BusLogic_HostAdapter_T *HostAdapter)
3040 if (HostAdapter->ProcessCompletedCCBsActive) return;
3041 HostAdapter->ProcessCompletedCCBsActive = true;
3042 while (HostAdapter->FirstCompletedCCB != NULL)
3044 BusLogic_CCB_T *CCB = HostAdapter->FirstCompletedCCB;
3045 SCSI_Command_T *Command = CCB->Command;
3046 HostAdapter->FirstCompletedCCB = CCB->Next;
3047 if (HostAdapter->FirstCompletedCCB == NULL)
3048 HostAdapter->LastCompletedCCB = NULL;
3050 Process the Completed CCB.
3052 if (CCB->Opcode == BusLogic_BusDeviceReset)
3054 int TargetID = CCB->TargetID;
3055 BusLogic_Warning("Bus Device Reset CCB #%ld to Target "
3056 "%d Completed\n", HostAdapter,
3057 CCB->SerialNumber, TargetID);
3058 BusLogic_IncrementErrorCounter(
3059 &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted);
3060 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
3061 HostAdapter->CommandsSinceReset[TargetID] = 0;
3062 HostAdapter->LastResetCompleted[TargetID] = jiffies;
3064 Place CCB back on the Host Adapter's free list.
3066 BusLogic_DeallocateCCB(CCB);
3068 Bus Device Reset CCBs have the Command field non-NULL only when a
3069 Bus Device Reset was requested for a Command that did not have a
3070 currently active CCB in the Host Adapter (i.e., a Synchronous
3071 Bus Device Reset), and hence would not have its Completion Routine
3072 called otherwise.
3074 while (Command != NULL)
3076 SCSI_Command_T *NextCommand = Command->reset_chain;
3077 Command->reset_chain = NULL;
3078 Command->result = DID_RESET << 16;
3079 Command->scsi_done(Command);
3080 Command = NextCommand;
3083 Iterate over the CCBs for this Host Adapter performing completion
3084 processing for any CCBs marked as Reset for this Target.
3086 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3087 if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID)
3089 Command = CCB->Command;
3090 BusLogic_DeallocateCCB(CCB);
3091 HostAdapter->ActiveCommands[TargetID]--;
3092 Command->result = DID_RESET << 16;
3093 Command->scsi_done(Command);
3095 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
3097 else
3100 Translate the Completion Code, Host Adapter Status, and Target
3101 Device Status into a SCSI Subsystem Result Code.
3103 switch (CCB->CompletionCode)
3105 case BusLogic_IncomingMailboxFree:
3106 case BusLogic_AbortedCommandNotFound:
3107 case BusLogic_InvalidCCB:
3108 BusLogic_Warning("CCB #%ld to Target %d Impossible State\n",
3109 HostAdapter, CCB->SerialNumber, CCB->TargetID);
3110 break;
3111 case BusLogic_CommandCompletedWithoutError:
3112 HostAdapter->TargetStatistics[CCB->TargetID]
3113 .CommandsCompleted++;
3114 HostAdapter->TargetFlags[CCB->TargetID]
3115 .CommandSuccessfulFlag = true;
3116 Command->result = DID_OK << 16;
3117 break;
3118 case BusLogic_CommandAbortedAtHostRequest:
3119 BusLogic_Warning("CCB #%ld to Target %d Aborted\n",
3120 HostAdapter, CCB->SerialNumber, CCB->TargetID);
3121 BusLogic_IncrementErrorCounter(
3122 &HostAdapter->TargetStatistics[CCB->TargetID]
3123 .CommandAbortsCompleted);
3124 Command->result = DID_ABORT << 16;
3125 break;
3126 case BusLogic_CommandCompletedWithError:
3127 Command->result =
3128 BusLogic_ComputeResultCode(HostAdapter,
3129 CCB->HostAdapterStatus,
3130 CCB->TargetDeviceStatus);
3131 if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
3133 HostAdapter->TargetStatistics[CCB->TargetID]
3134 .CommandsCompleted++;
3135 if (BusLogic_GlobalOptions.TraceErrors)
3137 int i;
3138 BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
3139 "Adapter Status %02X "
3140 "Target Status %02X\n",
3141 HostAdapter, CCB->SerialNumber,
3142 CCB->TargetID, Command->result,
3143 CCB->HostAdapterStatus,
3144 CCB->TargetDeviceStatus);
3145 BusLogic_Notice("CDB ", HostAdapter);
3146 for (i = 0; i < CCB->CDB_Length; i++)
3147 BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]);
3148 BusLogic_Notice("\n", HostAdapter);
3149 BusLogic_Notice("Sense ", HostAdapter);
3150 for (i = 0; i < CCB->SenseDataLength; i++)
3151 BusLogic_Notice(" %02X", HostAdapter,
3152 Command->sense_buffer[i]);
3153 BusLogic_Notice("\n", HostAdapter);
3156 break;
3159 When an INQUIRY command completes normally, save the
3160 CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
3161 Wide Data Transfers Supported) bits.
3163 if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 &&
3164 CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally)
3166 BusLogic_TargetFlags_T *TargetFlags =
3167 &HostAdapter->TargetFlags[CCB->TargetID];
3168 SCSI_Inquiry_T *InquiryResult =
3169 (SCSI_Inquiry_T *) Command->request_buffer;
3170 TargetFlags->TargetExists = true;
3171 TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
3172 TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
3175 Place CCB back on the Host Adapter's free list.
3177 BusLogic_DeallocateCCB(CCB);
3179 Call the SCSI Command Completion Routine.
3181 Command->scsi_done(Command);
3184 HostAdapter->ProcessCompletedCCBsActive = false;
3189 BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
3190 Adapters.
3193 static void BusLogic_InterruptHandler(int IRQ_Channel,
3194 void *DeviceIdentifier,
3195 Registers_T *InterruptRegisters)
3197 BusLogic_HostAdapter_T *HostAdapter =
3198 (BusLogic_HostAdapter_T *) DeviceIdentifier;
3199 ProcessorFlags_T ProcessorFlags;
3201 Acquire exclusive access to Host Adapter.
3203 BusLogic_AcquireHostAdapterLockIH(HostAdapter, &ProcessorFlags);
3205 Handle Interrupts appropriately for each Host Adapter type.
3207 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3209 BusLogic_InterruptRegister_T InterruptRegister;
3211 Read the Host Adapter Interrupt Register.
3213 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
3214 if (InterruptRegister.Bits.InterruptValid)
3217 Acknowledge the interrupt and reset the Host Adapter
3218 Interrupt Register.
3220 BusLogic_InterruptReset(HostAdapter);
3222 Process valid External SCSI Bus Reset and Incoming Mailbox
3223 Loaded Interrupts. Command Complete Interrupts are noted,
3224 and Outgoing Mailbox Available Interrupts are ignored, as
3225 they are never enabled.
3227 if (InterruptRegister.Bits.ExternalBusReset)
3228 HostAdapter->HostAdapterExternalReset = true;
3229 else if (InterruptRegister.Bits.IncomingMailboxLoaded)
3230 BusLogic_ScanIncomingMailboxes(HostAdapter);
3231 else if (InterruptRegister.Bits.CommandComplete)
3232 HostAdapter->HostAdapterCommandCompleted = true;
3235 else
3238 Check if there is a pending interrupt for this Host Adapter.
3240 if (FlashPoint_InterruptPending(HostAdapter->CardHandle))
3241 switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle))
3243 case FlashPoint_NormalInterrupt:
3244 break;
3245 case FlashPoint_ExternalBusReset:
3246 HostAdapter->HostAdapterExternalReset = true;
3247 break;
3248 case FlashPoint_InternalError:
3249 BusLogic_Warning("Internal FlashPoint Error detected"
3250 " - Resetting Host Adapter\n", HostAdapter);
3251 HostAdapter->HostAdapterInternalError = true;
3252 break;
3256 Process any completed CCBs.
3258 if (HostAdapter->FirstCompletedCCB != NULL)
3259 BusLogic_ProcessCompletedCCBs(HostAdapter);
3261 Reset the Host Adapter if requested.
3263 if (HostAdapter->HostAdapterExternalReset ||
3264 HostAdapter->HostAdapterInternalError)
3266 BusLogic_ResetHostAdapter(HostAdapter, NULL, 0);
3267 HostAdapter->HostAdapterExternalReset = false;
3268 HostAdapter->HostAdapterInternalError = false;
3269 scsi_mark_host_reset(HostAdapter->SCSI_Host);
3272 Release exclusive access to Host Adapter.
3274 BusLogic_ReleaseHostAdapterLockIH(HostAdapter, &ProcessorFlags);
3279 BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
3280 Mailbox for execution by Host Adapter. The Host Adapter's Lock should
3281 already have been acquired by the caller.
3284 static boolean BusLogic_WriteOutgoingMailbox(BusLogic_HostAdapter_T
3285 *HostAdapter,
3286 BusLogic_ActionCode_T ActionCode,
3287 BusLogic_CCB_T *CCB)
3289 BusLogic_OutgoingMailbox_T *NextOutgoingMailbox;
3290 NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
3291 if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
3293 CCB->Status = BusLogic_CCB_Active;
3295 The CCB field must be written before the Action Code field since
3296 the Host Adapter is operating asynchronously and the locking code
3297 does not protect against simultaneous access by the Host Adapter.
3299 NextOutgoingMailbox->CCB = Virtual_to_Bus(CCB);
3300 NextOutgoingMailbox->ActionCode = ActionCode;
3301 BusLogic_StartMailboxCommand(HostAdapter);
3302 if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
3303 NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
3304 HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
3305 if (ActionCode == BusLogic_MailboxStartCommand)
3307 HostAdapter->ActiveCommands[CCB->TargetID]++;
3308 if (CCB->Opcode != BusLogic_BusDeviceReset)
3309 HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++;
3311 return true;
3313 return false;
3318 BusLogic_QueueCommand creates a CCB for Command and places it into an
3319 Outgoing Mailbox for execution by the associated Host Adapter.
3322 int BusLogic_QueueCommand(SCSI_Command_T *Command,
3323 void (*CompletionRoutine)(SCSI_Command_T *))
3325 BusLogic_HostAdapter_T *HostAdapter =
3326 (BusLogic_HostAdapter_T *) Command->host->hostdata;
3327 BusLogic_TargetFlags_T *TargetFlags =
3328 &HostAdapter->TargetFlags[Command->target];
3329 BusLogic_TargetStatistics_T *TargetStatistics =
3330 HostAdapter->TargetStatistics;
3331 unsigned char *CDB = Command->cmnd;
3332 int CDB_Length = Command->cmd_len;
3333 int TargetID = Command->target;
3334 int LogicalUnit = Command->lun;
3335 void *BufferPointer = Command->request_buffer;
3336 int BufferLength = Command->request_bufflen;
3337 int SegmentCount = Command->use_sg;
3338 ProcessorFlags_T ProcessorFlags;
3339 BusLogic_CCB_T *CCB;
3341 SCSI REQUEST_SENSE commands will be executed automatically by the Host
3342 Adapter for any errors, so they should not be executed explicitly unless
3343 the Sense Data is zero indicating that no error occurred.
3345 if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0)
3347 Command->result = DID_OK << 16;
3348 CompletionRoutine(Command);
3349 return 0;
3352 Acquire exclusive access to Host Adapter.
3354 BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
3356 Allocate a CCB from the Host Adapter's free list. In the unlikely event
3357 that there are none available and memory allocation fails, wait 1 second
3358 and try again. If that fails, the Host Adapter is probably hung so signal
3359 an error as a Host Adapter Hard Reset should be initiated soon.
3361 CCB = BusLogic_AllocateCCB(HostAdapter);
3362 if (CCB == NULL)
3364 BusLogic_Delay(1);
3365 CCB = BusLogic_AllocateCCB(HostAdapter);
3366 if (CCB == NULL)
3368 Command->result = DID_ERROR << 16;
3369 CompletionRoutine(Command);
3370 goto Done;
3374 Initialize the fields in the BusLogic Command Control Block (CCB).
3376 if (SegmentCount == 0)
3378 CCB->Opcode = BusLogic_InitiatorCCB;
3379 CCB->DataLength = BufferLength;
3380 CCB->DataPointer = Virtual_to_Bus(BufferPointer);
3382 else
3384 SCSI_ScatterList_T *ScatterList = (SCSI_ScatterList_T *) BufferPointer;
3385 int Segment;
3386 CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
3387 CCB->DataLength = SegmentCount * sizeof(BusLogic_ScatterGatherSegment_T);
3388 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3389 CCB->DataPointer = Virtual_to_Bus(CCB->ScatterGatherList);
3390 else CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
3391 for (Segment = 0; Segment < SegmentCount; Segment++)
3393 CCB->ScatterGatherList[Segment].SegmentByteCount =
3394 ScatterList[Segment].length;
3395 CCB->ScatterGatherList[Segment].SegmentDataPointer =
3396 Virtual_to_Bus(ScatterList[Segment].address);
3399 switch (CDB[0])
3401 case READ_6:
3402 case READ_10:
3403 CCB->DataDirection = BusLogic_DataInLengthChecked;
3404 TargetStatistics[TargetID].ReadCommands++;
3405 BusLogic_IncrementByteCounter(
3406 &TargetStatistics[TargetID].TotalBytesRead, BufferLength);
3407 BusLogic_IncrementSizeBucket(
3408 TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength);
3409 break;
3410 case WRITE_6:
3411 case WRITE_10:
3412 CCB->DataDirection = BusLogic_DataOutLengthChecked;
3413 TargetStatistics[TargetID].WriteCommands++;
3414 BusLogic_IncrementByteCounter(
3415 &TargetStatistics[TargetID].TotalBytesWritten, BufferLength);
3416 BusLogic_IncrementSizeBucket(
3417 TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength);
3418 break;
3419 default:
3420 CCB->DataDirection = BusLogic_UncheckedDataTransfer;
3421 break;
3423 CCB->CDB_Length = CDB_Length;
3424 CCB->SenseDataLength = sizeof(Command->sense_buffer);
3425 CCB->HostAdapterStatus = 0;
3426 CCB->TargetDeviceStatus = 0;
3427 CCB->TargetID = TargetID;
3428 CCB->LogicalUnit = LogicalUnit;
3429 CCB->TagEnable = false;
3430 CCB->LegacyTagEnable = false;
3432 BusLogic recommends that after a Reset the first couple of commands that
3433 are sent to a Target Device be sent in a non Tagged Queue fashion so that
3434 the Host Adapter and Target Device can establish Synchronous and Wide
3435 Transfer before Queue Tag messages can interfere with the Synchronous and
3436 Wide Negotiation messages. By waiting to enable Tagged Queuing until after
3437 the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is
3438 assured that after a Reset any pending commands are requeued before Tagged
3439 Queuing is enabled and that the Tagged Queuing message will not occur while
3440 the partition table is being printed. In addition, some devices do not
3441 properly handle the transition from non-tagged to tagged commands, so it is
3442 necessary to wait until there are no pending commands for a target device
3443 before queuing tagged commands.
3445 if (HostAdapter->CommandsSinceReset[TargetID]++ >=
3446 BusLogic_MaxTaggedQueueDepth &&
3447 !TargetFlags->TaggedQueuingActive &&
3448 HostAdapter->ActiveCommands[TargetID] == 0 &&
3449 TargetFlags->TaggedQueuingSupported &&
3450 (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
3452 TargetFlags->TaggedQueuingActive = true;
3453 BusLogic_Notice("Tagged Queuing now active for Target %d\n",
3454 HostAdapter, TargetID);
3456 if (TargetFlags->TaggedQueuingActive)
3458 BusLogic_QueueTag_T QueueTag = BusLogic_SimpleQueueTag;
3460 When using Tagged Queuing with Simple Queue Tags, it appears that disk
3461 drive controllers do not guarantee that a queued command will not
3462 remain in a disconnected state indefinitely if commands that read or
3463 write nearer the head position continue to arrive without interruption.
3464 Therefore, for each Target Device this driver keeps track of the last
3465 time either the queue was empty or an Ordered Queue Tag was issued. If
3466 more than 4 seconds (one fifth of the 20 second disk timeout) have
3467 elapsed since this last sequence point, this command will be issued
3468 with an Ordered Queue Tag rather than a Simple Queue Tag, which forces
3469 the Target Device to complete all previously queued commands before
3470 this command may be executed.
3472 if (HostAdapter->ActiveCommands[TargetID] == 0)
3473 HostAdapter->LastSequencePoint[TargetID] = jiffies;
3474 else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 4*HZ)
3476 HostAdapter->LastSequencePoint[TargetID] = jiffies;
3477 QueueTag = BusLogic_OrderedQueueTag;
3479 if (HostAdapter->ExtendedLUNSupport)
3481 CCB->TagEnable = true;
3482 CCB->QueueTag = QueueTag;
3484 else
3486 CCB->LegacyTagEnable = true;
3487 CCB->LegacyQueueTag = QueueTag;
3490 memcpy(CCB->CDB, CDB, CDB_Length);
3491 CCB->SenseDataPointer = Virtual_to_Bus(&Command->sense_buffer);
3492 CCB->Command = Command;
3493 Command->scsi_done = CompletionRoutine;
3494 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3497 Place the CCB in an Outgoing Mailbox. The higher levels of the SCSI
3498 Subsystem should not attempt to queue more commands than can be placed
3499 in Outgoing Mailboxes, so there should always be one free. In the
3500 unlikely event that there are none available, wait 1 second and try
3501 again. If that fails, the Host Adapter is probably hung so signal an
3502 error as a Host Adapter Hard Reset should be initiated soon.
3504 if (!BusLogic_WriteOutgoingMailbox(
3505 HostAdapter, BusLogic_MailboxStartCommand, CCB))
3507 BusLogic_Warning("Unable to write Outgoing Mailbox - "
3508 "Pausing for 1 second\n", HostAdapter);
3509 BusLogic_Delay(1);
3510 if (!BusLogic_WriteOutgoingMailbox(
3511 HostAdapter, BusLogic_MailboxStartCommand, CCB))
3513 BusLogic_Warning("Still unable to write Outgoing Mailbox - "
3514 "Host Adapter Dead?\n", HostAdapter);
3515 BusLogic_DeallocateCCB(CCB);
3516 Command->result = DID_ERROR << 16;
3517 Command->scsi_done(Command);
3521 else
3524 Call the FlashPoint SCCB Manager to start execution of the CCB.
3526 CCB->Status = BusLogic_CCB_Active;
3527 HostAdapter->ActiveCommands[TargetID]++;
3528 TargetStatistics[TargetID].CommandsAttempted++;
3529 FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
3531 The Command may have already completed and BusLogic_QueueCompletedCCB
3532 been called, or it may still be pending.
3534 if (CCB->Status == BusLogic_CCB_Completed)
3535 BusLogic_ProcessCompletedCCBs(HostAdapter);
3538 Release exclusive access to Host Adapter.
3540 Done:
3541 BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
3542 return 0;
3547 BusLogic_AbortCommand aborts Command if possible.
3550 int BusLogic_AbortCommand(SCSI_Command_T *Command)
3552 BusLogic_HostAdapter_T *HostAdapter =
3553 (BusLogic_HostAdapter_T *) Command->host->hostdata;
3554 int TargetID = Command->target;
3555 ProcessorFlags_T ProcessorFlags;
3556 BusLogic_CCB_T *CCB;
3557 int Result;
3558 BusLogic_IncrementErrorCounter(
3559 &HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested);
3561 Acquire exclusive access to Host Adapter.
3563 BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
3565 If this Command has already completed, then no Abort is necessary.
3567 if (Command->serial_number != Command->serial_number_at_timeout)
3569 BusLogic_Warning("Unable to Abort Command to Target %d - "
3570 "Already Completed\n", HostAdapter, TargetID);
3571 Result = SCSI_ABORT_NOT_RUNNING;
3572 goto Done;
3575 Attempt to find an Active CCB for this Command. If no Active CCB for this
3576 Command is found, then no Abort is necessary.
3578 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3579 if (CCB->Command == Command) break;
3580 if (CCB == NULL)
3582 BusLogic_Warning("Unable to Abort Command to Target %d - "
3583 "No CCB Found\n", HostAdapter, TargetID);
3584 Result = SCSI_ABORT_NOT_RUNNING;
3585 goto Done;
3587 else if (CCB->Status == BusLogic_CCB_Completed)
3589 BusLogic_Warning("Unable to Abort Command to Target %d - "
3590 "CCB Completed\n", HostAdapter, TargetID);
3591 Result = SCSI_ABORT_NOT_RUNNING;
3592 goto Done;
3594 else if (CCB->Status == BusLogic_CCB_Reset)
3596 BusLogic_Warning("Unable to Abort Command to Target %d - "
3597 "CCB Reset\n", HostAdapter, TargetID);
3598 Result = SCSI_ABORT_PENDING;
3599 goto Done;
3601 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3604 Attempt to Abort this CCB. MultiMaster Firmware versions prior to 5.xx
3605 do not generate Abort Tag messages, but only generate the non-tagged
3606 Abort message. Since non-tagged commands are not sent by the Host
3607 Adapter until the queue of outstanding tagged commands has completed,
3608 and the Abort message is treated as a non-tagged command, it is
3609 effectively impossible to abort commands when Tagged Queuing is active.
3610 Firmware version 5.xx does generate Abort Tag messages, so it is
3611 possible to abort commands when Tagged Queuing is active.
3613 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
3614 HostAdapter->FirmwareVersion[0] < '5')
3616 BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
3617 "Abort Tag Not Supported\n",
3618 HostAdapter, CCB->SerialNumber, TargetID);
3619 Result = SCSI_ABORT_SNOOZE;
3621 else if (BusLogic_WriteOutgoingMailbox(
3622 HostAdapter, BusLogic_MailboxAbortCommand, CCB))
3624 BusLogic_Warning("Aborting CCB #%ld to Target %d\n",
3625 HostAdapter, CCB->SerialNumber, TargetID);
3626 BusLogic_IncrementErrorCounter(
3627 &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3628 Result = SCSI_ABORT_PENDING;
3630 else
3632 BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
3633 "No Outgoing Mailboxes\n",
3634 HostAdapter, CCB->SerialNumber, TargetID);
3635 Result = SCSI_ABORT_BUSY;
3638 else
3641 Call the FlashPoint SCCB Manager to abort execution of the CCB.
3643 BusLogic_Warning("Aborting CCB #%ld to Target %d\n",
3644 HostAdapter, CCB->SerialNumber, TargetID);
3645 BusLogic_IncrementErrorCounter(
3646 &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3647 FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB);
3649 The Abort may have already been completed and
3650 BusLogic_QueueCompletedCCB been called, or it
3651 may still be pending.
3653 Result = SCSI_ABORT_PENDING;
3654 if (CCB->Status == BusLogic_CCB_Completed)
3656 BusLogic_ProcessCompletedCCBs(HostAdapter);
3657 Result = SCSI_ABORT_SUCCESS;
3661 Release exclusive access to Host Adapter.
3663 Done:
3664 BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
3665 return Result;
3670 BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
3671 currently executing SCSI Commands as having been Reset.
3674 static int BusLogic_ResetHostAdapter(BusLogic_HostAdapter_T *HostAdapter,
3675 SCSI_Command_T *Command,
3676 unsigned int ResetFlags)
3678 ProcessorFlags_T ProcessorFlags;
3679 BusLogic_CCB_T *CCB;
3680 int TargetID, Result;
3681 boolean HardReset;
3682 if (HostAdapter->HostAdapterExternalReset)
3684 BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets);
3685 HardReset = false;
3687 else if (HostAdapter->HostAdapterInternalError)
3689 BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors);
3690 HardReset = true;
3692 else
3694 BusLogic_IncrementErrorCounter(
3695 &HostAdapter->TargetStatistics[Command->target]
3696 .HostAdapterResetsRequested);
3697 HardReset = true;
3700 Acquire exclusive access to Host Adapter.
3702 BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
3704 If this is an Asynchronous Reset and this Command has already completed,
3705 then no Reset is necessary.
3707 if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
3709 TargetID = Command->target;
3710 if (Command->serial_number != Command->serial_number_at_timeout)
3712 BusLogic_Warning("Unable to Reset Command to Target %d - "
3713 "Already Completed or Reset\n",
3714 HostAdapter, TargetID);
3715 Result = SCSI_RESET_NOT_RUNNING;
3716 goto Done;
3718 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3719 if (CCB->Command == Command) break;
3720 if (CCB == NULL)
3722 BusLogic_Warning("Unable to Reset Command to Target %d - "
3723 "No CCB Found\n", HostAdapter, TargetID);
3724 Result = SCSI_RESET_NOT_RUNNING;
3725 goto Done;
3727 else if (CCB->Status == BusLogic_CCB_Completed)
3729 BusLogic_Warning("Unable to Reset Command to Target %d - "
3730 "CCB Completed\n", HostAdapter, TargetID);
3731 Result = SCSI_RESET_NOT_RUNNING;
3732 goto Done;
3734 else if (CCB->Status == BusLogic_CCB_Reset &&
3735 HostAdapter->BusDeviceResetPendingCCB[TargetID] == NULL)
3737 BusLogic_Warning("Unable to Reset Command to Target %d - "
3738 "Reset Pending\n", HostAdapter, TargetID);
3739 Result = SCSI_RESET_PENDING;
3740 goto Done;
3743 if (Command == NULL)
3745 if (HostAdapter->HostAdapterInternalError)
3746 BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n",
3747 HostAdapter, HostAdapter->FullModelName);
3748 else BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n",
3749 HostAdapter, HostAdapter->FullModelName);
3751 else
3753 BusLogic_Warning("Resetting %s due to Target %d\n", HostAdapter,
3754 HostAdapter->FullModelName, Command->target);
3755 BusLogic_IncrementErrorCounter(
3756 &HostAdapter->TargetStatistics[Command->target]
3757 .HostAdapterResetsAttempted);
3760 Attempt to Reset and Reinitialize the Host Adapter.
3762 if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) &&
3763 BusLogic_InitializeHostAdapter(HostAdapter)))
3765 BusLogic_Error("Resetting %s Failed\n", HostAdapter,
3766 HostAdapter->FullModelName);
3767 Result = SCSI_RESET_ERROR;
3768 goto Done;
3770 if (Command != NULL)
3771 BusLogic_IncrementErrorCounter(
3772 &HostAdapter->TargetStatistics[Command->target]
3773 .HostAdapterResetsCompleted);
3775 Mark all currently executing CCBs as having been Reset.
3777 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3778 if (CCB->Status == BusLogic_CCB_Active)
3779 CCB->Status = BusLogic_CCB_Reset;
3781 Wait a few seconds between the Host Adapter Hard Reset which initiates
3782 a SCSI Bus Reset and issuing any SCSI Commands. Some SCSI devices get
3783 confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
3784 Note that a timer interrupt may occur here, but all active CCBs have
3785 already been marked Reset and so a reentrant call will return Pending.
3787 if (HardReset)
3788 BusLogic_Delay(HostAdapter->BusSettleTime);
3790 If this is a Synchronous Reset, perform completion processing for
3791 the Command being Reset.
3793 if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
3795 Command->result = DID_RESET << 16;
3796 Command->scsi_done(Command);
3799 Perform completion processing for all CCBs marked as Reset.
3801 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3802 if (CCB->Status == BusLogic_CCB_Reset)
3804 Command = CCB->Command;
3805 BusLogic_DeallocateCCB(CCB);
3806 while (Command != NULL)
3808 SCSI_Command_T *NextCommand = Command->reset_chain;
3809 Command->reset_chain = NULL;
3810 Command->result = DID_RESET << 16;
3811 Command->scsi_done(Command);
3812 Command = NextCommand;
3815 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
3817 HostAdapter->LastResetAttempted[TargetID] = jiffies;
3818 HostAdapter->LastResetCompleted[TargetID] = jiffies;
3820 Result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET;
3822 Release exclusive access to Host Adapter.
3824 Done:
3825 BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
3826 return Result;
3831 BusLogic_SendBusDeviceReset sends a Bus Device Reset to the Target
3832 Device associated with Command.
3835 static int BusLogic_SendBusDeviceReset(BusLogic_HostAdapter_T *HostAdapter,
3836 SCSI_Command_T *Command,
3837 unsigned int ResetFlags)
3839 int TargetID = Command->target;
3840 BusLogic_CCB_T *CCB, *XCCB;
3841 ProcessorFlags_T ProcessorFlags;
3842 int Result = -1;
3843 BusLogic_IncrementErrorCounter(
3844 &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsRequested);
3846 Acquire exclusive access to Host Adapter.
3848 BusLogic_AcquireHostAdapterLock(HostAdapter, &ProcessorFlags);
3850 If this is an Asynchronous Reset and this Command has already completed,
3851 then no Reset is necessary.
3853 if (ResetFlags & SCSI_RESET_ASYNCHRONOUS)
3855 if (Command->serial_number != Command->serial_number_at_timeout)
3857 BusLogic_Warning("Unable to Reset Command to Target %d - "
3858 "Already Completed\n", HostAdapter, TargetID);
3859 Result = SCSI_RESET_NOT_RUNNING;
3860 goto Done;
3862 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3863 if (CCB->Command == Command) break;
3864 if (CCB == NULL)
3866 BusLogic_Warning("Unable to Reset Command to Target %d - "
3867 "No CCB Found\n", HostAdapter, TargetID);
3868 Result = SCSI_RESET_NOT_RUNNING;
3869 goto Done;
3871 else if (CCB->Status == BusLogic_CCB_Completed)
3873 BusLogic_Warning("Unable to Reset Command to Target %d - "
3874 "CCB Completed\n", HostAdapter, TargetID);
3875 Result = SCSI_RESET_NOT_RUNNING;
3876 goto Done;
3878 else if (CCB->Status == BusLogic_CCB_Reset)
3880 BusLogic_Warning("Unable to Reset Command to Target %d - "
3881 "Reset Pending\n", HostAdapter, TargetID);
3882 Result = SCSI_RESET_PENDING;
3883 goto Done;
3885 else if (HostAdapter->BusDeviceResetPendingCCB[TargetID] != NULL)
3887 BusLogic_Warning("Bus Device Reset already pending to Target %d\n",
3888 HostAdapter, TargetID);
3889 goto Done;
3893 If this is a Synchronous Reset and a Bus Device Reset is already pending
3894 for this Target Device, do not send a second one. Add this Command to
3895 the list of Commands for which completion processing must be performed
3896 when the Bus Device Reset CCB completes.
3898 if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
3899 if ((CCB = HostAdapter->BusDeviceResetPendingCCB[TargetID]) != NULL)
3901 Command->reset_chain = CCB->Command;
3902 CCB->Command = Command;
3903 BusLogic_Warning("Unable to Reset Command to Target %d - "
3904 "Reset Pending\n", HostAdapter, TargetID);
3905 Result = SCSI_RESET_PENDING;
3906 goto Done;
3908 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3911 MultiMaster Firmware versions prior to 5.xx treat a Bus Device Reset as
3912 a non-tagged command. Since non-tagged commands are not sent by the
3913 Host Adapter until the queue of outstanding tagged commands has
3914 completed, it is effectively impossible to send a Bus Device Reset
3915 while there are tagged commands outstanding. Therefore, in that case a
3916 full Host Adapter Hard Reset and SCSI Bus Reset must be done.
3918 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
3919 HostAdapter->ActiveCommands[TargetID] > 0 &&
3920 HostAdapter->FirmwareVersion[0] < '5')
3921 goto Done;
3924 Allocate a CCB from the Host Adapter's free list. In the unlikely event
3925 that there are none available and memory allocation fails, attempt a full
3926 Host Adapter Hard Reset and SCSI Bus Reset.
3928 CCB = BusLogic_AllocateCCB(HostAdapter);
3929 if (CCB == NULL) goto Done;
3930 BusLogic_Warning("Sending Bus Device Reset CCB #%ld to Target %d\n",
3931 HostAdapter, CCB->SerialNumber, TargetID);
3932 CCB->Opcode = BusLogic_BusDeviceReset;
3933 CCB->TargetID = TargetID;
3935 For Synchronous Resets, arrange for the interrupt handler to perform
3936 completion processing for the Command being Reset.
3938 if (ResetFlags & SCSI_RESET_SYNCHRONOUS)
3940 Command->reset_chain = NULL;
3941 CCB->Command = Command;
3943 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3946 Attempt to write an Outgoing Mailbox with the Bus Device Reset CCB.
3947 If sending a Bus Device Reset is impossible, attempt a full Host
3948 Adapter Hard Reset and SCSI Bus Reset.
3950 if (!(BusLogic_WriteOutgoingMailbox(
3951 HostAdapter, BusLogic_MailboxStartCommand, CCB)))
3953 BusLogic_Warning("Unable to write Outgoing Mailbox for "
3954 "Bus Device Reset\n", HostAdapter);
3955 BusLogic_DeallocateCCB(CCB);
3956 goto Done;
3959 else
3962 Call the FlashPoint SCCB Manager to start execution of the CCB.
3964 CCB->Status = BusLogic_CCB_Active;
3965 HostAdapter->ActiveCommands[TargetID]++;
3966 FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
3969 If there is a currently executing CCB in the Host Adapter for this Command
3970 (i.e. this is an Asynchronous Reset), then an Incoming Mailbox entry may be
3971 made with a completion code of BusLogic_HostAdapterAssertedBusDeviceReset.
3972 If there is no active CCB for this Command (i.e. this is a Synchronous
3973 Reset), then the Bus Device Reset CCB's Command field will have been set
3974 to the Command so that the interrupt for the completion of the Bus Device
3975 Reset can call the Completion Routine for the Command. On successful
3976 execution of a Bus Device Reset, older firmware versions did return the
3977 pending CCBs with the appropriate completion code, but more recent firmware
3978 versions only return the Bus Device Reset CCB itself. This driver handles
3979 both cases by marking all the currently executing CCBs to this Target
3980 Device as Reset. When the Bus Device Reset CCB is processed by the
3981 interrupt handler, any remaining CCBs marked as Reset will have completion
3982 processing performed.
3984 BusLogic_IncrementErrorCounter(
3985 &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsAttempted);
3986 HostAdapter->BusDeviceResetPendingCCB[TargetID] = CCB;
3987 HostAdapter->LastResetAttempted[TargetID] = jiffies;
3988 for (XCCB = HostAdapter->All_CCBs; XCCB != NULL; XCCB = XCCB->NextAll)
3989 if (XCCB->Status == BusLogic_CCB_Active && XCCB->TargetID == TargetID)
3990 XCCB->Status = BusLogic_CCB_Reset;
3992 FlashPoint Host Adapters may have already completed the Bus Device
3993 Reset and BusLogic_QueueCompletedCCB been called, or it may still be
3994 pending.
3996 Result = SCSI_RESET_PENDING;
3997 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
3998 if (CCB->Status == BusLogic_CCB_Completed)
4000 BusLogic_ProcessCompletedCCBs(HostAdapter);
4001 Result = SCSI_RESET_SUCCESS;
4004 If a Bus Device Reset was not possible for some reason, force a full
4005 Host Adapter Hard Reset and SCSI Bus Reset.
4007 Done:
4008 if (Result < 0)
4009 Result = BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
4011 Release exclusive access to Host Adapter.
4013 BusLogic_ReleaseHostAdapterLock(HostAdapter, &ProcessorFlags);
4014 return Result;
4019 BusLogic_ResetCommand takes appropriate action to reset Command.
4022 int BusLogic_ResetCommand(SCSI_Command_T *Command, unsigned int ResetFlags)
4024 BusLogic_HostAdapter_T *HostAdapter =
4025 (BusLogic_HostAdapter_T *) Command->host->hostdata;
4026 int TargetID = Command->target;
4027 BusLogic_ErrorRecoveryStrategy_T
4028 ErrorRecoveryStrategy = HostAdapter->ErrorRecoveryStrategy[TargetID];
4030 Disable Tagged Queuing if it is active for this Target Device and if
4031 it has been less than 10 minutes since the last reset occurred, or since
4032 the system was initialized if no prior resets have occurred.
4034 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
4035 jiffies - HostAdapter->LastResetCompleted[TargetID] < 10*60*HZ)
4037 HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
4038 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
4039 BusLogic_Warning("Tagged Queuing now disabled for Target %d\n",
4040 HostAdapter, TargetID);
4042 switch (ErrorRecoveryStrategy)
4044 case BusLogic_ErrorRecovery_Default:
4045 if (ResetFlags & SCSI_RESET_SUGGEST_HOST_RESET)
4046 return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
4047 else if (ResetFlags & SCSI_RESET_SUGGEST_BUS_RESET)
4048 return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
4049 /* Fall through to Bus Device Reset case. */
4050 case BusLogic_ErrorRecovery_BusDeviceReset:
4052 The Bus Device Reset Error Recovery Strategy only graduates to a Hard
4053 Reset when no commands have completed successfully since the last Bus
4054 Device Reset and it has been at least 100 milliseconds. This prevents
4055 a sequence of commands that all timeout together from immediately
4056 forcing a Hard Reset before the Bus Device Reset has had a chance to
4057 clear the error condition.
4059 if (HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag ||
4060 jiffies - HostAdapter->LastResetAttempted[TargetID] < HZ/10)
4062 HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
4063 return BusLogic_SendBusDeviceReset(HostAdapter, Command, ResetFlags);
4065 /* Fall through to Hard Reset case. */
4066 case BusLogic_ErrorRecovery_HardReset:
4067 return BusLogic_ResetHostAdapter(HostAdapter, Command, ResetFlags);
4068 case BusLogic_ErrorRecovery_None:
4069 BusLogic_Warning("Error Recovery for Target %d Suppressed\n",
4070 HostAdapter, TargetID);
4071 break;
4073 return SCSI_RESET_PUNT;
4078 BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
4079 Parameters for Disk. The default disk geometry is 64 heads, 32 sectors, and
4080 the appropriate number of cylinders so as not to exceed drive capacity. In
4081 order for disks equal to or larger than 1 GB to be addressable by the BIOS
4082 without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
4083 may be enabled in AutoSCSI on FlashPoint Host Adapters and on "W" and "C"
4084 series MultiMaster Host Adapters, or by a dip switch setting on "S" and "A"
4085 series MultiMaster Host Adapters. With Extended Translation enabled, drives
4086 between 1 GB inclusive and 2 GB exclusive are given a disk geometry of 128
4087 heads and 32 sectors, and drives above 2 GB inclusive are given a disk
4088 geometry of 255 heads and 63 sectors. However, if the BIOS detects that the
4089 Extended Translation setting does not match the geometry in the partition
4090 table, then the translation inferred from the partition table will be used by
4091 the BIOS, and a warning may be displayed.
4094 int BusLogic_BIOSDiskParameters(SCSI_Disk_T *Disk, KernelDevice_T Device,
4095 int *Parameters)
4097 BusLogic_HostAdapter_T *HostAdapter =
4098 (BusLogic_HostAdapter_T *) Disk->device->host->hostdata;
4099 BIOS_DiskParameters_T *DiskParameters = (BIOS_DiskParameters_T *) Parameters;
4100 struct buffer_head *BufferHead;
4101 if (HostAdapter->ExtendedTranslationEnabled &&
4102 Disk->capacity >= 2*1024*1024 /* 1 GB in 512 byte sectors */)
4104 if (Disk->capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */)
4106 DiskParameters->Heads = 255;
4107 DiskParameters->Sectors = 63;
4109 else
4111 DiskParameters->Heads = 128;
4112 DiskParameters->Sectors = 32;
4115 else
4117 DiskParameters->Heads = 64;
4118 DiskParameters->Sectors = 32;
4120 DiskParameters->Cylinders =
4121 Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
4123 Attempt to read the first 1024 bytes from the disk device.
4125 BufferHead = bread(MKDEV(MAJOR(Device), MINOR(Device) & ~0x0F), 0, 1024);
4126 if (BufferHead == NULL) return 0;
4128 If the boot sector partition table flag is valid, search for a partition
4129 table entry whose end_head matches one of the standard BusLogic geometry
4130 translations (64/32, 128/32, or 255/63).
4132 if (*(unsigned short *) (BufferHead->b_data + 0x1FE) == 0xAA55)
4134 PartitionTable_T *FirstPartitionEntry =
4135 (PartitionTable_T *) (BufferHead->b_data + 0x1BE);
4136 PartitionTable_T *PartitionEntry = FirstPartitionEntry;
4137 int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
4138 unsigned char PartitionEntryEndHead, PartitionEntryEndSector;
4139 for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++)
4141 PartitionEntryEndHead = PartitionEntry->end_head;
4142 PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F;
4143 if (PartitionEntryEndHead == 64-1)
4145 DiskParameters->Heads = 64;
4146 DiskParameters->Sectors = 32;
4147 break;
4149 else if (PartitionEntryEndHead == 128-1)
4151 DiskParameters->Heads = 128;
4152 DiskParameters->Sectors = 32;
4153 break;
4155 else if (PartitionEntryEndHead == 255-1)
4157 DiskParameters->Heads = 255;
4158 DiskParameters->Sectors = 63;
4159 break;
4161 PartitionEntry++;
4163 if (PartitionNumber == 4)
4165 PartitionEntryEndHead = FirstPartitionEntry->end_head;
4166 PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F;
4168 DiskParameters->Cylinders =
4169 Disk->capacity / (DiskParameters->Heads * DiskParameters->Sectors);
4170 if (PartitionNumber < 4 &&
4171 PartitionEntryEndSector == DiskParameters->Sectors)
4173 if (DiskParameters->Cylinders != SavedCylinders)
4174 BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n",
4175 HostAdapter,
4176 DiskParameters->Heads, DiskParameters->Sectors);
4178 else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0)
4180 BusLogic_Warning("Warning: Partition Table appears to "
4181 "have Geometry %d/%d which is\n", HostAdapter,
4182 PartitionEntryEndHead + 1,
4183 PartitionEntryEndSector);
4184 BusLogic_Warning("not compatible with current BusLogic "
4185 "Host Adapter Geometry %d/%d\n", HostAdapter,
4186 DiskParameters->Heads, DiskParameters->Sectors);
4189 brelse(BufferHead);
4190 return 0;
4195 BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
4198 int BusLogic_ProcDirectoryInfo(char *ProcBuffer, char **StartPointer,
4199 off_t Offset, int BytesAvailable,
4200 int HostNumber, int WriteFlag)
4202 BusLogic_HostAdapter_T *HostAdapter;
4203 BusLogic_TargetStatistics_T *TargetStatistics;
4204 int TargetID, Length;
4205 char *Buffer;
4206 for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
4207 HostAdapter != NULL;
4208 HostAdapter = HostAdapter->Next)
4209 if (HostAdapter->HostNumber == HostNumber) break;
4210 if (HostAdapter == NULL)
4212 BusLogic_Error("Cannot find Host Adapter for SCSI Host %d\n",
4213 NULL, HostNumber);
4214 return 0;
4216 TargetStatistics = HostAdapter->TargetStatistics;
4217 if (WriteFlag)
4219 HostAdapter->ExternalHostAdapterResets = 0;
4220 HostAdapter->HostAdapterInternalErrors = 0;
4221 memset(TargetStatistics, 0,
4222 BusLogic_MaxTargetDevices * sizeof(BusLogic_TargetStatistics_T));
4223 return 0;
4225 Buffer = HostAdapter->MessageBuffer;
4226 Length = HostAdapter->MessageBufferLength;
4227 Length += sprintf(&Buffer[Length], "\n\
4228 Current Driver Queue Depth: %d\n\
4229 Currently Allocated CCBs: %d\n",
4230 HostAdapter->DriverQueueDepth,
4231 HostAdapter->AllocatedCCBs);
4232 Length += sprintf(&Buffer[Length], "\n\n\
4233 DATA TRANSFER STATISTICS\n\
4235 Target Tagged Queuing Queue Depth Active Attempted Completed\n\
4236 ====== ============== =========== ====== ========= =========\n");
4237 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4239 BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4240 if (!TargetFlags->TargetExists) continue;
4241 Length +=
4242 sprintf(&Buffer[Length], " %2d %s", TargetID,
4243 (TargetFlags->TaggedQueuingSupported
4244 ? (TargetFlags->TaggedQueuingActive
4245 ? " Active"
4246 : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
4247 ? " Permitted" : " Disabled"))
4248 : "Not Supported"));
4249 Length += sprintf(&Buffer[Length],
4250 " %3d %3u %9u %9u\n",
4251 HostAdapter->QueueDepth[TargetID],
4252 HostAdapter->ActiveCommands[TargetID],
4253 TargetStatistics[TargetID].CommandsAttempted,
4254 TargetStatistics[TargetID].CommandsCompleted);
4256 Length += sprintf(&Buffer[Length], "\n\
4257 Target Read Commands Write Commands Total Bytes Read Total Bytes Written\n\
4258 ====== ============= ============== =================== ===================\n");
4259 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4261 BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4262 if (!TargetFlags->TargetExists) continue;
4263 Length +=
4264 sprintf(&Buffer[Length], " %2d %9u %9u", TargetID,
4265 TargetStatistics[TargetID].ReadCommands,
4266 TargetStatistics[TargetID].WriteCommands);
4267 if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0)
4268 Length +=
4269 sprintf(&Buffer[Length], " %9u%09u",
4270 TargetStatistics[TargetID].TotalBytesRead.Billions,
4271 TargetStatistics[TargetID].TotalBytesRead.Units);
4272 else
4273 Length +=
4274 sprintf(&Buffer[Length], " %9u",
4275 TargetStatistics[TargetID].TotalBytesRead.Units);
4276 if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0)
4277 Length +=
4278 sprintf(&Buffer[Length], " %9u%09u\n",
4279 TargetStatistics[TargetID].TotalBytesWritten.Billions,
4280 TargetStatistics[TargetID].TotalBytesWritten.Units);
4281 else
4282 Length +=
4283 sprintf(&Buffer[Length], " %9u\n",
4284 TargetStatistics[TargetID].TotalBytesWritten.Units);
4286 Length += sprintf(&Buffer[Length], "\n\
4287 Target Command 0-1KB 1-2KB 2-4KB 4-8KB 8-16KB\n\
4288 ====== ======= ========= ========= ========= ========= =========\n");
4289 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4291 BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4292 if (!TargetFlags->TargetExists) continue;
4293 Length +=
4294 sprintf(&Buffer[Length],
4295 " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
4296 TargetStatistics[TargetID].ReadCommandSizeBuckets[0],
4297 TargetStatistics[TargetID].ReadCommandSizeBuckets[1],
4298 TargetStatistics[TargetID].ReadCommandSizeBuckets[2],
4299 TargetStatistics[TargetID].ReadCommandSizeBuckets[3],
4300 TargetStatistics[TargetID].ReadCommandSizeBuckets[4]);
4301 Length +=
4302 sprintf(&Buffer[Length],
4303 " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
4304 TargetStatistics[TargetID].WriteCommandSizeBuckets[0],
4305 TargetStatistics[TargetID].WriteCommandSizeBuckets[1],
4306 TargetStatistics[TargetID].WriteCommandSizeBuckets[2],
4307 TargetStatistics[TargetID].WriteCommandSizeBuckets[3],
4308 TargetStatistics[TargetID].WriteCommandSizeBuckets[4]);
4310 Length += sprintf(&Buffer[Length], "\n\
4311 Target Command 16-32KB 32-64KB 64-128KB 128-256KB 256KB+\n\
4312 ====== ======= ========= ========= ========= ========= =========\n");
4313 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4315 BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4316 if (!TargetFlags->TargetExists) continue;
4317 Length +=
4318 sprintf(&Buffer[Length],
4319 " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
4320 TargetStatistics[TargetID].ReadCommandSizeBuckets[5],
4321 TargetStatistics[TargetID].ReadCommandSizeBuckets[6],
4322 TargetStatistics[TargetID].ReadCommandSizeBuckets[7],
4323 TargetStatistics[TargetID].ReadCommandSizeBuckets[8],
4324 TargetStatistics[TargetID].ReadCommandSizeBuckets[9]);
4325 Length +=
4326 sprintf(&Buffer[Length],
4327 " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
4328 TargetStatistics[TargetID].WriteCommandSizeBuckets[5],
4329 TargetStatistics[TargetID].WriteCommandSizeBuckets[6],
4330 TargetStatistics[TargetID].WriteCommandSizeBuckets[7],
4331 TargetStatistics[TargetID].WriteCommandSizeBuckets[8],
4332 TargetStatistics[TargetID].WriteCommandSizeBuckets[9]);
4334 Length += sprintf(&Buffer[Length], "\n\n\
4335 ERROR RECOVERY STATISTICS\n\
4337 Command Aborts Bus Device Resets Host Adapter Resets\n\
4338 Target Requested Completed Requested Completed Requested Completed\n\
4339 ID \\\\\\\\ Attempted //// \\\\\\\\ Attempted //// \\\\\\\\ Attempted ////\n\
4340 ====== ===== ===== ===== ===== ===== ===== ===== ===== =====\n");
4341 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
4343 BusLogic_TargetFlags_T *TargetFlags = &HostAdapter->TargetFlags[TargetID];
4344 if (!TargetFlags->TargetExists) continue;
4345 Length +=
4346 sprintf(&Buffer[Length], "\
4347 %2d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", TargetID,
4348 TargetStatistics[TargetID].CommandAbortsRequested,
4349 TargetStatistics[TargetID].CommandAbortsAttempted,
4350 TargetStatistics[TargetID].CommandAbortsCompleted,
4351 TargetStatistics[TargetID].BusDeviceResetsRequested,
4352 TargetStatistics[TargetID].BusDeviceResetsAttempted,
4353 TargetStatistics[TargetID].BusDeviceResetsCompleted,
4354 TargetStatistics[TargetID].HostAdapterResetsRequested,
4355 TargetStatistics[TargetID].HostAdapterResetsAttempted,
4356 TargetStatistics[TargetID].HostAdapterResetsCompleted);
4358 Length += sprintf(&Buffer[Length], "\nExternal Host Adapter Resets: %d\n",
4359 HostAdapter->ExternalHostAdapterResets);
4360 Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %d\n",
4361 HostAdapter->HostAdapterInternalErrors);
4362 if (Length >= BusLogic_MessageBufferSize)
4363 BusLogic_Error("Message Buffer length %d exceeds size %d\n",
4364 HostAdapter, Length, BusLogic_MessageBufferSize);
4365 if ((Length -= Offset) <= 0) return 0;
4366 if (Length >= BytesAvailable) Length = BytesAvailable;
4367 memcpy(ProcBuffer, HostAdapter->MessageBuffer + Offset, Length);
4368 *StartPointer = ProcBuffer;
4369 return Length;
4374 BusLogic_Message prints Driver Messages.
4377 static void BusLogic_Message(BusLogic_MessageLevel_T MessageLevel,
4378 char *Format,
4379 BusLogic_HostAdapter_T *HostAdapter,
4380 ...)
4382 static char Buffer[BusLogic_LineBufferSize];
4383 static boolean BeginningOfLine = true;
4384 va_list Arguments;
4385 int Length = 0;
4386 va_start(Arguments, HostAdapter);
4387 Length = vsprintf(Buffer, Format, Arguments);
4388 va_end(Arguments);
4389 if (MessageLevel == BusLogic_AnnounceLevel)
4391 static int AnnouncementLines = 0;
4392 strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength],
4393 Buffer);
4394 HostAdapter->MessageBufferLength += Length;
4395 if (++AnnouncementLines <= 2)
4396 printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
4398 else if (MessageLevel == BusLogic_InfoLevel)
4400 strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength],
4401 Buffer);
4402 HostAdapter->MessageBufferLength += Length;
4403 if (BeginningOfLine)
4405 if (Buffer[0] != '\n' || Length > 1)
4406 printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
4407 HostAdapter->HostNumber, Buffer);
4409 else printk("%s", Buffer);
4411 else
4413 if (BeginningOfLine)
4415 if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized)
4416 printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
4417 HostAdapter->HostNumber, Buffer);
4418 else printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
4420 else printk("%s", Buffer);
4422 BeginningOfLine = (Buffer[Length-1] == '\n');
4427 BusLogic_ParseKeyword parses an individual option keyword. It returns true
4428 and updates the pointer if the keyword is recognized and false otherwise.
4431 static boolean BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
4433 char *Pointer = *StringPointer;
4434 while (*Keyword != '\0')
4436 char StringChar = *Pointer++;
4437 char KeywordChar = *Keyword++;
4438 if (StringChar >= 'A' && StringChar <= 'Z')
4439 StringChar += 'a' - 'Z';
4440 if (KeywordChar >= 'A' && KeywordChar <= 'Z')
4441 KeywordChar += 'a' - 'Z';
4442 if (StringChar != KeywordChar) return false;
4444 *StringPointer = Pointer;
4445 return true;
4450 BusLogic_ParseDriverOptions handles processing of BusLogic Driver Options
4451 specifications.
4453 BusLogic Driver Options may be specified either via the Linux Kernel Command
4454 Line or via the Loadable Kernel Module Installation Facility. Driver Options
4455 for multiple host adapters may be specified either by separating the option
4456 strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
4457 command line. Individual option specifications for a single host adapter are
4458 separated by commas. The Probing and Debugging Options apply to all host
4459 adapters whereas the remaining options apply individually only to the
4460 selected host adapter.
4462 The BusLogic Driver Probing Options comprise the following:
4464 IO:<integer>
4466 The "IO:" option specifies an ISA I/O Address to be probed for a non-PCI
4467 MultiMaster Host Adapter. If neither "IO:" nor "NoProbeISA" options are
4468 specified, then the standard list of BusLogic MultiMaster ISA I/O Addresses
4469 will be probed (0x330, 0x334, 0x230, 0x234, 0x130, and 0x134). Multiple
4470 "IO:" options may be specified to precisely determine the I/O Addresses to
4471 be probed, but the probe order will always follow the standard list.
4473 NoProbe
4475 The "NoProbe" option disables all probing and therefore no BusLogic Host
4476 Adapters will be detected.
4478 NoProbeISA
4480 The "NoProbeISA" option disables probing of the standard BusLogic ISA I/O
4481 Addresses and therefore only PCI MultiMaster and FlashPoint Host Adapters
4482 will be detected.
4484 NoProbePCI
4486 The "NoProbePCI" options disables the interrogation of PCI Configuration
4487 Space and therefore only ISA Multimaster Host Adapters will be detected, as
4488 well as PCI Multimaster Host Adapters that have their ISA Compatible I/O
4489 Port set to "Primary" or "Alternate".
4491 NoSortPCI
4493 The "NoSortPCI" option forces PCI MultiMaster Host Adapters to be
4494 enumerated in the order provided by the PCI BIOS, ignoring any setting of
4495 the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option.
4497 MultiMasterFirst
4499 The "MultiMasterFirst" option forces MultiMaster Host Adapters to be probed
4500 before FlashPoint Host Adapters. By default, if both FlashPoint and PCI
4501 MultiMaster Host Adapters are present, this driver will probe for
4502 FlashPoint Host Adapters first unless the BIOS primary disk is controlled
4503 by the first PCI MultiMaster Host Adapter, in which case MultiMaster Host
4504 Adapters will be probed first.
4506 FlashPointFirst
4508 The "FlashPointFirst" option forces FlashPoint Host Adapters to be probed
4509 before MultiMaster Host Adapters.
4511 The BusLogic Driver Tagged Queuing Options allow for explicitly specifying
4512 the Queue Depth and whether Tagged Queuing is permitted for each Target
4513 Device (assuming that the Target Device supports Tagged Queuing). The Queue
4514 Depth is the number of SCSI Commands that are allowed to be concurrently
4515 presented for execution (either to the Host Adapter or Target Device). Note
4516 that explicitly enabling Tagged Queuing may lead to problems; the option to
4517 enable or disable Tagged Queuing is provided primarily to allow disabling
4518 Tagged Queuing on Target Devices that do not implement it correctly. The
4519 following options are available:
4521 QueueDepth:<integer>
4523 The "QueueDepth:" or QD:" option specifies the Queue Depth to use for all
4524 Target Devices that support Tagged Queuing, as well as the maximum Queue
4525 Depth for devices that do not support Tagged Queuing. If no Queue Depth
4526 option is provided, the Queue Depth will be determined automatically based
4527 on the Host Adapter's Total Queue Depth and the number, type, speed, and
4528 capabilities of the detected Target Devices. For Host Adapters that
4529 require ISA Bounce Buffers, the Queue Depth is automatically set by default
4530 to BusLogic_TaggedQueueDepthBB or BusLogic_UntaggedQueueDepthBB to avoid
4531 excessive preallocation of DMA Bounce Buffer memory. Target Devices that
4532 do not support Tagged Queuing always have their Queue Depth set to
4533 BusLogic_UntaggedQueueDepth or BusLogic_UntaggedQueueDepthBB, unless a
4534 lower Queue Depth option is provided. A Queue Depth of 1 automatically
4535 disables Tagged Queuing.
4537 QueueDepth:[<integer>,<integer>...]
4539 The "QueueDepth:[...]" or "QD:[...]" option specifies the Queue Depth
4540 individually for each Target Device. If an <integer> is omitted, the
4541 associated Target Device will have its Queue Depth selected automatically.
4543 TaggedQueuing:Default
4545 The "TaggedQueuing:Default" or "TQ:Default" option permits Tagged Queuing
4546 based on the firmware version of the BusLogic Host Adapter and based on
4547 whether the Queue Depth allows queuing multiple commands.
4549 TaggedQueuing:Enable
4551 The "TaggedQueuing:Enable" or "TQ:Enable" option enables Tagged Queuing for
4552 all Target Devices on this Host Adapter, overriding any limitation that
4553 would otherwise be imposed based on the Host Adapter firmware version.
4555 TaggedQueuing:Disable
4557 The "TaggedQueuing:Disable" or "TQ:Disable" option disables Tagged Queuing
4558 for all Target Devices on this Host Adapter.
4560 TaggedQueuing:<Target-Spec>
4562 The "TaggedQueuing:<Target-Spec>" or "TQ:<Target-Spec>" option controls
4563 Tagged Queuing individually for each Target Device. <Target-Spec> is a
4564 sequence of "Y", "N", and "X" characters. "Y" enables Tagged Queuing, "N"
4565 disables Tagged Queuing, and "X" accepts the default based on the firmware
4566 version. The first character refers to Target Device 0, the second to
4567 Target Device 1, and so on; if the sequence of "Y", "N", and "X" characters
4568 does not cover all the Target Devices, unspecified characters are assumed
4569 to be "X".
4571 The BusLogic Driver Error Recovery Option allows for explicitly specifying
4572 the Error Recovery action to be performed when BusLogic_ResetCommand is
4573 called due to a SCSI Command failing to complete successfully. The following
4574 options are available:
4576 ErrorRecovery:Default
4578 The "ErrorRecovery:Default" or "ER:Default" option selects between the Hard
4579 Reset and Bus Device Reset options based on the recommendation of the SCSI
4580 Subsystem.
4582 ErrorRecovery:HardReset
4584 The "ErrorRecovery:HardReset" or "ER:HardReset" option will initiate a Host
4585 Adapter Hard Reset which also causes a SCSI Bus Reset.
4587 ErrorRecovery:BusDeviceReset
4589 The "ErrorRecovery:BusDeviceReset" or "ER:BusDeviceReset" option will send
4590 a Bus Device Reset message to the individual Target Device causing the
4591 error. If Error Recovery is again initiated for this Target Device and no
4592 SCSI Command to this Target Device has completed successfully since the Bus
4593 Device Reset message was sent, then a Hard Reset will be attempted.
4595 ErrorRecovery:None
4597 The "ErrorRecovery:None" or "ER:None" option suppresses Error Recovery.
4598 This option should only be selected if a SCSI Bus Reset or Bus Device Reset
4599 will cause the Target Device or a critical operation to suffer a complete
4600 and unrecoverable failure.
4602 ErrorRecovery:<Target-Spec>
4604 The "ErrorRecovery:<Target-Spec>" or "ER:<Target-Spec>" option controls
4605 Error Recovery individually for each Target Device. <Target-Spec> is a
4606 sequence of "D", "H", "B", and "N" characters. "D" selects Default, "H"
4607 selects Hard Reset, "B" selects Bus Device Reset, and "N" selects None.
4608 The first character refers to Target Device 0, the second to Target Device
4609 1, and so on; if the sequence of "D", "H", "B", and "N" characters does not
4610 cover all the possible Target Devices, unspecified characters are assumed
4611 to be "D".
4613 The BusLogic Driver Miscellaneous Options comprise the following:
4615 BusSettleTime:<seconds>
4617 The "BusSettleTime:" or "BST:" option specifies the Bus Settle Time in
4618 seconds. The Bus Settle Time is the amount of time to wait between a Host
4619 Adapter Hard Reset which initiates a SCSI Bus Reset and issuing any SCSI
4620 Commands. If unspecified, it defaults to BusLogic_DefaultBusSettleTime.
4622 InhibitTargetInquiry
4624 The "InhibitTargetInquiry" option inhibits the execution of an Inquire
4625 Target Devices or Inquire Installed Devices command on MultiMaster Host
4626 Adapters. This may be necessary with some older Target Devices that do not
4627 respond correctly when Logical Units above 0 are addressed.
4629 The BusLogic Driver Debugging Options comprise the following:
4631 TraceProbe
4633 The "TraceProbe" option enables tracing of Host Adapter Probing.
4635 TraceHardwareReset
4637 The "TraceHardwareReset" option enables tracing of Host Adapter Hardware
4638 Reset.
4640 TraceConfiguration
4642 The "TraceConfiguration" option enables tracing of Host Adapter
4643 Configuration.
4645 TraceErrors
4647 The "TraceErrors" option enables tracing of SCSI Commands that return an
4648 error from the Target Device. The CDB and Sense Data will be printed for
4649 each SCSI Command that fails.
4651 Debug
4653 The "Debug" option enables all debugging options.
4655 The following examples demonstrate setting the Queue Depth for Target Devices
4656 1 and 2 on the first host adapter to 7 and 15, the Queue Depth for all Target
4657 Devices on the second host adapter to 31, and the Bus Settle Time on the
4658 second host adapter to 30 seconds.
4660 Linux Kernel Command Line:
4662 linux BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30
4664 LILO Linux Boot Loader (in /etc/lilo.conf):
4666 append = "BusLogic=QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"
4668 INSMOD Loadable Kernel Module Installation Facility:
4670 insmod BusLogic.o \
4671 'BusLogic="QueueDepth:[,7,15];QueueDepth:31,BusSettleTime:30"'
4673 NOTE: Module Utilities 2.1.71 or later is required for correct parsing
4674 of driver options containing commas.
4678 static int __init BusLogic_ParseDriverOptions(char *OptionsString)
4680 while (true)
4682 BusLogic_DriverOptions_T *DriverOptions =
4683 &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++];
4684 int TargetID;
4685 memset(DriverOptions, 0, sizeof(BusLogic_DriverOptions_T));
4686 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
4687 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4688 BusLogic_ErrorRecovery_Default;
4689 while (*OptionsString != '\0' && *OptionsString != ';')
4691 /* Probing Options. */
4692 if (BusLogic_ParseKeyword(&OptionsString, "IO:"))
4694 BusLogic_IO_Address_T IO_Address =
4695 simple_strtoul(OptionsString, &OptionsString, 0);
4696 BusLogic_ProbeOptions.LimitedProbeISA = true;
4697 switch (IO_Address)
4699 case 0x330:
4700 BusLogic_ProbeOptions.Probe330 = true;
4701 break;
4702 case 0x334:
4703 BusLogic_ProbeOptions.Probe334 = true;
4704 break;
4705 case 0x230:
4706 BusLogic_ProbeOptions.Probe230 = true;
4707 break;
4708 case 0x234:
4709 BusLogic_ProbeOptions.Probe234 = true;
4710 break;
4711 case 0x130:
4712 BusLogic_ProbeOptions.Probe130 = true;
4713 break;
4714 case 0x134:
4715 BusLogic_ProbeOptions.Probe134 = true;
4716 break;
4717 default:
4718 BusLogic_Error("BusLogic: Invalid Driver Options "
4719 "(illegal I/O Address 0x%X)\n",
4720 NULL, IO_Address);
4721 return 0;
4724 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA"))
4725 BusLogic_ProbeOptions.NoProbeISA = true;
4726 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI"))
4727 BusLogic_ProbeOptions.NoProbePCI = true;
4728 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe"))
4729 BusLogic_ProbeOptions.NoProbe = true;
4730 else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI"))
4731 BusLogic_ProbeOptions.NoSortPCI = true;
4732 else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst"))
4733 BusLogic_ProbeOptions.MultiMasterFirst = true;
4734 else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst"))
4735 BusLogic_ProbeOptions.FlashPointFirst = true;
4736 /* Tagged Queuing Options. */
4737 else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") ||
4738 BusLogic_ParseKeyword(&OptionsString, "QD:["))
4740 for (TargetID = 0;
4741 TargetID < BusLogic_MaxTargetDevices;
4742 TargetID++)
4744 unsigned short QueueDepth =
4745 simple_strtoul(OptionsString, &OptionsString, 0);
4746 if (QueueDepth > BusLogic_MaxTaggedQueueDepth)
4748 BusLogic_Error("BusLogic: Invalid Driver Options "
4749 "(illegal Queue Depth %d)\n",
4750 NULL, QueueDepth);
4751 return 0;
4753 DriverOptions->QueueDepth[TargetID] = QueueDepth;
4754 if (*OptionsString == ',')
4755 OptionsString++;
4756 else if (*OptionsString == ']')
4757 break;
4758 else
4760 BusLogic_Error("BusLogic: Invalid Driver Options "
4761 "(',' or ']' expected at '%s')\n",
4762 NULL, OptionsString);
4763 return 0;
4766 if (*OptionsString != ']')
4768 BusLogic_Error("BusLogic: Invalid Driver Options "
4769 "(']' expected at '%s')\n",
4770 NULL, OptionsString);
4771 return 0;
4773 else OptionsString++;
4775 else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") ||
4776 BusLogic_ParseKeyword(&OptionsString, "QD:"))
4778 unsigned short QueueDepth =
4779 simple_strtoul(OptionsString, &OptionsString, 0);
4780 if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth)
4782 BusLogic_Error("BusLogic: Invalid Driver Options "
4783 "(illegal Queue Depth %d)\n",
4784 NULL, QueueDepth);
4785 return 0;
4787 DriverOptions->CommonQueueDepth = QueueDepth;
4788 for (TargetID = 0;
4789 TargetID < BusLogic_MaxTargetDevices;
4790 TargetID++)
4791 DriverOptions->QueueDepth[TargetID] = QueueDepth;
4793 else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") ||
4794 BusLogic_ParseKeyword(&OptionsString, "TQ:"))
4796 if (BusLogic_ParseKeyword(&OptionsString, "Default"))
4798 DriverOptions->TaggedQueuingPermitted = 0x0000;
4799 DriverOptions->TaggedQueuingPermittedMask = 0x0000;
4801 else if (BusLogic_ParseKeyword(&OptionsString, "Enable"))
4803 DriverOptions->TaggedQueuingPermitted = 0xFFFF;
4804 DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
4806 else if (BusLogic_ParseKeyword(&OptionsString, "Disable"))
4808 DriverOptions->TaggedQueuingPermitted = 0x0000;
4809 DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
4811 else
4813 unsigned short TargetBit;
4814 for (TargetID = 0, TargetBit = 1;
4815 TargetID < BusLogic_MaxTargetDevices;
4816 TargetID++, TargetBit <<= 1)
4817 switch (*OptionsString++)
4819 case 'Y':
4820 DriverOptions->TaggedQueuingPermitted |= TargetBit;
4821 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
4822 break;
4823 case 'N':
4824 DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
4825 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
4826 break;
4827 case 'X':
4828 break;
4829 default:
4830 OptionsString--;
4831 TargetID = BusLogic_MaxTargetDevices;
4832 break;
4836 /* Error Recovery Option. */
4837 else if (BusLogic_ParseKeyword(&OptionsString, "ErrorRecovery:") ||
4838 BusLogic_ParseKeyword(&OptionsString, "ER:"))
4840 if (BusLogic_ParseKeyword(&OptionsString, "Default"))
4841 for (TargetID = 0;
4842 TargetID < BusLogic_MaxTargetDevices;
4843 TargetID++)
4844 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4845 BusLogic_ErrorRecovery_Default;
4846 else if (BusLogic_ParseKeyword(&OptionsString, "HardReset"))
4847 for (TargetID = 0;
4848 TargetID < BusLogic_MaxTargetDevices;
4849 TargetID++)
4850 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4851 BusLogic_ErrorRecovery_HardReset;
4852 else if (BusLogic_ParseKeyword(&OptionsString, "BusDeviceReset"))
4853 for (TargetID = 0;
4854 TargetID < BusLogic_MaxTargetDevices;
4855 TargetID++)
4856 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4857 BusLogic_ErrorRecovery_BusDeviceReset;
4858 else if (BusLogic_ParseKeyword(&OptionsString, "None"))
4859 for (TargetID = 0;
4860 TargetID < BusLogic_MaxTargetDevices;
4861 TargetID++)
4862 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4863 BusLogic_ErrorRecovery_None;
4864 else
4865 for (TargetID = 0;
4866 TargetID < BusLogic_MaxTargetDevices;
4867 TargetID++)
4868 switch (*OptionsString++)
4870 case 'D':
4871 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4872 BusLogic_ErrorRecovery_Default;
4873 break;
4874 case 'H':
4875 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4876 BusLogic_ErrorRecovery_HardReset;
4877 break;
4878 case 'B':
4879 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4880 BusLogic_ErrorRecovery_BusDeviceReset;
4881 break;
4882 case 'N':
4883 DriverOptions->ErrorRecoveryStrategy[TargetID] =
4884 BusLogic_ErrorRecovery_None;
4885 break;
4886 default:
4887 OptionsString--;
4888 TargetID = BusLogic_MaxTargetDevices;
4889 break;
4892 /* Miscellaneous Options. */
4893 else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") ||
4894 BusLogic_ParseKeyword(&OptionsString, "BST:"))
4896 unsigned short BusSettleTime =
4897 simple_strtoul(OptionsString, &OptionsString, 0);
4898 if (BusSettleTime > 5 * 60)
4900 BusLogic_Error("BusLogic: Invalid Driver Options "
4901 "(illegal Bus Settle Time %d)\n",
4902 NULL, BusSettleTime);
4903 return 0;
4905 DriverOptions->BusSettleTime = BusSettleTime;
4907 else if (BusLogic_ParseKeyword(&OptionsString,
4908 "InhibitTargetInquiry"))
4909 DriverOptions->LocalOptions.InhibitTargetInquiry = true;
4910 /* Debugging Options. */
4911 else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe"))
4912 BusLogic_GlobalOptions.TraceProbe = true;
4913 else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset"))
4914 BusLogic_GlobalOptions.TraceHardwareReset = true;
4915 else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration"))
4916 BusLogic_GlobalOptions.TraceConfiguration = true;
4917 else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors"))
4918 BusLogic_GlobalOptions.TraceErrors = true;
4919 else if (BusLogic_ParseKeyword(&OptionsString, "Debug"))
4921 BusLogic_GlobalOptions.TraceProbe = true;
4922 BusLogic_GlobalOptions.TraceHardwareReset = true;
4923 BusLogic_GlobalOptions.TraceConfiguration = true;
4924 BusLogic_GlobalOptions.TraceErrors = true;
4926 if (*OptionsString == ',')
4927 OptionsString++;
4928 else if (*OptionsString != ';' && *OptionsString != '\0')
4930 BusLogic_Error("BusLogic: Unexpected Driver Option '%s' "
4931 "ignored\n", NULL, OptionsString);
4932 *OptionsString = '\0';
4935 if (!(BusLogic_DriverOptionsCount == 0 ||
4936 BusLogic_ProbeInfoCount == 0 ||
4937 BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount))
4939 BusLogic_Error("BusLogic: Invalid Driver Options "
4940 "(all or no I/O Addresses must be specified)\n", NULL);
4941 return 0;
4944 Tagged Queuing is disabled when the Queue Depth is 1 since queuing
4945 multiple commands is not possible.
4947 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
4948 if (DriverOptions->QueueDepth[TargetID] == 1)
4950 unsigned short TargetBit = 1 << TargetID;
4951 DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
4952 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
4954 if (*OptionsString == ';') OptionsString++;
4955 if (*OptionsString == '\0') return 0;
4957 return 1;
4962 BusLogic_Setup handles processing of Kernel Command Line Arguments.
4965 static int __init
4966 BusLogic_Setup(char *str)
4968 int ints[3];
4970 (void)get_options(str, ARRAY_SIZE(ints), ints);
4972 if (ints[0] != 0) {
4973 BusLogic_Error("BusLogic: Obsolete Command Line Entry "
4974 "Format Ignored\n", NULL);
4975 return 0;
4977 if (str == NULL || *str == '\0')
4978 return 0;
4979 return BusLogic_ParseDriverOptions(str);
4982 __setup("BusLogic=", BusLogic_Setup);
4985 Include Module support if requested.
4988 #ifdef MODULE
4990 SCSI_Host_Template_T driver_template = BUSLOGIC;
4992 #include "scsi_module.c"
4994 #endif