4 Linux Driver for BusLogic MultiMaster and FlashPoint SCSI Host Adapters
6 Copyright 1995-1998 by Leonard N. Zubkoff <lnz@dandelion.com>
8 This program is free software; you may redistribute and/or modify it under
9 the terms of the GNU General Public License Version 2 as published by the
10 Free Software Foundation.
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY, without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 The author respectfully requests that any modifications to this software be
18 sent directly to him for evaluation and testing.
20 Special thanks to Wayne Yen, Jin-Lon Hon, and Alex Win of BusLogic, whose
21 advice has been invaluable, to David Gentzel, for writing the original Linux
22 BusLogic driver, and to Paul Gortmaker, for being such a dedicated test site.
24 Finally, special thanks to Mylex/BusLogic for making the FlashPoint SCCB
25 Manager available as freely redistributable source code.
29 #define BusLogic_DriverVersion "2.1.16"
30 #define BusLogic_DriverDate "18 July 2002"
32 #include <linux/config.h>
33 #include <linux/module.h>
34 #include <linux/init.h>
35 #include <linux/interrupt.h>
36 #include <linux/types.h>
37 #include <linux/blkdev.h>
38 #include <linux/delay.h>
39 #include <linux/ioport.h>
41 #include <linux/stat.h>
42 #include <linux/pci.h>
43 #include <linux/spinlock.h>
44 #include <scsi/scsicam.h>
48 #include <asm/system.h>
53 #include "FlashPoint.c"
60 BusLogic_DriverOptionsCount is a count of the number of BusLogic Driver
61 Options specifications provided via the Linux Kernel Command Line or via
62 the Loadable Kernel Module Installation Facility.
65 static int BusLogic_DriverOptionsCount;
69 BusLogic_DriverOptions is an array of Driver Options structures representing
70 BusLogic Driver Options specifications provided via the Linux Kernel Command
71 Line or via the Loadable Kernel Module Installation Facility.
74 static struct BusLogic_DriverOptions BusLogic_DriverOptions[BusLogic_MaxHostAdapters];
78 BusLogic can be assigned a string by insmod.
81 MODULE_LICENSE("GPL");
83 static char *BusLogic;
84 MODULE_PARM(BusLogic, "s");
89 BusLogic_ProbeOptions is a set of Probe Options to be applied across
90 all BusLogic Host Adapters.
93 static struct BusLogic_ProbeOptions BusLogic_ProbeOptions;
97 BusLogic_GlobalOptions is a set of Global Options to be applied across
98 all BusLogic Host Adapters.
101 static struct BusLogic_GlobalOptions BusLogic_GlobalOptions;
105 BusLogic_FirstRegisteredHostAdapter and BusLogic_LastRegisteredHostAdapter
106 are pointers to the first and last registered BusLogic Host Adapters.
109 static struct BusLogic_HostAdapter *BusLogic_FirstRegisteredHostAdapter;
110 static struct BusLogic_HostAdapter *BusLogic_LastRegisteredHostAdapter;
114 BusLogic_ProbeInfoCount is the number of entries in BusLogic_ProbeInfoList.
117 static int BusLogic_ProbeInfoCount;
121 BusLogic_ProbeInfoList is the list of I/O Addresses and Bus Probe Information
122 to be checked for potential BusLogic Host Adapters. It is initialized by
123 interrogating the PCI Configuration Space on PCI machines as well as from the
124 list of standard BusLogic I/O Addresses.
127 static struct BusLogic_ProbeInfo *BusLogic_ProbeInfoList;
131 BusLogic_CommandFailureReason holds a string identifying the reason why a
132 call to BusLogic_Command failed. It is only non-NULL when BusLogic_Command
133 returns a failure code.
136 static char *BusLogic_CommandFailureReason;
139 BusLogic_AnnounceDriver announces the Driver Version and Date, Author's
140 Name, Copyright Notice, and Electronic Mail Address.
143 static void BusLogic_AnnounceDriver(struct BusLogic_HostAdapter *HostAdapter)
145 BusLogic_Announce("***** BusLogic SCSI Driver Version "
146 BusLogic_DriverVersion " of "
147 BusLogic_DriverDate " *****\n", HostAdapter);
148 BusLogic_Announce("Copyright 1995-1998 by Leonard N. Zubkoff "
149 "<lnz@dandelion.com>\n", HostAdapter);
154 BusLogic_DriverInfo returns the Host Adapter Name to identify this SCSI
155 Driver and Host Adapter.
158 static const char *BusLogic_DriverInfo(struct Scsi_Host *Host)
160 struct BusLogic_HostAdapter *HostAdapter =
161 (struct BusLogic_HostAdapter *) Host->hostdata;
162 return HostAdapter->FullModelName;
167 BusLogic_RegisterHostAdapter adds Host Adapter to the list of registered
168 BusLogic Host Adapters.
171 static void __init BusLogic_RegisterHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
173 HostAdapter->Next = NULL;
174 if (BusLogic_FirstRegisteredHostAdapter == NULL)
176 BusLogic_FirstRegisteredHostAdapter = HostAdapter;
177 BusLogic_LastRegisteredHostAdapter = HostAdapter;
181 BusLogic_LastRegisteredHostAdapter->Next = HostAdapter;
182 BusLogic_LastRegisteredHostAdapter = HostAdapter;
188 BusLogic_UnregisterHostAdapter removes Host Adapter from the list of
189 registered BusLogic Host Adapters.
192 static void BusLogic_UnregisterHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
194 if (HostAdapter == BusLogic_FirstRegisteredHostAdapter)
196 BusLogic_FirstRegisteredHostAdapter =
197 BusLogic_FirstRegisteredHostAdapter->Next;
198 if (HostAdapter == BusLogic_LastRegisteredHostAdapter)
199 BusLogic_LastRegisteredHostAdapter = NULL;
203 struct BusLogic_HostAdapter *PreviousHostAdapter =
204 BusLogic_FirstRegisteredHostAdapter;
205 while (PreviousHostAdapter != NULL &&
206 PreviousHostAdapter->Next != HostAdapter)
207 PreviousHostAdapter = PreviousHostAdapter->Next;
208 if (PreviousHostAdapter != NULL)
209 PreviousHostAdapter->Next = HostAdapter->Next;
211 HostAdapter->Next = NULL;
216 BusLogic_InitializeCCBs initializes a group of Command Control Blocks (CCBs)
217 for Host Adapter from the BlockSize bytes located at BlockPointer. The newly
218 created CCBs are added to Host Adapter's free list.
221 static void BusLogic_InitializeCCBs(struct BusLogic_HostAdapter *HostAdapter,
222 void *BlockPointer, int BlockSize,
223 dma_addr_t BlockPointerHandle)
225 struct BusLogic_CCB *CCB = (struct BusLogic_CCB *) BlockPointer;
226 unsigned int offset = 0;
227 memset(BlockPointer, 0, BlockSize);
228 CCB->AllocationGroupHead = BlockPointerHandle;
229 CCB->AllocationGroupSize = BlockSize;
230 while ((BlockSize -= sizeof(struct BusLogic_CCB)) >= 0)
232 CCB->Status = BusLogic_CCB_Free;
233 CCB->HostAdapter = HostAdapter;
234 CCB->DMA_Handle = (u32)BlockPointerHandle + offset;
235 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
237 CCB->CallbackFunction = BusLogic_QueueCompletedCCB;
238 CCB->BaseAddress = HostAdapter->FlashPointInfo.BaseAddress;
240 CCB->Next = HostAdapter->Free_CCBs;
241 CCB->NextAll = HostAdapter->All_CCBs;
242 HostAdapter->Free_CCBs = CCB;
243 HostAdapter->All_CCBs = CCB;
244 HostAdapter->AllocatedCCBs++;
246 offset += sizeof(struct BusLogic_CCB);
252 BusLogic_CreateInitialCCBs allocates the initial CCBs for Host Adapter.
255 static boolean __init BusLogic_CreateInitialCCBs(struct BusLogic_HostAdapter *HostAdapter)
257 int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB);
259 dma_addr_t BlockPointerHandle;
260 while (HostAdapter->AllocatedCCBs < HostAdapter->InitialCCBs)
262 BlockPointer = pci_alloc_consistent(HostAdapter->PCI_Device, BlockSize,
263 &BlockPointerHandle);
264 if (BlockPointer == NULL)
266 BusLogic_Error("UNABLE TO ALLOCATE CCB GROUP - DETACHING\n",
270 BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize,
278 BusLogic_DestroyCCBs deallocates the CCBs for Host Adapter.
281 static void BusLogic_DestroyCCBs(struct BusLogic_HostAdapter *HostAdapter)
283 struct BusLogic_CCB *NextCCB = HostAdapter->All_CCBs, *CCB, *Last_CCB = NULL;
284 HostAdapter->All_CCBs = NULL;
285 HostAdapter->Free_CCBs = NULL;
286 while ((CCB = NextCCB) != NULL)
288 NextCCB = CCB->NextAll;
289 if (CCB->AllocationGroupHead)
292 pci_free_consistent(HostAdapter->PCI_Device,
293 Last_CCB->AllocationGroupSize, Last_CCB,
294 Last_CCB->AllocationGroupHead);
299 pci_free_consistent(HostAdapter->PCI_Device,
300 Last_CCB->AllocationGroupSize, Last_CCB,
301 Last_CCB->AllocationGroupHead);
306 BusLogic_CreateAdditionalCCBs allocates Additional CCBs for Host Adapter. If
307 allocation fails and there are no remaining CCBs available, the Driver Queue
308 Depth is decreased to a known safe value to avoid potential deadlocks when
309 multiple host adapters share the same IRQ Channel.
312 static void BusLogic_CreateAdditionalCCBs(struct BusLogic_HostAdapter *HostAdapter,
314 boolean SuccessMessageP)
316 int BlockSize = BusLogic_CCB_AllocationGroupSize * sizeof(struct BusLogic_CCB);
317 int PreviouslyAllocated = HostAdapter->AllocatedCCBs;
319 dma_addr_t BlockPointerHandle;
320 if (AdditionalCCBs <= 0) return;
321 while (HostAdapter->AllocatedCCBs - PreviouslyAllocated < AdditionalCCBs)
323 BlockPointer = pci_alloc_consistent(HostAdapter->PCI_Device, BlockSize,
324 &BlockPointerHandle);
325 if (BlockPointer == NULL) break;
326 BusLogic_InitializeCCBs(HostAdapter, BlockPointer, BlockSize,
329 if (HostAdapter->AllocatedCCBs > PreviouslyAllocated)
332 BusLogic_Notice("Allocated %d additional CCBs (total now %d)\n",
334 HostAdapter->AllocatedCCBs - PreviouslyAllocated,
335 HostAdapter->AllocatedCCBs);
338 BusLogic_Notice("Failed to allocate additional CCBs\n", HostAdapter);
339 if (HostAdapter->DriverQueueDepth >
340 HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount)
342 HostAdapter->DriverQueueDepth =
343 HostAdapter->AllocatedCCBs - HostAdapter->TargetDeviceCount;
344 HostAdapter->SCSI_Host->can_queue = HostAdapter->DriverQueueDepth;
349 BusLogic_AllocateCCB allocates a CCB from Host Adapter's free list,
350 allocating more memory from the Kernel if necessary. The Host Adapter's
351 Lock should already have been acquired by the caller.
354 static struct BusLogic_CCB *BusLogic_AllocateCCB(struct BusLogic_HostAdapter
357 static unsigned long SerialNumber = 0;
358 struct BusLogic_CCB *CCB;
359 CCB = HostAdapter->Free_CCBs;
362 CCB->SerialNumber = ++SerialNumber;
363 HostAdapter->Free_CCBs = CCB->Next;
365 if (HostAdapter->Free_CCBs == NULL)
366 BusLogic_CreateAdditionalCCBs(HostAdapter,
367 HostAdapter->IncrementalCCBs,
371 BusLogic_CreateAdditionalCCBs(HostAdapter,
372 HostAdapter->IncrementalCCBs,
374 CCB = HostAdapter->Free_CCBs;
375 if (CCB == NULL) return NULL;
376 CCB->SerialNumber = ++SerialNumber;
377 HostAdapter->Free_CCBs = CCB->Next;
384 BusLogic_DeallocateCCB deallocates a CCB, returning it to the Host Adapter's
385 free list. The Host Adapter's Lock should already have been acquired by the
389 static void BusLogic_DeallocateCCB(struct BusLogic_CCB *CCB)
391 struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter;
392 if (CCB->Command->use_sg != 0)
394 pci_unmap_sg(HostAdapter->PCI_Device,
395 (struct scatterlist *)CCB->Command->request_buffer,
396 CCB->Command->use_sg,
397 scsi_to_pci_dma_dir(CCB->Command->sc_data_direction));
399 else if (CCB->Command->request_bufflen != 0)
401 pci_unmap_single(HostAdapter->PCI_Device, CCB->DataPointer,
403 scsi_to_pci_dma_dir(CCB->Command->sc_data_direction));
405 pci_unmap_single(HostAdapter->PCI_Device, CCB->SenseDataPointer,
406 CCB->SenseDataLength, PCI_DMA_FROMDEVICE);
408 CCB->Status = BusLogic_CCB_Free;
409 CCB->Next = HostAdapter->Free_CCBs;
410 HostAdapter->Free_CCBs = CCB;
415 BusLogic_Command sends the command OperationCode to HostAdapter, optionally
416 providing ParameterLength bytes of ParameterData and receiving at most
417 ReplyLength bytes of ReplyData; any excess reply data is received but
420 On success, this function returns the number of reply bytes read from
421 the Host Adapter (including any discarded data); on failure, it returns
422 -1 if the command was invalid, or -2 if a timeout occurred.
424 BusLogic_Command is called exclusively during host adapter detection and
425 initialization, so performance and latency are not critical, and exclusive
426 access to the Host Adapter hardware is assumed. Once the host adapter and
427 driver are initialized, the only Host Adapter command that is issued is the
428 single byte Execute Mailbox Command operation code, which does not require
429 waiting for the Host Adapter Ready bit to be set in the Status Register.
432 static int BusLogic_Command(struct BusLogic_HostAdapter *HostAdapter,
433 enum BusLogic_OperationCode OperationCode,
439 unsigned char *ParameterPointer = (unsigned char *) ParameterData;
440 unsigned char *ReplyPointer = (unsigned char *) ReplyData;
441 union BusLogic_StatusRegister StatusRegister;
442 union BusLogic_InterruptRegister InterruptRegister;
443 unsigned long ProcessorFlags = 0;
444 int ReplyBytes = 0, Result;
447 Clear out the Reply Data if provided.
450 memset(ReplyData, 0, ReplyLength);
452 If the IRQ Channel has not yet been acquired, then interrupts must be
453 disabled while issuing host adapter commands since a Command Complete
454 interrupt could occur if the IRQ Channel was previously enabled by another
455 BusLogic Host Adapter or another driver sharing the same IRQ Channel.
457 if (!HostAdapter->IRQ_ChannelAcquired)
459 local_irq_save(ProcessorFlags);
463 Wait for the Host Adapter Ready bit to be set and the Command/Parameter
464 Register Busy bit to be reset in the Status Register.
466 TimeoutCounter = 10000;
467 while (--TimeoutCounter >= 0)
469 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
470 if (StatusRegister.sr.HostAdapterReady &&
471 !StatusRegister.sr.CommandParameterRegisterBusy)
475 if (TimeoutCounter < 0)
477 BusLogic_CommandFailureReason = "Timeout waiting for Host Adapter Ready";
482 Write the OperationCode to the Command/Parameter Register.
484 HostAdapter->HostAdapterCommandCompleted = false;
485 BusLogic_WriteCommandParameterRegister(HostAdapter, OperationCode);
487 Write any additional Parameter Bytes.
489 TimeoutCounter = 10000;
490 while (ParameterLength > 0 && --TimeoutCounter >= 0)
493 Wait 100 microseconds to give the Host Adapter enough time to determine
494 whether the last value written to the Command/Parameter Register was
495 valid or not. If the Command Complete bit is set in the Interrupt
496 Register, then the Command Invalid bit in the Status Register will be
497 reset if the Operation Code or Parameter was valid and the command
498 has completed, or set if the Operation Code or Parameter was invalid.
499 If the Data In Register Ready bit is set in the Status Register, then
500 the Operation Code was valid, and data is waiting to be read back
501 from the Host Adapter. Otherwise, wait for the Command/Parameter
502 Register Busy bit in the Status Register to be reset.
505 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
506 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
507 if (InterruptRegister.ir.CommandComplete) break;
508 if (HostAdapter->HostAdapterCommandCompleted) break;
509 if (StatusRegister.sr.DataInRegisterReady) break;
510 if (StatusRegister.sr.CommandParameterRegisterBusy) continue;
511 BusLogic_WriteCommandParameterRegister(HostAdapter, *ParameterPointer++);
514 if (TimeoutCounter < 0)
516 BusLogic_CommandFailureReason =
517 "Timeout waiting for Parameter Acceptance";
522 The Modify I/O Address command does not cause a Command Complete Interrupt.
524 if (OperationCode == BusLogic_ModifyIOAddress)
526 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
527 if (StatusRegister.sr.CommandInvalid)
529 BusLogic_CommandFailureReason = "Modify I/O Address Invalid";
533 if (BusLogic_GlobalOptions.TraceConfiguration)
534 BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: "
535 "(Modify I/O Address)\n", HostAdapter,
536 OperationCode, StatusRegister.All);
541 Select an appropriate timeout value for awaiting command completion.
543 switch (OperationCode)
545 case BusLogic_InquireInstalledDevicesID0to7:
546 case BusLogic_InquireInstalledDevicesID8to15:
547 case BusLogic_InquireTargetDevices:
548 /* Approximately 60 seconds. */
549 TimeoutCounter = 60*10000;
552 /* Approximately 1 second. */
553 TimeoutCounter = 10000;
557 Receive any Reply Bytes, waiting for either the Command Complete bit to
558 be set in the Interrupt Register, or for the Interrupt Handler to set the
559 Host Adapter Command Completed bit in the Host Adapter structure.
561 while (--TimeoutCounter >= 0)
563 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
564 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
565 if (InterruptRegister.ir.CommandComplete) break;
566 if (HostAdapter->HostAdapterCommandCompleted) break;
567 if (StatusRegister.sr.DataInRegisterReady)
569 if (++ReplyBytes <= ReplyLength)
570 *ReplyPointer++ = BusLogic_ReadDataInRegister(HostAdapter);
571 else BusLogic_ReadDataInRegister(HostAdapter);
573 if (OperationCode == BusLogic_FetchHostAdapterLocalRAM &&
574 StatusRegister.sr.HostAdapterReady) break;
577 if (TimeoutCounter < 0)
579 BusLogic_CommandFailureReason = "Timeout waiting for Command Complete";
584 Clear any pending Command Complete Interrupt.
586 BusLogic_InterruptReset(HostAdapter);
588 Provide tracing information if requested.
590 if (BusLogic_GlobalOptions.TraceConfiguration)
593 BusLogic_Notice("BusLogic_Command(%02X) Status = %02X: %2d ==> %2d:",
594 HostAdapter, OperationCode,
595 StatusRegister.All, ReplyLength, ReplyBytes);
596 if (ReplyLength > ReplyBytes) ReplyLength = ReplyBytes;
597 for (i = 0; i < ReplyLength; i++)
598 BusLogic_Notice(" %02X", HostAdapter,
599 ((unsigned char *) ReplyData)[i]);
600 BusLogic_Notice("\n", HostAdapter);
603 Process Command Invalid conditions.
605 if (StatusRegister.sr.CommandInvalid)
608 Some early BusLogic Host Adapters may not recover properly from
609 a Command Invalid condition, so if this appears to be the case,
610 a Soft Reset is issued to the Host Adapter. Potentially invalid
611 commands are never attempted after Mailbox Initialization is
612 performed, so there should be no Host Adapter state lost by a
613 Soft Reset in response to a Command Invalid condition.
616 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
617 if (StatusRegister.sr.CommandInvalid ||
618 StatusRegister.sr.Reserved ||
619 StatusRegister.sr.DataInRegisterReady ||
620 StatusRegister.sr.CommandParameterRegisterBusy ||
621 !StatusRegister.sr.HostAdapterReady ||
622 !StatusRegister.sr.InitializationRequired ||
623 StatusRegister.sr.DiagnosticActive ||
624 StatusRegister.sr.DiagnosticFailure)
626 BusLogic_SoftReset(HostAdapter);
629 BusLogic_CommandFailureReason = "Command Invalid";
634 Handle Excess Parameters Supplied conditions.
636 if (ParameterLength > 0)
638 BusLogic_CommandFailureReason = "Excess Parameters Supplied";
643 Indicate the command completed successfully.
645 BusLogic_CommandFailureReason = NULL;
648 Restore the interrupt status if necessary and return.
651 if (!HostAdapter->IRQ_ChannelAcquired)
652 local_irq_restore(ProcessorFlags);
658 BusLogic_AppendProbeAddressISA appends a single ISA I/O Address to the list
659 of I/O Address and Bus Probe Information to be checked for potential BusLogic
663 static void __init BusLogic_AppendProbeAddressISA(unsigned long IO_Address)
665 struct BusLogic_ProbeInfo *ProbeInfo;
666 if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return;
667 ProbeInfo = &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
668 ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
669 ProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
670 ProbeInfo->IO_Address = IO_Address;
671 ProbeInfo->PCI_Device = NULL;
676 BusLogic_InitializeProbeInfoListISA initializes the list of I/O Address and
677 Bus Probe Information to be checked for potential BusLogic SCSI Host Adapters
678 only from the list of standard BusLogic MultiMaster ISA I/O Addresses.
681 static void __init BusLogic_InitializeProbeInfoListISA(struct BusLogic_HostAdapter
682 *PrototypeHostAdapter)
685 If BusLogic Driver Options specifications requested that ISA Bus Probes
686 be inhibited, do not proceed further.
688 if (BusLogic_ProbeOptions.NoProbeISA) return;
690 Append the list of standard BusLogic MultiMaster ISA I/O Addresses.
692 if (BusLogic_ProbeOptions.LimitedProbeISA
693 ? BusLogic_ProbeOptions.Probe330
694 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0)
695 BusLogic_AppendProbeAddressISA(0x330);
696 if (BusLogic_ProbeOptions.LimitedProbeISA
697 ? BusLogic_ProbeOptions.Probe334
698 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0)
699 BusLogic_AppendProbeAddressISA(0x334);
700 if (BusLogic_ProbeOptions.LimitedProbeISA
701 ? BusLogic_ProbeOptions.Probe230
702 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0)
703 BusLogic_AppendProbeAddressISA(0x230);
704 if (BusLogic_ProbeOptions.LimitedProbeISA
705 ? BusLogic_ProbeOptions.Probe234
706 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0)
707 BusLogic_AppendProbeAddressISA(0x234);
708 if (BusLogic_ProbeOptions.LimitedProbeISA
709 ? BusLogic_ProbeOptions.Probe130
710 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0)
711 BusLogic_AppendProbeAddressISA(0x130);
712 if (BusLogic_ProbeOptions.LimitedProbeISA
713 ? BusLogic_ProbeOptions.Probe134
714 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0)
715 BusLogic_AppendProbeAddressISA(0x134);
723 BusLogic_SortProbeInfo sorts a section of BusLogic_ProbeInfoList in order
724 of increasing PCI Bus and Device Number.
727 static void __init BusLogic_SortProbeInfo(struct BusLogic_ProbeInfo *ProbeInfoList,
730 int LastInterchange = ProbeInfoCount-1, Bound, j;
731 while (LastInterchange > 0)
733 Bound = LastInterchange;
735 for (j = 0; j < Bound; j++)
737 struct BusLogic_ProbeInfo *ProbeInfo1 = &ProbeInfoList[j];
738 struct BusLogic_ProbeInfo *ProbeInfo2 = &ProbeInfoList[j+1];
739 if (ProbeInfo1->Bus > ProbeInfo2->Bus ||
740 (ProbeInfo1->Bus == ProbeInfo2->Bus &&
741 (ProbeInfo1->Device > ProbeInfo2->Device)))
743 struct BusLogic_ProbeInfo TempProbeInfo;
744 memcpy(&TempProbeInfo, ProbeInfo1, sizeof(struct BusLogic_ProbeInfo));
745 memcpy(ProbeInfo1, ProbeInfo2, sizeof(struct BusLogic_ProbeInfo));
746 memcpy(ProbeInfo2, &TempProbeInfo, sizeof(struct BusLogic_ProbeInfo));
755 BusLogic_InitializeMultiMasterProbeInfo initializes the list of I/O Address
756 and Bus Probe Information to be checked for potential BusLogic MultiMaster
757 SCSI Host Adapters by interrogating the PCI Configuration Space on PCI
758 machines as well as from the list of standard BusLogic MultiMaster ISA
759 I/O Addresses. It returns the number of PCI MultiMaster Host Adapters found.
762 static int __init BusLogic_InitializeMultiMasterProbeInfo(struct BusLogic_HostAdapter
763 *PrototypeHostAdapter)
765 struct BusLogic_ProbeInfo *PrimaryProbeInfo =
766 &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount];
767 int NonPrimaryPCIMultiMasterIndex = BusLogic_ProbeInfoCount + 1;
768 int NonPrimaryPCIMultiMasterCount = 0, PCIMultiMasterCount = 0;
769 boolean ForceBusDeviceScanningOrder = false;
770 boolean ForceBusDeviceScanningOrderChecked = false;
771 boolean StandardAddressSeen[6];
772 struct pci_dev *PCI_Device = NULL;
774 if (BusLogic_ProbeInfoCount >= BusLogic_MaxHostAdapters) return 0;
775 BusLogic_ProbeInfoCount++;
776 for (i = 0; i < 6; i++)
777 StandardAddressSeen[i] = false;
779 Iterate over the MultiMaster PCI Host Adapters. For each enumerated host
780 adapter, determine whether its ISA Compatible I/O Port is enabled and if
781 so, whether it is assigned the Primary I/O Address. A host adapter that is
782 assigned the Primary I/O Address will always be the preferred boot device.
783 The MultiMaster BIOS will first recognize a host adapter at the Primary I/O
784 Address, then any other PCI host adapters, and finally any host adapters
785 located at the remaining standard ISA I/O Addresses. When a PCI host
786 adapter is found with its ISA Compatible I/O Port enabled, a command is
787 issued to disable the ISA Compatible I/O Port, and it is noted that the
788 particular standard ISA I/O Address need not be probed.
790 PrimaryProbeInfo->IO_Address = 0;
791 while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
792 PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER,
793 PCI_Device)) != NULL)
795 struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
796 struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation;
797 enum BusLogic_ISACompatibleIOPort ModifyIOAddressRequest;
799 unsigned char Device;
800 unsigned int IRQ_Channel;
801 unsigned long BaseAddress0;
802 unsigned long BaseAddress1;
803 unsigned long IO_Address;
804 unsigned long PCI_Address;
806 if (pci_enable_device(PCI_Device))
809 if (pci_set_dma_mask(PCI_Device, (u64)0xffffffff))
812 Bus = PCI_Device->bus->number;
813 Device = PCI_Device->devfn >> 3;
814 IRQ_Channel = PCI_Device->irq;
815 IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
816 PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
818 if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM)
820 BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
821 "MultiMaster Host Adapter\n", NULL, BaseAddress0);
822 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
823 NULL, Bus, Device, IO_Address);
826 if (pci_resource_flags(PCI_Device,1) & IORESOURCE_IO)
828 BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
829 "MultiMaster Host Adapter\n", NULL, BaseAddress1);
830 BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n",
831 NULL, Bus, Device, PCI_Address);
834 if (IRQ_Channel == 0)
836 BusLogic_Error("BusLogic: IRQ Channel %d invalid for "
837 "MultiMaster Host Adapter\n", NULL, IRQ_Channel);
838 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
839 NULL, Bus, Device, IO_Address);
842 if (BusLogic_GlobalOptions.TraceProbe)
844 BusLogic_Notice("BusLogic: PCI MultiMaster Host Adapter "
845 "detected at\n", NULL);
846 BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address "
847 "0x%X PCI Address 0x%X\n", NULL,
848 Bus, Device, IO_Address, PCI_Address);
851 Issue the Inquire PCI Host Adapter Information command to determine
852 the ISA Compatible I/O Port. If the ISA Compatible I/O Port is
853 known and enabled, note that the particular Standard ISA I/O
854 Address should not be probed.
856 HostAdapter->IO_Address = IO_Address;
857 BusLogic_InterruptReset(HostAdapter);
858 if (BusLogic_Command(HostAdapter,
859 BusLogic_InquirePCIHostAdapterInformation,
860 NULL, 0, &PCIHostAdapterInformation,
861 sizeof(PCIHostAdapterInformation))
862 == sizeof(PCIHostAdapterInformation))
864 if (PCIHostAdapterInformation.ISACompatibleIOPort < 6)
865 StandardAddressSeen[PCIHostAdapterInformation
866 .ISACompatibleIOPort] = true;
868 else PCIHostAdapterInformation.ISACompatibleIOPort =
871 * Issue the Modify I/O Address command to disable the ISA Compatible
872 * I/O Port. On PCI Host Adapters, the Modify I/O Address command
873 * allows modification of the ISA compatible I/O Address that the Host
874 * Adapter responds to; it does not affect the PCI compliant I/O Address
875 * assigned at system initialization.
877 ModifyIOAddressRequest = BusLogic_IO_Disable;
878 BusLogic_Command(HostAdapter, BusLogic_ModifyIOAddress,
879 &ModifyIOAddressRequest,
880 sizeof(ModifyIOAddressRequest), NULL, 0);
882 For the first MultiMaster Host Adapter enumerated, issue the Fetch
883 Host Adapter Local RAM command to read byte 45 of the AutoSCSI area,
884 for the setting of the "Use Bus And Device # For PCI Scanning Seq."
885 option. Issue the Inquire Board ID command since this option is
886 only valid for the BT-948/958/958D.
888 if (!ForceBusDeviceScanningOrderChecked)
890 struct BusLogic_FetchHostAdapterLocalRAMRequest
891 FetchHostAdapterLocalRAMRequest;
892 struct BusLogic_AutoSCSIByte45 AutoSCSIByte45;
893 struct BusLogic_BoardID BoardID;
894 FetchHostAdapterLocalRAMRequest.ByteOffset =
895 BusLogic_AutoSCSI_BaseOffset + 45;
896 FetchHostAdapterLocalRAMRequest.ByteCount =
897 sizeof(AutoSCSIByte45);
898 BusLogic_Command(HostAdapter,
899 BusLogic_FetchHostAdapterLocalRAM,
900 &FetchHostAdapterLocalRAMRequest,
901 sizeof(FetchHostAdapterLocalRAMRequest),
902 &AutoSCSIByte45, sizeof(AutoSCSIByte45));
903 BusLogic_Command(HostAdapter, BusLogic_InquireBoardID,
904 NULL, 0, &BoardID, sizeof(BoardID));
905 if (BoardID.FirmwareVersion1stDigit == '5')
906 ForceBusDeviceScanningOrder =
907 AutoSCSIByte45.ForceBusDeviceScanningOrder;
908 ForceBusDeviceScanningOrderChecked = true;
911 Determine whether this MultiMaster Host Adapter has its ISA
912 Compatible I/O Port enabled and is assigned the Primary I/O Address.
913 If it does, then it is the Primary MultiMaster Host Adapter and must
914 be recognized first. If it does not, then it is added to the list
915 for probing after any Primary MultiMaster Host Adapter is probed.
917 if (PCIHostAdapterInformation.ISACompatibleIOPort == BusLogic_IO_330)
919 PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
920 PrimaryProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
921 PrimaryProbeInfo->IO_Address = IO_Address;
922 PrimaryProbeInfo->PCI_Address = PCI_Address;
923 PrimaryProbeInfo->Bus = Bus;
924 PrimaryProbeInfo->Device = Device;
925 PrimaryProbeInfo->IRQ_Channel = IRQ_Channel;
926 PrimaryProbeInfo->PCI_Device = PCI_Device;
927 PCIMultiMasterCount++;
929 else if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
931 struct BusLogic_ProbeInfo *ProbeInfo =
932 &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
933 ProbeInfo->HostAdapterType = BusLogic_MultiMaster;
934 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
935 ProbeInfo->IO_Address = IO_Address;
936 ProbeInfo->PCI_Address = PCI_Address;
937 ProbeInfo->Bus = Bus;
938 ProbeInfo->Device = Device;
939 ProbeInfo->IRQ_Channel = IRQ_Channel;
940 ProbeInfo->PCI_Device = PCI_Device;
941 NonPrimaryPCIMultiMasterCount++;
942 PCIMultiMasterCount++;
944 else BusLogic_Warning("BusLogic: Too many Host Adapters "
948 If the AutoSCSI "Use Bus And Device # For PCI Scanning Seq." option is ON
949 for the first enumerated MultiMaster Host Adapter, and if that host adapter
950 is a BT-948/958/958D, then the MultiMaster BIOS will recognize MultiMaster
951 Host Adapters in the order of increasing PCI Bus and Device Number. In
952 that case, sort the probe information into the same order the BIOS uses.
953 If this option is OFF, then the MultiMaster BIOS will recognize MultiMaster
954 Host Adapters in the order they are enumerated by the PCI BIOS, and hence
955 no sorting is necessary.
957 if (ForceBusDeviceScanningOrder)
958 BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[
959 NonPrimaryPCIMultiMasterIndex],
960 NonPrimaryPCIMultiMasterCount);
962 If no PCI MultiMaster Host Adapter is assigned the Primary I/O Address,
963 then the Primary I/O Address must be probed explicitly before any PCI
964 host adapters are probed.
966 if (!BusLogic_ProbeOptions.NoProbeISA)
967 if (PrimaryProbeInfo->IO_Address == 0 &&
968 (BusLogic_ProbeOptions.LimitedProbeISA
969 ? BusLogic_ProbeOptions.Probe330
970 : check_region(0x330, BusLogic_MultiMasterAddressCount) == 0))
972 PrimaryProbeInfo->HostAdapterType = BusLogic_MultiMaster;
973 PrimaryProbeInfo->HostAdapterBusType = BusLogic_ISA_Bus;
974 PrimaryProbeInfo->IO_Address = 0x330;
977 Append the list of standard BusLogic MultiMaster ISA I/O Addresses,
978 omitting the Primary I/O Address which has already been handled.
980 if (!BusLogic_ProbeOptions.NoProbeISA)
982 if (!StandardAddressSeen[1] &&
983 (BusLogic_ProbeOptions.LimitedProbeISA
984 ? BusLogic_ProbeOptions.Probe334
985 : check_region(0x334, BusLogic_MultiMasterAddressCount) == 0))
986 BusLogic_AppendProbeAddressISA(0x334);
987 if (!StandardAddressSeen[2] &&
988 (BusLogic_ProbeOptions.LimitedProbeISA
989 ? BusLogic_ProbeOptions.Probe230
990 : check_region(0x230, BusLogic_MultiMasterAddressCount) == 0))
991 BusLogic_AppendProbeAddressISA(0x230);
992 if (!StandardAddressSeen[3] &&
993 (BusLogic_ProbeOptions.LimitedProbeISA
994 ? BusLogic_ProbeOptions.Probe234
995 : check_region(0x234, BusLogic_MultiMasterAddressCount) == 0))
996 BusLogic_AppendProbeAddressISA(0x234);
997 if (!StandardAddressSeen[4] &&
998 (BusLogic_ProbeOptions.LimitedProbeISA
999 ? BusLogic_ProbeOptions.Probe130
1000 : check_region(0x130, BusLogic_MultiMasterAddressCount) == 0))
1001 BusLogic_AppendProbeAddressISA(0x130);
1002 if (!StandardAddressSeen[5] &&
1003 (BusLogic_ProbeOptions.LimitedProbeISA
1004 ? BusLogic_ProbeOptions.Probe134
1005 : check_region(0x134, BusLogic_MultiMasterAddressCount) == 0))
1006 BusLogic_AppendProbeAddressISA(0x134);
1009 Iterate over the older non-compliant MultiMaster PCI Host Adapters,
1010 noting the PCI bus location and assigned IRQ Channel.
1013 while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
1014 PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC,
1015 PCI_Device)) != NULL)
1018 unsigned char Device;
1019 unsigned int IRQ_Channel;
1020 unsigned long IO_Address;
1022 if (pci_enable_device(PCI_Device))
1025 if (pci_set_dma_mask(PCI_Device, (u64)0xffffffff))
1028 Bus = PCI_Device->bus->number;
1029 Device = PCI_Device->devfn >> 3;
1030 IRQ_Channel = PCI_Device->irq;
1031 IO_Address = pci_resource_start(PCI_Device, 0);
1033 if (IO_Address == 0 || IRQ_Channel == 0) continue;
1034 for (i = 0; i < BusLogic_ProbeInfoCount; i++)
1036 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[i];
1037 if (ProbeInfo->IO_Address == IO_Address &&
1038 ProbeInfo->HostAdapterType == BusLogic_MultiMaster)
1040 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
1041 ProbeInfo->PCI_Address = 0;
1042 ProbeInfo->Bus = Bus;
1043 ProbeInfo->Device = Device;
1044 ProbeInfo->IRQ_Channel = IRQ_Channel;
1045 ProbeInfo->PCI_Device = PCI_Device;
1050 return PCIMultiMasterCount;
1055 BusLogic_InitializeFlashPointProbeInfo initializes the list of I/O Address
1056 and Bus Probe Information to be checked for potential BusLogic FlashPoint
1057 Host Adapters by interrogating the PCI Configuration Space. It returns the
1058 number of FlashPoint Host Adapters found.
1061 static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAdapter
1062 *PrototypeHostAdapter)
1064 int FlashPointIndex = BusLogic_ProbeInfoCount, FlashPointCount = 0;
1065 struct pci_dev *PCI_Device = NULL;
1067 Interrogate PCI Configuration Space for any FlashPoint Host Adapters.
1069 while ((PCI_Device = pci_find_device(PCI_VENDOR_ID_BUSLOGIC,
1070 PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT,
1071 PCI_Device)) != NULL)
1074 unsigned char Device;
1075 unsigned int IRQ_Channel;
1076 unsigned long BaseAddress0;
1077 unsigned long BaseAddress1;
1078 unsigned long IO_Address;
1079 unsigned long PCI_Address;
1081 if (pci_enable_device(PCI_Device))
1084 if (pci_set_dma_mask(PCI_Device, (u64)0xffffffff))
1087 Bus = PCI_Device->bus->number;
1088 Device = PCI_Device->devfn >> 3;
1089 IRQ_Channel = PCI_Device->irq;
1090 IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
1091 PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
1092 #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
1093 if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM)
1095 BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for "
1096 "FlashPoint Host Adapter\n", NULL, BaseAddress0);
1097 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
1098 NULL, Bus, Device, IO_Address);
1101 if (pci_resource_flags(PCI_Device, 1) & IORESOURCE_IO)
1103 BusLogic_Error("BusLogic: Base Address1 0x%X not Memory for "
1104 "FlashPoint Host Adapter\n", NULL, BaseAddress1);
1105 BusLogic_Error("at PCI Bus %d Device %d PCI Address 0x%X\n",
1106 NULL, Bus, Device, PCI_Address);
1109 if (IRQ_Channel == 0)
1111 BusLogic_Error("BusLogic: IRQ Channel %d invalid for "
1112 "FlashPoint Host Adapter\n", NULL, IRQ_Channel);
1113 BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n",
1114 NULL, Bus, Device, IO_Address);
1117 if (BusLogic_GlobalOptions.TraceProbe)
1119 BusLogic_Notice("BusLogic: FlashPoint Host Adapter "
1120 "detected at\n", NULL);
1121 BusLogic_Notice("BusLogic: PCI Bus %d Device %d I/O Address "
1122 "0x%X PCI Address 0x%X\n", NULL,
1123 Bus, Device, IO_Address, PCI_Address);
1125 if (BusLogic_ProbeInfoCount < BusLogic_MaxHostAdapters)
1127 struct BusLogic_ProbeInfo *ProbeInfo =
1128 &BusLogic_ProbeInfoList[BusLogic_ProbeInfoCount++];
1129 ProbeInfo->HostAdapterType = BusLogic_FlashPoint;
1130 ProbeInfo->HostAdapterBusType = BusLogic_PCI_Bus;
1131 ProbeInfo->IO_Address = IO_Address;
1132 ProbeInfo->PCI_Address = PCI_Address;
1133 ProbeInfo->Bus = Bus;
1134 ProbeInfo->Device = Device;
1135 ProbeInfo->IRQ_Channel = IRQ_Channel;
1136 ProbeInfo->PCI_Device = PCI_Device;
1139 else BusLogic_Warning("BusLogic: Too many Host Adapters "
1140 "detected\n", NULL);
1142 BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
1143 "PCI Bus %d Device %d\n", NULL, Bus, Device);
1144 BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, irq %d, "
1145 "but FlashPoint\n", NULL, IO_Address, PCI_Address, IRQ_Channel);
1146 BusLogic_Error("BusLogic: support was omitted in this kernel "
1147 "configuration.\n", NULL);
1151 The FlashPoint BIOS will scan for FlashPoint Host Adapters in the order of
1152 increasing PCI Bus and Device Number, so sort the probe information into
1153 the same order the BIOS uses.
1155 BusLogic_SortProbeInfo(&BusLogic_ProbeInfoList[FlashPointIndex],
1157 return FlashPointCount;
1162 BusLogic_InitializeProbeInfoList initializes the list of I/O Address and Bus
1163 Probe Information to be checked for potential BusLogic SCSI Host Adapters by
1164 interrogating the PCI Configuration Space on PCI machines as well as from the
1165 list of standard BusLogic MultiMaster ISA I/O Addresses. By default, if both
1166 FlashPoint and PCI MultiMaster Host Adapters are present, this driver will
1167 probe for FlashPoint Host Adapters first unless the BIOS primary disk is
1168 controlled by the first PCI MultiMaster Host Adapter, in which case
1169 MultiMaster Host Adapters will be probed first. The BusLogic Driver Options
1170 specifications "MultiMasterFirst" and "FlashPointFirst" can be used to force
1171 a particular probe order.
1174 static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter
1175 *PrototypeHostAdapter)
1178 If a PCI BIOS is present, interrogate it for MultiMaster and FlashPoint
1179 Host Adapters; otherwise, default to the standard ISA MultiMaster probe.
1181 if (!BusLogic_ProbeOptions.NoProbePCI)
1183 if (BusLogic_ProbeOptions.MultiMasterFirst)
1185 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1186 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1188 else if (BusLogic_ProbeOptions.FlashPointFirst)
1190 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1191 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1195 int FlashPointCount =
1196 BusLogic_InitializeFlashPointProbeInfo(PrototypeHostAdapter);
1197 int PCIMultiMasterCount =
1198 BusLogic_InitializeMultiMasterProbeInfo(PrototypeHostAdapter);
1199 if (FlashPointCount > 0 && PCIMultiMasterCount > 0)
1201 struct BusLogic_ProbeInfo *ProbeInfo =
1202 &BusLogic_ProbeInfoList[FlashPointCount];
1203 struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
1204 struct BusLogic_FetchHostAdapterLocalRAMRequest
1205 FetchHostAdapterLocalRAMRequest;
1206 struct BusLogic_BIOSDriveMapByte Drive0MapByte;
1207 while (ProbeInfo->HostAdapterBusType != BusLogic_PCI_Bus)
1209 HostAdapter->IO_Address = ProbeInfo->IO_Address;
1210 FetchHostAdapterLocalRAMRequest.ByteOffset =
1211 BusLogic_BIOS_BaseOffset + BusLogic_BIOS_DriveMapOffset + 0;
1212 FetchHostAdapterLocalRAMRequest.ByteCount =
1213 sizeof(Drive0MapByte);
1214 BusLogic_Command(HostAdapter,
1215 BusLogic_FetchHostAdapterLocalRAM,
1216 &FetchHostAdapterLocalRAMRequest,
1217 sizeof(FetchHostAdapterLocalRAMRequest),
1218 &Drive0MapByte, sizeof(Drive0MapByte));
1220 If the Map Byte for BIOS Drive 0 indicates that BIOS Drive 0
1221 is controlled by this PCI MultiMaster Host Adapter, then
1222 reverse the probe order so that MultiMaster Host Adapters are
1223 probed before FlashPoint Host Adapters.
1225 if (Drive0MapByte.DiskGeometry !=
1226 BusLogic_BIOS_Disk_Not_Installed)
1228 struct BusLogic_ProbeInfo
1229 SavedProbeInfo[BusLogic_MaxHostAdapters];
1230 int MultiMasterCount =
1231 BusLogic_ProbeInfoCount - FlashPointCount;
1232 memcpy(SavedProbeInfo,
1233 BusLogic_ProbeInfoList,
1234 BusLogic_ProbeInfoCount
1235 * sizeof(struct BusLogic_ProbeInfo));
1236 memcpy(&BusLogic_ProbeInfoList[0],
1237 &SavedProbeInfo[FlashPointCount],
1238 MultiMasterCount * sizeof(struct BusLogic_ProbeInfo));
1239 memcpy(&BusLogic_ProbeInfoList[MultiMasterCount],
1241 FlashPointCount * sizeof(struct BusLogic_ProbeInfo));
1246 else BusLogic_InitializeProbeInfoListISA(PrototypeHostAdapter);
1250 #endif /* CONFIG_PCI */
1254 BusLogic_Failure prints a standardized error message, and then returns false.
1257 static boolean BusLogic_Failure(struct BusLogic_HostAdapter *HostAdapter,
1260 BusLogic_AnnounceDriver(HostAdapter);
1261 if (HostAdapter->HostAdapterBusType == BusLogic_PCI_Bus)
1263 BusLogic_Error("While configuring BusLogic PCI Host Adapter at\n",
1265 BusLogic_Error("Bus %d Device %d I/O Address 0x%X PCI Address 0x%X:\n",
1266 HostAdapter, HostAdapter->Bus, HostAdapter->Device,
1267 HostAdapter->IO_Address, HostAdapter->PCI_Address);
1269 else BusLogic_Error("While configuring BusLogic Host Adapter at "
1270 "I/O Address 0x%X:\n", HostAdapter,
1271 HostAdapter->IO_Address);
1272 BusLogic_Error("%s FAILED - DETACHING\n", HostAdapter, ErrorMessage);
1273 if (BusLogic_CommandFailureReason != NULL)
1274 BusLogic_Error("ADDITIONAL FAILURE INFO - %s\n", HostAdapter,
1275 BusLogic_CommandFailureReason);
1281 BusLogic_ProbeHostAdapter probes for a BusLogic Host Adapter.
1284 static boolean __init BusLogic_ProbeHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
1286 union BusLogic_StatusRegister StatusRegister;
1287 union BusLogic_InterruptRegister InterruptRegister;
1288 union BusLogic_GeometryRegister GeometryRegister;
1290 FlashPoint Host Adapters are Probed by the FlashPoint SCCB Manager.
1292 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1294 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1295 FlashPointInfo->BaseAddress =
1296 (u32) HostAdapter->IO_Address;
1297 FlashPointInfo->IRQ_Channel = HostAdapter->IRQ_Channel;
1298 FlashPointInfo->Present = false;
1299 if (!(FlashPoint_ProbeHostAdapter(FlashPointInfo) == 0 &&
1300 FlashPointInfo->Present))
1302 BusLogic_Error("BusLogic: FlashPoint Host Adapter detected at "
1303 "PCI Bus %d Device %d\n", HostAdapter,
1304 HostAdapter->Bus, HostAdapter->Device);
1305 BusLogic_Error("BusLogic: I/O Address 0x%X PCI Address 0x%X, "
1306 "but FlashPoint\n", HostAdapter,
1307 HostAdapter->IO_Address, HostAdapter->PCI_Address);
1308 BusLogic_Error("BusLogic: Probe Function failed to validate it.\n",
1312 if (BusLogic_GlobalOptions.TraceProbe)
1313 BusLogic_Notice("BusLogic_Probe(0x%X): FlashPoint Found\n",
1314 HostAdapter, HostAdapter->IO_Address);
1316 Indicate the Host Adapter Probe completed successfully.
1321 Read the Status, Interrupt, and Geometry Registers to test if there are I/O
1322 ports that respond, and to check the values to determine if they are from a
1323 BusLogic Host Adapter. A nonexistent I/O port will return 0xFF, in which
1324 case there is definitely no BusLogic Host Adapter at this base I/O Address.
1325 The test here is a subset of that used by the BusLogic Host Adapter BIOS.
1327 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1328 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
1329 GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1330 if (BusLogic_GlobalOptions.TraceProbe)
1331 BusLogic_Notice("BusLogic_Probe(0x%X): Status 0x%02X, Interrupt 0x%02X, "
1332 "Geometry 0x%02X\n", HostAdapter,
1333 HostAdapter->IO_Address, StatusRegister.All,
1334 InterruptRegister.All, GeometryRegister.All);
1335 if (StatusRegister.All == 0 ||
1336 StatusRegister.sr.DiagnosticActive ||
1337 StatusRegister.sr.CommandParameterRegisterBusy ||
1338 StatusRegister.sr.Reserved ||
1339 StatusRegister.sr.CommandInvalid ||
1340 InterruptRegister.ir.Reserved != 0)
1343 Check the undocumented Geometry Register to test if there is an I/O port
1344 that responded. Adaptec Host Adapters do not implement the Geometry
1345 Register, so this test helps serve to avoid incorrectly recognizing an
1346 Adaptec 1542A or 1542B as a BusLogic. Unfortunately, the Adaptec 1542C
1347 series does respond to the Geometry Register I/O port, but it will be
1348 rejected later when the Inquire Extended Setup Information command is
1349 issued in BusLogic_CheckHostAdapter. The AMI FastDisk Host Adapter is a
1350 BusLogic clone that implements the same interface as earlier BusLogic
1351 Host Adapters, including the undocumented commands, and is therefore
1352 supported by this driver. However, the AMI FastDisk always returns 0x00
1353 upon reading the Geometry Register, so the extended translation option
1354 should always be left disabled on the AMI FastDisk.
1356 if (GeometryRegister.All == 0xFF) return false;
1358 Indicate the Host Adapter Probe completed successfully.
1365 BusLogic_HardwareResetHostAdapter issues a Hardware Reset to the Host Adapter
1366 and waits for Host Adapter Diagnostics to complete. If HardReset is true, a
1367 Hard Reset is performed which also initiates a SCSI Bus Reset. Otherwise, a
1368 Soft Reset is performed which only resets the Host Adapter without forcing a
1372 static boolean BusLogic_HardwareResetHostAdapter(struct BusLogic_HostAdapter
1376 union BusLogic_StatusRegister StatusRegister;
1379 FlashPoint Host Adapters are Hard Reset by the FlashPoint SCCB Manager.
1381 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1383 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1384 FlashPointInfo->HostSoftReset = !HardReset;
1385 FlashPointInfo->ReportDataUnderrun = true;
1386 HostAdapter->CardHandle =
1387 FlashPoint_HardwareResetHostAdapter(FlashPointInfo);
1388 if (HostAdapter->CardHandle == FlashPoint_BadCardHandle) return false;
1390 Indicate the Host Adapter Hard Reset completed successfully.
1395 Issue a Hard Reset or Soft Reset Command to the Host Adapter. The Host
1396 Adapter should respond by setting Diagnostic Active in the Status Register.
1399 BusLogic_HardReset(HostAdapter);
1400 else BusLogic_SoftReset(HostAdapter);
1402 Wait until Diagnostic Active is set in the Status Register.
1404 TimeoutCounter = 5*10000;
1405 while (--TimeoutCounter >= 0)
1407 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1408 if (StatusRegister.sr.DiagnosticActive) break;
1411 if (BusLogic_GlobalOptions.TraceHardwareReset)
1412 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Active, "
1413 "Status 0x%02X\n", HostAdapter,
1414 HostAdapter->IO_Address, StatusRegister.All);
1415 if (TimeoutCounter < 0) return false;
1417 Wait 100 microseconds to allow completion of any initial diagnostic
1418 activity which might leave the contents of the Status Register
1423 Wait until Diagnostic Active is reset in the Status Register.
1425 TimeoutCounter = 10*10000;
1426 while (--TimeoutCounter >= 0)
1428 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1429 if (!StatusRegister.sr.DiagnosticActive) break;
1432 if (BusLogic_GlobalOptions.TraceHardwareReset)
1433 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Diagnostic Completed, "
1434 "Status 0x%02X\n", HostAdapter,
1435 HostAdapter->IO_Address, StatusRegister.All);
1436 if (TimeoutCounter < 0) return false;
1438 Wait until at least one of the Diagnostic Failure, Host Adapter Ready,
1439 or Data In Register Ready bits is set in the Status Register.
1441 TimeoutCounter = 10000;
1442 while (--TimeoutCounter >= 0)
1444 StatusRegister.All = BusLogic_ReadStatusRegister(HostAdapter);
1445 if (StatusRegister.sr.DiagnosticFailure ||
1446 StatusRegister.sr.HostAdapterReady ||
1447 StatusRegister.sr.DataInRegisterReady)
1451 if (BusLogic_GlobalOptions.TraceHardwareReset)
1452 BusLogic_Notice("BusLogic_HardwareReset(0x%X): Host Adapter Ready, "
1453 "Status 0x%02X\n", HostAdapter,
1454 HostAdapter->IO_Address, StatusRegister.All);
1455 if (TimeoutCounter < 0) return false;
1457 If Diagnostic Failure is set or Host Adapter Ready is reset, then an
1458 error occurred during the Host Adapter diagnostics. If Data In Register
1459 Ready is set, then there is an Error Code available.
1461 if (StatusRegister.sr.DiagnosticFailure ||
1462 !StatusRegister.sr.HostAdapterReady)
1464 BusLogic_CommandFailureReason = NULL;
1465 BusLogic_Failure(HostAdapter, "HARD RESET DIAGNOSTICS");
1466 BusLogic_Error("HOST ADAPTER STATUS REGISTER = %02X\n",
1467 HostAdapter, StatusRegister.All);
1468 if (StatusRegister.sr.DataInRegisterReady)
1470 unsigned char ErrorCode = BusLogic_ReadDataInRegister(HostAdapter);
1471 BusLogic_Error("HOST ADAPTER ERROR CODE = %d\n",
1472 HostAdapter, ErrorCode);
1477 Indicate the Host Adapter Hard Reset completed successfully.
1484 BusLogic_CheckHostAdapter checks to be sure this really is a BusLogic
1488 static boolean __init BusLogic_CheckHostAdapter(struct BusLogic_HostAdapter *HostAdapter)
1490 struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation;
1491 unsigned char RequestedReplyLength;
1492 boolean Result = true;
1494 FlashPoint Host Adapters do not require this protection.
1496 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
1498 Issue the Inquire Extended Setup Information command. Only genuine
1499 BusLogic Host Adapters and true clones support this command. Adaptec 1542C
1500 series Host Adapters that respond to the Geometry Register I/O port will
1503 RequestedReplyLength = sizeof(ExtendedSetupInformation);
1504 if (BusLogic_Command(HostAdapter,
1505 BusLogic_InquireExtendedSetupInformation,
1506 &RequestedReplyLength,
1507 sizeof(RequestedReplyLength),
1508 &ExtendedSetupInformation,
1509 sizeof(ExtendedSetupInformation))
1510 != sizeof(ExtendedSetupInformation))
1513 Provide tracing information if requested and return.
1515 if (BusLogic_GlobalOptions.TraceProbe)
1516 BusLogic_Notice("BusLogic_Check(0x%X): MultiMaster %s\n", HostAdapter,
1517 HostAdapter->IO_Address, (Result ? "Found" : "Not Found"));
1523 BusLogic_ReadHostAdapterConfiguration reads the Configuration Information
1524 from Host Adapter and initializes the Host Adapter structure.
1527 static boolean __init BusLogic_ReadHostAdapterConfiguration(struct BusLogic_HostAdapter
1530 struct BusLogic_BoardID BoardID;
1531 struct BusLogic_Configuration Configuration;
1532 struct BusLogic_SetupInformation SetupInformation;
1533 struct BusLogic_ExtendedSetupInformation ExtendedSetupInformation;
1534 unsigned char HostAdapterModelNumber[5];
1535 unsigned char FirmwareVersion3rdDigit;
1536 unsigned char FirmwareVersionLetter;
1537 struct BusLogic_PCIHostAdapterInformation PCIHostAdapterInformation;
1538 struct BusLogic_FetchHostAdapterLocalRAMRequest FetchHostAdapterLocalRAMRequest;
1539 struct BusLogic_AutoSCSIData AutoSCSIData;
1540 union BusLogic_GeometryRegister GeometryRegister;
1541 unsigned char RequestedReplyLength;
1542 unsigned char *TargetPointer, Character;
1545 Configuration Information for FlashPoint Host Adapters is provided in the
1546 FlashPoint_Info structure by the FlashPoint SCCB Manager's Probe Function.
1547 Initialize fields in the Host Adapter structure from the FlashPoint_Info
1550 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
1552 struct FlashPoint_Info *FlashPointInfo = &HostAdapter->FlashPointInfo;
1553 TargetPointer = HostAdapter->ModelName;
1554 *TargetPointer++ = 'B';
1555 *TargetPointer++ = 'T';
1556 *TargetPointer++ = '-';
1557 for (i = 0; i < sizeof(FlashPointInfo->ModelNumber); i++)
1558 *TargetPointer++ = FlashPointInfo->ModelNumber[i];
1559 *TargetPointer++ = '\0';
1560 strcpy(HostAdapter->FirmwareVersion, FlashPoint_FirmwareVersion);
1561 HostAdapter->SCSI_ID = FlashPointInfo->SCSI_ID;
1562 HostAdapter->ExtendedTranslationEnabled =
1563 FlashPointInfo->ExtendedTranslationEnabled;
1564 HostAdapter->ParityCheckingEnabled =
1565 FlashPointInfo->ParityCheckingEnabled;
1566 HostAdapter->BusResetEnabled = !FlashPointInfo->HostSoftReset;
1567 HostAdapter->LevelSensitiveInterrupt = true;
1568 HostAdapter->HostWideSCSI = FlashPointInfo->HostWideSCSI;
1569 HostAdapter->HostDifferentialSCSI = false;
1570 HostAdapter->HostSupportsSCAM = true;
1571 HostAdapter->HostUltraSCSI = true;
1572 HostAdapter->ExtendedLUNSupport = true;
1573 HostAdapter->TerminationInfoValid = true;
1574 HostAdapter->LowByteTerminated = FlashPointInfo->LowByteTerminated;
1575 HostAdapter->HighByteTerminated = FlashPointInfo->HighByteTerminated;
1576 HostAdapter->SCAM_Enabled = FlashPointInfo->SCAM_Enabled;
1577 HostAdapter->SCAM_Level2 = FlashPointInfo->SCAM_Level2;
1578 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1579 HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1580 HostAdapter->MaxLogicalUnits = 32;
1581 HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1582 HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1583 HostAdapter->DriverQueueDepth = 255;
1584 HostAdapter->HostAdapterQueueDepth = HostAdapter->DriverQueueDepth;
1585 HostAdapter->SynchronousPermitted = FlashPointInfo->SynchronousPermitted;
1586 HostAdapter->FastPermitted = FlashPointInfo->FastPermitted;
1587 HostAdapter->UltraPermitted = FlashPointInfo->UltraPermitted;
1588 HostAdapter->WidePermitted = FlashPointInfo->WidePermitted;
1589 HostAdapter->DisconnectPermitted = FlashPointInfo->DisconnectPermitted;
1590 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1594 Issue the Inquire Board ID command.
1596 if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardID, NULL, 0,
1597 &BoardID, sizeof(BoardID)) != sizeof(BoardID))
1598 return BusLogic_Failure(HostAdapter, "INQUIRE BOARD ID");
1600 Issue the Inquire Configuration command.
1602 if (BusLogic_Command(HostAdapter, BusLogic_InquireConfiguration, NULL, 0,
1603 &Configuration, sizeof(Configuration))
1604 != sizeof(Configuration))
1605 return BusLogic_Failure(HostAdapter, "INQUIRE CONFIGURATION");
1607 Issue the Inquire Setup Information command.
1609 RequestedReplyLength = sizeof(SetupInformation);
1610 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
1611 &RequestedReplyLength, sizeof(RequestedReplyLength),
1612 &SetupInformation, sizeof(SetupInformation))
1613 != sizeof(SetupInformation))
1614 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
1616 Issue the Inquire Extended Setup Information command.
1618 RequestedReplyLength = sizeof(ExtendedSetupInformation);
1619 if (BusLogic_Command(HostAdapter, BusLogic_InquireExtendedSetupInformation,
1620 &RequestedReplyLength, sizeof(RequestedReplyLength),
1621 &ExtendedSetupInformation,
1622 sizeof(ExtendedSetupInformation))
1623 != sizeof(ExtendedSetupInformation))
1624 return BusLogic_Failure(HostAdapter, "INQUIRE EXTENDED SETUP INFORMATION");
1626 Issue the Inquire Firmware Version 3rd Digit command.
1628 FirmwareVersion3rdDigit = '\0';
1629 if (BoardID.FirmwareVersion1stDigit > '0')
1630 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit,
1631 NULL, 0, &FirmwareVersion3rdDigit,
1632 sizeof(FirmwareVersion3rdDigit))
1633 != sizeof(FirmwareVersion3rdDigit))
1634 return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT");
1636 Issue the Inquire Host Adapter Model Number command.
1638 if (ExtendedSetupInformation.BusType == 'A' &&
1639 BoardID.FirmwareVersion1stDigit == '2')
1640 /* BusLogic BT-542B ISA 2.xx */
1641 strcpy(HostAdapterModelNumber, "542B");
1642 else if (ExtendedSetupInformation.BusType == 'E' &&
1643 BoardID.FirmwareVersion1stDigit == '2' &&
1644 (BoardID.FirmwareVersion2ndDigit <= '1' ||
1645 (BoardID.FirmwareVersion2ndDigit == '2' &&
1646 FirmwareVersion3rdDigit == '0')))
1647 /* BusLogic BT-742A EISA 2.1x or 2.20 */
1648 strcpy(HostAdapterModelNumber, "742A");
1649 else if (ExtendedSetupInformation.BusType == 'E' &&
1650 BoardID.FirmwareVersion1stDigit == '0')
1651 /* AMI FastDisk EISA Series 441 0.x */
1652 strcpy(HostAdapterModelNumber, "747A");
1655 RequestedReplyLength = sizeof(HostAdapterModelNumber);
1656 if (BusLogic_Command(HostAdapter, BusLogic_InquireHostAdapterModelNumber,
1657 &RequestedReplyLength, sizeof(RequestedReplyLength),
1658 &HostAdapterModelNumber,
1659 sizeof(HostAdapterModelNumber))
1660 != sizeof(HostAdapterModelNumber))
1661 return BusLogic_Failure(HostAdapter,
1662 "INQUIRE HOST ADAPTER MODEL NUMBER");
1665 BusLogic MultiMaster Host Adapters can be identified by their model number
1666 and the major version number of their firmware as follows:
1668 5.xx BusLogic "W" Series Host Adapters:
1670 4.xx BusLogic "C" Series Host Adapters:
1671 BT-946C/956C/956CD/747C/757C/757CD/445C/545C/540CF
1672 3.xx BusLogic "S" Series Host Adapters:
1673 BT-747S/747D/757S/757D/445S/545S/542D
1674 BT-542B/742A (revision H)
1675 2.xx BusLogic "A" Series Host Adapters:
1676 BT-542B/742A (revision G and below)
1677 0.xx AMI FastDisk VLB/EISA BusLogic Clone Host Adapter
1680 Save the Model Name and Host Adapter Name in the Host Adapter structure.
1682 TargetPointer = HostAdapter->ModelName;
1683 *TargetPointer++ = 'B';
1684 *TargetPointer++ = 'T';
1685 *TargetPointer++ = '-';
1686 for (i = 0; i < sizeof(HostAdapterModelNumber); i++)
1688 Character = HostAdapterModelNumber[i];
1689 if (Character == ' ' || Character == '\0') break;
1690 *TargetPointer++ = Character;
1692 *TargetPointer++ = '\0';
1694 Save the Firmware Version in the Host Adapter structure.
1696 TargetPointer = HostAdapter->FirmwareVersion;
1697 *TargetPointer++ = BoardID.FirmwareVersion1stDigit;
1698 *TargetPointer++ = '.';
1699 *TargetPointer++ = BoardID.FirmwareVersion2ndDigit;
1700 if (FirmwareVersion3rdDigit != ' ' && FirmwareVersion3rdDigit != '\0')
1701 *TargetPointer++ = FirmwareVersion3rdDigit;
1702 *TargetPointer = '\0';
1704 Issue the Inquire Firmware Version Letter command.
1706 if (strcmp(HostAdapter->FirmwareVersion, "3.3") >= 0)
1708 if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersionLetter,
1709 NULL, 0, &FirmwareVersionLetter,
1710 sizeof(FirmwareVersionLetter))
1711 != sizeof(FirmwareVersionLetter))
1712 return BusLogic_Failure(HostAdapter,
1713 "INQUIRE FIRMWARE VERSION LETTER");
1714 if (FirmwareVersionLetter != ' ' && FirmwareVersionLetter != '\0')
1715 *TargetPointer++ = FirmwareVersionLetter;
1716 *TargetPointer = '\0';
1719 Save the Host Adapter SCSI ID in the Host Adapter structure.
1721 HostAdapter->SCSI_ID = Configuration.HostAdapterID;
1723 Determine the Bus Type and save it in the Host Adapter structure, determine
1724 and save the IRQ Channel if necessary, and determine and save the DMA
1725 Channel for ISA Host Adapters.
1727 HostAdapter->HostAdapterBusType =
1728 BusLogic_HostAdapterBusTypes[HostAdapter->ModelName[3] - '4'];
1729 if (HostAdapter->IRQ_Channel == 0)
1731 if (Configuration.IRQ_Channel9)
1732 HostAdapter->IRQ_Channel = 9;
1733 else if (Configuration.IRQ_Channel10)
1734 HostAdapter->IRQ_Channel = 10;
1735 else if (Configuration.IRQ_Channel11)
1736 HostAdapter->IRQ_Channel = 11;
1737 else if (Configuration.IRQ_Channel12)
1738 HostAdapter->IRQ_Channel = 12;
1739 else if (Configuration.IRQ_Channel14)
1740 HostAdapter->IRQ_Channel = 14;
1741 else if (Configuration.IRQ_Channel15)
1742 HostAdapter->IRQ_Channel = 15;
1744 if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus)
1746 if (Configuration.DMA_Channel5)
1747 HostAdapter->DMA_Channel = 5;
1748 else if (Configuration.DMA_Channel6)
1749 HostAdapter->DMA_Channel = 6;
1750 else if (Configuration.DMA_Channel7)
1751 HostAdapter->DMA_Channel = 7;
1754 Determine whether Extended Translation is enabled and save it in
1755 the Host Adapter structure.
1757 GeometryRegister.All = BusLogic_ReadGeometryRegister(HostAdapter);
1758 HostAdapter->ExtendedTranslationEnabled =
1759 GeometryRegister.gr.ExtendedTranslationEnabled;
1761 Save the Scatter Gather Limits, Level Sensitive Interrupt flag, Wide
1762 SCSI flag, Differential SCSI flag, SCAM Supported flag, and
1763 Ultra SCSI flag in the Host Adapter structure.
1765 HostAdapter->HostAdapterScatterGatherLimit =
1766 ExtendedSetupInformation.ScatterGatherLimit;
1767 HostAdapter->DriverScatterGatherLimit =
1768 HostAdapter->HostAdapterScatterGatherLimit;
1769 if (HostAdapter->HostAdapterScatterGatherLimit > BusLogic_ScatterGatherLimit)
1770 HostAdapter->DriverScatterGatherLimit = BusLogic_ScatterGatherLimit;
1771 if (ExtendedSetupInformation.Misc.LevelSensitiveInterrupt)
1772 HostAdapter->LevelSensitiveInterrupt = true;
1773 HostAdapter->HostWideSCSI = ExtendedSetupInformation.HostWideSCSI;
1774 HostAdapter->HostDifferentialSCSI =
1775 ExtendedSetupInformation.HostDifferentialSCSI;
1776 HostAdapter->HostSupportsSCAM = ExtendedSetupInformation.HostSupportsSCAM;
1777 HostAdapter->HostUltraSCSI = ExtendedSetupInformation.HostUltraSCSI;
1779 Determine whether Extended LUN Format CCBs are supported and save the
1780 information in the Host Adapter structure.
1782 if (HostAdapter->FirmwareVersion[0] == '5' ||
1783 (HostAdapter->FirmwareVersion[0] == '4' && HostAdapter->HostWideSCSI))
1784 HostAdapter->ExtendedLUNSupport = true;
1786 Issue the Inquire PCI Host Adapter Information command to read the
1787 Termination Information from "W" series MultiMaster Host Adapters.
1789 if (HostAdapter->FirmwareVersion[0] == '5')
1791 if (BusLogic_Command(HostAdapter,
1792 BusLogic_InquirePCIHostAdapterInformation,
1793 NULL, 0, &PCIHostAdapterInformation,
1794 sizeof(PCIHostAdapterInformation))
1795 != sizeof(PCIHostAdapterInformation))
1796 return BusLogic_Failure(HostAdapter,
1797 "INQUIRE PCI HOST ADAPTER INFORMATION");
1799 Save the Termination Information in the Host Adapter structure.
1801 if (PCIHostAdapterInformation.GenericInfoValid)
1803 HostAdapter->TerminationInfoValid = true;
1804 HostAdapter->LowByteTerminated =
1805 PCIHostAdapterInformation.LowByteTerminated;
1806 HostAdapter->HighByteTerminated =
1807 PCIHostAdapterInformation.HighByteTerminated;
1811 Issue the Fetch Host Adapter Local RAM command to read the AutoSCSI data
1812 from "W" and "C" series MultiMaster Host Adapters.
1814 if (HostAdapter->FirmwareVersion[0] >= '4')
1816 FetchHostAdapterLocalRAMRequest.ByteOffset =
1817 BusLogic_AutoSCSI_BaseOffset;
1818 FetchHostAdapterLocalRAMRequest.ByteCount = sizeof(AutoSCSIData);
1819 if (BusLogic_Command(HostAdapter,
1820 BusLogic_FetchHostAdapterLocalRAM,
1821 &FetchHostAdapterLocalRAMRequest,
1822 sizeof(FetchHostAdapterLocalRAMRequest),
1823 &AutoSCSIData, sizeof(AutoSCSIData))
1824 != sizeof(AutoSCSIData))
1825 return BusLogic_Failure(HostAdapter, "FETCH HOST ADAPTER LOCAL RAM");
1827 Save the Parity Checking Enabled, Bus Reset Enabled, and Termination
1828 Information in the Host Adapter structure.
1830 HostAdapter->ParityCheckingEnabled = AutoSCSIData.ParityCheckingEnabled;
1831 HostAdapter->BusResetEnabled = AutoSCSIData.BusResetEnabled;
1832 if (HostAdapter->FirmwareVersion[0] == '4')
1834 HostAdapter->TerminationInfoValid = true;
1835 HostAdapter->LowByteTerminated = AutoSCSIData.LowByteTerminated;
1836 HostAdapter->HighByteTerminated = AutoSCSIData.HighByteTerminated;
1839 Save the Wide Permitted, Fast Permitted, Synchronous Permitted,
1840 Disconnect Permitted, Ultra Permitted, and SCAM Information in the
1841 Host Adapter structure.
1843 HostAdapter->WidePermitted = AutoSCSIData.WidePermitted;
1844 HostAdapter->FastPermitted = AutoSCSIData.FastPermitted;
1845 HostAdapter->SynchronousPermitted =
1846 AutoSCSIData.SynchronousPermitted;
1847 HostAdapter->DisconnectPermitted =
1848 AutoSCSIData.DisconnectPermitted;
1849 if (HostAdapter->HostUltraSCSI)
1850 HostAdapter->UltraPermitted = AutoSCSIData.UltraPermitted;
1851 if (HostAdapter->HostSupportsSCAM)
1853 HostAdapter->SCAM_Enabled = AutoSCSIData.SCAM_Enabled;
1854 HostAdapter->SCAM_Level2 = AutoSCSIData.SCAM_Level2;
1858 Initialize fields in the Host Adapter structure for "S" and "A" series
1859 MultiMaster Host Adapters.
1861 if (HostAdapter->FirmwareVersion[0] < '4')
1863 if (SetupInformation.SynchronousInitiationEnabled)
1865 HostAdapter->SynchronousPermitted = 0xFF;
1866 if (HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)
1868 if (ExtendedSetupInformation.Misc.FastOnEISA)
1869 HostAdapter->FastPermitted = 0xFF;
1870 if (strcmp(HostAdapter->ModelName, "BT-757") == 0)
1871 HostAdapter->WidePermitted = 0xFF;
1874 HostAdapter->DisconnectPermitted = 0xFF;
1875 HostAdapter->ParityCheckingEnabled =
1876 SetupInformation.ParityCheckingEnabled;
1877 HostAdapter->BusResetEnabled = true;
1880 Determine the maximum number of Target IDs and Logical Units supported by
1881 this driver for Wide and Narrow Host Adapters.
1883 HostAdapter->MaxTargetDevices = (HostAdapter->HostWideSCSI ? 16 : 8);
1884 HostAdapter->MaxLogicalUnits = (HostAdapter->ExtendedLUNSupport ? 32 : 8);
1886 Select appropriate values for the Mailbox Count, Driver Queue Depth,
1887 Initial CCBs, and Incremental CCBs variables based on whether or not Strict
1888 Round Robin Mode is supported. If Strict Round Robin Mode is supported,
1889 then there is no performance degradation in using the maximum possible
1890 number of Outgoing and Incoming Mailboxes and allowing the Tagged and
1891 Untagged Queue Depths to determine the actual utilization. If Strict Round
1892 Robin Mode is not supported, then the Host Adapter must scan all the
1893 Outgoing Mailboxes whenever an Outgoing Mailbox entry is made, which can
1894 cause a substantial performance penalty. The host adapters actually have
1895 room to store the following number of CCBs internally; that is, they can
1896 internally queue and manage this many active commands on the SCSI bus
1897 simultaneously. Performance measurements demonstrate that the Driver Queue
1898 Depth should be set to the Mailbox Count, rather than the Host Adapter
1899 Queue Depth (internal CCB capacity), as it is more efficient to have the
1900 queued commands waiting in Outgoing Mailboxes if necessary than to block
1901 the process in the higher levels of the SCSI Subsystem.
1904 100 BT-946C/956C/956CD/747C/757C/757CD/445C
1906 30 BT-747S/747D/757S/757D/445S/545S/542D/542B/742A
1908 if (HostAdapter->FirmwareVersion[0] == '5')
1909 HostAdapter->HostAdapterQueueDepth = 192;
1910 else if (HostAdapter->FirmwareVersion[0] == '4')
1911 HostAdapter->HostAdapterQueueDepth =
1912 (HostAdapter->HostAdapterBusType != BusLogic_ISA_Bus ? 100 : 50);
1913 else HostAdapter->HostAdapterQueueDepth = 30;
1914 if (strcmp(HostAdapter->FirmwareVersion, "3.31") >= 0)
1916 HostAdapter->StrictRoundRobinModeSupport = true;
1917 HostAdapter->MailboxCount = BusLogic_MaxMailboxes;
1921 HostAdapter->StrictRoundRobinModeSupport = false;
1922 HostAdapter->MailboxCount = 32;
1924 HostAdapter->DriverQueueDepth = HostAdapter->MailboxCount;
1925 HostAdapter->InitialCCBs = 4 * BusLogic_CCB_AllocationGroupSize;
1926 HostAdapter->IncrementalCCBs = BusLogic_CCB_AllocationGroupSize;
1928 Tagged Queuing support is available and operates properly on all "W" series
1929 MultiMaster Host Adapters, on "C" series MultiMaster Host Adapters with
1930 firmware version 4.22 and above, and on "S" series MultiMaster Host
1931 Adapters with firmware version 3.35 and above.
1933 HostAdapter->TaggedQueuingPermitted = 0;
1934 switch (HostAdapter->FirmwareVersion[0])
1937 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1940 if (strcmp(HostAdapter->FirmwareVersion, "4.22") >= 0)
1941 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1944 if (strcmp(HostAdapter->FirmwareVersion, "3.35") >= 0)
1945 HostAdapter->TaggedQueuingPermitted = 0xFFFF;
1949 Determine the Host Adapter BIOS Address if the BIOS is enabled and
1950 save it in the Host Adapter structure. The BIOS is disabled if the
1953 HostAdapter->BIOS_Address = ExtendedSetupInformation.BIOS_Address << 12;
1955 ISA Host Adapters require Bounce Buffers if there is more than 16MB memory.
1957 if (HostAdapter->HostAdapterBusType == BusLogic_ISA_Bus &&
1958 (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1959 HostAdapter->BounceBuffersRequired = true;
1961 BusLogic BT-445S Host Adapters prior to board revision E have a hardware
1962 bug whereby when the BIOS is enabled, transfers to/from the same address
1963 range the BIOS occupies modulo 16MB are handled incorrectly. Only properly
1964 functioning BT-445S Host Adapters have firmware version 3.37, so require
1965 that ISA Bounce Buffers be used for the buggy BT-445S models if there is
1966 more than 16MB memory.
1968 if (HostAdapter->BIOS_Address > 0 &&
1969 strcmp(HostAdapter->ModelName, "BT-445S") == 0 &&
1970 strcmp(HostAdapter->FirmwareVersion, "3.37") < 0 &&
1971 (void *) high_memory > (void *) MAX_DMA_ADDRESS)
1972 HostAdapter->BounceBuffersRequired = true;
1974 Initialize parameters common to MultiMaster and FlashPoint Host Adapters.
1978 Initialize the Host Adapter Full Model Name from the Model Name.
1980 strcpy(HostAdapter->FullModelName, "BusLogic ");
1981 strcat(HostAdapter->FullModelName, HostAdapter->ModelName);
1983 Select an appropriate value for the Tagged Queue Depth either from a
1984 BusLogic Driver Options specification, or based on whether this Host
1985 Adapter requires that ISA Bounce Buffers be used. The Tagged Queue Depth
1986 is left at 0 for automatic determination in BusLogic_SelectQueueDepths.
1987 Initialize the Untagged Queue Depth.
1989 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
1991 unsigned char QueueDepth = 0;
1992 if (HostAdapter->DriverOptions != NULL &&
1993 HostAdapter->DriverOptions->QueueDepth[TargetID] > 0)
1994 QueueDepth = HostAdapter->DriverOptions->QueueDepth[TargetID];
1995 else if (HostAdapter->BounceBuffersRequired)
1996 QueueDepth = BusLogic_TaggedQueueDepthBB;
1997 HostAdapter->QueueDepth[TargetID] = QueueDepth;
1999 if (HostAdapter->BounceBuffersRequired)
2000 HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepthBB;
2001 else HostAdapter->UntaggedQueueDepth = BusLogic_UntaggedQueueDepth;
2002 if (HostAdapter->DriverOptions != NULL)
2003 HostAdapter->CommonQueueDepth =
2004 HostAdapter->DriverOptions->CommonQueueDepth;
2005 if (HostAdapter->CommonQueueDepth > 0 &&
2006 HostAdapter->CommonQueueDepth < HostAdapter->UntaggedQueueDepth)
2007 HostAdapter->UntaggedQueueDepth = HostAdapter->CommonQueueDepth;
2009 Tagged Queuing is only allowed if Disconnect/Reconnect is permitted.
2010 Therefore, mask the Tagged Queuing Permitted Default bits with the
2011 Disconnect/Reconnect Permitted bits.
2013 HostAdapter->TaggedQueuingPermitted &= HostAdapter->DisconnectPermitted;
2015 Combine the default Tagged Queuing Permitted bits with any BusLogic Driver
2016 Options Tagged Queuing specification.
2018 if (HostAdapter->DriverOptions != NULL)
2019 HostAdapter->TaggedQueuingPermitted =
2020 (HostAdapter->DriverOptions->TaggedQueuingPermitted &
2021 HostAdapter->DriverOptions->TaggedQueuingPermittedMask) |
2022 (HostAdapter->TaggedQueuingPermitted &
2023 ~HostAdapter->DriverOptions->TaggedQueuingPermittedMask);
2026 Select an appropriate value for Bus Settle Time either from a BusLogic
2027 Driver Options specification, or from BusLogic_DefaultBusSettleTime.
2029 if (HostAdapter->DriverOptions != NULL &&
2030 HostAdapter->DriverOptions->BusSettleTime > 0)
2031 HostAdapter->BusSettleTime = HostAdapter->DriverOptions->BusSettleTime;
2032 else HostAdapter->BusSettleTime = BusLogic_DefaultBusSettleTime;
2034 Indicate reading the Host Adapter Configuration completed successfully.
2041 BusLogic_ReportHostAdapterConfiguration reports the configuration of
2045 static boolean __init BusLogic_ReportHostAdapterConfiguration(struct BusLogic_HostAdapter
2048 unsigned short AllTargetsMask = (1 << HostAdapter->MaxTargetDevices) - 1;
2049 unsigned short SynchronousPermitted, FastPermitted;
2050 unsigned short UltraPermitted, WidePermitted;
2051 unsigned short DisconnectPermitted, TaggedQueuingPermitted;
2052 boolean CommonSynchronousNegotiation, CommonTaggedQueueDepth;
2053 char SynchronousString[BusLogic_MaxTargetDevices+1];
2054 char WideString[BusLogic_MaxTargetDevices+1];
2055 char DisconnectString[BusLogic_MaxTargetDevices+1];
2056 char TaggedQueuingString[BusLogic_MaxTargetDevices+1];
2057 char *SynchronousMessage = SynchronousString;
2058 char *WideMessage = WideString;
2059 char *DisconnectMessage = DisconnectString;
2060 char *TaggedQueuingMessage = TaggedQueuingString;
2062 BusLogic_Info("Configuring BusLogic Model %s %s%s%s%s SCSI Host Adapter\n",
2063 HostAdapter, HostAdapter->ModelName,
2064 BusLogic_HostAdapterBusNames[HostAdapter->HostAdapterBusType],
2065 (HostAdapter->HostWideSCSI ? " Wide" : ""),
2066 (HostAdapter->HostDifferentialSCSI ? " Differential" : ""),
2067 (HostAdapter->HostUltraSCSI ? " Ultra" : ""));
2068 BusLogic_Info(" Firmware Version: %s, I/O Address: 0x%X, "
2069 "IRQ Channel: %d/%s\n", HostAdapter,
2070 HostAdapter->FirmwareVersion,
2071 HostAdapter->IO_Address, HostAdapter->IRQ_Channel,
2072 (HostAdapter->LevelSensitiveInterrupt ? "Level" : "Edge"));
2073 if (HostAdapter->HostAdapterBusType != BusLogic_PCI_Bus)
2075 BusLogic_Info(" DMA Channel: ", HostAdapter);
2076 if (HostAdapter->DMA_Channel > 0)
2077 BusLogic_Info("%d, ", HostAdapter, HostAdapter->DMA_Channel);
2078 else BusLogic_Info("None, ", HostAdapter);
2079 if (HostAdapter->BIOS_Address > 0)
2080 BusLogic_Info("BIOS Address: 0x%X, ", HostAdapter,
2081 HostAdapter->BIOS_Address);
2082 else BusLogic_Info("BIOS Address: None, ", HostAdapter);
2086 BusLogic_Info(" PCI Bus: %d, Device: %d, Address: ",
2087 HostAdapter, HostAdapter->Bus, HostAdapter->Device);
2088 if (HostAdapter->PCI_Address > 0)
2089 BusLogic_Info("0x%X, ", HostAdapter, HostAdapter->PCI_Address);
2090 else BusLogic_Info("Unassigned, ", HostAdapter);
2092 BusLogic_Info("Host Adapter SCSI ID: %d\n", HostAdapter,
2093 HostAdapter->SCSI_ID);
2094 BusLogic_Info(" Parity Checking: %s, Extended Translation: %s\n",
2096 (HostAdapter->ParityCheckingEnabled
2097 ? "Enabled" : "Disabled"),
2098 (HostAdapter->ExtendedTranslationEnabled
2099 ? "Enabled" : "Disabled"));
2100 AllTargetsMask &= ~(1 << HostAdapter->SCSI_ID);
2101 SynchronousPermitted = HostAdapter->SynchronousPermitted & AllTargetsMask;
2102 FastPermitted = HostAdapter->FastPermitted & AllTargetsMask;
2103 UltraPermitted = HostAdapter->UltraPermitted & AllTargetsMask;
2104 if ((BusLogic_MultiMasterHostAdapterP(HostAdapter) &&
2105 (HostAdapter->FirmwareVersion[0] >= '4' ||
2106 HostAdapter->HostAdapterBusType == BusLogic_EISA_Bus)) ||
2107 BusLogic_FlashPointHostAdapterP(HostAdapter))
2109 CommonSynchronousNegotiation = false;
2110 if (SynchronousPermitted == 0)
2112 SynchronousMessage = "Disabled";
2113 CommonSynchronousNegotiation = true;
2115 else if (SynchronousPermitted == AllTargetsMask)
2117 if (FastPermitted == 0)
2119 SynchronousMessage = "Slow";
2120 CommonSynchronousNegotiation = true;
2122 else if (FastPermitted == AllTargetsMask)
2124 if (UltraPermitted == 0)
2126 SynchronousMessage = "Fast";
2127 CommonSynchronousNegotiation = true;
2129 else if (UltraPermitted == AllTargetsMask)
2131 SynchronousMessage = "Ultra";
2132 CommonSynchronousNegotiation = true;
2136 if (!CommonSynchronousNegotiation)
2139 TargetID < HostAdapter->MaxTargetDevices;
2141 SynchronousString[TargetID] =
2142 ((!(SynchronousPermitted & (1 << TargetID))) ? 'N' :
2143 (!(FastPermitted & (1 << TargetID)) ? 'S' :
2144 (!(UltraPermitted & (1 << TargetID)) ? 'F' : 'U')));
2145 SynchronousString[HostAdapter->SCSI_ID] = '#';
2146 SynchronousString[HostAdapter->MaxTargetDevices] = '\0';
2149 else SynchronousMessage =
2150 (SynchronousPermitted == 0 ? "Disabled" : "Enabled");
2151 WidePermitted = HostAdapter->WidePermitted & AllTargetsMask;
2152 if (WidePermitted == 0)
2153 WideMessage = "Disabled";
2154 else if (WidePermitted == AllTargetsMask)
2155 WideMessage = "Enabled";
2158 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2159 WideString[TargetID] =
2160 ((WidePermitted & (1 << TargetID)) ? 'Y' : 'N');
2161 WideString[HostAdapter->SCSI_ID] = '#';
2162 WideString[HostAdapter->MaxTargetDevices] = '\0';
2164 DisconnectPermitted = HostAdapter->DisconnectPermitted & AllTargetsMask;
2165 if (DisconnectPermitted == 0)
2166 DisconnectMessage = "Disabled";
2167 else if (DisconnectPermitted == AllTargetsMask)
2168 DisconnectMessage = "Enabled";
2171 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2172 DisconnectString[TargetID] =
2173 ((DisconnectPermitted & (1 << TargetID)) ? 'Y' : 'N');
2174 DisconnectString[HostAdapter->SCSI_ID] = '#';
2175 DisconnectString[HostAdapter->MaxTargetDevices] = '\0';
2177 TaggedQueuingPermitted =
2178 HostAdapter->TaggedQueuingPermitted & AllTargetsMask;
2179 if (TaggedQueuingPermitted == 0)
2180 TaggedQueuingMessage = "Disabled";
2181 else if (TaggedQueuingPermitted == AllTargetsMask)
2182 TaggedQueuingMessage = "Enabled";
2185 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2186 TaggedQueuingString[TargetID] =
2187 ((TaggedQueuingPermitted & (1 << TargetID)) ? 'Y' : 'N');
2188 TaggedQueuingString[HostAdapter->SCSI_ID] = '#';
2189 TaggedQueuingString[HostAdapter->MaxTargetDevices] = '\0';
2191 BusLogic_Info(" Synchronous Negotiation: %s, Wide Negotiation: %s\n",
2192 HostAdapter, SynchronousMessage, WideMessage);
2193 BusLogic_Info(" Disconnect/Reconnect: %s, Tagged Queuing: %s\n",
2194 HostAdapter, DisconnectMessage, TaggedQueuingMessage);
2195 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
2197 BusLogic_Info(" Scatter/Gather Limit: %d of %d segments, "
2198 "Mailboxes: %d\n", HostAdapter,
2199 HostAdapter->DriverScatterGatherLimit,
2200 HostAdapter->HostAdapterScatterGatherLimit,
2201 HostAdapter->MailboxCount);
2202 BusLogic_Info(" Driver Queue Depth: %d, "
2203 "Host Adapter Queue Depth: %d\n",
2204 HostAdapter, HostAdapter->DriverQueueDepth,
2205 HostAdapter->HostAdapterQueueDepth);
2207 else BusLogic_Info(" Driver Queue Depth: %d, "
2208 "Scatter/Gather Limit: %d segments\n",
2209 HostAdapter, HostAdapter->DriverQueueDepth,
2210 HostAdapter->DriverScatterGatherLimit);
2211 BusLogic_Info(" Tagged Queue Depth: ", HostAdapter);
2212 CommonTaggedQueueDepth = true;
2213 for (TargetID = 1; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2214 if (HostAdapter->QueueDepth[TargetID] != HostAdapter->QueueDepth[0])
2216 CommonTaggedQueueDepth = false;
2219 if (CommonTaggedQueueDepth)
2221 if (HostAdapter->QueueDepth[0] > 0)
2222 BusLogic_Info("%d", HostAdapter, HostAdapter->QueueDepth[0]);
2223 else BusLogic_Info("Automatic", HostAdapter);
2225 else BusLogic_Info("Individual", HostAdapter);
2226 BusLogic_Info(", Untagged Queue Depth: %d\n", HostAdapter,
2227 HostAdapter->UntaggedQueueDepth);
2228 if (HostAdapter->TerminationInfoValid)
2230 if (HostAdapter->HostWideSCSI)
2231 BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter,
2232 (HostAdapter->LowByteTerminated
2233 ? (HostAdapter->HighByteTerminated
2234 ? "Both Enabled" : "Low Enabled")
2235 : (HostAdapter->HighByteTerminated
2236 ? "High Enabled" : "Both Disabled")));
2237 else BusLogic_Info(" SCSI Bus Termination: %s", HostAdapter,
2238 (HostAdapter->LowByteTerminated ?
2239 "Enabled" : "Disabled"));
2240 if (HostAdapter->HostSupportsSCAM)
2241 BusLogic_Info(", SCAM: %s", HostAdapter,
2242 (HostAdapter->SCAM_Enabled
2243 ? (HostAdapter->SCAM_Level2
2244 ? "Enabled, Level 2" : "Enabled, Level 1")
2246 BusLogic_Info("\n", HostAdapter);
2249 Indicate reporting the Host Adapter configuration completed successfully.
2256 BusLogic_AcquireResources acquires the system resources necessary to use
2260 static boolean __init BusLogic_AcquireResources(struct BusLogic_HostAdapter *HostAdapter)
2262 if (HostAdapter->IRQ_Channel == 0)
2264 BusLogic_Error("NO LEGAL INTERRUPT CHANNEL ASSIGNED - DETACHING\n",
2269 Acquire shared access to the IRQ Channel.
2271 if (request_irq(HostAdapter->IRQ_Channel, BusLogic_InterruptHandler,
2272 SA_SHIRQ, HostAdapter->FullModelName, HostAdapter) < 0)
2274 BusLogic_Error("UNABLE TO ACQUIRE IRQ CHANNEL %d - DETACHING\n",
2275 HostAdapter, HostAdapter->IRQ_Channel);
2278 HostAdapter->IRQ_ChannelAcquired = true;
2280 Acquire exclusive access to the DMA Channel.
2282 if (HostAdapter->DMA_Channel > 0)
2284 if (request_dma(HostAdapter->DMA_Channel,
2285 HostAdapter->FullModelName) < 0)
2287 BusLogic_Error("UNABLE TO ACQUIRE DMA CHANNEL %d - DETACHING\n",
2288 HostAdapter, HostAdapter->DMA_Channel);
2291 set_dma_mode(HostAdapter->DMA_Channel, DMA_MODE_CASCADE);
2292 enable_dma(HostAdapter->DMA_Channel);
2293 HostAdapter->DMA_ChannelAcquired = true;
2296 Indicate the System Resource Acquisition completed successfully,
2303 BusLogic_ReleaseResources releases any system resources previously acquired
2304 by BusLogic_AcquireResources.
2307 static void BusLogic_ReleaseResources(struct BusLogic_HostAdapter *HostAdapter)
2310 Release shared access to the IRQ Channel.
2312 if (HostAdapter->IRQ_ChannelAcquired)
2313 free_irq(HostAdapter->IRQ_Channel, HostAdapter);
2315 Release exclusive access to the DMA Channel.
2317 if (HostAdapter->DMA_ChannelAcquired)
2318 free_dma(HostAdapter->DMA_Channel);
2320 Release any allocated memory structs not released elsewhere
2322 if (HostAdapter->MailboxSpace)
2323 pci_free_consistent(HostAdapter->PCI_Device, HostAdapter->MailboxSize,
2324 HostAdapter->MailboxSpace,
2325 HostAdapter->MailboxSpaceHandle);
2326 HostAdapter->MailboxSpace = NULL;
2327 HostAdapter->MailboxSpaceHandle = 0;
2328 HostAdapter->MailboxSize = 0;
2333 BusLogic_InitializeHostAdapter initializes Host Adapter. This is the only
2334 function called during SCSI Host Adapter detection which modifies the state
2335 of the Host Adapter from its initial power on or hard reset state.
2338 static boolean BusLogic_InitializeHostAdapter(struct BusLogic_HostAdapter
2341 struct BusLogic_ExtendedMailboxRequest ExtendedMailboxRequest;
2342 enum BusLogic_RoundRobinModeRequest RoundRobinModeRequest;
2343 enum BusLogic_SetCCBFormatRequest SetCCBFormatRequest;
2346 Initialize the pointers to the first and last CCBs that are queued for
2347 completion processing.
2349 HostAdapter->FirstCompletedCCB = NULL;
2350 HostAdapter->LastCompletedCCB = NULL;
2352 Initialize the Bus Device Reset Pending CCB, Tagged Queuing Active,
2353 Command Successful Flag, Active Commands, and Commands Since Reset
2354 for each Target Device.
2356 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2358 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
2359 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
2360 HostAdapter->TargetFlags[TargetID].CommandSuccessfulFlag = false;
2361 HostAdapter->ActiveCommands[TargetID] = 0;
2362 HostAdapter->CommandsSinceReset[TargetID] = 0;
2365 FlashPoint Host Adapters do not use Outgoing and Incoming Mailboxes.
2367 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) goto Done;
2369 Initialize the Outgoing and Incoming Mailbox pointers.
2371 HostAdapter->MailboxSize = HostAdapter->MailboxCount *
2372 (sizeof(struct BusLogic_OutgoingMailbox) + sizeof(struct BusLogic_IncomingMailbox));
2373 HostAdapter->MailboxSpace = pci_alloc_consistent(HostAdapter->PCI_Device,
2374 HostAdapter->MailboxSize, &HostAdapter->MailboxSpaceHandle);
2375 if (HostAdapter->MailboxSpace == NULL)
2376 return BusLogic_Failure(HostAdapter, "MAILBOX ALLOCATION");
2377 HostAdapter->FirstOutgoingMailbox =
2378 (struct BusLogic_OutgoingMailbox *) HostAdapter->MailboxSpace;
2379 HostAdapter->LastOutgoingMailbox =
2380 HostAdapter->FirstOutgoingMailbox + HostAdapter->MailboxCount - 1;
2381 HostAdapter->NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
2382 HostAdapter->FirstIncomingMailbox =
2383 (struct BusLogic_IncomingMailbox *) (HostAdapter->LastOutgoingMailbox + 1);
2384 HostAdapter->LastIncomingMailbox =
2385 HostAdapter->FirstIncomingMailbox + HostAdapter->MailboxCount - 1;
2386 HostAdapter->NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
2389 Initialize the Outgoing and Incoming Mailbox structures.
2391 memset(HostAdapter->FirstOutgoingMailbox, 0,
2392 HostAdapter->MailboxCount * sizeof(struct BusLogic_OutgoingMailbox));
2393 memset(HostAdapter->FirstIncomingMailbox, 0,
2394 HostAdapter->MailboxCount * sizeof(struct BusLogic_IncomingMailbox));
2396 Initialize the Host Adapter's Pointer to the Outgoing/Incoming Mailboxes.
2398 ExtendedMailboxRequest.MailboxCount = HostAdapter->MailboxCount;
2399 ExtendedMailboxRequest.BaseMailboxAddress =
2400 (u32) HostAdapter->MailboxSpaceHandle;
2401 if (BusLogic_Command(HostAdapter, BusLogic_InitializeExtendedMailbox,
2402 &ExtendedMailboxRequest,
2403 sizeof(ExtendedMailboxRequest), NULL, 0) < 0)
2404 return BusLogic_Failure(HostAdapter, "MAILBOX INITIALIZATION");
2406 Enable Strict Round Robin Mode if supported by the Host Adapter. In
2407 Strict Round Robin Mode, the Host Adapter only looks at the next Outgoing
2408 Mailbox for each new command, rather than scanning through all the
2409 Outgoing Mailboxes to find any that have new commands in them. Strict
2410 Round Robin Mode is significantly more efficient.
2412 if (HostAdapter->StrictRoundRobinModeSupport)
2414 RoundRobinModeRequest = BusLogic_StrictRoundRobinMode;
2415 if (BusLogic_Command(HostAdapter, BusLogic_EnableStrictRoundRobinMode,
2416 &RoundRobinModeRequest,
2417 sizeof(RoundRobinModeRequest), NULL, 0) < 0)
2418 return BusLogic_Failure(HostAdapter, "ENABLE STRICT ROUND ROBIN MODE");
2421 For Host Adapters that support Extended LUN Format CCBs, issue the Set CCB
2422 Format command to allow 32 Logical Units per Target Device.
2424 if (HostAdapter->ExtendedLUNSupport)
2426 SetCCBFormatRequest = BusLogic_ExtendedLUNFormatCCB;
2427 if (BusLogic_Command(HostAdapter, BusLogic_SetCCBFormat,
2428 &SetCCBFormatRequest, sizeof(SetCCBFormatRequest),
2430 return BusLogic_Failure(HostAdapter, "SET CCB FORMAT");
2433 Announce Successful Initialization.
2436 if (!HostAdapter->HostAdapterInitialized)
2438 BusLogic_Info("*** %s Initialized Successfully ***\n",
2439 HostAdapter, HostAdapter->FullModelName);
2440 BusLogic_Info("\n", HostAdapter);
2442 else BusLogic_Warning("*** %s Initialized Successfully ***\n",
2443 HostAdapter, HostAdapter->FullModelName);
2444 HostAdapter->HostAdapterInitialized = true;
2446 Indicate the Host Adapter Initialization completed successfully.
2453 BusLogic_TargetDeviceInquiry inquires about the Target Devices accessible
2454 through Host Adapter.
2457 static boolean __init BusLogic_TargetDeviceInquiry(struct BusLogic_HostAdapter
2460 u16 InstalledDevices;
2461 u8 InstalledDevicesID0to7[8];
2462 struct BusLogic_SetupInformation SetupInformation;
2463 u8 SynchronousPeriod[BusLogic_MaxTargetDevices];
2464 unsigned char RequestedReplyLength;
2467 Wait a few seconds between the Host Adapter Hard Reset which initiates
2468 a SCSI Bus Reset and issuing any SCSI Commands. Some SCSI devices get
2469 confused if they receive SCSI Commands too soon after a SCSI Bus Reset.
2471 BusLogic_Delay(HostAdapter->BusSettleTime);
2473 FlashPoint Host Adapters do not provide for Target Device Inquiry.
2475 if (BusLogic_FlashPointHostAdapterP(HostAdapter)) return true;
2477 Inhibit the Target Device Inquiry if requested.
2479 if (HostAdapter->DriverOptions != NULL &&
2480 HostAdapter->DriverOptions->LocalOptions.InhibitTargetInquiry)
2483 Issue the Inquire Target Devices command for host adapters with firmware
2484 version 4.25 or later, or the Inquire Installed Devices ID 0 to 7 command
2485 for older host adapters. This is necessary to force Synchronous Transfer
2486 Negotiation so that the Inquire Setup Information and Inquire Synchronous
2487 Period commands will return valid data. The Inquire Target Devices command
2488 is preferable to Inquire Installed Devices ID 0 to 7 since it only probes
2489 Logical Unit 0 of each Target Device.
2491 if (strcmp(HostAdapter->FirmwareVersion, "4.25") >= 0)
2495 * Issue a Inquire Target Devices command. Inquire Target Devices only
2496 * tests Logical Unit 0 of each Target Device unlike the Inquire Installed
2497 * Devices commands which test Logical Units 0 - 7. Two bytes are
2498 * returned, where byte 0 bit 0 set indicates that Target Device 0 exists,
2502 if (BusLogic_Command(HostAdapter, BusLogic_InquireTargetDevices, NULL, 0,
2503 &InstalledDevices, sizeof(InstalledDevices))
2504 != sizeof(InstalledDevices))
2505 return BusLogic_Failure(HostAdapter, "INQUIRE TARGET DEVICES");
2506 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2507 HostAdapter->TargetFlags[TargetID].TargetExists =
2508 (InstalledDevices & (1 << TargetID) ? true : false);
2514 * Issue an Inquire Installed Devices command. For each Target Device,
2515 * a byte is returned where bit 0 set indicates that Logical Unit 0
2516 * exists, bit 1 set indicates that Logical Unit 1 exists, and so on.
2519 if (BusLogic_Command(HostAdapter, BusLogic_InquireInstalledDevicesID0to7,
2520 NULL, 0, &InstalledDevicesID0to7,
2521 sizeof(InstalledDevicesID0to7))
2522 != sizeof(InstalledDevicesID0to7))
2523 return BusLogic_Failure(HostAdapter,
2524 "INQUIRE INSTALLED DEVICES ID 0 TO 7");
2525 for (TargetID = 0; TargetID < 8; TargetID++)
2526 HostAdapter->TargetFlags[TargetID].TargetExists =
2527 (InstalledDevicesID0to7[TargetID] != 0 ? true : false);
2530 Issue the Inquire Setup Information command.
2532 RequestedReplyLength = sizeof(SetupInformation);
2533 if (BusLogic_Command(HostAdapter, BusLogic_InquireSetupInformation,
2534 &RequestedReplyLength, sizeof(RequestedReplyLength),
2535 &SetupInformation, sizeof(SetupInformation))
2536 != sizeof(SetupInformation))
2537 return BusLogic_Failure(HostAdapter, "INQUIRE SETUP INFORMATION");
2538 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2539 HostAdapter->SynchronousOffset[TargetID] =
2541 ? SetupInformation.SynchronousValuesID0to7[TargetID].Offset
2542 : SetupInformation.SynchronousValuesID8to15[TargetID-8].Offset);
2543 if (strcmp(HostAdapter->FirmwareVersion, "5.06L") >= 0)
2544 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2545 HostAdapter->TargetFlags[TargetID].WideTransfersActive =
2547 ? (SetupInformation.WideTransfersActiveID0to7 & (1 << TargetID)
2549 : (SetupInformation.WideTransfersActiveID8to15 & (1 << (TargetID-8))
2552 Issue the Inquire Synchronous Period command.
2554 if (HostAdapter->FirmwareVersion[0] >= '3')
2557 /* Issue a Inquire Synchronous Period command. For each Target Device,
2558 * a byte is returned which represents the Synchronous Transfer Period
2559 * in units of 10 nanoseconds.
2562 RequestedReplyLength = sizeof(SynchronousPeriod);
2563 if (BusLogic_Command(HostAdapter, BusLogic_InquireSynchronousPeriod,
2564 &RequestedReplyLength, sizeof(RequestedReplyLength),
2565 &SynchronousPeriod, sizeof(SynchronousPeriod))
2566 != sizeof(SynchronousPeriod))
2567 return BusLogic_Failure(HostAdapter, "INQUIRE SYNCHRONOUS PERIOD");
2568 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2569 HostAdapter->SynchronousPeriod[TargetID] = SynchronousPeriod[TargetID];
2572 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2573 if (SetupInformation.SynchronousValuesID0to7[TargetID].Offset > 0)
2574 HostAdapter->SynchronousPeriod[TargetID] =
2575 20 + 5 * SetupInformation.SynchronousValuesID0to7[TargetID]
2578 Indicate the Target Device Inquiry completed successfully.
2584 BusLogic_InitializeHostStructure initializes the fields in the SCSI Host
2585 structure. The base, io_port, n_io_ports, irq, and dma_channel fields in the
2586 SCSI Host structure are intentionally left uninitialized, as this driver
2587 handles acquisition and release of these resources explicitly, as well as
2588 ensuring exclusive access to the Host Adapter hardware and data structures
2589 through explicit acquisition and release of the Host Adapter's Lock.
2592 static void __init BusLogic_InitializeHostStructure(struct BusLogic_HostAdapter
2594 struct Scsi_Host *Host)
2596 Host->max_id = HostAdapter->MaxTargetDevices;
2597 Host->max_lun = HostAdapter->MaxLogicalUnits;
2598 Host->max_channel = 0;
2599 Host->unique_id = HostAdapter->IO_Address;
2600 Host->this_id = HostAdapter->SCSI_ID;
2601 Host->can_queue = HostAdapter->DriverQueueDepth;
2602 Host->sg_tablesize = HostAdapter->DriverScatterGatherLimit;
2603 Host->unchecked_isa_dma = HostAdapter->BounceBuffersRequired;
2604 Host->cmd_per_lun = HostAdapter->UntaggedQueueDepth;
2608 BusLogic_SlaveConfigure will actually set the queue depth on individual
2609 scsi devices as they are permanently added to the device chain. We
2610 shamelessly rip off the SelectQueueDepths code to make this work mostly
2611 like it used to. Since we don't get called once at the end of the scan
2612 but instead get called for each device, we have to do things a bit
2615 static int BusLogic_SlaveConfigure(struct scsi_device *Device)
2617 struct BusLogic_HostAdapter *HostAdapter =
2618 (struct BusLogic_HostAdapter *) Device->host->hostdata;
2619 int TargetID = Device->id;
2620 int QueueDepth = HostAdapter->QueueDepth[TargetID];
2622 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingSupported &&
2623 (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
2625 if (QueueDepth == 0)
2626 QueueDepth = BusLogic_MaxAutomaticTaggedQueueDepth;
2627 HostAdapter->QueueDepth[TargetID] = QueueDepth;
2628 scsi_adjust_queue_depth(Device, MSG_SIMPLE_TAG, QueueDepth);
2632 HostAdapter->TaggedQueuingPermitted &= ~(1 << TargetID);
2633 QueueDepth = HostAdapter->UntaggedQueueDepth;
2634 HostAdapter->QueueDepth[TargetID] = QueueDepth;
2635 scsi_adjust_queue_depth(Device, 0, QueueDepth);
2638 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
2639 if (HostAdapter->TargetFlags[TargetID].TargetExists)
2641 QueueDepth += HostAdapter->QueueDepth[TargetID];
2643 if (QueueDepth > HostAdapter->AllocatedCCBs)
2644 BusLogic_CreateAdditionalCCBs(HostAdapter,
2646 - HostAdapter->AllocatedCCBs,
2652 BusLogic_DetectHostAdapter probes for BusLogic Host Adapters at the standard
2653 I/O Addresses where they may be located, initializing, registering, and
2654 reporting the configuration of each BusLogic Host Adapter it finds. It
2655 returns the number of BusLogic Host Adapters successfully initialized and
2659 static int __init BusLogic_DetectHostAdapter(struct scsi_host_template *HostTemplate)
2661 int BusLogicHostAdapterCount = 0, DriverOptionsIndex = 0, ProbeIndex;
2662 struct BusLogic_HostAdapter *PrototypeHostAdapter;
2663 if (BusLogic_ProbeOptions.NoProbe) return 0;
2664 BusLogic_ProbeInfoList = (struct BusLogic_ProbeInfo *)
2665 kmalloc(BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo),
2667 if (BusLogic_ProbeInfoList == NULL)
2669 BusLogic_Error("BusLogic: Unable to allocate Probe Info List\n", NULL);
2672 memset(BusLogic_ProbeInfoList, 0,
2673 BusLogic_MaxHostAdapters * sizeof(struct BusLogic_ProbeInfo));
2674 PrototypeHostAdapter = (struct BusLogic_HostAdapter *)
2675 kmalloc(sizeof(struct BusLogic_HostAdapter), GFP_ATOMIC);
2676 if (PrototypeHostAdapter == NULL)
2678 kfree(BusLogic_ProbeInfoList);
2679 BusLogic_Error("BusLogic: Unable to allocate Prototype "
2680 "Host Adapter\n", NULL);
2683 memset(PrototypeHostAdapter, 0, sizeof(struct BusLogic_HostAdapter));
2685 if (BusLogic != NULL)
2686 BusLogic_Setup(BusLogic);
2688 BusLogic_InitializeProbeInfoList(PrototypeHostAdapter);
2689 for (ProbeIndex = 0; ProbeIndex < BusLogic_ProbeInfoCount; ProbeIndex++)
2691 struct BusLogic_ProbeInfo *ProbeInfo = &BusLogic_ProbeInfoList[ProbeIndex];
2692 struct BusLogic_HostAdapter *HostAdapter = PrototypeHostAdapter;
2693 struct Scsi_Host *Host;
2694 if (ProbeInfo->IO_Address == 0) continue;
2695 memset(HostAdapter, 0, sizeof(struct BusLogic_HostAdapter));
2696 HostAdapter->HostAdapterType = ProbeInfo->HostAdapterType;
2697 HostAdapter->HostAdapterBusType = ProbeInfo->HostAdapterBusType;
2698 HostAdapter->IO_Address = ProbeInfo->IO_Address;
2699 HostAdapter->PCI_Address = ProbeInfo->PCI_Address;
2700 HostAdapter->Bus = ProbeInfo->Bus;
2701 HostAdapter->Device = ProbeInfo->Device;
2702 HostAdapter->IRQ_Channel = ProbeInfo->IRQ_Channel;
2703 HostAdapter->AddressCount =
2704 BusLogic_HostAdapterAddressCount[HostAdapter->HostAdapterType];
2706 Probe the Host Adapter. If unsuccessful, abort further initialization.
2708 if (!BusLogic_ProbeHostAdapter(HostAdapter)) continue;
2710 Hard Reset the Host Adapter. If unsuccessful, abort further
2713 if (!BusLogic_HardwareResetHostAdapter(HostAdapter, true)) continue;
2715 Check the Host Adapter. If unsuccessful, abort further initialization.
2717 if (!BusLogic_CheckHostAdapter(HostAdapter)) continue;
2719 Initialize the Driver Options field if provided.
2721 if (DriverOptionsIndex < BusLogic_DriverOptionsCount)
2722 HostAdapter->DriverOptions =
2723 &BusLogic_DriverOptions[DriverOptionsIndex++];
2725 Announce the Driver Version and Date, Author's Name, Copyright Notice,
2726 and Electronic Mail Address.
2728 BusLogic_AnnounceDriver(HostAdapter);
2730 Register usage of the I/O Address range. From this point onward, any
2731 failure will be assumed to be due to a problem with the Host Adapter,
2732 rather than due to having mistakenly identified this port as belonging
2733 to a BusLogic Host Adapter. The I/O Address range will not be
2734 released, thereby preventing it from being incorrectly identified as
2735 any other type of Host Adapter.
2737 if (!request_region(HostAdapter->IO_Address, HostAdapter->AddressCount,
2738 "BusLogic")) continue;
2740 Register the SCSI Host structure.
2743 Host = scsi_host_alloc(HostTemplate, sizeof(struct BusLogic_HostAdapter));
2746 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2749 HostAdapter = (struct BusLogic_HostAdapter *) Host->hostdata;
2750 memcpy(HostAdapter, PrototypeHostAdapter, sizeof(struct BusLogic_HostAdapter));
2751 HostAdapter->SCSI_Host = Host;
2752 HostAdapter->HostNumber = Host->host_no;
2754 Add Host Adapter to the end of the list of registered BusLogic
2757 BusLogic_RegisterHostAdapter(HostAdapter);
2759 Read the Host Adapter Configuration, Configure the Host Adapter,
2760 Acquire the System Resources necessary to use the Host Adapter, then
2761 Create the Initial CCBs, Initialize the Host Adapter, and finally
2762 perform Target Device Inquiry.
2764 if (BusLogic_ReadHostAdapterConfiguration(HostAdapter) &&
2765 BusLogic_ReportHostAdapterConfiguration(HostAdapter) &&
2766 BusLogic_AcquireResources(HostAdapter) &&
2767 BusLogic_CreateInitialCCBs(HostAdapter) &&
2768 BusLogic_InitializeHostAdapter(HostAdapter) &&
2769 BusLogic_TargetDeviceInquiry(HostAdapter))
2772 Initialization has been completed successfully. Release and
2773 re-register usage of the I/O Address range so that the Model
2774 Name of the Host Adapter will appear, and initialize the SCSI
2777 release_region(HostAdapter->IO_Address,
2778 HostAdapter->AddressCount);
2779 if(!request_region(HostAdapter->IO_Address,
2780 HostAdapter->AddressCount,
2781 HostAdapter->FullModelName)) {
2782 printk(KERN_WARNING "BusLogic: Release and re-register of "
2783 "port 0x%04lx failed \n",
2784 (unsigned long)HostAdapter->IO_Address);
2785 BusLogic_DestroyCCBs(HostAdapter);
2786 BusLogic_ReleaseResources(HostAdapter);
2787 BusLogic_UnregisterHostAdapter(HostAdapter);
2788 scsi_host_put(Host);
2791 BusLogic_InitializeHostStructure(HostAdapter, Host);
2792 scsi_add_host(Host, NULL);
2793 scsi_scan_host(Host);
2794 BusLogicHostAdapterCount++;
2800 An error occurred during Host Adapter Configuration Querying, Host
2801 Adapter Configuration, Resource Acquisition, CCB Creation, Host
2802 Adapter Initialization, or Target Device Inquiry, so remove Host
2803 Adapter from the list of registered BusLogic Host Adapters, destroy
2804 the CCBs, Release the System Resources, and Unregister the SCSI
2807 BusLogic_DestroyCCBs(HostAdapter);
2808 BusLogic_ReleaseResources(HostAdapter);
2809 BusLogic_UnregisterHostAdapter(HostAdapter);
2810 scsi_host_put(Host);
2813 kfree(PrototypeHostAdapter);
2814 kfree(BusLogic_ProbeInfoList);
2815 BusLogic_ProbeInfoList = NULL;
2816 return BusLogicHostAdapterCount;
2821 BusLogic_ReleaseHostAdapter releases all resources previously acquired to
2822 support a specific Host Adapter, including the I/O Address range, and
2823 unregisters the BusLogic Host Adapter.
2826 static int __exit BusLogic_ReleaseHostAdapter(struct Scsi_Host *Host)
2828 struct BusLogic_HostAdapter *HostAdapter =
2829 (struct BusLogic_HostAdapter *) Host->hostdata;
2831 FlashPoint Host Adapters must first be released by the FlashPoint
2834 if (BusLogic_FlashPointHostAdapterP(HostAdapter))
2835 FlashPoint_ReleaseHostAdapter(HostAdapter->CardHandle);
2837 Destroy the CCBs and release any system resources acquired to
2838 support Host Adapter.
2840 BusLogic_DestroyCCBs(HostAdapter);
2841 BusLogic_ReleaseResources(HostAdapter);
2843 Release usage of the I/O Address range.
2845 release_region(HostAdapter->IO_Address, HostAdapter->AddressCount);
2847 Remove Host Adapter from the list of registered BusLogic Host Adapters.
2849 BusLogic_UnregisterHostAdapter(HostAdapter);
2855 BusLogic_QueueCompletedCCB queues CCB for completion processing.
2858 static void BusLogic_QueueCompletedCCB(struct BusLogic_CCB *CCB)
2860 struct BusLogic_HostAdapter *HostAdapter = CCB->HostAdapter;
2861 CCB->Status = BusLogic_CCB_Completed;
2863 if (HostAdapter->FirstCompletedCCB == NULL)
2865 HostAdapter->FirstCompletedCCB = CCB;
2866 HostAdapter->LastCompletedCCB = CCB;
2870 HostAdapter->LastCompletedCCB->Next = CCB;
2871 HostAdapter->LastCompletedCCB = CCB;
2873 HostAdapter->ActiveCommands[CCB->TargetID]--;
2878 BusLogic_ComputeResultCode computes a SCSI Subsystem Result Code from
2879 the Host Adapter Status and Target Device Status.
2882 static int BusLogic_ComputeResultCode(struct BusLogic_HostAdapter *HostAdapter,
2883 enum BusLogic_HostAdapterStatus
2885 enum BusLogic_TargetDeviceStatus
2889 switch (HostAdapterStatus)
2891 case BusLogic_CommandCompletedNormally:
2892 case BusLogic_LinkedCommandCompleted:
2893 case BusLogic_LinkedCommandCompletedWithFlag:
2894 HostStatus = DID_OK;
2896 case BusLogic_SCSISelectionTimeout:
2897 HostStatus = DID_TIME_OUT;
2899 case BusLogic_InvalidOutgoingMailboxActionCode:
2900 case BusLogic_InvalidCommandOperationCode:
2901 case BusLogic_InvalidCommandParameter:
2902 BusLogic_Warning("BusLogic Driver Protocol Error 0x%02X\n",
2903 HostAdapter, HostAdapterStatus);
2904 case BusLogic_DataUnderRun:
2905 case BusLogic_DataOverRun:
2906 case BusLogic_UnexpectedBusFree:
2907 case BusLogic_LinkedCCBhasInvalidLUN:
2908 case BusLogic_AutoRequestSenseFailed:
2909 case BusLogic_TaggedQueuingMessageRejected:
2910 case BusLogic_UnsupportedMessageReceived:
2911 case BusLogic_HostAdapterHardwareFailed:
2912 case BusLogic_TargetDeviceReconnectedImproperly:
2913 case BusLogic_AbortQueueGenerated:
2914 case BusLogic_HostAdapterSoftwareError:
2915 case BusLogic_HostAdapterHardwareTimeoutError:
2916 case BusLogic_SCSIParityErrorDetected:
2917 HostStatus = DID_ERROR;
2919 case BusLogic_InvalidBusPhaseRequested:
2920 case BusLogic_TargetFailedResponseToATN:
2921 case BusLogic_HostAdapterAssertedRST:
2922 case BusLogic_OtherDeviceAssertedRST:
2923 case BusLogic_HostAdapterAssertedBusDeviceReset:
2924 HostStatus = DID_RESET;
2927 BusLogic_Warning("Unknown Host Adapter Status 0x%02X\n",
2928 HostAdapter, HostAdapterStatus);
2929 HostStatus = DID_ERROR;
2932 return (HostStatus << 16) | TargetDeviceStatus;
2937 BusLogic_ScanIncomingMailboxes scans the Incoming Mailboxes saving any
2938 Incoming Mailbox entries for completion processing.
2941 static void BusLogic_ScanIncomingMailboxes(struct BusLogic_HostAdapter *HostAdapter)
2944 Scan through the Incoming Mailboxes in Strict Round Robin fashion, saving
2945 any completed CCBs for further processing. It is essential that for each
2946 CCB and SCSI Command issued, command completion processing is performed
2947 exactly once. Therefore, only Incoming Mailboxes with completion code
2948 Command Completed Without Error, Command Completed With Error, or Command
2949 Aborted At Host Request are saved for completion processing. When an
2950 Incoming Mailbox has a completion code of Aborted Command Not Found, the
2951 CCB had already completed or been aborted before the current Abort request
2952 was processed, and so completion processing has already occurred and no
2953 further action should be taken.
2955 struct BusLogic_IncomingMailbox *NextIncomingMailbox =
2956 HostAdapter->NextIncomingMailbox;
2957 enum BusLogic_CompletionCode CompletionCode;
2958 while ((CompletionCode = NextIncomingMailbox->CompletionCode) !=
2959 BusLogic_IncomingMailboxFree)
2962 We are only allowed to do this because we limit our architectures we
2963 run on to machines where bus_to_virt() actually works. There *needs*
2964 to be a dma_addr_to_virt() in the new PCI DMA mapping interface to
2965 replace bus_to_virt() or else this code is going to become very
2968 struct BusLogic_CCB *CCB = (struct BusLogic_CCB *)
2969 Bus_to_Virtual(NextIncomingMailbox->CCB);
2970 if (CompletionCode != BusLogic_AbortedCommandNotFound)
2972 if (CCB->Status == BusLogic_CCB_Active ||
2973 CCB->Status == BusLogic_CCB_Reset)
2976 Save the Completion Code for this CCB and queue the CCB
2977 for completion processing.
2979 CCB->CompletionCode = CompletionCode;
2980 BusLogic_QueueCompletedCCB(CCB);
2985 If a CCB ever appears in an Incoming Mailbox and is not marked
2986 as status Active or Reset, then there is most likely a bug in
2987 the Host Adapter firmware.
2989 BusLogic_Warning("Illegal CCB #%ld status %d in "
2990 "Incoming Mailbox\n", HostAdapter,
2991 CCB->SerialNumber, CCB->Status);
2994 NextIncomingMailbox->CompletionCode = BusLogic_IncomingMailboxFree;
2995 if (++NextIncomingMailbox > HostAdapter->LastIncomingMailbox)
2996 NextIncomingMailbox = HostAdapter->FirstIncomingMailbox;
2998 HostAdapter->NextIncomingMailbox = NextIncomingMailbox;
3003 BusLogic_ProcessCompletedCCBs iterates over the completed CCBs for Host
3004 Adapter setting the SCSI Command Result Codes, deallocating the CCBs, and
3005 calling the SCSI Subsystem Completion Routines. The Host Adapter's Lock
3006 should already have been acquired by the caller.
3009 static void BusLogic_ProcessCompletedCCBs(struct BusLogic_HostAdapter *HostAdapter)
3011 if (HostAdapter->ProcessCompletedCCBsActive) return;
3012 HostAdapter->ProcessCompletedCCBsActive = true;
3013 while (HostAdapter->FirstCompletedCCB != NULL)
3015 struct BusLogic_CCB *CCB = HostAdapter->FirstCompletedCCB;
3016 struct scsi_cmnd *Command = CCB->Command;
3017 HostAdapter->FirstCompletedCCB = CCB->Next;
3018 if (HostAdapter->FirstCompletedCCB == NULL)
3019 HostAdapter->LastCompletedCCB = NULL;
3021 Process the Completed CCB.
3023 if (CCB->Opcode == BusLogic_BusDeviceReset)
3025 int TargetID = CCB->TargetID;
3026 BusLogic_Warning("Bus Device Reset CCB #%ld to Target "
3027 "%d Completed\n", HostAdapter,
3028 CCB->SerialNumber, TargetID);
3029 BusLogic_IncrementErrorCounter(
3030 &HostAdapter->TargetStatistics[TargetID].BusDeviceResetsCompleted);
3031 HostAdapter->TargetFlags[TargetID].TaggedQueuingActive = false;
3032 HostAdapter->CommandsSinceReset[TargetID] = 0;
3033 HostAdapter->LastResetCompleted[TargetID] = jiffies;
3035 Place CCB back on the Host Adapter's free list.
3037 BusLogic_DeallocateCCB(CCB);
3038 #if 0 /* this needs to be redone different for new EH */
3040 Bus Device Reset CCBs have the Command field non-NULL only when a
3041 Bus Device Reset was requested for a Command that did not have a
3042 currently active CCB in the Host Adapter (i.e., a Synchronous
3043 Bus Device Reset), and hence would not have its Completion Routine
3046 while (Command != NULL)
3048 struct scsi_cmnd *NextCommand = Command->reset_chain;
3049 Command->reset_chain = NULL;
3050 Command->result = DID_RESET << 16;
3051 Command->scsi_done(Command);
3052 Command = NextCommand;
3056 Iterate over the CCBs for this Host Adapter performing completion
3057 processing for any CCBs marked as Reset for this Target.
3059 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3060 if (CCB->Status == BusLogic_CCB_Reset && CCB->TargetID == TargetID)
3062 Command = CCB->Command;
3063 BusLogic_DeallocateCCB(CCB);
3064 HostAdapter->ActiveCommands[TargetID]--;
3065 Command->result = DID_RESET << 16;
3066 Command->scsi_done(Command);
3068 HostAdapter->BusDeviceResetPendingCCB[TargetID] = NULL;
3073 Translate the Completion Code, Host Adapter Status, and Target
3074 Device Status into a SCSI Subsystem Result Code.
3076 switch (CCB->CompletionCode)
3078 case BusLogic_IncomingMailboxFree:
3079 case BusLogic_AbortedCommandNotFound:
3080 case BusLogic_InvalidCCB:
3081 BusLogic_Warning("CCB #%ld to Target %d Impossible State\n",
3082 HostAdapter, CCB->SerialNumber, CCB->TargetID);
3084 case BusLogic_CommandCompletedWithoutError:
3085 HostAdapter->TargetStatistics[CCB->TargetID]
3086 .CommandsCompleted++;
3087 HostAdapter->TargetFlags[CCB->TargetID]
3088 .CommandSuccessfulFlag = true;
3089 Command->result = DID_OK << 16;
3091 case BusLogic_CommandAbortedAtHostRequest:
3092 BusLogic_Warning("CCB #%ld to Target %d Aborted\n",
3093 HostAdapter, CCB->SerialNumber, CCB->TargetID);
3094 BusLogic_IncrementErrorCounter(
3095 &HostAdapter->TargetStatistics[CCB->TargetID]
3096 .CommandAbortsCompleted);
3097 Command->result = DID_ABORT << 16;
3099 case BusLogic_CommandCompletedWithError:
3101 BusLogic_ComputeResultCode(HostAdapter,
3102 CCB->HostAdapterStatus,
3103 CCB->TargetDeviceStatus);
3104 if (CCB->HostAdapterStatus != BusLogic_SCSISelectionTimeout)
3106 HostAdapter->TargetStatistics[CCB->TargetID]
3107 .CommandsCompleted++;
3108 if (BusLogic_GlobalOptions.TraceErrors)
3111 BusLogic_Notice("CCB #%ld Target %d: Result %X Host "
3112 "Adapter Status %02X "
3113 "Target Status %02X\n",
3114 HostAdapter, CCB->SerialNumber,
3115 CCB->TargetID, Command->result,
3116 CCB->HostAdapterStatus,
3117 CCB->TargetDeviceStatus);
3118 BusLogic_Notice("CDB ", HostAdapter);
3119 for (i = 0; i < CCB->CDB_Length; i++)
3120 BusLogic_Notice(" %02X", HostAdapter, CCB->CDB[i]);
3121 BusLogic_Notice("\n", HostAdapter);
3122 BusLogic_Notice("Sense ", HostAdapter);
3123 for (i = 0; i < CCB->SenseDataLength; i++)
3124 BusLogic_Notice(" %02X", HostAdapter,
3125 Command->sense_buffer[i]);
3126 BusLogic_Notice("\n", HostAdapter);
3132 When an INQUIRY command completes normally, save the
3133 CmdQue (Tagged Queuing Supported) and WBus16 (16 Bit
3134 Wide Data Transfers Supported) bits.
3136 if (CCB->CDB[0] == INQUIRY && CCB->CDB[1] == 0 &&
3137 CCB->HostAdapterStatus == BusLogic_CommandCompletedNormally)
3139 struct BusLogic_TargetFlags *TargetFlags =
3140 &HostAdapter->TargetFlags[CCB->TargetID];
3141 struct SCSI_Inquiry *InquiryResult =
3142 (struct SCSI_Inquiry *) Command->request_buffer;
3143 TargetFlags->TargetExists = true;
3144 TargetFlags->TaggedQueuingSupported = InquiryResult->CmdQue;
3145 TargetFlags->WideTransfersSupported = InquiryResult->WBus16;
3148 Place CCB back on the Host Adapter's free list.
3150 BusLogic_DeallocateCCB(CCB);
3152 Call the SCSI Command Completion Routine.
3154 Command->scsi_done(Command);
3157 HostAdapter->ProcessCompletedCCBsActive = false;
3162 BusLogic_InterruptHandler handles hardware interrupts from BusLogic Host
3166 static irqreturn_t BusLogic_InterruptHandler(int IRQ_Channel,
3167 void *DeviceIdentifier,
3168 struct pt_regs *InterruptRegisters)
3170 struct BusLogic_HostAdapter *HostAdapter =
3171 (struct BusLogic_HostAdapter *) DeviceIdentifier;
3172 unsigned long ProcessorFlags;
3174 Acquire exclusive access to Host Adapter.
3176 BusLogic_AcquireHostAdapterLockIH(HostAdapter, &ProcessorFlags);
3178 Handle Interrupts appropriately for each Host Adapter type.
3180 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3182 union BusLogic_InterruptRegister InterruptRegister;
3184 Read the Host Adapter Interrupt Register.
3186 InterruptRegister.All = BusLogic_ReadInterruptRegister(HostAdapter);
3187 if (InterruptRegister.ir.InterruptValid)
3190 Acknowledge the interrupt and reset the Host Adapter
3193 BusLogic_InterruptReset(HostAdapter);
3195 Process valid External SCSI Bus Reset and Incoming Mailbox
3196 Loaded Interrupts. Command Complete Interrupts are noted,
3197 and Outgoing Mailbox Available Interrupts are ignored, as
3198 they are never enabled.
3200 if (InterruptRegister.ir.ExternalBusReset)
3201 HostAdapter->HostAdapterExternalReset = true;
3202 else if (InterruptRegister.ir.IncomingMailboxLoaded)
3203 BusLogic_ScanIncomingMailboxes(HostAdapter);
3204 else if (InterruptRegister.ir.CommandComplete)
3205 HostAdapter->HostAdapterCommandCompleted = true;
3211 Check if there is a pending interrupt for this Host Adapter.
3213 if (FlashPoint_InterruptPending(HostAdapter->CardHandle))
3214 switch (FlashPoint_HandleInterrupt(HostAdapter->CardHandle))
3216 case FlashPoint_NormalInterrupt:
3218 case FlashPoint_ExternalBusReset:
3219 HostAdapter->HostAdapterExternalReset = true;
3221 case FlashPoint_InternalError:
3222 BusLogic_Warning("Internal FlashPoint Error detected"
3223 " - Resetting Host Adapter\n", HostAdapter);
3224 HostAdapter->HostAdapterInternalError = true;
3229 Process any completed CCBs.
3231 if (HostAdapter->FirstCompletedCCB != NULL)
3232 BusLogic_ProcessCompletedCCBs(HostAdapter);
3234 Reset the Host Adapter if requested.
3236 if (HostAdapter->HostAdapterExternalReset)
3238 BusLogic_Warning("Resetting %s due to External SCSI Bus Reset\n",
3239 HostAdapter, HostAdapter->FullModelName);
3240 BusLogic_IncrementErrorCounter(&HostAdapter->ExternalHostAdapterResets);
3241 BusLogic_ResetHostAdapter(HostAdapter, false);
3242 HostAdapter->HostAdapterExternalReset = false;
3244 else if (HostAdapter->HostAdapterInternalError)
3246 BusLogic_Warning("Resetting %s due to Host Adapter Internal Error\n",
3247 HostAdapter, HostAdapter->FullModelName);
3248 BusLogic_IncrementErrorCounter(&HostAdapter->HostAdapterInternalErrors);
3249 BusLogic_ResetHostAdapter(HostAdapter, true);
3250 HostAdapter->HostAdapterInternalError = false;
3253 Release exclusive access to Host Adapter.
3255 BusLogic_ReleaseHostAdapterLockIH(HostAdapter, &ProcessorFlags);
3261 BusLogic_WriteOutgoingMailbox places CCB and Action Code into an Outgoing
3262 Mailbox for execution by Host Adapter. The Host Adapter's Lock should
3263 already have been acquired by the caller.
3266 static boolean BusLogic_WriteOutgoingMailbox(struct BusLogic_HostAdapter
3268 enum BusLogic_ActionCode ActionCode,
3269 struct BusLogic_CCB *CCB)
3271 struct BusLogic_OutgoingMailbox *NextOutgoingMailbox;
3272 NextOutgoingMailbox = HostAdapter->NextOutgoingMailbox;
3273 if (NextOutgoingMailbox->ActionCode == BusLogic_OutgoingMailboxFree)
3275 CCB->Status = BusLogic_CCB_Active;
3277 The CCB field must be written before the Action Code field since
3278 the Host Adapter is operating asynchronously and the locking code
3279 does not protect against simultaneous access by the Host Adapter.
3281 NextOutgoingMailbox->CCB = CCB->DMA_Handle;
3282 NextOutgoingMailbox->ActionCode = ActionCode;
3283 BusLogic_StartMailboxCommand(HostAdapter);
3284 if (++NextOutgoingMailbox > HostAdapter->LastOutgoingMailbox)
3285 NextOutgoingMailbox = HostAdapter->FirstOutgoingMailbox;
3286 HostAdapter->NextOutgoingMailbox = NextOutgoingMailbox;
3287 if (ActionCode == BusLogic_MailboxStartCommand)
3289 HostAdapter->ActiveCommands[CCB->TargetID]++;
3290 if (CCB->Opcode != BusLogic_BusDeviceReset)
3291 HostAdapter->TargetStatistics[CCB->TargetID].CommandsAttempted++;
3298 /* Error Handling (EH) support */
3300 static int BusLogic_host_reset(Scsi_Cmnd *SCpnt)
3302 struct BusLogic_HostAdapter *HostAdapter =
3303 (struct BusLogic_HostAdapter *) SCpnt->device->host->hostdata;
3305 unsigned int id = SCpnt->device->id;
3306 struct BusLogic_TargetStatistics *stats = &HostAdapter->TargetStatistics[id];
3307 BusLogic_IncrementErrorCounter(&stats->HostAdapterResetsRequested);
3309 return BusLogic_ResetHostAdapter(HostAdapter, false);
3313 BusLogic_QueueCommand creates a CCB for Command and places it into an
3314 Outgoing Mailbox for execution by the associated Host Adapter.
3317 static int BusLogic_QueueCommand(struct scsi_cmnd *Command,
3318 void (*CompletionRoutine)(struct scsi_cmnd *))
3320 struct BusLogic_HostAdapter *HostAdapter =
3321 (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
3322 struct BusLogic_TargetFlags *TargetFlags =
3323 &HostAdapter->TargetFlags[Command->device->id];
3324 struct BusLogic_TargetStatistics *TargetStatistics =
3325 HostAdapter->TargetStatistics;
3326 unsigned char *CDB = Command->cmnd;
3327 int CDB_Length = Command->cmd_len;
3328 int TargetID = Command->device->id;
3329 int LogicalUnit = Command->device->lun;
3330 void *BufferPointer = Command->request_buffer;
3331 int BufferLength = Command->request_bufflen;
3332 int SegmentCount = Command->use_sg;
3333 struct BusLogic_CCB *CCB;
3335 SCSI REQUEST_SENSE commands will be executed automatically by the Host
3336 Adapter for any errors, so they should not be executed explicitly unless
3337 the Sense Data is zero indicating that no error occurred.
3339 if (CDB[0] == REQUEST_SENSE && Command->sense_buffer[0] != 0)
3341 Command->result = DID_OK << 16;
3342 CompletionRoutine(Command);
3346 Allocate a CCB from the Host Adapter's free list. In the unlikely event
3347 that there are none available and memory allocation fails, wait 1 second
3348 and try again. If that fails, the Host Adapter is probably hung so signal
3349 an error as a Host Adapter Hard Reset should be initiated soon.
3351 CCB = BusLogic_AllocateCCB(HostAdapter);
3354 BusLogic_ReleaseHostAdapterLock(HostAdapter);
3356 BusLogic_AcquireHostAdapterLock(HostAdapter);
3357 CCB = BusLogic_AllocateCCB(HostAdapter);
3360 Command->result = DID_ERROR << 16;
3361 CompletionRoutine(Command);
3366 Initialize the fields in the BusLogic Command Control Block (CCB).
3368 if (SegmentCount == 0 && BufferLength != 0)
3370 CCB->Opcode = BusLogic_InitiatorCCB;
3371 CCB->DataLength = BufferLength;
3373 pci_map_single(HostAdapter->PCI_Device, BufferPointer, BufferLength,
3374 scsi_to_pci_dma_dir(Command->sc_data_direction));
3376 else if (SegmentCount != 0)
3378 struct scatterlist *ScatterList = (struct scatterlist *) BufferPointer;
3381 Count = pci_map_sg(HostAdapter->PCI_Device, ScatterList, SegmentCount,
3382 scsi_to_pci_dma_dir(Command->sc_data_direction));
3383 CCB->Opcode = BusLogic_InitiatorCCB_ScatterGather;
3384 CCB->DataLength = Count * sizeof(struct BusLogic_ScatterGatherSegment);
3385 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3386 CCB->DataPointer = (unsigned int)CCB->DMA_Handle +
3387 ((unsigned long)&CCB->ScatterGatherList -
3388 (unsigned long)CCB);
3389 else CCB->DataPointer = Virtual_to_32Bit_Virtual(CCB->ScatterGatherList);
3390 for (Segment = 0; Segment < Count; Segment++)
3392 CCB->ScatterGatherList[Segment].SegmentByteCount =
3393 sg_dma_len(ScatterList+Segment);
3394 CCB->ScatterGatherList[Segment].SegmentDataPointer =
3395 sg_dma_address(ScatterList+Segment);
3400 CCB->Opcode = BusLogic_InitiatorCCB;
3401 CCB->DataLength = BufferLength;
3402 CCB->DataPointer = 0;
3408 CCB->DataDirection = BusLogic_DataInLengthChecked;
3409 TargetStatistics[TargetID].ReadCommands++;
3410 BusLogic_IncrementByteCounter(
3411 &TargetStatistics[TargetID].TotalBytesRead, BufferLength);
3412 BusLogic_IncrementSizeBucket(
3413 TargetStatistics[TargetID].ReadCommandSizeBuckets, BufferLength);
3417 CCB->DataDirection = BusLogic_DataOutLengthChecked;
3418 TargetStatistics[TargetID].WriteCommands++;
3419 BusLogic_IncrementByteCounter(
3420 &TargetStatistics[TargetID].TotalBytesWritten, BufferLength);
3421 BusLogic_IncrementSizeBucket(
3422 TargetStatistics[TargetID].WriteCommandSizeBuckets, BufferLength);
3425 CCB->DataDirection = BusLogic_UncheckedDataTransfer;
3428 CCB->CDB_Length = CDB_Length;
3429 CCB->HostAdapterStatus = 0;
3430 CCB->TargetDeviceStatus = 0;
3431 CCB->TargetID = TargetID;
3432 CCB->LogicalUnit = LogicalUnit;
3433 CCB->TagEnable = false;
3434 CCB->LegacyTagEnable = false;
3436 BusLogic recommends that after a Reset the first couple of commands that
3437 are sent to a Target Device be sent in a non Tagged Queue fashion so that
3438 the Host Adapter and Target Device can establish Synchronous and Wide
3439 Transfer before Queue Tag messages can interfere with the Synchronous and
3440 Wide Negotiation messages. By waiting to enable Tagged Queuing until after
3441 the first BusLogic_MaxTaggedQueueDepth commands have been queued, it is
3442 assured that after a Reset any pending commands are requeued before Tagged
3443 Queuing is enabled and that the Tagged Queuing message will not occur while
3444 the partition table is being printed. In addition, some devices do not
3445 properly handle the transition from non-tagged to tagged commands, so it is
3446 necessary to wait until there are no pending commands for a target device
3447 before queuing tagged commands.
3449 if (HostAdapter->CommandsSinceReset[TargetID]++ >=
3450 BusLogic_MaxTaggedQueueDepth &&
3451 !TargetFlags->TaggedQueuingActive &&
3452 HostAdapter->ActiveCommands[TargetID] == 0 &&
3453 TargetFlags->TaggedQueuingSupported &&
3454 (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)))
3456 TargetFlags->TaggedQueuingActive = true;
3457 BusLogic_Notice("Tagged Queuing now active for Target %d\n",
3458 HostAdapter, TargetID);
3460 if (TargetFlags->TaggedQueuingActive)
3462 enum BusLogic_QueueTag QueueTag = BusLogic_SimpleQueueTag;
3464 When using Tagged Queuing with Simple Queue Tags, it appears that disk
3465 drive controllers do not guarantee that a queued command will not
3466 remain in a disconnected state indefinitely if commands that read or
3467 write nearer the head position continue to arrive without interruption.
3468 Therefore, for each Target Device this driver keeps track of the last
3469 time either the queue was empty or an Ordered Queue Tag was issued. If
3470 more than 4 seconds (one fifth of the 20 second disk timeout) have
3471 elapsed since this last sequence point, this command will be issued
3472 with an Ordered Queue Tag rather than a Simple Queue Tag, which forces
3473 the Target Device to complete all previously queued commands before
3474 this command may be executed.
3476 if (HostAdapter->ActiveCommands[TargetID] == 0)
3477 HostAdapter->LastSequencePoint[TargetID] = jiffies;
3478 else if (jiffies - HostAdapter->LastSequencePoint[TargetID] > 4*HZ)
3480 HostAdapter->LastSequencePoint[TargetID] = jiffies;
3481 QueueTag = BusLogic_OrderedQueueTag;
3483 if (HostAdapter->ExtendedLUNSupport)
3485 CCB->TagEnable = true;
3486 CCB->QueueTag = QueueTag;
3490 CCB->LegacyTagEnable = true;
3491 CCB->LegacyQueueTag = QueueTag;
3494 memcpy(CCB->CDB, CDB, CDB_Length);
3495 CCB->SenseDataLength = sizeof(Command->sense_buffer);
3496 CCB->SenseDataPointer = pci_map_single(HostAdapter->PCI_Device,
3497 Command->sense_buffer,
3498 CCB->SenseDataLength,
3499 PCI_DMA_FROMDEVICE);
3500 CCB->Command = Command;
3501 Command->scsi_done = CompletionRoutine;
3502 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3505 Place the CCB in an Outgoing Mailbox. The higher levels of the SCSI
3506 Subsystem should not attempt to queue more commands than can be placed
3507 in Outgoing Mailboxes, so there should always be one free. In the
3508 unlikely event that there are none available, wait 1 second and try
3509 again. If that fails, the Host Adapter is probably hung so signal an
3510 error as a Host Adapter Hard Reset should be initiated soon.
3512 if (!BusLogic_WriteOutgoingMailbox(
3513 HostAdapter, BusLogic_MailboxStartCommand, CCB))
3515 BusLogic_ReleaseHostAdapterLock(HostAdapter);
3516 BusLogic_Warning("Unable to write Outgoing Mailbox - "
3517 "Pausing for 1 second\n", HostAdapter);
3519 BusLogic_AcquireHostAdapterLock(HostAdapter);
3520 if (!BusLogic_WriteOutgoingMailbox(
3521 HostAdapter, BusLogic_MailboxStartCommand, CCB))
3523 BusLogic_Warning("Still unable to write Outgoing Mailbox - "
3524 "Host Adapter Dead?\n", HostAdapter);
3525 BusLogic_DeallocateCCB(CCB);
3526 Command->result = DID_ERROR << 16;
3527 Command->scsi_done(Command);
3534 Call the FlashPoint SCCB Manager to start execution of the CCB.
3536 CCB->Status = BusLogic_CCB_Active;
3537 HostAdapter->ActiveCommands[TargetID]++;
3538 TargetStatistics[TargetID].CommandsAttempted++;
3539 FlashPoint_StartCCB(HostAdapter->CardHandle, CCB);
3541 The Command may have already completed and BusLogic_QueueCompletedCCB
3542 been called, or it may still be pending.
3544 if (CCB->Status == BusLogic_CCB_Completed)
3545 BusLogic_ProcessCompletedCCBs(HostAdapter);
3552 BusLogic_AbortCommand aborts Command if possible.
3555 static int BusLogic_AbortCommand(struct scsi_cmnd *Command)
3557 struct BusLogic_HostAdapter *HostAdapter =
3558 (struct BusLogic_HostAdapter *) Command->device->host->hostdata;
3560 int TargetID = Command->device->id;
3561 struct BusLogic_CCB *CCB;
3562 BusLogic_IncrementErrorCounter(
3563 &HostAdapter->TargetStatistics[TargetID].CommandAbortsRequested);
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);
3574 Attempt to find an Active CCB for this Command. If no Active CCB for this
3575 Command is found, then no Abort is necessary.
3577 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3578 if (CCB->Command == Command) break;
3581 BusLogic_Warning("Unable to Abort Command to Target %d - "
3582 "No CCB Found\n", HostAdapter, TargetID);
3585 else if (CCB->Status == BusLogic_CCB_Completed)
3587 BusLogic_Warning("Unable to Abort Command to Target %d - "
3588 "CCB Completed\n", HostAdapter, TargetID);
3591 else if (CCB->Status == BusLogic_CCB_Reset)
3593 BusLogic_Warning("Unable to Abort Command to Target %d - "
3594 "CCB Reset\n", HostAdapter, TargetID);
3597 if (BusLogic_MultiMasterHostAdapterP(HostAdapter))
3600 Attempt to Abort this CCB. MultiMaster Firmware versions prior to 5.xx
3601 do not generate Abort Tag messages, but only generate the non-tagged
3602 Abort message. Since non-tagged commands are not sent by the Host
3603 Adapter until the queue of outstanding tagged commands has completed,
3604 and the Abort message is treated as a non-tagged command, it is
3605 effectively impossible to abort commands when Tagged Queuing is active.
3606 Firmware version 5.xx does generate Abort Tag messages, so it is
3607 possible to abort commands when Tagged Queuing is active.
3609 if (HostAdapter->TargetFlags[TargetID].TaggedQueuingActive &&
3610 HostAdapter->FirmwareVersion[0] < '5')
3612 BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
3613 "Abort Tag Not Supported\n",
3614 HostAdapter, CCB->SerialNumber, TargetID);
3617 else if (BusLogic_WriteOutgoingMailbox(
3618 HostAdapter, BusLogic_MailboxAbortCommand, CCB))
3620 BusLogic_Warning("Aborting CCB #%ld to Target %d\n",
3621 HostAdapter, CCB->SerialNumber, TargetID);
3622 BusLogic_IncrementErrorCounter(
3623 &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3628 BusLogic_Warning("Unable to Abort CCB #%ld to Target %d - "
3629 "No Outgoing Mailboxes\n",
3630 HostAdapter, CCB->SerialNumber, TargetID);
3637 Call the FlashPoint SCCB Manager to abort execution of the CCB.
3639 BusLogic_Warning("Aborting CCB #%ld to Target %d\n",
3640 HostAdapter, CCB->SerialNumber, TargetID);
3641 BusLogic_IncrementErrorCounter(
3642 &HostAdapter->TargetStatistics[TargetID].CommandAbortsAttempted);
3643 FlashPoint_AbortCCB(HostAdapter->CardHandle, CCB);
3645 The Abort may have already been completed and
3646 BusLogic_QueueCompletedCCB been called, or it
3647 may still be pending.
3649 if (CCB->Status == BusLogic_CCB_Completed)
3651 BusLogic_ProcessCompletedCCBs(HostAdapter);
3659 BusLogic_ResetHostAdapter resets Host Adapter if possible, marking all
3660 currently executing SCSI Commands as having been Reset.
3663 static int BusLogic_ResetHostAdapter(struct BusLogic_HostAdapter *HostAdapter,
3666 struct BusLogic_CCB *CCB;
3670 * Attempt to Reset and Reinitialize the Host Adapter.
3673 if (!(BusLogic_HardwareResetHostAdapter(HostAdapter, HardReset) &&
3674 BusLogic_InitializeHostAdapter(HostAdapter))) {
3675 BusLogic_Error("Resetting %s Failed\n", HostAdapter,
3676 HostAdapter->FullModelName);
3681 * Deallocate all currently executing CCBs.
3684 for (CCB = HostAdapter->All_CCBs; CCB != NULL; CCB = CCB->NextAll)
3685 if (CCB->Status == BusLogic_CCB_Active)
3686 BusLogic_DeallocateCCB(CCB);
3688 * Wait a few seconds between the Host Adapter Hard Reset which
3689 * initiates a SCSI Bus Reset and issuing any SCSI Commands. Some
3690 * SCSI devices get confused if they receive SCSI Commands too soon
3691 * after a SCSI Bus Reset.
3695 BusLogic_ReleaseHostAdapterLock(HostAdapter);
3696 BusLogic_Delay(HostAdapter->BusSettleTime);
3697 BusLogic_AcquireHostAdapterLock(HostAdapter);
3700 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++) {
3701 HostAdapter->LastResetAttempted[TargetID] = jiffies;
3702 HostAdapter->LastResetCompleted[TargetID] = jiffies;
3708 BusLogic_BIOSDiskParameters returns the Heads/Sectors/Cylinders BIOS Disk
3709 Parameters for Disk. The default disk geometry is 64 heads, 32 sectors, and
3710 the appropriate number of cylinders so as not to exceed drive capacity. In
3711 order for disks equal to or larger than 1 GB to be addressable by the BIOS
3712 without exceeding the BIOS limitation of 1024 cylinders, Extended Translation
3713 may be enabled in AutoSCSI on FlashPoint Host Adapters and on "W" and "C"
3714 series MultiMaster Host Adapters, or by a dip switch setting on "S" and "A"
3715 series MultiMaster Host Adapters. With Extended Translation enabled, drives
3716 between 1 GB inclusive and 2 GB exclusive are given a disk geometry of 128
3717 heads and 32 sectors, and drives above 2 GB inclusive are given a disk
3718 geometry of 255 heads and 63 sectors. However, if the BIOS detects that the
3719 Extended Translation setting does not match the geometry in the partition
3720 table, then the translation inferred from the partition table will be used by
3721 the BIOS, and a warning may be displayed.
3724 static int BusLogic_BIOSDiskParameters(struct scsi_device *sdev, struct block_device *Device,
3725 sector_t capacity, int *Parameters)
3727 struct BusLogic_HostAdapter *HostAdapter = (struct BusLogic_HostAdapter *) sdev->host->hostdata;
3728 struct BIOS_DiskParameters *DiskParameters = (struct BIOS_DiskParameters *) Parameters;
3730 if (HostAdapter->ExtendedTranslationEnabled &&
3731 capacity >= 2*1024*1024 /* 1 GB in 512 byte sectors */)
3733 if (capacity >= 4*1024*1024 /* 2 GB in 512 byte sectors */)
3735 DiskParameters->Heads = 255;
3736 DiskParameters->Sectors = 63;
3740 DiskParameters->Heads = 128;
3741 DiskParameters->Sectors = 32;
3746 DiskParameters->Heads = 64;
3747 DiskParameters->Sectors = 32;
3749 DiskParameters->Cylinders =
3750 (unsigned long)capacity / (DiskParameters->Heads * DiskParameters->Sectors);
3751 buf = scsi_bios_ptable(Device);
3752 if (buf == NULL) return 0;
3754 If the boot sector partition table flag is valid, search for a partition
3755 table entry whose end_head matches one of the standard BusLogic geometry
3756 translations (64/32, 128/32, or 255/63).
3758 if (*(unsigned short *) (buf+64) == 0xAA55)
3760 struct partition *FirstPartitionEntry = (struct partition *) buf;
3761 struct partition *PartitionEntry = FirstPartitionEntry;
3762 int SavedCylinders = DiskParameters->Cylinders, PartitionNumber;
3763 unsigned char PartitionEntryEndHead=0, PartitionEntryEndSector=0;
3764 for (PartitionNumber = 0; PartitionNumber < 4; PartitionNumber++)
3766 PartitionEntryEndHead = PartitionEntry->end_head;
3767 PartitionEntryEndSector = PartitionEntry->end_sector & 0x3F;
3768 if (PartitionEntryEndHead == 64-1)
3770 DiskParameters->Heads = 64;
3771 DiskParameters->Sectors = 32;
3774 else if (PartitionEntryEndHead == 128-1)
3776 DiskParameters->Heads = 128;
3777 DiskParameters->Sectors = 32;
3780 else if (PartitionEntryEndHead == 255-1)
3782 DiskParameters->Heads = 255;
3783 DiskParameters->Sectors = 63;
3788 if (PartitionNumber == 4)
3790 PartitionEntryEndHead = FirstPartitionEntry->end_head;
3791 PartitionEntryEndSector = FirstPartitionEntry->end_sector & 0x3F;
3793 DiskParameters->Cylinders =
3794 (unsigned long)capacity / (DiskParameters->Heads * DiskParameters->Sectors);
3795 if (PartitionNumber < 4 &&
3796 PartitionEntryEndSector == DiskParameters->Sectors)
3798 if (DiskParameters->Cylinders != SavedCylinders)
3799 BusLogic_Warning("Adopting Geometry %d/%d from Partition Table\n",
3801 DiskParameters->Heads, DiskParameters->Sectors);
3803 else if (PartitionEntryEndHead > 0 || PartitionEntryEndSector > 0)
3805 BusLogic_Warning("Warning: Partition Table appears to "
3806 "have Geometry %d/%d which is\n", HostAdapter,
3807 PartitionEntryEndHead + 1,
3808 PartitionEntryEndSector);
3809 BusLogic_Warning("not compatible with current BusLogic "
3810 "Host Adapter Geometry %d/%d\n", HostAdapter,
3811 DiskParameters->Heads, DiskParameters->Sectors);
3820 BugLogic_ProcDirectoryInfo implements /proc/scsi/BusLogic/<N>.
3823 static int BusLogic_ProcDirectoryInfo(struct Scsi_Host *shost, char *ProcBuffer,
3824 char **StartPointer, off_t Offset,
3825 int BytesAvailable, int WriteFlag)
3827 struct BusLogic_HostAdapter *HostAdapter;
3828 struct BusLogic_TargetStatistics *TargetStatistics;
3829 int TargetID, Length;
3831 for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
3832 HostAdapter != NULL;
3833 HostAdapter = HostAdapter->Next)
3834 if (HostAdapter->HostNumber == shost->host_no) break;
3835 if (HostAdapter == NULL)
3837 BusLogic_Error("Cannot find Host Adapter for SCSI Host %d\n",
3838 NULL, shost->host_no);
3841 TargetStatistics = HostAdapter->TargetStatistics;
3844 HostAdapter->ExternalHostAdapterResets = 0;
3845 HostAdapter->HostAdapterInternalErrors = 0;
3846 memset(TargetStatistics, 0,
3847 BusLogic_MaxTargetDevices * sizeof(struct BusLogic_TargetStatistics));
3850 Buffer = HostAdapter->MessageBuffer;
3851 Length = HostAdapter->MessageBufferLength;
3852 Length += sprintf(&Buffer[Length], "\n\
3853 Current Driver Queue Depth: %d\n\
3854 Currently Allocated CCBs: %d\n",
3855 HostAdapter->DriverQueueDepth,
3856 HostAdapter->AllocatedCCBs);
3857 Length += sprintf(&Buffer[Length], "\n\n\
3858 DATA TRANSFER STATISTICS\n\
3860 Target Tagged Queuing Queue Depth Active Attempted Completed\n\
3861 ====== ============== =========== ====== ========= =========\n");
3862 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
3864 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3865 if (!TargetFlags->TargetExists) continue;
3867 sprintf(&Buffer[Length], " %2d %s", TargetID,
3868 (TargetFlags->TaggedQueuingSupported
3869 ? (TargetFlags->TaggedQueuingActive
3871 : (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)
3872 ? " Permitted" : " Disabled"))
3873 : "Not Supported"));
3874 Length += sprintf(&Buffer[Length],
3875 " %3d %3u %9u %9u\n",
3876 HostAdapter->QueueDepth[TargetID],
3877 HostAdapter->ActiveCommands[TargetID],
3878 TargetStatistics[TargetID].CommandsAttempted,
3879 TargetStatistics[TargetID].CommandsCompleted);
3881 Length += sprintf(&Buffer[Length], "\n\
3882 Target Read Commands Write Commands Total Bytes Read Total Bytes Written\n\
3883 ====== ============= ============== =================== ===================\n");
3884 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
3886 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3887 if (!TargetFlags->TargetExists) continue;
3889 sprintf(&Buffer[Length], " %2d %9u %9u", TargetID,
3890 TargetStatistics[TargetID].ReadCommands,
3891 TargetStatistics[TargetID].WriteCommands);
3892 if (TargetStatistics[TargetID].TotalBytesRead.Billions > 0)
3894 sprintf(&Buffer[Length], " %9u%09u",
3895 TargetStatistics[TargetID].TotalBytesRead.Billions,
3896 TargetStatistics[TargetID].TotalBytesRead.Units);
3899 sprintf(&Buffer[Length], " %9u",
3900 TargetStatistics[TargetID].TotalBytesRead.Units);
3901 if (TargetStatistics[TargetID].TotalBytesWritten.Billions > 0)
3903 sprintf(&Buffer[Length], " %9u%09u\n",
3904 TargetStatistics[TargetID].TotalBytesWritten.Billions,
3905 TargetStatistics[TargetID].TotalBytesWritten.Units);
3908 sprintf(&Buffer[Length], " %9u\n",
3909 TargetStatistics[TargetID].TotalBytesWritten.Units);
3911 Length += sprintf(&Buffer[Length], "\n\
3912 Target Command 0-1KB 1-2KB 2-4KB 4-8KB 8-16KB\n\
3913 ====== ======= ========= ========= ========= ========= =========\n");
3914 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
3916 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3917 if (!TargetFlags->TargetExists) continue;
3919 sprintf(&Buffer[Length],
3920 " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
3921 TargetStatistics[TargetID].ReadCommandSizeBuckets[0],
3922 TargetStatistics[TargetID].ReadCommandSizeBuckets[1],
3923 TargetStatistics[TargetID].ReadCommandSizeBuckets[2],
3924 TargetStatistics[TargetID].ReadCommandSizeBuckets[3],
3925 TargetStatistics[TargetID].ReadCommandSizeBuckets[4]);
3927 sprintf(&Buffer[Length],
3928 " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
3929 TargetStatistics[TargetID].WriteCommandSizeBuckets[0],
3930 TargetStatistics[TargetID].WriteCommandSizeBuckets[1],
3931 TargetStatistics[TargetID].WriteCommandSizeBuckets[2],
3932 TargetStatistics[TargetID].WriteCommandSizeBuckets[3],
3933 TargetStatistics[TargetID].WriteCommandSizeBuckets[4]);
3935 Length += sprintf(&Buffer[Length], "\n\
3936 Target Command 16-32KB 32-64KB 64-128KB 128-256KB 256KB+\n\
3937 ====== ======= ========= ========= ========= ========= =========\n");
3938 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
3940 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3941 if (!TargetFlags->TargetExists) continue;
3943 sprintf(&Buffer[Length],
3944 " %2d Read %9u %9u %9u %9u %9u\n", TargetID,
3945 TargetStatistics[TargetID].ReadCommandSizeBuckets[5],
3946 TargetStatistics[TargetID].ReadCommandSizeBuckets[6],
3947 TargetStatistics[TargetID].ReadCommandSizeBuckets[7],
3948 TargetStatistics[TargetID].ReadCommandSizeBuckets[8],
3949 TargetStatistics[TargetID].ReadCommandSizeBuckets[9]);
3951 sprintf(&Buffer[Length],
3952 " %2d Write %9u %9u %9u %9u %9u\n", TargetID,
3953 TargetStatistics[TargetID].WriteCommandSizeBuckets[5],
3954 TargetStatistics[TargetID].WriteCommandSizeBuckets[6],
3955 TargetStatistics[TargetID].WriteCommandSizeBuckets[7],
3956 TargetStatistics[TargetID].WriteCommandSizeBuckets[8],
3957 TargetStatistics[TargetID].WriteCommandSizeBuckets[9]);
3959 Length += sprintf(&Buffer[Length], "\n\n\
3960 ERROR RECOVERY STATISTICS\n\
3962 Command Aborts Bus Device Resets Host Adapter Resets\n\
3963 Target Requested Completed Requested Completed Requested Completed\n\
3964 ID \\\\\\\\ Attempted //// \\\\\\\\ Attempted //// \\\\\\\\ Attempted ////\n\
3965 ====== ===== ===== ===== ===== ===== ===== ===== ===== =====\n");
3966 for (TargetID = 0; TargetID < HostAdapter->MaxTargetDevices; TargetID++)
3968 struct BusLogic_TargetFlags *TargetFlags = &HostAdapter->TargetFlags[TargetID];
3969 if (!TargetFlags->TargetExists) continue;
3971 sprintf(&Buffer[Length], "\
3972 %2d %5d %5d %5d %5d %5d %5d %5d %5d %5d\n", TargetID,
3973 TargetStatistics[TargetID].CommandAbortsRequested,
3974 TargetStatistics[TargetID].CommandAbortsAttempted,
3975 TargetStatistics[TargetID].CommandAbortsCompleted,
3976 TargetStatistics[TargetID].BusDeviceResetsRequested,
3977 TargetStatistics[TargetID].BusDeviceResetsAttempted,
3978 TargetStatistics[TargetID].BusDeviceResetsCompleted,
3979 TargetStatistics[TargetID].HostAdapterResetsRequested,
3980 TargetStatistics[TargetID].HostAdapterResetsAttempted,
3981 TargetStatistics[TargetID].HostAdapterResetsCompleted);
3983 Length += sprintf(&Buffer[Length], "\nExternal Host Adapter Resets: %d\n",
3984 HostAdapter->ExternalHostAdapterResets);
3985 Length += sprintf(&Buffer[Length], "Host Adapter Internal Errors: %d\n",
3986 HostAdapter->HostAdapterInternalErrors);
3987 if (Length >= BusLogic_MessageBufferSize)
3988 BusLogic_Error("Message Buffer length %d exceeds size %d\n",
3989 HostAdapter, Length, BusLogic_MessageBufferSize);
3990 if ((Length -= Offset) <= 0) return 0;
3991 if (Length >= BytesAvailable) Length = BytesAvailable;
3992 memcpy(ProcBuffer, HostAdapter->MessageBuffer + Offset, Length);
3993 *StartPointer = ProcBuffer;
3999 BusLogic_Message prints Driver Messages.
4002 static void BusLogic_Message(enum BusLogic_MessageLevel MessageLevel,
4004 struct BusLogic_HostAdapter *HostAdapter,
4007 static char Buffer[BusLogic_LineBufferSize];
4008 static boolean BeginningOfLine = true;
4011 va_start(Arguments, HostAdapter);
4012 Length = vsprintf(Buffer, Format, Arguments);
4014 if (MessageLevel == BusLogic_AnnounceLevel)
4016 static int AnnouncementLines = 0;
4017 strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength],
4019 HostAdapter->MessageBufferLength += Length;
4020 if (++AnnouncementLines <= 2)
4021 printk("%sscsi: %s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
4023 else if (MessageLevel == BusLogic_InfoLevel)
4025 strcpy(&HostAdapter->MessageBuffer[HostAdapter->MessageBufferLength],
4027 HostAdapter->MessageBufferLength += Length;
4028 if (BeginningOfLine)
4030 if (Buffer[0] != '\n' || Length > 1)
4031 printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
4032 HostAdapter->HostNumber, Buffer);
4034 else printk("%s", Buffer);
4038 if (BeginningOfLine)
4040 if (HostAdapter != NULL && HostAdapter->HostAdapterInitialized)
4041 printk("%sscsi%d: %s", BusLogic_MessageLevelMap[MessageLevel],
4042 HostAdapter->HostNumber, Buffer);
4043 else printk("%s%s", BusLogic_MessageLevelMap[MessageLevel], Buffer);
4045 else printk("%s", Buffer);
4047 BeginningOfLine = (Buffer[Length-1] == '\n');
4052 BusLogic_ParseKeyword parses an individual option keyword. It returns true
4053 and updates the pointer if the keyword is recognized and false otherwise.
4056 static boolean __init BusLogic_ParseKeyword(char **StringPointer, char *Keyword)
4058 char *Pointer = *StringPointer;
4059 while (*Keyword != '\0')
4061 char StringChar = *Pointer++;
4062 char KeywordChar = *Keyword++;
4063 if (StringChar >= 'A' && StringChar <= 'Z')
4064 StringChar += 'a' - 'Z';
4065 if (KeywordChar >= 'A' && KeywordChar <= 'Z')
4066 KeywordChar += 'a' - 'Z';
4067 if (StringChar != KeywordChar) return false;
4069 *StringPointer = Pointer;
4075 BusLogic_ParseDriverOptions handles processing of BusLogic Driver Options
4078 BusLogic Driver Options may be specified either via the Linux Kernel Command
4079 Line or via the Loadable Kernel Module Installation Facility. Driver Options
4080 for multiple host adapters may be specified either by separating the option
4081 strings by a semicolon, or by specifying multiple "BusLogic=" strings on the
4082 command line. Individual option specifications for a single host adapter are
4083 separated by commas. The Probing and Debugging Options apply to all host
4084 adapters whereas the remaining options apply individually only to the
4085 selected host adapter.
4087 The BusLogic Driver Probing Options are described in
4088 <file:Documentation/scsi/BusLogic.txt>.
4091 static int __init BusLogic_ParseDriverOptions(char *OptionsString)
4095 struct BusLogic_DriverOptions *DriverOptions =
4096 &BusLogic_DriverOptions[BusLogic_DriverOptionsCount++];
4098 memset(DriverOptions, 0, sizeof(struct BusLogic_DriverOptions));
4099 while (*OptionsString != '\0' && *OptionsString != ';')
4101 /* Probing Options. */
4102 if (BusLogic_ParseKeyword(&OptionsString, "IO:"))
4104 unsigned long IO_Address =
4105 simple_strtoul(OptionsString, &OptionsString, 0);
4106 BusLogic_ProbeOptions.LimitedProbeISA = true;
4110 BusLogic_ProbeOptions.Probe330 = true;
4113 BusLogic_ProbeOptions.Probe334 = true;
4116 BusLogic_ProbeOptions.Probe230 = true;
4119 BusLogic_ProbeOptions.Probe234 = true;
4122 BusLogic_ProbeOptions.Probe130 = true;
4125 BusLogic_ProbeOptions.Probe134 = true;
4128 BusLogic_Error("BusLogic: Invalid Driver Options "
4129 "(invalid I/O Address 0x%X)\n",
4134 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbeISA"))
4135 BusLogic_ProbeOptions.NoProbeISA = true;
4136 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbePCI"))
4137 BusLogic_ProbeOptions.NoProbePCI = true;
4138 else if (BusLogic_ParseKeyword(&OptionsString, "NoProbe"))
4139 BusLogic_ProbeOptions.NoProbe = true;
4140 else if (BusLogic_ParseKeyword(&OptionsString, "NoSortPCI"))
4141 BusLogic_ProbeOptions.NoSortPCI = true;
4142 else if (BusLogic_ParseKeyword(&OptionsString, "MultiMasterFirst"))
4143 BusLogic_ProbeOptions.MultiMasterFirst = true;
4144 else if (BusLogic_ParseKeyword(&OptionsString, "FlashPointFirst"))
4145 BusLogic_ProbeOptions.FlashPointFirst = true;
4146 /* Tagged Queuing Options. */
4147 else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:[") ||
4148 BusLogic_ParseKeyword(&OptionsString, "QD:["))
4151 TargetID < BusLogic_MaxTargetDevices;
4154 unsigned short QueueDepth =
4155 simple_strtoul(OptionsString, &OptionsString, 0);
4156 if (QueueDepth > BusLogic_MaxTaggedQueueDepth)
4158 BusLogic_Error("BusLogic: Invalid Driver Options "
4159 "(invalid Queue Depth %d)\n",
4163 DriverOptions->QueueDepth[TargetID] = QueueDepth;
4164 if (*OptionsString == ',')
4166 else if (*OptionsString == ']')
4170 BusLogic_Error("BusLogic: Invalid Driver Options "
4171 "(',' or ']' expected at '%s')\n",
4172 NULL, OptionsString);
4176 if (*OptionsString != ']')
4178 BusLogic_Error("BusLogic: Invalid Driver Options "
4179 "(']' expected at '%s')\n",
4180 NULL, OptionsString);
4183 else OptionsString++;
4185 else if (BusLogic_ParseKeyword(&OptionsString, "QueueDepth:") ||
4186 BusLogic_ParseKeyword(&OptionsString, "QD:"))
4188 unsigned short QueueDepth =
4189 simple_strtoul(OptionsString, &OptionsString, 0);
4190 if (QueueDepth == 0 || QueueDepth > BusLogic_MaxTaggedQueueDepth)
4192 BusLogic_Error("BusLogic: Invalid Driver Options "
4193 "(invalid Queue Depth %d)\n",
4197 DriverOptions->CommonQueueDepth = QueueDepth;
4199 TargetID < BusLogic_MaxTargetDevices;
4201 DriverOptions->QueueDepth[TargetID] = QueueDepth;
4203 else if (BusLogic_ParseKeyword(&OptionsString, "TaggedQueuing:") ||
4204 BusLogic_ParseKeyword(&OptionsString, "TQ:"))
4206 if (BusLogic_ParseKeyword(&OptionsString, "Default"))
4208 DriverOptions->TaggedQueuingPermitted = 0x0000;
4209 DriverOptions->TaggedQueuingPermittedMask = 0x0000;
4211 else if (BusLogic_ParseKeyword(&OptionsString, "Enable"))
4213 DriverOptions->TaggedQueuingPermitted = 0xFFFF;
4214 DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
4216 else if (BusLogic_ParseKeyword(&OptionsString, "Disable"))
4218 DriverOptions->TaggedQueuingPermitted = 0x0000;
4219 DriverOptions->TaggedQueuingPermittedMask = 0xFFFF;
4223 unsigned short TargetBit;
4224 for (TargetID = 0, TargetBit = 1;
4225 TargetID < BusLogic_MaxTargetDevices;
4226 TargetID++, TargetBit <<= 1)
4227 switch (*OptionsString++)
4230 DriverOptions->TaggedQueuingPermitted |= TargetBit;
4231 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
4234 DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
4235 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
4241 TargetID = BusLogic_MaxTargetDevices;
4246 /* Miscellaneous Options. */
4247 else if (BusLogic_ParseKeyword(&OptionsString, "BusSettleTime:") ||
4248 BusLogic_ParseKeyword(&OptionsString, "BST:"))
4250 unsigned short BusSettleTime =
4251 simple_strtoul(OptionsString, &OptionsString, 0);
4252 if (BusSettleTime > 5 * 60)
4254 BusLogic_Error("BusLogic: Invalid Driver Options "
4255 "(invalid Bus Settle Time %d)\n",
4256 NULL, BusSettleTime);
4259 DriverOptions->BusSettleTime = BusSettleTime;
4261 else if (BusLogic_ParseKeyword(&OptionsString,
4262 "InhibitTargetInquiry"))
4263 DriverOptions->LocalOptions.InhibitTargetInquiry = true;
4264 /* Debugging Options. */
4265 else if (BusLogic_ParseKeyword(&OptionsString, "TraceProbe"))
4266 BusLogic_GlobalOptions.TraceProbe = true;
4267 else if (BusLogic_ParseKeyword(&OptionsString, "TraceHardwareReset"))
4268 BusLogic_GlobalOptions.TraceHardwareReset = true;
4269 else if (BusLogic_ParseKeyword(&OptionsString, "TraceConfiguration"))
4270 BusLogic_GlobalOptions.TraceConfiguration = true;
4271 else if (BusLogic_ParseKeyword(&OptionsString, "TraceErrors"))
4272 BusLogic_GlobalOptions.TraceErrors = true;
4273 else if (BusLogic_ParseKeyword(&OptionsString, "Debug"))
4275 BusLogic_GlobalOptions.TraceProbe = true;
4276 BusLogic_GlobalOptions.TraceHardwareReset = true;
4277 BusLogic_GlobalOptions.TraceConfiguration = true;
4278 BusLogic_GlobalOptions.TraceErrors = true;
4280 if (*OptionsString == ',')
4282 else if (*OptionsString != ';' && *OptionsString != '\0')
4284 BusLogic_Error("BusLogic: Unexpected Driver Option '%s' "
4285 "ignored\n", NULL, OptionsString);
4286 *OptionsString = '\0';
4289 if (!(BusLogic_DriverOptionsCount == 0 ||
4290 BusLogic_ProbeInfoCount == 0 ||
4291 BusLogic_DriverOptionsCount == BusLogic_ProbeInfoCount))
4293 BusLogic_Error("BusLogic: Invalid Driver Options "
4294 "(all or no I/O Addresses must be specified)\n", NULL);
4298 Tagged Queuing is disabled when the Queue Depth is 1 since queuing
4299 multiple commands is not possible.
4301 for (TargetID = 0; TargetID < BusLogic_MaxTargetDevices; TargetID++)
4302 if (DriverOptions->QueueDepth[TargetID] == 1)
4304 unsigned short TargetBit = 1 << TargetID;
4305 DriverOptions->TaggedQueuingPermitted &= ~TargetBit;
4306 DriverOptions->TaggedQueuingPermittedMask |= TargetBit;
4308 if (*OptionsString == ';') OptionsString++;
4309 if (*OptionsString == '\0') return 0;
4318 static struct scsi_host_template driver_template = {
4319 .module = THIS_MODULE,
4320 .proc_name = "BusLogic",
4321 .proc_info = BusLogic_ProcDirectoryInfo,
4323 .info = BusLogic_DriverInfo,
4324 .queuecommand = BusLogic_QueueCommand,
4325 .slave_configure = BusLogic_SlaveConfigure,
4326 .bios_param = BusLogic_BIOSDiskParameters,
4327 .eh_host_reset_handler = BusLogic_host_reset,
4329 .eh_abort_handler = BusLogic_AbortCommand,
4331 .unchecked_isa_dma = 1,
4333 .use_clustering = ENABLE_CLUSTERING,
4337 BusLogic_Setup handles processing of Kernel Command Line Arguments.
4340 static int __init BusLogic_Setup(char *str)
4344 (void)get_options(str, ARRAY_SIZE(ints), ints);
4347 BusLogic_Error("BusLogic: Obsolete Command Line Entry "
4348 "Format Ignored\n", NULL);
4351 if (str == NULL || *str == '\0')
4353 return BusLogic_ParseDriverOptions(str);
4357 * Initialization function
4360 static int __init BusLogic_init(void) {
4364 BusLogic_Setup(BusLogic);
4367 return BusLogic_DetectHostAdapter(&driver_template) ? 0 : -ENODEV;
4371 * Exit function. Deletes all hosts associated with this driver.
4374 static void __exit BusLogic_exit(void)
4376 struct BusLogic_HostAdapter *HostAdapter;
4377 for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
4378 HostAdapter != NULL; HostAdapter = HostAdapter->Next) {
4379 struct Scsi_Host *host = HostAdapter->SCSI_Host;
4380 scsi_remove_host(host);
4383 for (HostAdapter = BusLogic_FirstRegisteredHostAdapter;
4384 HostAdapter != NULL; HostAdapter = HostAdapter->Next) {
4385 struct Scsi_Host *host = HostAdapter->SCSI_Host;
4386 BusLogic_ReleaseHostAdapter(host);
4390 __setup("BusLogic=", BusLogic_Setup);
4392 module_init(BusLogic_init);
4393 module_exit(BusLogic_exit);